Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "ComputeLinearFVFaceThread.h" 11 : #include "LinearSystem.h" 12 : #include "LinearFVKernel.h" 13 : #include "LinearFVFluxKernel.h" 14 : #include "FEProblemBase.h" 15 : 16 4957 : ComputeLinearFVFaceThread::ComputeLinearFVFaceThread(FEProblemBase & fe_problem, 17 : const unsigned int system_num, 18 : const Moose::FV::LinearFVComputationMode mode, 19 : const std::set<TagID> & vector_tags, 20 4957 : const std::set<TagID> & matrix_tags) 21 4957 : : _fe_problem(fe_problem), 22 4957 : _system_number(system_num), 23 4957 : _mode(mode), 24 4957 : _vector_tags(vector_tags), 25 4957 : _matrix_tags(matrix_tags), 26 4957 : _system_contrib_objects_ready(false) 27 : { 28 4957 : } 29 : 30 : // Splitting Constructor 31 0 : ComputeLinearFVFaceThread::ComputeLinearFVFaceThread(ComputeLinearFVFaceThread & x, 32 0 : Threads::split /*split*/) 33 0 : : _fe_problem(x._fe_problem), 34 0 : _system_number(x._system_number), 35 0 : _mode(x._mode), 36 0 : _vector_tags(x._vector_tags), 37 0 : _matrix_tags(x._matrix_tags), 38 0 : _system_contrib_objects_ready(x._system_contrib_objects_ready) 39 : { 40 0 : } 41 : 42 : void 43 4957 : ComputeLinearFVFaceThread::operator()(const FaceInfoRange & range) 44 : { 45 4957 : ParallelUniqueId puid; 46 4957 : _tid = puid.id; 47 : 48 4957 : _old_subdomain = Moose::INVALID_BLOCK_ID; 49 4957 : _old_neighbor_subdomain = Moose::INVALID_BLOCK_ID; 50 : 51 4957 : setupSystemContributionObjects(); 52 4957 : printGeneralExecutionInformation(); 53 : 54 : // Iterate over all the elements in the range 55 2818559 : for (const auto & face_info : range) 56 : { 57 2813602 : _subdomain = face_info->elem().subdomain_id(); 58 2813602 : _neighbor_subdomain = 59 2813602 : face_info->neighborPtr() ? face_info->neighbor().subdomain_id() : _subdomain; 60 2813602 : if (_subdomain != _old_subdomain || _neighbor_subdomain != _old_neighbor_subdomain) 61 : { 62 18731 : fetchBlockSystemContributionObjects(); 63 18731 : printBlockExecutionInformation(); 64 : } 65 : 66 2813602 : const Real face_area = face_info->faceArea() * face_info->faceCoord(); 67 : 68 : // Time to execute the kernels that contribute to the matrix and 69 : // right hand side 70 5695214 : for (auto & kernel : _fv_flux_kernels) 71 : { 72 2881612 : kernel->setupFaceData(face_info); 73 2881612 : kernel->setCurrentFaceArea(face_area); 74 2881612 : kernel->addMatrixContribution(); 75 2881612 : kernel->addRightHandSideContribution(); 76 : } 77 : } 78 4957 : } 79 : 80 : void 81 0 : ComputeLinearFVFaceThread::join(const ComputeLinearFVFaceThread & /*y*/) 82 : { 83 0 : } 84 : 85 : void 86 4957 : ComputeLinearFVFaceThread::setupSystemContributionObjects() 87 : { 88 : // The reason why we need to grab vectors and matrices separately is that 89 : // we want to grab a union instead of an intersection. 90 4957 : std::vector<LinearFVFluxKernel *> kernels_after_vectors; 91 4957 : _fe_problem.theWarehouse() 92 9914 : .query() 93 4957 : .template condition<AttribSysNum>(_system_number) 94 4957 : .template condition<AttribSystem>("LinearFVFluxKernel") 95 4957 : .template condition<AttribThread>(_tid) 96 4957 : .template condition<AttribVectorTags>(_vector_tags) 97 4957 : .queryInto(kernels_after_vectors); 98 : 99 4957 : std::vector<LinearFVFluxKernel *> kernels_after_matrices; 100 4957 : _fe_problem.theWarehouse() 101 9914 : .query() 102 4957 : .template condition<AttribSysNum>(_system_number) 103 4957 : .template condition<AttribSystem>("LinearFVFluxKernel") 104 4957 : .template condition<AttribThread>(_tid) 105 4957 : .template condition<AttribMatrixTags>(_matrix_tags) 106 4957 : .queryInto(kernels_after_matrices); 107 : 108 : // We fetch the union of the available objects 109 4957 : std::vector<LinearFVFluxKernel *> kernels; 110 4957 : MooseUtils::getUnion(kernels_after_vectors, kernels_after_matrices, kernels); 111 : 112 : // As a last step, we make sure the kernels know which vectors/matrices they need to contribute to 113 10477 : for (auto & kernel : kernels) 114 5520 : kernel->linkTaggedVectorsAndMatrices(_vector_tags, _matrix_tags); 115 : 116 4957 : _system_contrib_objects_ready = true; 117 4957 : } 118 : 119 : void 120 18731 : ComputeLinearFVFaceThread::fetchBlockSystemContributionObjects() 121 : { 122 : mooseAssert(_system_contrib_objects_ready, 123 : "The system contribution objects need to be set up before we fetch the " 124 : "block-restricted objects!"); 125 : 126 18731 : _fv_flux_kernels.clear(); 127 : 128 18731 : if (_subdomain != _old_subdomain) 129 : { 130 : // We just filter based on subdomain ID on top of everything else 131 5401 : std::vector<LinearFVFluxKernel *> kernels_after_vector; 132 5401 : _fe_problem.theWarehouse() 133 10802 : .query() 134 5401 : .template condition<AttribSysNum>(_system_number) 135 5401 : .template condition<AttribSystem>("LinearFVFluxKernel") 136 5401 : .template condition<AttribThread>(_tid) 137 5401 : .template condition<AttribVectorTags>(_vector_tags) 138 5401 : .template condition<AttribSubdomains>(_subdomain) 139 5401 : .queryInto(kernels_after_vector); 140 5401 : std::vector<LinearFVFluxKernel *> kernels_after_matrix; 141 5401 : _fe_problem.theWarehouse() 142 10802 : .query() 143 5401 : .template condition<AttribSysNum>(_system_number) 144 5401 : .template condition<AttribSystem>("LinearFVFluxKernel") 145 5401 : .template condition<AttribThread>(_tid) 146 5401 : .template condition<AttribMatrixTags>(_matrix_tags) 147 5401 : .template condition<AttribSubdomains>(_subdomain) 148 5401 : .queryInto(kernels_after_matrix); 149 : 150 : // We populate the list of kernels with the union of the two vectors 151 5401 : MooseUtils::getUnion(kernels_after_vector, kernels_after_matrix, _fv_flux_kernels_elem); 152 5401 : _old_subdomain = _subdomain; 153 5401 : } 154 18731 : _fv_flux_kernels.insert(_fv_flux_kernels_elem.begin(), _fv_flux_kernels_elem.end()); 155 : 156 18731 : if (_neighbor_subdomain != _old_neighbor_subdomain) 157 : { 158 : // Here we just filter based on subdomain ID on top of everything else 159 18567 : std::vector<LinearFVFluxKernel *> kernels_after_vector; 160 18567 : _fe_problem.theWarehouse() 161 37134 : .query() 162 18567 : .template condition<AttribSysNum>(_system_number) 163 18567 : .template condition<AttribSystem>("LinearFVFluxKernel") 164 18567 : .template condition<AttribThread>(_tid) 165 18567 : .template condition<AttribVectorTags>(_vector_tags) 166 18567 : .template condition<AttribSubdomains>(_neighbor_subdomain) 167 18567 : .queryInto(kernels_after_vector); 168 18567 : std::vector<LinearFVFluxKernel *> kernels_after_matrix; 169 18567 : _fe_problem.theWarehouse() 170 37134 : .query() 171 18567 : .template condition<AttribSysNum>(_system_number) 172 18567 : .template condition<AttribSystem>("LinearFVFluxKernel") 173 18567 : .template condition<AttribThread>(_tid) 174 18567 : .template condition<AttribMatrixTags>(_matrix_tags) 175 18567 : .template condition<AttribSubdomains>(_neighbor_subdomain) 176 18567 : .queryInto(kernels_after_matrix); 177 : 178 : // We populate the list of kernels with the union of the two vectors 179 18567 : MooseUtils::getUnion(kernels_after_vector, kernels_after_matrix, _fv_flux_kernels_neighbor); 180 18567 : _old_neighbor_subdomain = _neighbor_subdomain; 181 18567 : } 182 18731 : _fv_flux_kernels.insert(_fv_flux_kernels_neighbor.begin(), _fv_flux_kernels_neighbor.end()); 183 18731 : } 184 : 185 : void 186 4957 : ComputeLinearFVFaceThread::printGeneralExecutionInformation() const 187 : { 188 4957 : if (!_fe_problem.shouldPrintExecution(_tid)) 189 4943 : return; 190 14 : auto & console = _fe_problem.console(); 191 14 : auto execute_on = _fe_problem.getCurrentExecuteOnFlag(); 192 14 : console << "[DBG] Beginning linear finite volume flux objects loop on " << execute_on 193 14 : << std::endl; 194 14 : mooseDoOnce(console << "[DBG] Loop on faces (FaceInfo), objects ordered on each face: " 195 : << std::endl; 196 : console << "[DBG] - linear finite volume flux kernels" << std::endl); 197 14 : } 198 : 199 : void 200 18731 : ComputeLinearFVFaceThread::printBlockExecutionInformation() const 201 : { 202 18731 : if (!_fe_problem.shouldPrintExecution(_tid) || _fv_flux_kernels.empty()) 203 18710 : return; 204 : 205 : // Print the location of the execution 206 21 : auto & console = _fe_problem.console(); 207 21 : console << "[DBG] Linear flux kernels on block " 208 21 : << _fe_problem.mesh().getSubdomainName(_subdomain); 209 21 : if (_neighbor_subdomain != Moose::INVALID_BLOCK_ID) 210 21 : console << " and neighbor " << _fe_problem.mesh().getSubdomainName(_neighbor_subdomain) 211 21 : << std::endl; 212 : else 213 0 : console << " with no neighbor block" << std::endl; 214 : 215 : // Print the list of objects 216 21 : std::vector<MooseObject *> kernels_to_print; 217 49 : for (const auto & kernel : _fv_flux_kernels) 218 28 : kernels_to_print.push_back(dynamic_cast<MooseObject *>(kernel)); 219 42 : console << ConsoleUtils::formatString(ConsoleUtils::mooseObjectVectorToString(kernels_to_print), 220 21 : "[DBG]") 221 21 : << std::endl; 222 21 : }