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 "ComputeFullJacobianThread.h" 11 : #include "NonlinearSystem.h" 12 : #include "FEProblem.h" 13 : #include "KernelBase.h" 14 : #include "IntegratedBCBase.h" 15 : #include "HDGKernel.h" 16 : #include "DGKernel.h" 17 : #include "InterfaceKernelBase.h" 18 : #include "MooseVariableFE.h" 19 : #include "MooseVariableScalar.h" 20 : #include "NonlocalKernel.h" 21 : #include "NonlocalIntegratedBC.h" 22 : #include "FVElementalKernel.h" 23 : #include "libmesh/threads.h" 24 : 25 77770 : ComputeFullJacobianThread::ComputeFullJacobianThread(FEProblemBase & fe_problem, 26 77770 : const std::set<TagID> & tags) 27 77770 : : ComputeJacobianThread(fe_problem, tags) 28 : { 29 77770 : } 30 : 31 : // Splitting Constructor 32 7267 : ComputeFullJacobianThread::ComputeFullJacobianThread(ComputeFullJacobianThread & x, 33 7267 : Threads::split split) 34 7267 : : ComputeJacobianThread(x, split) 35 : { 36 7267 : } 37 : 38 92180 : ComputeFullJacobianThread::~ComputeFullJacobianThread() {} 39 : 40 : void 41 14201338 : ComputeFullJacobianThread::computeOnElement() 42 : { 43 14201338 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 44 44314643 : for (const auto & it : ce) 45 : { 46 30113305 : MooseVariableFieldBase & ivariable = *(it.first); 47 30113305 : MooseVariableFieldBase & jvariable = *(it.second); 48 : 49 30113305 : if (ivariable.isFV()) 50 2995296 : continue; 51 : 52 27118009 : unsigned int ivar = ivariable.number(); 53 27118009 : unsigned int jvar = jvariable.number(); 54 : 55 53023765 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 56 25905756 : _tag_kernels->hasActiveVariableBlockObjects(ivar, _subdomain, _tid)) 57 : { 58 : // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be 59 : // any) 60 24778274 : const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid); 61 75193816 : for (const auto & kernel : kernels) 62 50415542 : if ((kernel->variable().number() == ivar) && kernel->isImplicit()) 63 : { 64 50372288 : kernel->prepareShapes(jvar); 65 50372288 : kernel->computeOffDiagJacobian(jvar); 66 : } 67 : } 68 : } 69 : 70 : /// done only when nonlocal kernels exist in the system 71 14201338 : if (_fe_problem.checkNonlocalCouplingRequirement()) 72 : { 73 3792 : auto & cne = _fe_problem.nonlocalCouplingEntries(_tid, _nl.number()); 74 7676 : for (const auto & it : cne) 75 : { 76 3884 : MooseVariableFieldBase & ivariable = *(it.first); 77 3884 : MooseVariableFieldBase & jvariable = *(it.second); 78 : 79 3884 : if (ivariable.isFV()) 80 0 : continue; 81 : 82 3884 : unsigned int ivar = ivariable.number(); 83 3884 : unsigned int jvar = jvariable.number(); 84 : 85 7768 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 86 3884 : _tag_kernels->hasActiveVariableBlockObjects(ivar, _subdomain, _tid)) 87 : { 88 3864 : const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid); 89 8216 : for (const auto & kernel : kernels) 90 : { 91 : std::shared_ptr<NonlocalKernel> nonlocal_kernel = 92 4352 : std::dynamic_pointer_cast<NonlocalKernel>(kernel); 93 4352 : if (nonlocal_kernel) 94 264 : if ((kernel->variable().number() == ivar) && kernel->isImplicit()) 95 : { 96 264 : kernel->prepareShapes(jvar); 97 264 : kernel->computeNonlocalOffDiagJacobian(jvar); 98 : } 99 4352 : } 100 : } 101 : } 102 : } 103 : 104 14201338 : const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid); 105 14201338 : if (scalar_vars.size() > 0) 106 : { 107 : // go over nl-variables (non-scalar) 108 142814 : const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid); 109 383196 : for (const auto & ivariable : vars) 110 473552 : if (ivariable->activeOnSubdomain(_subdomain) > 0 && 111 233170 : _tag_kernels->hasActiveVariableBlockObjects(ivariable->number(), _subdomain, _tid)) 112 : { 113 : // for each variable get the list of active kernels 114 : const auto & kernels = 115 226831 : _tag_kernels->getActiveVariableBlockObjects(ivariable->number(), _subdomain, _tid); 116 763689 : for (const auto & kernel : kernels) 117 536858 : if (kernel->isImplicit()) 118 : { 119 : // now, get the list of coupled scalar vars and compute their off-diag jacobians 120 536858 : const auto & coupled_scalar_vars = kernel->getCoupledMooseScalarVars(); 121 : 122 : // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones) 123 626994 : for (const auto & jvariable : coupled_scalar_vars) 124 90136 : if (_nl.hasScalarVariable(jvariable->name())) 125 90136 : kernel->computeOffDiagJacobianScalar(jvariable->number()); 126 : } 127 : } 128 : } 129 : 130 14201338 : if (_fe_problem.haveFV()) 131 5036790 : for (auto fv_kernel : _fv_kernels) 132 2491683 : if (fv_kernel->isImplicit()) 133 2491683 : fv_kernel->computeOffDiagJacobian(); 134 14201338 : } 135 : 136 : void 137 188968 : ComputeFullJacobianThread::computeOnBoundary(BoundaryID bnd_id, const Elem * lower_d_elem) 138 : { 139 188968 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 140 733473 : for (const auto & it : ce) 141 : { 142 544505 : MooseVariableFieldBase & ivariable = *(it.first); 143 544505 : MooseVariableFieldBase & jvariable = *(it.second); 144 : 145 : // We don't currently support coupling with FV variables 146 544505 : if (ivariable.isFV() || jvariable.isFV()) 147 2568 : continue; 148 : 149 541937 : const auto ivar = ivariable.number(); 150 541937 : const auto jvar = jvariable.number(); 151 : 152 541937 : if (!ivariable.activeOnSubdomain(_subdomain)) 153 77184 : continue; 154 : 155 : // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be 156 : // any) 157 464753 : if (lower_d_elem) 158 : { 159 11896 : auto lower_d_subdomain = lower_d_elem->subdomain_id(); 160 19528 : if (!jvariable.activeOnSubdomain(_subdomain) && 161 7632 : !jvariable.activeOnSubdomain(lower_d_subdomain)) 162 3584 : continue; 163 : } 164 : else 165 : { 166 452857 : if (!jvariable.activeOnSubdomain(_subdomain)) 167 25584 : continue; 168 : } 169 : 170 435585 : if (!_ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 171 0 : continue; 172 : 173 435585 : const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 174 900729 : for (const auto & bc : bcs) 175 465144 : if (bc->shouldApply() && bc->variable().number() == ivar && bc->isImplicit()) 176 : { 177 281950 : bc->prepareShapes(jvar); 178 281950 : bc->computeOffDiagJacobian(jvar); 179 : } 180 : } 181 : 182 : /// done only when nonlocal integrated_bcs exist in the system 183 188968 : if (_fe_problem.checkNonlocalCouplingRequirement()) 184 : { 185 370 : auto & cne = _fe_problem.nonlocalCouplingEntries(_tid, _nl.number()); 186 740 : for (const auto & it : cne) 187 : { 188 370 : MooseVariableFieldBase & ivariable = *(it.first); 189 370 : MooseVariableFieldBase & jvariable = *(it.second); 190 : 191 370 : if (ivariable.isFV()) 192 0 : continue; 193 : 194 370 : unsigned int ivar = ivariable.number(); 195 370 : unsigned int jvar = jvariable.number(); 196 : 197 740 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 198 370 : _ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 199 : { 200 : const std::vector<std::shared_ptr<IntegratedBCBase>> & integrated_bcs = 201 370 : _ibc_warehouse->getBoundaryObjects(bnd_id, _tid); 202 740 : for (const auto & integrated_bc : integrated_bcs) 203 : { 204 : std::shared_ptr<NonlocalIntegratedBC> nonlocal_integrated_bc = 205 370 : std::dynamic_pointer_cast<NonlocalIntegratedBC>(integrated_bc); 206 370 : if (nonlocal_integrated_bc) 207 370 : if ((integrated_bc->variable().number() == ivar) && integrated_bc->isImplicit()) 208 : { 209 370 : integrated_bc->prepareShapes(jvar); 210 370 : integrated_bc->computeNonlocalOffDiagJacobian(jvar); 211 : } 212 370 : } 213 : } 214 : } 215 : } 216 : 217 188968 : const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid); 218 188968 : if (scalar_vars.size() > 0) 219 : { 220 : // go over nl-variables (non-scalar) 221 19262 : const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid); 222 57340 : for (const auto & ivar : vars) 223 76156 : if (ivar->activeOnSubdomain(_subdomain) > 0 && 224 38078 : _ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 225 : { 226 : // for each variable get the list of active kernels 227 38078 : const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 228 76156 : for (const auto & bc : bcs) 229 38078 : if (bc->variable().number() == ivar->number() && bc->isImplicit()) 230 : { 231 : // now, get the list of coupled scalar vars and compute their off-diag jacobians 232 : const std::vector<MooseVariableScalar *> coupled_scalar_vars = 233 19262 : bc->getCoupledMooseScalarVars(); 234 : 235 : // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones) 236 19308 : for (const auto & jvar : coupled_scalar_vars) 237 46 : if (_nl.hasScalarVariable(jvar->name())) 238 46 : bc->computeOffDiagJacobianScalar(jvar->number()); 239 19262 : } 240 : } 241 : } 242 188968 : } 243 : 244 : void 245 6614 : ComputeFullJacobianThread::computeOnInterface(BoundaryID bnd_id) 246 : { 247 6614 : if (_ik_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 248 : { 249 6614 : const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 250 33271 : for (const auto & it : ce) 251 : { 252 26657 : MooseVariableFieldBase & ivariable = *(it.first); 253 26657 : MooseVariableFieldBase & jvariable = *(it.second); 254 : 255 26657 : if (ivariable.isFV()) 256 0 : continue; 257 : 258 26657 : unsigned int ivar = ivariable.number(); 259 26657 : unsigned int jvar = jvariable.number(); 260 : 261 26657 : const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 262 54130 : for (const auto & interface_kernel : int_ks) 263 : { 264 27473 : if (!interface_kernel->isImplicit()) 265 0 : continue; 266 : 267 27473 : interface_kernel->prepareShapes(jvar); 268 27473 : interface_kernel->prepareNeighborShapes(jvar); 269 : 270 27473 : if (interface_kernel->variable().number() == ivar) 271 13675 : interface_kernel->computeElementOffDiagJacobian(jvar); 272 : 273 27473 : if (interface_kernel->neighborVariable().number() == ivar) 274 13675 : interface_kernel->computeNeighborOffDiagJacobian(jvar); 275 : } 276 : } 277 : } 278 6614 : } 279 : 280 : void 281 44720 : ComputeFullJacobianThread::computeOnInternalFace(const Elem * neighbor) 282 : { 283 44720 : if (_dg_warehouse->hasActiveBlockObjects(_subdomain, _tid)) 284 : { 285 44720 : const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 286 132439 : for (const auto & it : ce) 287 : { 288 87719 : MooseVariableFieldBase & ivariable = *(it.first); 289 87719 : MooseVariableFieldBase & jvariable = *(it.second); 290 : 291 87719 : if (ivariable.isFV()) 292 0 : continue; 293 : 294 87719 : unsigned int ivar = ivariable.number(); 295 87719 : unsigned int jvar = jvariable.number(); 296 : 297 87719 : const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid); 298 189576 : for (const auto & dg : dgks) 299 : { 300 : // this check may skip some couplings... 301 169698 : if (dg->variable().number() == ivar && dg->isImplicit() && 302 236714 : dg->hasBlocks(neighbor->subdomain_id()) && 303 67016 : (jvariable.activeOnSubdomain(_subdomain) || 304 6048 : jvariable.activeOnSubdomains(_fe_problem.mesh().interiorLowerDBlocks()))) 305 : { 306 64808 : dg->prepareShapes(jvar); 307 64808 : dg->prepareNeighborShapes(jvar); 308 64808 : dg->computeOffDiagJacobian(jvar); 309 : } 310 : } 311 : } 312 : } 313 44720 : } 314 : 315 : void 316 467787 : ComputeFullJacobianThread::computeOnInternalFace() 317 : { 318 : mooseAssert(_hdg_warehouse->hasActiveBlockObjects(_subdomain, _tid), 319 : "We should not be called if we have no active HDG kernels"); 320 1000409 : for (const auto & hdg_kernel : _hdg_warehouse->getActiveBlockObjects(_subdomain, _tid)) 321 : { 322 : mooseAssert( 323 : hdg_kernel->hasBlocks(_subdomain), 324 : "We queried the warehouse for active blocks on this subdomain, so this better be active"); 325 : mooseAssert( 326 : _neighbor_subdomain != Moose::INVALID_BLOCK_ID, 327 : "We should have set a valid neighbor subdomain ID if we made it in side this method"); 328 532622 : if (hdg_kernel->hasBlocks(_neighbor_subdomain)) 329 532614 : hdg_kernel->computeJacobianOnSide(); 330 : } 331 467787 : }