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 "ComputeNodalKernelJacobiansThread.h" 11 : 12 : // MOOSE includes 13 : #include "Assembly.h" 14 : #include "AuxiliarySystem.h" 15 : #include "FEProblem.h" 16 : #include "MooseMesh.h" 17 : #include "MooseVariableFE.h" 18 : #include "NodalKernelBase.h" 19 : #include "NonlinearSystemBase.h" 20 : 21 : #include "libmesh/sparse_matrix.h" 22 : 23 3698 : ComputeNodalKernelJacobiansThread::ComputeNodalKernelJacobiansThread( 24 : FEProblemBase & fe_problem, 25 : NonlinearSystemBase & nl, 26 : MooseObjectTagWarehouse<NodalKernelBase> & nodal_kernels, 27 3698 : const std::set<TagID> & tags) 28 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(fe_problem), 29 3698 : _fe_problem(fe_problem), 30 3698 : _nl(nl), 31 7396 : _aux_sys(fe_problem.getAuxiliarySystem()), 32 3698 : _tags(tags), 33 3698 : _nodal_kernels(nodal_kernels), 34 3698 : _num_cached(0) 35 : { 36 3698 : } 37 : 38 : // Splitting Constructor 39 1194 : ComputeNodalKernelJacobiansThread::ComputeNodalKernelJacobiansThread( 40 1194 : ComputeNodalKernelJacobiansThread & x, Threads::split split) 41 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(x, split), 42 1194 : _fe_problem(x._fe_problem), 43 1194 : _nl(x._nl), 44 1194 : _aux_sys(x._aux_sys), 45 1194 : _tags(x._tags), 46 1194 : _nodal_kernels(x._nodal_kernels), 47 1194 : _num_cached(0) 48 : { 49 1194 : } 50 : 51 : void 52 4892 : ComputeNodalKernelJacobiansThread::pre() 53 : { 54 4892 : _num_cached = 0; 55 : 56 4892 : if (!_tags.size() || _tags.size() == _fe_problem.numMatrixTags()) 57 4650 : _nkernel_warehouse = &_nodal_kernels; 58 242 : else if (_tags.size() == 1) 59 0 : _nkernel_warehouse = &(_nodal_kernels.getMatrixTagObjectWarehouse(*(_tags.begin()), _tid)); 60 : else 61 242 : _nkernel_warehouse = &(_nodal_kernels.getMatrixTagsObjectWarehouse(_tags, _tid)); 62 4892 : } 63 : 64 : void 65 277637 : ComputeNodalKernelJacobiansThread::onNode(ConstNodeRange::const_iterator & node_it) 66 : { 67 277637 : const Node * node = *node_it; 68 : 69 277637 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 70 1323001 : for (const auto & it : ce) 71 : { 72 1045364 : MooseVariableFEBase & ivariable = *(it.first); 73 1045364 : MooseVariableFEBase & jvariable = *(it.second); 74 : 75 1045364 : unsigned int ivar = ivariable.number(); 76 1045364 : unsigned int jvar = jvariable.number(); 77 : 78 : // The NodalKernels that are active and are coupled to the jvar in question 79 1045364 : std::vector<std::shared_ptr<NodalKernelBase>> active_involved_kernels; 80 : 81 1045364 : const auto & block_ids = _aux_sys.mesh().getNodeBlockIds(*node); 82 2093618 : for (const auto & block : block_ids) 83 : { 84 1048254 : if (_nkernel_warehouse->hasActiveBlockObjects(block, _tid)) 85 : { 86 : // Loop over each NodalKernel to see if it's involved with the jvar 87 1031762 : const auto & objects = _nkernel_warehouse->getActiveBlockObjects(block, _tid); 88 3838866 : for (const auto & nodal_kernel : objects) 89 : { 90 2807104 : if (nodal_kernel->variable().number() == ivar) 91 : { 92 : // If this NodalKernel is acting on the jvar add it to the list and short-circuit the 93 : // loop 94 1150810 : if (nodal_kernel->variable().number() == jvar) 95 : { 96 623940 : active_involved_kernels.push_back(nodal_kernel); 97 623940 : continue; 98 : } 99 : 100 : // See if this NodalKernel is coupled to the jvar 101 : const std::vector<MooseVariableFEBase *> & coupled_vars = 102 526870 : nodal_kernel->getCoupledMooseVars(); 103 696378 : for (const auto & var : coupled_vars) 104 495860 : if (var->number() == jvar) 105 : { 106 326352 : active_involved_kernels.push_back(nodal_kernel); 107 326352 : break; // It only takes one 108 : } 109 : } 110 : } 111 : } 112 : } 113 : 114 : // Did we find any NodalKernels coupled to this jvar? 115 1045364 : if (!active_involved_kernels.empty()) 116 : { 117 : // prepare variables 118 823240 : for (auto * var : _aux_sys._nodal_vars[_tid]) 119 59343 : var->prepareAux(); 120 : 121 763897 : _fe_problem.reinitNode(node, _tid); 122 : 123 1714189 : for (const auto & nodal_kernel : active_involved_kernels) 124 : { 125 950292 : nodal_kernel->setSubdomains(block_ids); 126 950292 : nodal_kernel->computeOffDiagJacobian(jvar); 127 : } 128 : 129 763897 : _num_cached++; 130 : 131 763897 : if (_num_cached == 20) // Cache 20 nodes worth before adding into the residual 132 : { 133 36877 : _num_cached = 0; 134 36877 : _fe_problem.addCachedJacobian(_tid); 135 : } 136 : } 137 1045364 : } 138 277637 : } 139 : 140 : void 141 1194 : ComputeNodalKernelJacobiansThread::join(const ComputeNodalKernelJacobiansThread & /*y*/) 142 : { 143 1194 : } 144 : 145 : void 146 4892 : ComputeNodalKernelJacobiansThread::printGeneralExecutionInformation() const 147 : { 148 4892 : if (!_fe_problem.shouldPrintExecution(_tid) || !_nkernel_warehouse->hasActiveObjects()) 149 4883 : return; 150 : 151 9 : const auto & console = _fe_problem.console(); 152 9 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag(); 153 9 : console << "[DBG] Executing nodal kernels contribution to Jacobian on nodes on " << execute_on 154 9 : << std::endl; 155 27 : console << _nkernel_warehouse->activeObjectsToFormattedString() << std::endl; 156 : }