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 : // MOOSE includes 11 : #include "ComputeElemAuxBcsThread.h" 12 : #include "AuxiliarySystem.h" 13 : #include "FEProblem.h" 14 : #include "DisplacedProblem.h" 15 : #include "Assembly.h" 16 : #include "AuxKernel.h" 17 : #include "SwapBackSentinel.h" 18 : 19 : #include "libmesh/threads.h" 20 : 21 : template <typename AuxKernelType> 22 24799 : ComputeElemAuxBcsThread<AuxKernelType>::ComputeElemAuxBcsThread( 23 : FEProblemBase & fe_problem, 24 : const MooseObjectWarehouse<AuxKernelType> & storage, 25 : bool need_materials) 26 24799 : : _fe_problem(fe_problem), 27 24799 : _aux_sys(fe_problem.getAuxiliarySystem()), 28 24799 : _storage(storage), 29 24799 : _need_materials(need_materials) 30 : { 31 24799 : } 32 : 33 : // Splitting Constructor 34 : template <typename AuxKernelType> 35 2396 : ComputeElemAuxBcsThread<AuxKernelType>::ComputeElemAuxBcsThread(ComputeElemAuxBcsThread & x, 36 : Threads::split /*split*/) 37 2396 : : _fe_problem(x._fe_problem), 38 2396 : _aux_sys(x._aux_sys), 39 2396 : _storage(x._storage), 40 2396 : _need_materials(x._need_materials) 41 : { 42 2396 : } 43 : 44 : template <typename AuxKernelType> 45 : void 46 27195 : ComputeElemAuxBcsThread<AuxKernelType>::operator()(const ConstBndElemRange & range) 47 : { 48 27195 : ParallelUniqueId puid; 49 27195 : _tid = puid.id; 50 : 51 : // Reference to all boundary restricted AuxKernels for the current thread 52 27195 : const auto & boundary_kernels = _storage.getActiveBoundaryObjects(_tid); 53 : 54 27195 : printGeneralExecutionInformation(); 55 : 56 3883271 : for (const auto & belem : range) 57 : { 58 3856082 : const Elem * elem = belem->_elem; 59 3856082 : unsigned short int side = belem->_side; 60 3856082 : BoundaryID boundary_id = belem->_bnd_id; 61 3856082 : SubdomainID last_did = Elem::invalid_subdomain_id; 62 : 63 : // need to update the boundary ID in assembly 64 3856082 : _fe_problem.setCurrentBoundaryID(boundary_id, _tid); 65 : 66 3856082 : if (elem->processor_id() == _fe_problem.processor_id()) 67 : { 68 : // Locate the AuxKernel objects for the current BoundaryID 69 3001361 : const auto iter = boundary_kernels.find(boundary_id); 70 : 71 3001361 : if (iter != boundary_kernels.end() && !(iter->second.empty())) 72 : { 73 111120 : printBoundaryExecutionInformation(boundary_id, iter->second); 74 111120 : auto did = elem->subdomain_id(); 75 111120 : if (did != last_did) 76 : { 77 111120 : _fe_problem.subdomainSetup(did, _tid); 78 111120 : last_did = did; 79 : } 80 111120 : _fe_problem.setCurrentSubdomainID(elem, _tid); 81 111120 : _fe_problem.prepare(elem, _tid); 82 111120 : _fe_problem.reinitElemFace(elem, side, _tid); 83 : 84 111120 : const Elem * lower_d_elem = _fe_problem.mesh().getLowerDElem(elem, side); 85 111120 : _fe_problem.setCurrentLowerDElem(lower_d_elem, _tid); 86 111120 : if (lower_d_elem) 87 825 : _fe_problem.reinitLowerDElem(lower_d_elem, _tid); 88 : 89 111120 : const Elem * neighbor = elem->neighbor_ptr(side); 90 : 91 : // The last check here is absolutely necessary otherwise we will attempt to evaluate 92 : // neighbor materials on neighbor elements that aren't evaluable, e.g. don't have algebraic 93 : // ghosting 94 111120 : bool compute_interface = 95 112716 : neighbor && neighbor->active() && 96 1596 : _fe_problem.getInterfaceMaterialsWarehouse().hasActiveBoundaryObjects(boundary_id, 97 : _tid); 98 : 99 : // Set up Sentinel class so that, even if reinitMaterialsFace() throws, we 100 : // still remember to swap back during stack unwinding. 101 111120 : SwapBackSentinel sentinel(_fe_problem, &FEProblem::swapBackMaterialsFace, _tid); 102 111120 : SwapBackSentinel neighbor_sentinel( 103 : _fe_problem, &FEProblem::swapBackMaterialsNeighbor, _tid, compute_interface); 104 : 105 111120 : if (_need_materials) 106 : { 107 111120 : std::unordered_set<unsigned int> needed_mat_props; 108 229132 : for (const auto & aux : iter->second) 109 : { 110 118012 : const auto & mp_deps = aux->getMatPropDependencies(); 111 118012 : needed_mat_props.insert(mp_deps.begin(), mp_deps.end()); 112 : } 113 111120 : _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid); 114 : 115 111120 : _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid); 116 : 117 111120 : _fe_problem.reinitMaterialsBoundary(boundary_id, _tid); 118 : 119 111120 : if (compute_interface) 120 : { 121 380 : _fe_problem.reinitNeighbor(elem, side, _tid); 122 380 : _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid); 123 380 : _fe_problem.reinitMaterialsInterface(boundary_id, _tid); 124 : } 125 111120 : } 126 : 127 229120 : for (const auto & aux : iter->second) 128 : { 129 118006 : aux->compute(); 130 118000 : aux->insert(); 131 : } 132 : 133 111114 : if (_need_materials) 134 111114 : _fe_problem.clearActiveMaterialProperties(_tid); 135 111114 : } 136 : } 137 : } 138 27189 : } 139 : 140 : template <typename AuxKernelType> 141 : void 142 2396 : ComputeElemAuxBcsThread<AuxKernelType>::join(const ComputeElemAuxBcsThread & /*y*/) 143 : { 144 2396 : } 145 : 146 : template <typename AuxKernelType> 147 : void 148 27195 : ComputeElemAuxBcsThread<AuxKernelType>::printGeneralExecutionInformation() const 149 : { 150 27195 : if (_fe_problem.shouldPrintExecution(_tid) && _storage.hasActiveObjects()) 151 : { 152 456 : const auto & console = _fe_problem.console(); 153 456 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag(); 154 456 : console << "[DBG] Executing boundary restricted auxkernels on boundary elements on " 155 456 : << execute_on << std::endl; 156 : } 157 27195 : } 158 : 159 : template <typename AuxKernelType> 160 : void 161 111120 : ComputeElemAuxBcsThread<AuxKernelType>::printBoundaryExecutionInformation( 162 : unsigned int boundary_id, const std::vector<std::shared_ptr<AuxKernelType>> & kernels) const 163 : { 164 116760 : if (!_fe_problem.shouldPrintExecution(_tid) || !_storage.hasActiveObjects() || 165 116760 : _boundaries_exec_printed.count(boundary_id)) 166 110244 : return; 167 : 168 876 : const auto & console = _fe_problem.console(); 169 876 : console << "[DBG] Ordering on boundary " << boundary_id << std::endl; 170 876 : std::vector<MooseObject *> objs_ptrs; 171 1752 : for (auto & kernel_ptr : kernels) 172 876 : if (kernel_ptr->hasBoundary(boundary_id)) 173 876 : objs_ptrs.push_back(dynamic_cast<MooseObject *>(kernel_ptr.get())); 174 876 : std::string list_kernels = ConsoleUtils::mooseObjectVectorToString(objs_ptrs); 175 876 : console << ConsoleUtils::formatString(list_kernels, "[DBG]") << std::endl; 176 876 : _boundaries_exec_printed.insert(boundary_id); 177 876 : } 178 : 179 : template class ComputeElemAuxBcsThread<AuxKernel>; 180 : template class ComputeElemAuxBcsThread<VectorAuxKernel>; 181 : template class ComputeElemAuxBcsThread<ArrayAuxKernel>;