https://mooseframework.inl.gov
ComputeFullJacobianThread.C
Go to the documentation of this file.
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 
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 
26  const std::set<TagID> & tags)
27  : ComputeJacobianThread(fe_problem, tags)
28 {
29 }
30 
31 // Splitting Constructor
35 {
36 }
37 
39 
40 void
42 {
43  auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
44  for (const auto & it : ce)
45  {
46  MooseVariableFieldBase & ivariable = *(it.first);
47  MooseVariableFieldBase & jvariable = *(it.second);
48 
49  if (ivariable.isFV())
50  continue;
51 
52  unsigned int ivar = ivariable.number();
53  unsigned int jvar = jvariable.number();
54 
55  if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) &&
57  {
58  // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be
59  // any)
60  const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid);
61  for (const auto & kernel : kernels)
62  if ((kernel->variable().number() == ivar) && kernel->isImplicit())
63  {
64  kernel->prepareShapes(jvar);
65  kernel->computeOffDiagJacobian(jvar);
66  }
67  }
68  }
69 
72  {
74  for (const auto & it : cne)
75  {
76  MooseVariableFieldBase & ivariable = *(it.first);
77  MooseVariableFieldBase & jvariable = *(it.second);
78 
79  if (ivariable.isFV())
80  continue;
81 
82  unsigned int ivar = ivariable.number();
83  unsigned int jvar = jvariable.number();
84 
85  if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) &&
87  {
88  const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid);
89  for (const auto & kernel : kernels)
90  {
91  std::shared_ptr<NonlocalKernel> nonlocal_kernel =
93  if (nonlocal_kernel)
94  if ((kernel->variable().number() == ivar) && kernel->isImplicit())
95  {
96  kernel->prepareShapes(jvar);
97  kernel->computeNonlocalOffDiagJacobian(jvar);
98  }
99  }
100  }
101  }
102  }
103 
104  const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid);
105  if (scalar_vars.size() > 0)
106  {
107  // go over nl-variables (non-scalar)
108  const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid);
109  for (const auto & ivariable : vars)
110  if (ivariable->activeOnSubdomain(_subdomain) > 0 &&
112  {
113  // for each variable get the list of active kernels
114  const auto & kernels =
116  for (const auto & kernel : kernels)
117  if (kernel->isImplicit())
118  {
119  // now, get the list of coupled scalar vars and compute their off-diag jacobians
120  const auto & coupled_scalar_vars = kernel->getCoupledMooseScalarVars();
121 
122  // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones)
123  for (const auto & jvariable : coupled_scalar_vars)
124  if (_nl.hasScalarVariable(jvariable->name()))
125  kernel->computeOffDiagJacobianScalar(jvariable->number());
126  }
127  }
128  }
129 
130  if (_fe_problem.haveFV())
131  for (auto fv_kernel : _fv_kernels)
132  if (fv_kernel->isImplicit())
133  fv_kernel->computeOffDiagJacobian();
134 }
135 
136 void
138 {
139  auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
140  for (const auto & it : ce)
141  {
142  MooseVariableFieldBase & ivariable = *(it.first);
143  MooseVariableFieldBase & jvariable = *(it.second);
144 
145  // We don't currently support coupling with FV variables
146  if (ivariable.isFV() || jvariable.isFV())
147  continue;
148 
149  const auto ivar = ivariable.number();
150  const auto jvar = jvariable.number();
151 
152  if (!ivariable.activeOnSubdomain(_subdomain))
153  continue;
154 
155  // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be
156  // any)
157  if (lower_d_elem)
158  {
159  auto lower_d_subdomain = lower_d_elem->subdomain_id();
160  if (!jvariable.activeOnSubdomain(_subdomain) &&
161  !jvariable.activeOnSubdomain(lower_d_subdomain))
162  continue;
163  }
164  else
165  {
166  if (!jvariable.activeOnSubdomain(_subdomain))
167  continue;
168  }
169 
171  continue;
172 
173  const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
174  for (const auto & bc : bcs)
175  if (bc->shouldApply() && bc->variable().number() == ivar && bc->isImplicit())
176  {
177  bc->prepareShapes(jvar);
178  bc->computeOffDiagJacobian(jvar);
179  }
180  }
181 
184  {
186  for (const auto & it : cne)
187  {
188  MooseVariableFieldBase & ivariable = *(it.first);
189  MooseVariableFieldBase & jvariable = *(it.second);
190 
191  if (ivariable.isFV())
192  continue;
193 
194  unsigned int ivar = ivariable.number();
195  unsigned int jvar = jvariable.number();
196 
197  if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) &&
199  {
200  const std::vector<std::shared_ptr<IntegratedBCBase>> & integrated_bcs =
202  for (const auto & integrated_bc : integrated_bcs)
203  {
204  std::shared_ptr<NonlocalIntegratedBC> nonlocal_integrated_bc =
206  if (nonlocal_integrated_bc)
207  if ((integrated_bc->variable().number() == ivar) && integrated_bc->isImplicit())
208  {
209  integrated_bc->prepareShapes(jvar);
210  integrated_bc->computeNonlocalOffDiagJacobian(jvar);
211  }
212  }
213  }
214  }
215  }
216 
217  const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid);
218  if (scalar_vars.size() > 0)
219  {
220  // go over nl-variables (non-scalar)
221  const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid);
222  for (const auto & ivar : vars)
223  if (ivar->activeOnSubdomain(_subdomain) > 0 &&
225  {
226  // for each variable get the list of active kernels
227  const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
228  for (const auto & bc : bcs)
229  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  bc->getCoupledMooseScalarVars();
234 
235  // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones)
236  for (const auto & jvar : coupled_scalar_vars)
237  if (_nl.hasScalarVariable(jvar->name()))
238  bc->computeOffDiagJacobianScalar(jvar->number());
239  }
240  }
241  }
242 }
243 
244 void
246 {
248  {
249  const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
250  for (const auto & it : ce)
251  {
252  MooseVariableFieldBase & ivariable = *(it.first);
253  MooseVariableFieldBase & jvariable = *(it.second);
254 
255  if (ivariable.isFV())
256  continue;
257 
258  unsigned int ivar = ivariable.number();
259  unsigned int jvar = jvariable.number();
260 
261  const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
262  for (const auto & interface_kernel : int_ks)
263  {
264  if (!interface_kernel->isImplicit())
265  continue;
266 
267  interface_kernel->prepareShapes(jvar);
268  interface_kernel->prepareNeighborShapes(jvar);
269 
270  if (interface_kernel->variable().number() == ivar)
271  interface_kernel->computeElementOffDiagJacobian(jvar);
272 
273  if (interface_kernel->neighborVariable().number() == ivar)
274  interface_kernel->computeNeighborOffDiagJacobian(jvar);
275  }
276  }
277  }
278 }
279 
280 void
282 {
284  {
285  const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
286  for (const auto & it : ce)
287  {
288  MooseVariableFieldBase & ivariable = *(it.first);
289  MooseVariableFieldBase & jvariable = *(it.second);
290 
291  if (ivariable.isFV())
292  continue;
293 
294  unsigned int ivar = ivariable.number();
295  unsigned int jvar = jvariable.number();
296 
297  const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid);
298  for (const auto & dg : dgks)
299  {
300  // this check may skip some couplings...
301  if (dg->variable().number() == ivar && dg->isImplicit() &&
302  dg->hasBlocks(neighbor->subdomain_id()) &&
303  (jvariable.activeOnSubdomain(_subdomain) ||
305  {
306  dg->prepareShapes(jvar);
307  dg->prepareNeighborShapes(jvar);
308  dg->computeOffDiagJacobian(jvar);
309  }
310  }
311  }
312  }
313 }
314 
315 void
317 {
319  "We should not be called if we have no active HDG kernels");
320  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(
327  "We should have set a valid neighbor subdomain ID if we made it in side this method");
328  if (hdg_kernel->hasBlocks(_neighbor_subdomain))
329  hdg_kernel->computeJacobianOnSide();
330  }
331 }
const std::vector< std::shared_ptr< T > > & getActiveVariableBlockObjects(unsigned int variable_id, SubdomainID block_id, THREAD_ID tid=0) const
const std::vector< MooseVariableFieldBase * > & getVariables(THREAD_ID tid)
Definition: SystemBase.h:752
std::vector< std::pair< MooseVariableFEBase *, MooseVariableFEBase * > > & couplingEntries(const THREAD_ID tid, const unsigned int nl_sys_num)
const std::vector< MooseVariableScalar * > & getScalarVariables(THREAD_ID tid)
Definition: SystemBase.h:757
const std::set< SubdomainID > & interiorLowerDBlocks() const
Definition: MooseMesh.h:1403
bool hasActiveBlockObjects(THREAD_ID tid=0) const
const std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
MooseObjectWarehouse< InterfaceKernelBase > * _ik_warehouse
virtual void computeOnInternalFace() override
virtual bool haveFV() const override
returns true if this problem includes/needs finite volume functionality.
unsigned int number() const
Get variable number coming from libMesh.
ComputeFullJacobianThread(FEProblemBase &fe_problem, const std::set< TagID > &tags)
NonlocalIntegratedBC is used for solving integral terms in integro-differential equations.
virtual bool checkNonlocalCouplingRequirement() const override
char ** vars
virtual bool isFV() const
virtual void prepareShapes(unsigned int var_num)
Prepare shape functions.
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
This class provides an interface for common operations on field variables of both FE and FV types wit...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
const SubdomainID INVALID_BLOCK_ID
Definition: MooseTypes.C:20
bool hasActiveVariableBlockObjects(unsigned int variable_id, SubdomainID block_id, THREAD_ID tid=0) const
Methods for checking/getting variable kernels for a variable and SubdomainID.
bool activeOnSubdomains(const std::set< SubdomainID > &subdomains) const
Is the variable active on the subdomains?
MooseObjectWarehouse< HDGKernel > * _hdg_warehouse
boundary_id_type BoundaryID
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getBoundaryObjects(THREAD_ID tid=0) const
void prepareShapes(unsigned int var_num) override final
Prepare shape functions.
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1159
NonlinearSystemBase & _nl
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
tbb::split split
MooseObjectWarehouse< IntegratedBCBase > * _ibc_warehouse
std::vector< std::pair< MooseVariableFEBase *, MooseVariableFEBase * > > & nonlocalCouplingEntries(const THREAD_ID tid, const unsigned int nl_sys_num)
virtual MooseMesh & mesh() override
virtual void computeOnBoundary(BoundaryID bnd_id, const Elem *lower_d_elem) override
NonlocalKernel is used for solving integral terms in integro-differential equations.
virtual void computeOnInterface(BoundaryID bnd_id) override
bool activeOnSubdomain(SubdomainID subdomain) const
Is the variable active on the subdomain?
SubdomainID _subdomain
The subdomain for the current element.
MooseObjectWarehouse< KernelBase > * _tag_kernels
MooseObjectWarehouse< DGKernelBase > * _dg_warehouse
virtual bool hasScalarVariable(const std::string &var_name) const
Definition: SystemBase.C:859
std::vector< FVElementalKernel * > _fv_kernels
Current subdomain FVElementalKernels.
virtual void computeOnElement() override
SubdomainID _neighbor_subdomain
The subdomain for the current neighbor.