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 3653 : ComputeNodalKernelJacobiansThread::ComputeNodalKernelJacobiansThread( 24 : FEProblemBase & fe_problem, 25 : NonlinearSystemBase & nl, 26 : MooseObjectTagWarehouse<NodalKernelBase> & nodal_kernels, 27 3653 : const std::set<TagID> & tags) 28 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(fe_problem), 29 3653 : _fe_problem(fe_problem), 30 3653 : _nl(nl), 31 7306 : _aux_sys(fe_problem.getAuxiliarySystem()), 32 3653 : _tags(tags), 33 3653 : _nodal_kernels(nodal_kernels), 34 3653 : _num_cached(0) 35 : { 36 3653 : } 37 : 38 : // Splitting Constructor 39 1182 : ComputeNodalKernelJacobiansThread::ComputeNodalKernelJacobiansThread( 40 1182 : ComputeNodalKernelJacobiansThread & x, Threads::split split) 41 : : ThreadedNodeLoop<ConstNodeRange, ConstNodeRange::const_iterator>(x, split), 42 1182 : _fe_problem(x._fe_problem), 43 1182 : _nl(x._nl), 44 1182 : _aux_sys(x._aux_sys), 45 1182 : _tags(x._tags), 46 1182 : _nodal_kernels(x._nodal_kernels), 47 1182 : _num_cached(0) 48 : { 49 1182 : } 50 : 51 : void 52 4835 : ComputeNodalKernelJacobiansThread::pre() 53 : { 54 4835 : _num_cached = 0; 55 : 56 4835 : if (!_tags.size() || _tags.size() == _fe_problem.numMatrixTags()) 57 4595 : _nkernel_warehouse = &_nodal_kernels; 58 240 : else if (_tags.size() == 1) 59 0 : _nkernel_warehouse = &(_nodal_kernels.getMatrixTagObjectWarehouse(*(_tags.begin()), _tid)); 60 : else 61 240 : _nkernel_warehouse = &(_nodal_kernels.getMatrixTagsObjectWarehouse(_tags, _tid)); 62 4835 : } 63 : 64 : void 65 279402 : ComputeNodalKernelJacobiansThread::onNode(ConstNodeRange::const_iterator & node_it) 66 : { 67 279402 : const Node * node = *node_it; 68 : 69 279402 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 70 1333305 : for (const auto & it : ce) 71 : { 72 1053903 : MooseVariableFEBase & ivariable = *(it.first); 73 1053903 : MooseVariableFEBase & jvariable = *(it.second); 74 : 75 1053903 : unsigned int ivar = ivariable.number(); 76 1053903 : unsigned int jvar = jvariable.number(); 77 : 78 : // The NodalKernels that are active and are coupled to the jvar in question 79 1053903 : std::vector<std::shared_ptr<NodalKernelBase>> active_involved_kernels; 80 : 81 1053903 : const auto & block_ids = _aux_sys.mesh().getNodeBlockIds(*node); 82 2110531 : for (const auto & block : block_ids) 83 : { 84 1056628 : if (_nkernel_warehouse->hasActiveBlockObjects(block, _tid)) 85 : { 86 : // Loop over each NodalKernel to see if it's involved with the jvar 87 1041098 : const auto & objects = _nkernel_warehouse->getActiveBlockObjects(block, _tid); 88 3863407 : for (const auto & nodal_kernel : objects) 89 : { 90 2822309 : 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 1159761 : if (nodal_kernel->variable().number() == jvar) 95 : { 96 627771 : active_involved_kernels.push_back(nodal_kernel); 97 627771 : continue; 98 : } 99 : 100 : // See if this NodalKernel is coupled to the jvar 101 : const std::vector<MooseVariableFEBase *> & coupled_vars = 102 531990 : nodal_kernel->getCoupledMooseVars(); 103 700594 : for (const auto & var : coupled_vars) 104 491576 : if (var->number() == jvar) 105 : { 106 322972 : active_involved_kernels.push_back(nodal_kernel); 107 322972 : break; // It only takes one 108 : } 109 : } 110 : } 111 : } 112 : } 113 : 114 : // Did we find any NodalKernels coupled to this jvar? 115 1053903 : if (!active_involved_kernels.empty()) 116 : { 117 : // prepare variables 118 819062 : for (auto * var : _aux_sys._nodal_vars[_tid]) 119 58248 : var->prepareAux(); 120 : 121 760814 : _fe_problem.reinitNode(node, _tid); 122 : 123 1711557 : for (const auto & nodal_kernel : active_involved_kernels) 124 : { 125 950743 : nodal_kernel->setSubdomains(block_ids); 126 950743 : nodal_kernel->computeOffDiagJacobian(jvar); 127 : } 128 : 129 760814 : _num_cached++; 130 : 131 760814 : if (_num_cached == 20) // Cache 20 nodes worth before adding into the residual 132 : { 133 36724 : _num_cached = 0; 134 : // vectors are thread-safe, but matrices are not yet 135 36724 : Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx); 136 36724 : _fe_problem.addCachedJacobian(_tid); 137 36724 : } 138 : } 139 1053903 : } 140 279402 : } 141 : 142 : void 143 1182 : ComputeNodalKernelJacobiansThread::join(const ComputeNodalKernelJacobiansThread & /*y*/) 144 : { 145 1182 : } 146 : 147 : void 148 4835 : ComputeNodalKernelJacobiansThread::printGeneralExecutionInformation() const 149 : { 150 4835 : if (!_fe_problem.shouldPrintExecution(_tid) || !_nkernel_warehouse->hasActiveObjects()) 151 4825 : return; 152 : 153 10 : const auto & console = _fe_problem.console(); 154 10 : const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag(); 155 10 : console << "[DBG] Executing nodal kernels contribution to Jacobian on nodes on " << execute_on 156 10 : << std::endl; 157 10 : console << _nkernel_warehouse->activeObjectsToFormattedString() << std::endl; 158 : }