www.mooseframework.org
ComputeFullJacobianThread.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "DGKernel.h"
16 #include "InterfaceKernelBase.h"
17 #include "MooseVariableFE.h"
18 #include "MooseVariableScalar.h"
19 #include "NonlocalKernel.h"
20 #include "NonlocalIntegratedBC.h"
21 #include "FVElementalKernel.h"
22 #include "libmesh/threads.h"
23 
25  const std::set<TagID> & tags)
26  : ComputeJacobianThread(fe_problem, tags)
27 {
28 }
29 
30 // Splitting Constructor
32  Threads::split split)
34 {
35 }
36 
38 
39 void
41 {
42  auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
43  for (const auto & it : ce)
44  {
45  MooseVariableFieldBase & ivariable = *(it.first);
46  MooseVariableFieldBase & jvariable = *(it.second);
47 
48  if (ivariable.isFV())
49  continue;
50 
51  unsigned int ivar = ivariable.number();
52  unsigned int jvar = jvariable.number();
53 
54  if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) &&
56  {
57  // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be
58  // any)
59  const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid);
60  for (const auto & kernel : kernels)
61  if ((kernel->variable().number() == ivar) && kernel->isImplicit())
62  {
63  kernel->prepareShapes(jvar);
64  kernel->computeOffDiagJacobian(jvar);
65  }
66  }
67  }
68 
71  {
73  for (const auto & it : cne)
74  {
75  MooseVariableFieldBase & ivariable = *(it.first);
76  MooseVariableFieldBase & jvariable = *(it.second);
77 
78  if (ivariable.isFV())
79  continue;
80 
81  unsigned int ivar = ivariable.number();
82  unsigned int jvar = jvariable.number();
83 
84  if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) &&
86  {
87  const auto & kernels = _tag_kernels->getActiveVariableBlockObjects(ivar, _subdomain, _tid);
88  for (const auto & kernel : kernels)
89  {
90  std::shared_ptr<NonlocalKernel> nonlocal_kernel =
92  if (nonlocal_kernel)
93  if ((kernel->variable().number() == ivar) && kernel->isImplicit())
94  {
95  kernel->prepareShapes(jvar);
96  kernel->computeNonlocalOffDiagJacobian(jvar);
97  }
98  }
99  }
100  }
101  }
102 
103  const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid);
104  if (scalar_vars.size() > 0)
105  {
106  // go over nl-variables (non-scalar)
107  const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid);
108  for (const auto & ivariable : vars)
109  if (ivariable->activeOnSubdomain(_subdomain) > 0 &&
111  {
112  // for each variable get the list of active kernels
113  const auto & kernels =
115  for (const auto & kernel : kernels)
116  if (kernel->isImplicit())
117  {
118  // now, get the list of coupled scalar vars and compute their off-diag jacobians
119  const auto & coupled_scalar_vars = kernel->getCoupledMooseScalarVars();
120 
121  // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones)
122  for (const auto & jvariable : coupled_scalar_vars)
123  if (_nl.hasScalarVariable(jvariable->name()))
124  kernel->computeOffDiagJacobianScalar(jvariable->number());
125  }
126  }
127  }
128 
129  if (_fe_problem.haveFV())
130  for (auto fv_kernel : _fv_kernels)
131  if (fv_kernel->isImplicit())
132  fv_kernel->computeOffDiagJacobian();
133 }
134 
135 void
137 {
138  auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
139  for (const auto & it : ce)
140  {
141  MooseVariableFieldBase & ivariable = *(it.first);
142  MooseVariableFieldBase & jvariable = *(it.second);
143 
144  // We don't currently support coupling with FV variables
145  if (ivariable.isFV() || jvariable.isFV())
146  continue;
147 
148  const auto ivar = ivariable.number();
149  const auto jvar = jvariable.number();
150 
151  if (!ivariable.activeOnSubdomain(_subdomain))
152  continue;
153 
154  // only if there are dofs for j-variable (if it is subdomain restricted var, there may not be
155  // any)
156  if (lower_d_elem)
157  {
158  auto lower_d_subdomain = lower_d_elem->subdomain_id();
159  if (!jvariable.activeOnSubdomain(_subdomain) &&
160  !jvariable.activeOnSubdomain(lower_d_subdomain))
161  continue;
162  }
163  else
164  {
165  if (!jvariable.activeOnSubdomain(_subdomain))
166  continue;
167  }
168 
170  continue;
171 
172  const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
173  for (const auto & bc : bcs)
174  if (bc->shouldApply() && bc->variable().number() == ivar && bc->isImplicit())
175  {
176  bc->prepareShapes(jvar);
177  bc->computeOffDiagJacobian(jvar);
178  }
179  }
180 
183  {
185  for (const auto & it : cne)
186  {
187  MooseVariableFieldBase & ivariable = *(it.first);
188  MooseVariableFieldBase & jvariable = *(it.second);
189 
190  if (ivariable.isFV())
191  continue;
192 
193  unsigned int ivar = ivariable.number();
194  unsigned int jvar = jvariable.number();
195 
196  if (ivariable.activeOnSubdomain(_subdomain) && jvariable.activeOnSubdomain(_subdomain) &&
198  {
199  const std::vector<std::shared_ptr<IntegratedBCBase>> & integrated_bcs =
201  for (const auto & integrated_bc : integrated_bcs)
202  {
203  std::shared_ptr<NonlocalIntegratedBC> nonlocal_integrated_bc =
205  if (nonlocal_integrated_bc)
206  if ((integrated_bc->variable().number() == ivar) && integrated_bc->isImplicit())
207  {
208  integrated_bc->prepareShapes(jvar);
209  integrated_bc->computeNonlocalOffDiagJacobian(jvar);
210  }
211  }
212  }
213  }
214  }
215 
216  const std::vector<MooseVariableScalar *> & scalar_vars = _nl.getScalarVariables(_tid);
217  if (scalar_vars.size() > 0)
218  {
219  // go over nl-variables (non-scalar)
220  const std::vector<MooseVariableFieldBase *> & vars = _nl.getVariables(_tid);
221  for (const auto & ivar : vars)
222  if (ivar->activeOnSubdomain(_subdomain) > 0 &&
224  {
225  // for each variable get the list of active kernels
226  const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
227  for (const auto & bc : bcs)
228  if (bc->variable().number() == ivar->number() && bc->isImplicit())
229  {
230  // now, get the list of coupled scalar vars and compute their off-diag jacobians
231  const std::vector<MooseVariableScalar *> coupled_scalar_vars =
232  bc->getCoupledMooseScalarVars();
233 
234  // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones)
235  for (const auto & jvar : coupled_scalar_vars)
236  if (_nl.hasScalarVariable(jvar->name()))
237  bc->computeOffDiagJacobianScalar(jvar->number());
238  }
239  }
240  }
241 }
242 
243 void
245 {
247  {
248  const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
249  for (const auto & it : ce)
250  {
251  MooseVariableFieldBase & ivariable = *(it.first);
252  MooseVariableFieldBase & jvariable = *(it.second);
253 
254  if (ivariable.isFV())
255  continue;
256 
257  unsigned int ivar = ivariable.number();
258  unsigned int jvar = jvariable.number();
259 
260  const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
261  for (const auto & interface_kernel : int_ks)
262  {
263  if (!interface_kernel->isImplicit())
264  continue;
265 
266  interface_kernel->prepareShapes(jvar);
267  interface_kernel->prepareNeighborShapes(jvar);
268 
269  if (interface_kernel->variable().number() == ivar)
270  interface_kernel->computeElementOffDiagJacobian(jvar);
271 
272  if (interface_kernel->neighborVariable().number() == ivar)
273  interface_kernel->computeNeighborOffDiagJacobian(jvar);
274  }
275  }
276  }
277 }
278 
279 void
281 {
283  {
284  const auto & ce = _fe_problem.couplingEntries(_tid, _nl.number());
285  for (const auto & it : ce)
286  {
287  MooseVariableFieldBase & ivariable = *(it.first);
288  MooseVariableFieldBase & jvariable = *(it.second);
289 
290  if (ivariable.isFV())
291  continue;
292 
293  unsigned int ivar = ivariable.number();
294  unsigned int jvar = jvariable.number();
295 
296  const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid);
297  for (const auto & dg : dgks)
298  {
299  // this check may skip some couplings...
300  if (dg->variable().number() == ivar && dg->isImplicit() &&
301  dg->hasBlocks(neighbor->subdomain_id()) &&
302  (jvariable.activeOnSubdomain(_subdomain) ||
304  {
305  dg->prepareShapes(jvar);
306  dg->prepareNeighborShapes(jvar);
307  dg->computeOffDiagJacobian(jvar);
308  }
309  }
310  }
311  }
312 }
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:742
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:747
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 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 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
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.
virtual void computeOnInternalFace(const Elem *neighbor) override
boundary_id_type BoundaryID
virtual bool checkNonlocalCouplingRequirement()
Definition: SubProblem.h:88
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:1132
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
const SubdomainID INTERNAL_SIDE_LOWERD_ID
Definition: MooseTypes.C:20
std::vector< std::pair< MooseVariableFEBase *, MooseVariableFEBase * > > & nonlocalCouplingEntries(const THREAD_ID tid, const unsigned int nl_sys_num)
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:832
std::vector< FVElementalKernel * > _fv_kernels
Current subdomain FVElementalKernels.
virtual void computeOnElement() override