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 "ComputeDiracThread.h" 11 : 12 : // Moose Includes 13 : #include "ParallelUniqueId.h" 14 : #include "DiracKernel.h" 15 : #include "Problem.h" 16 : #include "NonlinearSystem.h" 17 : #include "MooseVariableFE.h" 18 : #include "Assembly.h" 19 : #include "ThreadedElementLoop.h" 20 : 21 : #include "libmesh/threads.h" 22 : 23 35838 : ComputeDiracThread::ComputeDiracThread(FEProblemBase & feproblem, 24 : const std::set<TagID> & tags, 25 35838 : bool is_jacobian) 26 : : ThreadedElementLoop<DistElemRange>(feproblem), 27 35838 : _is_jacobian(is_jacobian), 28 71676 : _nl(feproblem.currentNonlinearSystem()), 29 35838 : _tags(tags), 30 35838 : _dirac_kernels(_nl.getDiracKernelWarehouse()) 31 : { 32 35838 : } 33 : 34 : // Splitting Constructor 35 0 : ComputeDiracThread::ComputeDiracThread(ComputeDiracThread & x, Threads::split split) 36 : : ThreadedElementLoop<DistElemRange>(x, split), 37 0 : _is_jacobian(x._is_jacobian), 38 0 : _nl(x._nl), 39 0 : _tags(x._tags), 40 0 : _dirac_kernels(x._dirac_kernels) 41 : { 42 0 : } 43 : 44 35838 : ComputeDiracThread::~ComputeDiracThread() {} 45 : 46 : void 47 35838 : ComputeDiracThread::pre() 48 : { 49 : // Force TID=0 because we run this object _NON THREADED_ 50 : // Take this out if we ever get Dirac's working with threads! 51 35838 : _tid = 0; 52 35838 : } 53 : 54 : void 55 30521 : ComputeDiracThread::subdomainChanged() 56 : { 57 30521 : _fe_problem.subdomainSetup(_subdomain, _tid); 58 : 59 30521 : std::set<MooseVariableFEBase *> needed_moose_vars; 60 30521 : _dirac_kernels.updateVariableDependency(needed_moose_vars, _tid); 61 : 62 : // Update material dependencies 63 30521 : std::unordered_set<unsigned int> needed_mat_props; 64 30521 : _dirac_kernels.updateMatPropDependency(needed_mat_props, _tid); 65 : 66 30521 : _fe_problem.setActiveElementalMooseVariables(needed_moose_vars, _tid); 67 30521 : _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid); 68 : 69 : // If users pass a empty vector or a full size of vector, 70 : // we take all kernels 71 30521 : if (!_tags.size() || _tags.size() == _fe_problem.numMatrixTags()) 72 20603 : _dirac_warehouse = &_dirac_kernels; 73 : // If we have one tag only, We call tag based storage 74 9918 : else if (_tags.size() == 1) 75 0 : _dirac_warehouse = _is_jacobian 76 0 : ? &(_dirac_kernels.getMatrixTagObjectWarehouse(*(_tags.begin()), _tid)) 77 0 : : &(_dirac_kernels.getVectorTagObjectWarehouse(*(_tags.begin()), _tid)); 78 : // This one may be expensive, and hopefully we do not use it so often 79 : else 80 19756 : _dirac_warehouse = _is_jacobian ? &(_dirac_kernels.getMatrixTagsObjectWarehouse(_tags, _tid)) 81 9838 : : &(_dirac_kernels.getVectorTagsObjectWarehouse(_tags, _tid)); 82 30521 : } 83 : 84 : void 85 303320 : ComputeDiracThread::onElement(const Elem * elem) 86 : { 87 303320 : const bool has_dirac_kernels_on_elem = _fe_problem.reinitDirac(elem, _tid); 88 303320 : if (!has_dirac_kernels_on_elem) 89 0 : return; 90 : 91 303320 : std::set<MooseVariableFEBase *> needed_moose_vars; 92 303320 : const auto & dkernels = _dirac_warehouse->getActiveObjects(_tid); 93 : 94 : // Only call reinitMaterials() if one or more DiracKernels has 95 : // actually called getMaterialProperty(). Loop over all the 96 : // DiracKernels and check whether this is the case. 97 617839 : for (const auto & dirac_kernel : dkernels) 98 : { 99 : // If any of the DiracKernels have had getMaterialProperty() 100 : // called, we need to reinit Materials. 101 321218 : if (dirac_kernel->getMaterialPropertyCalled()) 102 : { 103 6699 : _fe_problem.reinitMaterials(_subdomain, _tid, /*swap_stateful=*/false); 104 6699 : break; 105 : } 106 : } 107 : 108 625374 : for (const auto & dirac_kernel : dkernels) 109 : { 110 322054 : if (!dirac_kernel->hasPointsOnElem(elem)) 111 15100 : continue; 112 306954 : else if (!_is_jacobian) 113 : { 114 269579 : dirac_kernel->computeResidual(); 115 269579 : continue; 116 : } 117 : 118 : // Get a list of coupled variables from the SubProblem 119 : const auto & coupling_entries = 120 37375 : dirac_kernel->subProblem().assembly(_tid, _nl.number()).couplingEntries(); 121 : 122 : // Loop over the list of coupled variable pairs 123 110359 : for (const auto & it : coupling_entries) 124 : { 125 72984 : const MooseVariableFEBase * const ivariable = it.first; 126 72984 : const MooseVariableFEBase * const jvariable = it.second; 127 : 128 : // A variant of the check that is in 129 : // ComputeFullJacobianThread::computeJacobian(). We 130 : // only want to call computeOffDiagJacobian() if both 131 : // variables are active on this subdomain, and the 132 : // off-diagonal variable actually has dofs. 133 72984 : if (dirac_kernel->variable().number() == ivariable->number() && 134 110519 : ivariable->activeOnSubdomain(_subdomain) && jvariable->activeOnSubdomain(_subdomain) && 135 37535 : (jvariable->numberOfDofs() > 0)) 136 : { 137 37535 : dirac_kernel->prepareShapes(jvariable->number()); 138 37535 : dirac_kernel->computeOffDiagJacobian(jvariable->number()); 139 : } 140 : } 141 : } 142 : 143 : // Note that we do not call swapBackMaterials() here as they were 144 : // never swapped in the first place. This avoids messing up 145 : // stored values of stateful material properties. 146 303320 : } 147 : 148 : void 149 303320 : ComputeDiracThread::postElement(const Elem * /*elem*/) 150 : { 151 303320 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx); 152 303320 : if (!_is_jacobian) 153 266124 : _fe_problem.addResidual(_tid); 154 : else 155 37196 : _fe_problem.addJacobian(_tid); 156 303320 : } 157 : 158 : void 159 35838 : ComputeDiracThread::post() 160 : { 161 35838 : _fe_problem.clearActiveElementalMooseVariables(_tid); 162 35838 : _fe_problem.clearActiveMaterialProperties(_tid); 163 35838 : } 164 : 165 : void 166 0 : ComputeDiracThread::join(const ComputeDiracThread & /*y*/) 167 : { 168 0 : } 169 : 170 : void 171 35838 : ComputeDiracThread::printGeneralExecutionInformation() const 172 : { 173 35838 : if (!_fe_problem.shouldPrintExecution(_tid)) 174 31630 : return; 175 4208 : const auto & console = _fe_problem.console(); 176 4208 : console << "[DBG] Executing Dirac Kernels on " << _fe_problem.getCurrentExecuteOnFlag().name() 177 4208 : << std::endl; 178 : } 179 : 180 : void 181 30521 : ComputeDiracThread::printBlockExecutionInformation() const 182 : { 183 36953 : if (!_fe_problem.shouldPrintExecution(_tid) || _blocks_exec_printed.count(_subdomain) || 184 6432 : !_dirac_warehouse->hasActiveBlockObjects(_subdomain, _tid)) 185 24089 : return; 186 : 187 6432 : const auto & dkernels = _dirac_warehouse->getActiveBlockObjects(_subdomain, _tid); 188 6432 : const auto & console = _fe_problem.console(); 189 6432 : console << "[DBG] Ordering of DiracKernels on subdomain " << _subdomain << std::endl; 190 6432 : printExecutionOrdering<DiracKernelBase>(dkernels, false); 191 6432 : _blocks_exec_printed.insert(_subdomain); 192 : }