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 82895 : ComputeFullJacobianThread::ComputeFullJacobianThread(FEProblemBase & fe_problem, 26 82895 : const std::set<TagID> & tags) 27 82895 : : ComputeJacobianThread(fe_problem, tags) 28 : { 29 82895 : } 30 : 31 : // Splitting Constructor 32 6359 : ComputeFullJacobianThread::ComputeFullJacobianThread(ComputeFullJacobianThread & x, 33 6359 : Threads::split split) 34 6359 : : ComputeJacobianThread(x, split) 35 : { 36 6359 : } 37 : 38 95496 : ComputeFullJacobianThread::~ComputeFullJacobianThread() {} 39 : 40 : void 41 15954634 : ComputeFullJacobianThread::computeOnElement() 42 : { 43 15954634 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 44 52266475 : for (const auto & it : ce) 45 : { 46 36311841 : MooseVariableFieldBase & ivariable = *(it.first); 47 36311841 : MooseVariableFieldBase & jvariable = *(it.second); 48 : 49 36311841 : if (ivariable.isFV()) 50 6437403 : continue; 51 : 52 29874438 : unsigned int ivar = ivariable.number(); 53 29874438 : unsigned int jvar = jvariable.number(); 54 : 55 58191116 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 56 28316678 : _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 26067159 : const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid); 61 78686525 : for (const auto & kernel : kernels) 62 52619366 : if ((kernel->variable().number() == ivar) && kernel->isImplicit()) 63 : { 64 52572108 : kernel->prepareShapes(jvar); 65 52572108 : kernel->computeOffDiagJacobian(jvar); 66 : } 67 : } 68 : } 69 : 70 : /// done only when nonlocal kernels exist in the system 71 15954634 : if (_fe_problem.checkNonlocalCouplingRequirement()) 72 : { 73 4452 : auto & cne = _fe_problem.nonlocalCouplingEntries(_tid, _nl.number()); 74 9016 : for (const auto & it : cne) 75 : { 76 4564 : MooseVariableFieldBase & ivariable = *(it.first); 77 4564 : MooseVariableFieldBase & jvariable = *(it.second); 78 : 79 4564 : if (ivariable.isFV()) 80 0 : continue; 81 : 82 4564 : unsigned int ivar = ivariable.number(); 83 4564 : unsigned int jvar = jvariable.number(); 84 : 85 9128 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 86 4564 : _tag_kernels->hasActiveVariableBlockObjects(ivar, _subdomain, _tid)) 87 : { 88 4536 : const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid); 89 9688 : for (const auto & kernel : kernels) 90 : { 91 : std::shared_ptr<NonlocalKernel> nonlocal_kernel = 92 5152 : std::dynamic_pointer_cast<NonlocalKernel>(kernel); 93 5152 : if (nonlocal_kernel) 94 336 : if ((kernel->variable().number() == ivar) && kernel->isImplicit()) 95 : { 96 336 : kernel->prepareShapes(jvar); 97 336 : kernel->computeNonlocalOffDiagJacobian(jvar); 98 : } 99 5152 : } 100 : } 101 : } 102 : } 103 : 104 15954634 : const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid); 105 15954634 : if (scalar_vars.size() > 0) 106 : { 107 : // go over nl-variables (non-scalar) 108 141204 : const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid); 109 379733 : for (const auto & ivariable : vars) 110 470062 : if (ivariable->activeOnSubdomain(_subdomain) > 0 && 111 231533 : _tag_kernels->hasActiveVariableBlockObjects(ivariable->number(), _subdomain, _tid)) 112 : { 113 : // for each variable get the list of active kernels 114 : const auto & kernels = 115 225299 : _tag_kernels->getActiveVariableBlockObjects(ivariable->number(), _subdomain, _tid); 116 759092 : for (const auto & kernel : kernels) 117 533793 : if (kernel->isImplicit()) 118 : { 119 : // now, get the list of coupled scalar vars and compute their off-diag jacobians 120 533793 : const auto & coupled_scalar_vars = kernel->getCoupledMooseScalarVars(); 121 : 122 : // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones) 123 623971 : for (const auto & jvariable : coupled_scalar_vars) 124 90178 : if (_nl.hasScalarVariable(jvariable->name())) 125 90178 : kernel->computeOffDiagJacobianScalar(jvariable->number()); 126 : } 127 : } 128 : } 129 : 130 15954634 : if (_fe_problem.haveFV()) 131 8471954 : for (auto fv_kernel : _fv_kernels) 132 4667078 : if (fv_kernel->isImplicit()) 133 4667078 : fv_kernel->computeOffDiagJacobian(); 134 15954634 : } 135 : 136 : void 137 197635 : ComputeFullJacobianThread::computeOnBoundary(BoundaryID bnd_id, const Elem * lower_d_elem) 138 : { 139 197635 : auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 140 882511 : for (const auto & it : ce) 141 : { 142 684876 : MooseVariableFieldBase & ivariable = *(it.first); 143 684876 : MooseVariableFieldBase & jvariable = *(it.second); 144 : 145 : // We don't currently support coupling with FV variables 146 684876 : if (ivariable.isFV() || jvariable.isFV()) 147 864 : continue; 148 : 149 684012 : const auto ivar = ivariable.number(); 150 684012 : const auto jvar = jvariable.number(); 151 : 152 684012 : if (!ivariable.activeOnSubdomain(_subdomain)) 153 77190 : continue; 154 : 155 : // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be 156 : // any) 157 606822 : if (lower_d_elem) 158 : { 159 11728 : auto lower_d_subdomain = lower_d_elem->subdomain_id(); 160 19264 : if (!jvariable.activeOnSubdomain(_subdomain) && 161 7536 : !jvariable.activeOnSubdomain(lower_d_subdomain)) 162 3552 : continue; 163 : } 164 : else 165 : { 166 595094 : if (!jvariable.activeOnSubdomain(_subdomain)) 167 25731 : continue; 168 : } 169 : 170 577539 : if (!_ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 171 0 : continue; 172 : 173 577539 : const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 174 1229767 : for (const auto & bc : bcs) 175 652228 : if (bc->shouldApply() && bc->variable().number() == ivar && bc->isImplicit()) 176 : { 177 347758 : bc->prepareShapes(jvar); 178 347758 : bc->computeOffDiagJacobian(jvar); 179 : } 180 : } 181 : 182 : /// done only when nonlocal integrated_bcs exist in the system 183 197635 : if (_fe_problem.checkNonlocalCouplingRequirement()) 184 : { 185 434 : auto & cne = _fe_problem.nonlocalCouplingEntries(_tid, _nl.number()); 186 868 : for (const auto & it : cne) 187 : { 188 434 : MooseVariableFieldBase & ivariable = *(it.first); 189 434 : MooseVariableFieldBase & jvariable = *(it.second); 190 : 191 434 : if (ivariable.isFV()) 192 0 : continue; 193 : 194 434 : unsigned int ivar = ivariable.number(); 195 434 : unsigned int jvar = jvariable.number(); 196 : 197 868 : if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) && 198 434 : _ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 199 : { 200 : const std::vector<std::shared_ptr<IntegratedBCBase>> & integrated_bcs = 201 434 : _ibc_warehouse->getBoundaryObjects(bnd_id, _tid); 202 868 : for (const auto & integrated_bc : integrated_bcs) 203 : { 204 : std::shared_ptr<NonlocalIntegratedBC> nonlocal_integrated_bc = 205 434 : std::dynamic_pointer_cast<NonlocalIntegratedBC>(integrated_bc); 206 434 : if (nonlocal_integrated_bc) 207 434 : if ((integrated_bc->variable().number() == ivar) && integrated_bc->isImplicit()) 208 : { 209 434 : integrated_bc->prepareShapes(jvar); 210 434 : integrated_bc->computeNonlocalOffDiagJacobian(jvar); 211 : } 212 434 : } 213 : } 214 : } 215 : } 216 : 217 197635 : const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid); 218 197635 : if (scalar_vars.size() > 0) 219 : { 220 : // go over nl-variables (non-scalar) 221 19320 : const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid); 222 57456 : for (const auto & ivar : vars) 223 76272 : if (ivar->activeOnSubdomain(_subdomain) > 0 && 224 38136 : _ibc_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 225 : { 226 : // for each variable get the list of active kernels 227 38136 : const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 228 76272 : for (const auto & bc : bcs) 229 38136 : 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 19320 : bc->getCoupledMooseScalarVars(); 234 : 235 : // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones) 236 19384 : for (const auto & jvar : coupled_scalar_vars) 237 64 : if (_nl.hasScalarVariable(jvar->name())) 238 64 : bc->computeOffDiagJacobianScalar(jvar->number()); 239 19320 : } 240 : } 241 : } 242 197635 : } 243 : 244 : void 245 6646 : ComputeFullJacobianThread::computeOnInterface(BoundaryID bnd_id) 246 : { 247 6646 : if (_ik_warehouse->hasActiveBoundaryObjects(bnd_id, _tid)) 248 : { 249 6646 : const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 250 33434 : for (const auto & it : ce) 251 : { 252 26788 : MooseVariableFieldBase & ivariable = *(it.first); 253 26788 : MooseVariableFieldBase & jvariable = *(it.second); 254 : 255 26788 : if (ivariable.isFV()) 256 0 : continue; 257 : 258 26788 : unsigned int ivar = ivariable.number(); 259 26788 : unsigned int jvar = jvariable.number(); 260 : 261 26788 : const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid); 262 54396 : for (const auto & interface_kernel : int_ks) 263 : { 264 27608 : if (!interface_kernel->isImplicit()) 265 0 : continue; 266 : 267 27608 : interface_kernel->prepareShapes(jvar); 268 27608 : interface_kernel->prepareNeighborShapes(jvar); 269 : 270 27608 : if (interface_kernel->variable().number() == ivar) 271 13740 : interface_kernel->computeElementOffDiagJacobian(jvar); 272 : 273 27608 : if (interface_kernel->neighborVariable().number() == ivar) 274 13740 : interface_kernel->computeNeighborOffDiagJacobian(jvar); 275 : } 276 : } 277 : } 278 6646 : } 279 : 280 : void 281 41110 : ComputeFullJacobianThread::computeOnInternalFace(const Elem * neighbor) 282 : { 283 41110 : if (_dg_warehouse->hasActiveBlockObjects(_subdomain, _tid)) 284 : { 285 41110 : const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number()); 286 124235 : for (const auto & it : ce) 287 : { 288 83125 : MooseVariableFieldBase & ivariable = *(it.first); 289 83125 : MooseVariableFieldBase & jvariable = *(it.second); 290 : 291 83125 : if (ivariable.isFV()) 292 0 : continue; 293 : 294 83125 : unsigned int ivar = ivariable.number(); 295 83125 : unsigned int jvar = jvariable.number(); 296 : 297 83125 : const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid); 298 176357 : for (const auto & dg : dgks) 299 : { 300 : // this check may skip some couplings... 301 153080 : if (dg->variable().number() == ivar && dg->isImplicit() && 302 212004 : dg->hasBlocks(neighbor->subdomain_id()) && 303 58924 : (jvariable.activeOnSubdomain(_subdomain) || 304 6060 : jvariable.activeOnSubdomains(_fe_problem.mesh().interiorLowerDBlocks()))) 305 : { 306 56716 : dg->prepareShapes(jvar); 307 56716 : dg->prepareNeighborShapes(jvar); 308 56716 : dg->computeOffDiagJacobian(jvar); 309 : } 310 : } 311 : } 312 : } 313 41110 : } 314 : 315 : void 316 1501152 : ComputeFullJacobianThread::computeOnInternalFace() 317 : { 318 : mooseAssert(_hdg_warehouse->hasActiveBlockObjects(_subdomain, _tid), 319 : "We should not be called if we have no active HDG kernels"); 320 3617016 : 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 2115864 : if (hdg_kernel->hasBlocks(_neighbor_subdomain)) 329 2115856 : hdg_kernel->computeJacobianOnSide(); 330 : } 331 1501152 : }