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 35506 : ComputeDiracThread::ComputeDiracThread(FEProblemBase & feproblem, 24 : const std::set<TagID> & tags, 25 35506 : bool is_jacobian) 26 : : ThreadedElementLoop<DistElemRange>(feproblem), 27 35506 : _is_jacobian(is_jacobian), 28 71012 : _nl(feproblem.currentNonlinearSystem()), 29 35506 : _tags(tags), 30 35506 : _dirac_kernels(_nl.getDiracKernelWarehouse()) 31 : { 32 35506 : } 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 35506 : ComputeDiracThread::~ComputeDiracThread() {} 45 : 46 : void 47 35506 : 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 35506 : _tid = 0; 52 35506 : } 53 : 54 : void 55 29276 : ComputeDiracThread::subdomainChanged() 56 : { 57 29276 : _fe_problem.subdomainSetup(_subdomain, _tid); 58 : 59 29276 : std::set<MooseVariableFEBase *> needed_moose_vars; 60 29276 : _dirac_kernels.updateVariableDependency(needed_moose_vars, _tid); 61 : 62 : // Update material dependencies 63 29276 : std::unordered_set<unsigned int> needed_mat_props; 64 29276 : _dirac_kernels.updateMatPropDependency(needed_mat_props, _tid); 65 : 66 29276 : _fe_problem.setActiveElementalMooseVariables(needed_moose_vars, _tid); 67 29276 : _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 29276 : if (!_tags.size() || _tags.size() == _fe_problem.numMatrixTags()) 72 19098 : _dirac_warehouse = &_dirac_kernels; 73 : // If we have one tag only, We call tag based storage 74 10178 : 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 20274 : _dirac_warehouse = _is_jacobian ? &(_dirac_kernels.getMatrixTagsObjectWarehouse(_tags, _tid)) 81 10096 : : &(_dirac_kernels.getVectorTagsObjectWarehouse(_tags, _tid)); 82 29276 : } 83 : 84 : void 85 304016 : ComputeDiracThread::onElement(const Elem * elem) 86 : { 87 304016 : const bool has_dirac_kernels_on_elem = _fe_problem.reinitDirac(elem, _tid); 88 304016 : if (!has_dirac_kernels_on_elem) 89 0 : return; 90 : 91 304016 : std::set<MooseVariableFEBase *> needed_moose_vars; 92 304016 : 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 616392 : for (const auto & dirac_kernel : dkernels) 98 : { 99 : // If any of the DiracKernels have had getMaterialProperty() 100 : // called, we need to reinit Materials. 101 318918 : if (dirac_kernel->getMaterialPropertyCalled()) 102 : { 103 6542 : _fe_problem.reinitMaterials(_subdomain, _tid, /*swap_stateful=*/false); 104 6542 : break; 105 : } 106 : } 107 : 108 623866 : for (const auto & dirac_kernel : dkernels) 109 : { 110 319850 : if (!dirac_kernel->hasPointsOnElem(elem)) 111 12847 : continue; 112 307003 : else if (!_is_jacobian) 113 : { 114 269426 : dirac_kernel->computeResidual(); 115 269426 : continue; 116 : } 117 : 118 : // Get a list of coupled variables from the SubProblem 119 : const auto & coupling_entries = 120 37577 : dirac_kernel->subProblem().assembly(_tid, _nl.number()).couplingEntries(); 121 : 122 : // Loop over the list of coupled variable pairs 123 111049 : for (const auto & it : coupling_entries) 124 : { 125 73472 : const MooseVariableFEBase * const ivariable = it.first; 126 73472 : 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 73472 : if (dirac_kernel->variable().number() == ivariable->number() && 134 111256 : ivariable->activeOnSubdomain(_subdomain) && jvariable->activeOnSubdomain(_subdomain) && 135 37784 : (jvariable->numberOfDofs() > 0)) 136 : { 137 37784 : dirac_kernel->prepareShapes(jvariable->number()); 138 37784 : 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 304016 : } 147 : 148 : void 149 304016 : ComputeDiracThread::postElement(const Elem * /*elem*/) 150 : { 151 304016 : if (!_is_jacobian) 152 266601 : _fe_problem.addResidual(_tid); 153 : else 154 37415 : _fe_problem.addJacobian(_tid); 155 304016 : } 156 : 157 : void 158 35506 : ComputeDiracThread::post() 159 : { 160 35506 : _fe_problem.clearActiveElementalMooseVariables(_tid); 161 35506 : _fe_problem.clearActiveMaterialProperties(_tid); 162 35506 : } 163 : 164 : void 165 0 : ComputeDiracThread::join(const ComputeDiracThread & /*y*/) 166 : { 167 0 : } 168 : 169 : void 170 35506 : ComputeDiracThread::printGeneralExecutionInformation() const 171 : { 172 35506 : if (!_fe_problem.shouldPrintExecution(_tid)) 173 32071 : return; 174 3435 : const auto & console = _fe_problem.console(); 175 3435 : console << "[DBG] Executing Dirac Kernels on " << _fe_problem.getCurrentExecuteOnFlag().name() 176 3435 : << std::endl; 177 : } 178 : 179 : void 180 29276 : ComputeDiracThread::printBlockExecutionInformation() const 181 : { 182 34174 : if (!_fe_problem.shouldPrintExecution(_tid) || _blocks_exec_printed.count(_subdomain) || 183 4898 : !_dirac_warehouse->hasActiveBlockObjects(_subdomain, _tid)) 184 24378 : return; 185 : 186 4898 : const auto & dkernels = _dirac_warehouse->getActiveBlockObjects(_subdomain, _tid); 187 4898 : const auto & console = _fe_problem.console(); 188 4898 : console << "[DBG] Ordering of DiracKernels on subdomain " << _subdomain << std::endl; 189 9796 : printExecutionOrdering<DiracKernelBase>(dkernels, false); 190 4898 : _blocks_exec_printed.insert(_subdomain); 191 : }