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 89114 : ComputeFullJacobianThread::ComputeFullJacobianThread(FEProblemBase & fe_problem, 26 89114 : const std::set<TagID> & tags) 27 89114 : : ComputeJacobianThread(fe_problem, tags) 28 : { 29 89114 : } 30 : 31 : // Splitting Constructor 32 6288 : ComputeFullJacobianThread::ComputeFullJacobianThread(ComputeFullJacobianThread & x, 33 6288 : Threads::split split) 34 6288 : : ComputeJacobianThread(x, split) 35 : { 36 6288 : } 37 : 38 101574 : ComputeFullJacobianThread::~ComputeFullJacobianThread() {} 39 : 40 : void 41 17721464 : ComputeFullJacobianThread::computeOnElement() 42 : { 43 17721464 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 44 57454006 : for (const auto & it : ce) 45 : { 46 39732542 : MooseVariableFieldBase & ivariable = *(it.first); 47 39732542 : MooseVariableFieldBase & jvariable = *(it.second); 48 : 49 39732542 : if (ivariable.isFV()) 50 6755163 : continue; 51 : 52 32977379 : unsigned int ivar = ivariable.number(); 53 32977379 : unsigned int jvar = jvariable.number(); 54 : 55 64279297 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 56 31301918 : _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 28984982 : const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid); 61 87628580 : for (const auto & kernel : kernels) 62 58643598 : if ((kernel->variable().number() == ivar) && kernel->isImplicit()) 63 : { 64 58594318 : kernel->prepareShapes(jvar); 65 58594318 : kernel->computeOffDiagJacobian(jvar); 66 : } 67 : } 68 : } 69 : 70 : /// done only when nonlocal kernels exist in the system 71 17721464 : if (_fe_problem.checkNonlocalCouplingRequirement()) 72 : { 73 5064 : auto & cne = _fe_problem.nonlocalCouplingEntries(_tid, _nl.number()); 74 10252 : for (const auto & it : cne) 75 : { 76 5188 : MooseVariableFieldBase & ivariable = *(it.first); 77 5188 : MooseVariableFieldBase & jvariable = *(it.second); 78 : 79 5188 : if (ivariable.isFV()) 80 0 : continue; 81 : 82 5188 : unsigned int ivar = ivariable.number(); 83 5188 : unsigned int jvar = jvariable.number(); 84 : 85 10376 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 86 5188 : _tag_kernels->hasActiveVariableBlockObjects(ivar, _subdomain, _tid)) 87 : { 88 5160 : const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid); 89 10984 : for (const auto & kernel : kernels) 90 : { 91 : std::shared_ptr<NonlocalKernel> nonlocal_kernel = 92 5824 : std::dynamic_pointer_cast<NonlocalKernel>(kernel); 93 5824 : if (nonlocal_kernel) 94 360 : if ((kernel->variable().number() == ivar) && kernel->isImplicit()) 95 : { 96 360 : kernel->prepareShapes(jvar); 97 360 : kernel->computeNonlocalOffDiagJacobian(jvar); 98 : } 99 5824 : } 100 : } 101 : } 102 : } 103 : 104 17721464 : const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid); 105 17721464 : if (scalar_vars.size() > 0) 106 : { 107 : // go over nl-variables (non-scalar) 108 159204 : const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid); 109 427665 : for (const auto & ivariable : vars) 110 529258 : if (ivariable->activeOnSubdomain(_subdomain) > 0 && 111 260797 : _tag_kernels->hasActiveVariableBlockObjects(ivariable->number(), _subdomain, _tid)) 112 : { 113 : // for each variable get the list of active kernels 114 : const auto & kernels = 115 253861 : _tag_kernels->getActiveVariableBlockObjects(ivariable->number(), _subdomain, _tid); 116 855228 : for (const auto & kernel : kernels) 117 601367 : if (kernel->isImplicit()) 118 : { 119 : // now, get the list of coupled scalar vars and compute their off-diag jacobians 120 601367 : const auto & coupled_scalar_vars = kernel->getCoupledMooseScalarVars(); 121 : 122 : // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones) 123 702805 : for (const auto & jvariable : coupled_scalar_vars) 124 101438 : if (_nl.hasScalarVariable(jvariable->name())) 125 101438 : kernel->computeOffDiagJacobianScalar(jvariable->number()); 126 : } 127 : } 128 : } 129 : 130 17721464 : if (_fe_problem.haveFV()) 131 9008699 : for (auto fv_kernel : _fv_kernels) 132 4918731 : if (fv_kernel->isImplicit()) 133 4918731 : fv_kernel->computeOffDiagJacobian(); 134 17721464 : } 135 : 136 : void 137 216599 : ComputeFullJacobianThread::computeOnBoundary(BoundaryID bnd_id, const Elem * lower_d_elem) 138 : { 139 216599 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 140 953897 : for (const auto & it : ce) 141 : { 142 737298 : MooseVariableFieldBase & ivariable = *(it.first); 143 737298 : MooseVariableFieldBase & jvariable = *(it.second); 144 : 145 : // We don't currently support coupling with FV variables 146 737298 : if (ivariable.isFV() || jvariable.isFV()) 147 1107 : continue; 148 : 149 736191 : const auto ivar = ivariable.number(); 150 736191 : const auto jvar = jvariable.number(); 151 : 152 736191 : if (!ivariable.activeOnSubdomain(_subdomain)) 153 86076 : continue; 154 : 155 : // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be 156 : // any) 157 650115 : if (lower_d_elem) 158 : { 159 13200 : auto lower_d_subdomain = lower_d_elem->subdomain_id(); 160 21666 : if (!jvariable.activeOnSubdomain(_subdomain) && 161 8466 : !jvariable.activeOnSubdomain(lower_d_subdomain)) 162 3974 : continue; 163 : } 164 : else 165 : { 166 636915 : if (!jvariable.activeOnSubdomain(_subdomain)) 167 28638 : continue; 168 : } 169 : 170 617503 : if (!_ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 171 0 : continue; 172 : 173 617503 : const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 174 1310871 : for (const auto & bc : bcs) 175 693368 : if (bc->shouldApply() && bc->variable().number() == ivar && bc->isImplicit()) 176 : { 177 374440 : bc->prepareShapes(jvar); 178 374440 : bc->computeOffDiagJacobian(jvar); 179 : } 180 : } 181 : 182 : /// done only when nonlocal integrated_bcs exist in the system 183 216599 : if (_fe_problem.checkNonlocalCouplingRequirement()) 184 : { 185 494 : auto & cne = _fe_problem.nonlocalCouplingEntries(_tid, _nl.number()); 186 988 : for (const auto & it : cne) 187 : { 188 494 : MooseVariableFieldBase & ivariable = *(it.first); 189 494 : MooseVariableFieldBase & jvariable = *(it.second); 190 : 191 494 : if (ivariable.isFV()) 192 0 : continue; 193 : 194 494 : unsigned int ivar = ivariable.number(); 195 494 : unsigned int jvar = jvariable.number(); 196 : 197 988 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 198 494 : _ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 199 : { 200 : const std::vector<std::shared_ptr<IntegratedBCBase>> & integrated_bcs = 201 494 : _ibc_warehouse->getBoundaryObjects(bnd_id, _tid); 202 988 : for (const auto & integrated_bc : integrated_bcs) 203 : { 204 : std::shared_ptr<NonlocalIntegratedBC> nonlocal_integrated_bc = 205 494 : std::dynamic_pointer_cast<NonlocalIntegratedBC>(integrated_bc); 206 494 : if (nonlocal_integrated_bc) 207 494 : if ((integrated_bc->variable().number() == ivar) && integrated_bc->isImplicit()) 208 : { 209 494 : integrated_bc->prepareShapes(jvar); 210 494 : integrated_bc->computeNonlocalOffDiagJacobian(jvar); 211 : } 212 494 : } 213 : } 214 : } 215 : } 216 : 217 216599 : const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid); 218 216599 : if (scalar_vars.size() > 0) 219 : { 220 : // go over nl-variables (non-scalar) 221 21728 : const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid); 222 64624 : for (const auto & ivar : vars) 223 85792 : if (ivar->activeOnSubdomain(_subdomain) > 0 && 224 42896 : _ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 225 : { 226 : // for each variable get the list of active kernels 227 42896 : const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 228 85792 : for (const auto & bc : bcs) 229 42896 : 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 21728 : bc->getCoupledMooseScalarVars(); 234 : 235 : // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones) 236 21800 : for (const auto & jvar : coupled_scalar_vars) 237 72 : if (_nl.hasScalarVariable(jvar->name())) 238 72 : bc->computeOffDiagJacobianScalar(jvar->number()); 239 21728 : } 240 : } 241 : } 242 216599 : } 243 : 244 : void 245 7476 : ComputeFullJacobianThread::computeOnInterface(BoundaryID bnd_id) 246 : { 247 7476 : if (_ik_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 248 : { 249 7476 : const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 250 37599 : for (const auto & it : ce) 251 : { 252 30123 : MooseVariableFieldBase & ivariable = *(it.first); 253 30123 : MooseVariableFieldBase & jvariable = *(it.second); 254 : 255 30123 : if (ivariable.isFV()) 256 0 : continue; 257 : 258 30123 : unsigned int ivar = ivariable.number(); 259 30123 : unsigned int jvar = jvariable.number(); 260 : 261 30123 : const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 262 61166 : for (const auto & interface_kernel : int_ks) 263 : { 264 31043 : if (!interface_kernel->isImplicit()) 265 0 : continue; 266 : 267 31043 : interface_kernel->prepareShapes(jvar); 268 31043 : interface_kernel->prepareNeighborShapes(jvar); 269 : 270 31043 : if (interface_kernel->variable().number() == ivar) 271 15453 : interface_kernel->computeElementOffDiagJacobian(jvar); 272 : 273 31043 : if (interface_kernel->neighborVariable().number() == ivar) 274 15453 : interface_kernel->computeNeighborOffDiagJacobian(jvar); 275 : } 276 : } 277 : } 278 7476 : } 279 : 280 : void 281 45956 : ComputeFullJacobianThread::computeOnInternalFace(const Elem * neighbor) 282 : { 283 45956 : if (_dg_warehouse->hasActiveBlockObjects(_subdomain, _tid)) 284 : { 285 45956 : const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 286 140209 : for (const auto & it : ce) 287 : { 288 94253 : MooseVariableFieldBase & ivariable = *(it.first); 289 94253 : MooseVariableFieldBase & jvariable = *(it.second); 290 : 291 94253 : if (ivariable.isFV()) 292 0 : continue; 293 : 294 94253 : unsigned int ivar = ivariable.number(); 295 94253 : unsigned int jvar = jvariable.number(); 296 : 297 94253 : const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid); 298 199820 : for (const auto & dg : dgks) 299 : { 300 : // this check may skip some couplings... 301 172918 : if (dg->variable().number() == ivar && dg->isImplicit() && 302 239341 : dg->hasBlocks(neighbor->subdomain_id()) && 303 66423 : (jvariable.activeOnSubdomain(_subdomain) || 304 6818 : jvariable.activeOnSubdomains(_fe_problem.mesh().interiorLowerDBlocks()))) 305 : { 306 63939 : dg->prepareShapes(jvar); 307 63939 : dg->prepareNeighborShapes(jvar); 308 63939 : dg->computeOffDiagJacobian(jvar); 309 : } 310 : } 311 : } 312 : } 313 45956 : } 314 : 315 : void 316 1508335 : ComputeFullJacobianThread::computeOnInternalFace() 317 : { 318 : mooseAssert(_hdg_warehouse->hasActiveBlockObjects(_subdomain, _tid), 319 : "We should not be called if we have no active HDG kernels"); 320 3631382 : 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 2123047 : if (hdg_kernel->hasBlocks(_neighbor_subdomain)) 329 2123038 : hdg_kernel->computeJacobianOnSide(); 330 : } 331 1508335 : }