https://mooseframework.inl.gov
NonlinearThread.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 
10 #include "NonlinearThread.h"
11 #include "NonlinearSystem.h"
12 #include "Problem.h"
13 #include "FEProblem.h"
14 #include "KernelBase.h"
15 #include "IntegratedBCBase.h"
16 #include "DGKernelBase.h"
17 #include "InterfaceKernelBase.h"
18 #include "Material.h"
19 #include "TimeKernel.h"
20 #include "SwapBackSentinel.h"
21 #include "FVTimeKernel.h"
22 #include "ComputeJacobianThread.h"
23 
24 #include "libmesh/threads.h"
25 
27  : ThreadedElementLoop<ConstElemRange>(fe_problem),
28  _nl(fe_problem.currentNonlinearSystem()),
29  _num_cached(0),
30  _integrated_bcs(_nl.getIntegratedBCWarehouse()),
31  _dg_kernels(_nl.getDGKernelWarehouse()),
32  _interface_kernels(_nl.getInterfaceKernelWarehouse()),
33  _kernels(_nl.getKernelWarehouse()),
34  _hdg_kernels(_nl.getHDGKernelWarehouse()),
35  _has_active_objects(_integrated_bcs.hasActiveObjects() || _dg_kernels.hasActiveObjects() ||
36  _interface_kernels.hasActiveObjects() || _kernels.hasActiveObjects() ||
37  _fe_problem.haveFV()),
38  _should_execute_dg(false)
39 {
40 }
41 
42 // Splitting Constructor
45  _nl(x._nl),
46  _num_cached(x._num_cached),
47  _integrated_bcs(x._integrated_bcs),
48  _dg_kernels(x._dg_kernels),
49  _interface_kernels(x._interface_kernels),
50  _kernels(x._kernels),
51  _tag_kernels(x._tag_kernels),
52  _hdg_kernels(x._hdg_kernels),
53  _has_active_objects(x._has_active_objects),
54  _should_execute_dg(x._should_execute_dg)
55 {
56 }
57 
59 
60 void
61 NonlinearThread::operator()(const ConstElemRange & range, bool bypass_threading)
62 {
64  ThreadedElementLoop<ConstElemRange>::operator()(range, bypass_threading);
65 }
66 
67 void
69 {
70  // This should come first to setup the residual objects before we do dependency determination of
71  // material properties and variables
73 
75 
76  // Update variable Dependencies
77  std::set<MooseVariableFEBase *> needed_moose_vars;
82 
83  // Update FE variable coupleable vector tags
84  std::set<TagID> needed_fe_var_vector_tags;
86  _subdomain, needed_fe_var_vector_tags, _tid);
88  _subdomain, needed_fe_var_vector_tags, _tid);
90  _subdomain, needed_fe_var_vector_tags, _tid);
91 
92  // Update material dependencies
93  std::unordered_set<unsigned int> needed_mat_props;
98 
99  if (_fe_problem.haveFV())
100  {
101  // Re-query the finite volume elemental kernels
102  _fv_kernels.clear();
104  .query()
105  .template condition<AttribSysNum>(_nl.number())
106  .template condition<AttribSystem>("FVElementalKernel")
107  .template condition<AttribSubdomains>(_subdomain)
108  .template condition<AttribThread>(_tid)
110  for (const auto fv_kernel : _fv_kernels)
111  {
112  const auto & fv_mv_deps = fv_kernel->getMooseVariableDependencies();
113  needed_moose_vars.insert(fv_mv_deps.begin(), fv_mv_deps.end());
114  const auto & fv_mp_deps = fv_kernel->getMatPropDependencies();
115  needed_mat_props.insert(fv_mp_deps.begin(), fv_mp_deps.end());
116  }
117  }
118 
119  // Cache these to avoid computing them on every side
122 
124  _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_fe_var_vector_tags, _tid);
125  _fe_problem.prepareMaterials(needed_mat_props, _subdomain, _tid);
126 }
127 
128 void
129 NonlinearThread::onElement(const Elem * const elem)
130 {
131  // Set up Sentinel class so that, even if reinitMaterials() throws in prepareElement, we
132  // still remember to swap back during stack unwinding.
134 
135  prepareElement(elem);
136 
137  if (dynamic_cast<ComputeJacobianThread *>(this))
138  if (_nl.getScalarVariables(_tid).size() > 0)
140 
142 }
143 
144 void
146 {
148  {
149  const auto & kernels = _tag_kernels->getActiveBlockObjects(_subdomain, _tid);
150  for (const auto & kernel : kernels)
151  compute(*kernel);
152  }
153 
154  if (_fe_problem.haveFV())
155  for (auto kernel : _fv_kernels)
156  compute(*kernel);
157 }
158 
159 void
160 NonlinearThread::onBoundary(const Elem * const elem,
161  const unsigned int side,
162  const BoundaryID bnd_id,
163  const Elem * const lower_d_elem /*=nullptr*/)
164 {
166  {
167  // Set up Sentinel class so that, after we swap in reinitMaterialsFace in prepareFace, even if
168  // one of our callees throws we remember to swap back during stack unwinding. We put our
169  // sentinel here as opposed to in prepareFace because we certainly don't want our materials
170  // swapped back before we proceed to residual/Jacobian computation
172 
173  prepareFace(elem, side, bnd_id, lower_d_elem);
174  computeOnBoundary(bnd_id, lower_d_elem);
175 
176  if (lower_d_elem)
177  accumulateLower();
178  }
179 }
180 
181 void
182 NonlinearThread::computeOnBoundary(BoundaryID bnd_id, const Elem * /*lower_d_elem*/)
183 {
184  const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
185  for (const auto & bc : bcs)
186  if (bc->shouldApply())
187  compute(*bc);
188 }
189 
190 void
191 NonlinearThread::onInterface(const Elem * elem, unsigned int side, BoundaryID bnd_id)
192 {
194  {
195 
196  // Pointer to the neighbor we are currently working on.
197  const Elem * neighbor = elem->neighbor_ptr(side);
198 
199  if (neighbor->active())
200  {
201  _fe_problem.reinitNeighbor(elem, side, _tid);
202 
203  // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
204  // still remember to swap back during stack unwinding. Note that face, boundary, and interface
205  // all operate with the same MaterialData object
207  _fe_problem.reinitMaterialsFaceOnBoundary(bnd_id, elem->subdomain_id(), _tid);
209 
211  _fe_problem.reinitMaterialsNeighborOnBoundary(bnd_id, neighbor->subdomain_id(), _tid);
212 
213  // Has to happen after face and neighbor properties have been computed. Note that we don't use
214  // a sentinel here because FEProblem::swapBackMaterialsFace is going to handle face materials,
215  // boundary materials, and interface materials (e.g. it queries the boundary material data
216  // with the current element and side
218 
219  computeOnInterface(bnd_id);
220 
222  }
223  }
224 }
225 
226 void
228 {
229  const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
230  for (const auto & interface_kernel : int_ks)
231  compute(*interface_kernel);
232 }
233 
234 void
235 NonlinearThread::onInternalSide(const Elem * elem, unsigned int side)
236 {
237  if (_should_execute_dg)
238  {
239  // Pointer to the neighbor we are currently working on.
240  const Elem * neighbor = elem->neighbor_ptr(side);
241 
243 
244  // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
245  // still remember to swap back during stack unwinding.
247  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
248 
250  _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
251 
252  computeOnInternalFace(neighbor);
253 
255  }
256  if (_subdomain_has_hdg)
257  {
258  // Set up Sentinel class so that, after we swap in reinitMaterialsFace in prepareFace, even if
259  // one of our callees throws we remember to swap back during stack unwinding. We put our
260  // sentinel here as opposed to in prepareFace because we certainly don't want our materials
261  // swapped back before we proceed to residual/Jacobian computation
263 
264  prepareFace(elem, side, Moose::INVALID_BOUNDARY_ID, nullptr);
266  }
267 }
268 
269 void
270 NonlinearThread::onExternalSide(const Elem * elem, unsigned int side)
271 {
272  // Check that we don't have any interface kernels defined on this boundary
273  const auto boundary_ids = _mesh.getBoundaryIDs(elem, side);
274 
275  bool has_interface_kernels = false;
276  for (const auto bid : boundary_ids)
278  has_interface_kernels = true;
279 
280  if (has_interface_kernels)
281  mooseError("Element ",
282  elem->id(),
283  " on side ",
284  side,
285  " is missing a neighbor (hence identified as an external side) but "
286  "has interface kernel(s) defined on the boundary.");
287 }
288 
289 void
291 {
292  const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid);
293  for (const auto & dg_kernel : dgks)
294  if (dg_kernel->hasBlocks(neighbor->subdomain_id()))
295  compute(*dg_kernel, neighbor);
296 }
297 
298 void
300 {
301  compute(static_cast<ResidualObject &>(kernel));
302 }
303 
304 void
306 {
307  compute(static_cast<ResidualObject &>(kernel));
308 }
309 
310 void
312 {
313  compute(static_cast<ResidualObject &>(bc));
314 }
315 
316 void
317 NonlinearThread::compute(DGKernelBase & dg, const Elem * /*neighbor*/)
318 {
319  compute(static_cast<ResidualObject &>(dg));
320 }
321 
322 void
324 {
325  compute(static_cast<ResidualObject &>(ik));
326 }
327 
328 void
329 NonlinearThread::postElement(const Elem * /*elem*/)
330 {
331  accumulate();
332 }
333 
334 void
336 {
338 }
339 
340 void
342 {
344  {
345  const auto & console = _fe_problem.console();
346  const auto execute_on = _fe_problem.getCurrentExecuteOnFlag();
347  console << "[DBG] Beginning elemental loop to compute " + objectType() + " on " << execute_on
348  << std::endl;
349  mooseDoOnce(
350  console << "[DBG] Execution order on each element:" << std::endl;
351  console << "[DBG] - kernels on element quadrature points" << std::endl;
352  console << "[DBG] - finite volume elemental kernels on element" << std::endl;
353  console << "[DBG] - integrated boundary conditions on element side quadrature points"
354  << std::endl;
355  console << "[DBG] - DG kernels on element side quadrature points" << std::endl;
356  console << "[DBG] - interface kernels on element side quadrature points" << std::endl;);
357  }
358 }
359 
360 void
362 {
363  // Number of objects executing is approximated by size of warehouses
364  const int num_objects = _kernels.size() + _fv_kernels.size() + _integrated_bcs.size() +
366  const auto & console = _fe_problem.console();
367  const auto block_name = _mesh.getSubdomainName(_subdomain);
368 
369  if (_fe_problem.shouldPrintExecution(_tid) && num_objects > 0)
370  {
371  if (_blocks_exec_printed.count(_subdomain))
372  return;
373  console << "[DBG] Ordering of " + objectType() + " Objects on block " << block_name << " ("
374  << _subdomain << ")" << std::endl;
376  {
377  console << "[DBG] Ordering of kernels:" << std::endl;
378  console << _kernels.activeObjectsToFormattedString() << std::endl;
379  }
380  if (_fv_kernels.size())
381  {
382  console << "[DBG] Ordering of FV elemental kernels:" << std::endl;
383  std::string fvkernels =
384  std::accumulate(_fv_kernels.begin() + 1,
385  _fv_kernels.end(),
386  _fv_kernels[0]->name(),
387  [](const std::string & str_out, FVElementalKernel * kernel)
388  { return str_out + " " + kernel->name(); });
389  console << ConsoleUtils::formatString(fvkernels, "[DBG]") << std::endl;
390  }
392  {
393  console << "[DBG] Ordering of DG kernels:" << std::endl;
394  console << _dg_kernels.activeObjectsToFormattedString() << std::endl;
395  }
396  }
397  else if (_fe_problem.shouldPrintExecution(_tid) && num_objects == 0 &&
399  console << "[DBG] No Active " + objectType() + " Objects on block " << block_name << " ("
400  << _subdomain << ")" << std::endl;
401 
403 }
404 
405 void
407 {
411  return;
412 
413  const auto & console = _fe_problem.console();
414  const auto b_name = _mesh.getBoundaryName(bid);
415  console << "[DBG] Ordering of " + objectType() + " Objects on boundary " << b_name << " (" << bid
416  << ")" << std::endl;
417 
419  {
420  console << "[DBG] Ordering of integrated boundary conditions:" << std::endl;
421  console << _integrated_bcs.activeObjectsToFormattedString() << std::endl;
422  }
423 
424  // We have not checked if we have a neighbor. This could be premature for saying we are executing
425  // interface kernels. However, we should assume the execution will happen on another side of the
426  // same boundary
428  {
429  console << "[DBG] Ordering of interface kernels:" << std::endl;
430  console << _interface_kernels.activeObjectsToFormattedString() << std::endl;
431  }
432 
433  _boundaries_exec_printed.insert(bid);
434 }
435 
436 void
437 NonlinearThread::prepareFace(const Elem * const elem,
438  const unsigned int side,
439  const BoundaryID bnd_id,
440  const Elem * const lower_d_elem)
441 {
442  _fe_problem.reinitElemFace(elem, side, _tid);
443 
444  // Needed to use lower-dimensional variables on Materials
445  if (lower_d_elem)
446  _fe_problem.reinitLowerDElem(lower_d_elem, _tid);
447 
448  if (bnd_id != Moose::INVALID_BOUNDARY_ID)
449  {
450  _fe_problem.reinitMaterialsFaceOnBoundary(bnd_id, elem->subdomain_id(), _tid);
452  }
453  // Currently only used by HDG
454  else
455  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
456 }
457 
458 bool
459 NonlinearThread::shouldComputeInternalSide(const Elem & elem, const Elem & neighbor) const
460 {
461  // ThreadedElementLoop<ConstElemRange>::shouldComputeInternalSide gets expensive on high
462  // h-refinement cases so we avoid it if possible
463  _should_execute_dg = false;
464  if (_subdomain_has_dg)
468 }
std::string activeObjectsToFormattedString(THREAD_ID tid=0, const std::string &prefix="[DBG]") const
Output the active content of the warehouse to a string, meant to be output to the console...
unsigned int size(THREAD_ID tid=0) const
Return how many kernels we store in the current warehouse.
virtual bool shouldComputeInternalSide(const Elem &elem, const Elem &neighbor) const
Whether to compute the internal side for the provided element-neighbor pair.
Base class for assembly-like calculations.
virtual void accumulate()=0
Add element residual/Jacobian into assembly global data.
virtual void accumulateLower()=0
Add lower-d residual/Jacobian into assembly global data.
const std::vector< MooseVariableScalar * > & getScalarVariables(THREAD_ID tid)
Definition: SystemBase.h:759
bool hasActiveBlockObjects(THREAD_ID tid=0) const
virtual void compute(ResidualObject &ro)=0
Will dispatch to computeResidual/computeJacobian/computeResidualAndJacobian based on the derived clas...
const std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
MooseObjectWarehouse< InterfaceKernelBase > * _ik_warehouse
virtual void computeOnBoundary(BoundaryID bnd_id, const Elem *lower_d_elem)
virtual bool haveFV() const override
returns true if this problem includes/needs finite volume functionality.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
const BoundaryID INVALID_BOUNDARY_ID
Definition: MooseTypes.C:22
MooseObjectTagWarehouse< IntegratedBCBase > & _integrated_bcs
Reference to BC storage structures.
void reinitMaterialsFaceOnBoundary(const BoundaryID boundary_id, const SubdomainID blk_id, const THREAD_ID tid, const bool swap_stateful=true, const std::deque< MaterialBase *> *const reinit_mats=nullptr)
reinit materials on element faces on a boundary (internal or external) This specific routine helps us...
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
std::vector< T * > & queryInto(std::vector< T *> &results, Args &&... args)
queryInto executes the query and stores the results in the given vector.
Definition: TheWarehouse.h:312
void reinitMaterialsBoundary(BoundaryID boundary_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase *> *reinit_mats=nullptr)
reinit materials on a boundary
const std::string & getBoundaryName(const BoundaryID boundary_id) const
Return the name of the boundary given the id.
Definition: MooseMesh.C:1814
const MaterialWarehouse & getMaterialWarehouse() const
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void prepareFace(const Elem *elem, unsigned int side, BoundaryID bnd_id=Moose::INVALID_BOUNDARY_ID, const Elem *lower_d_elem=nullptr)
Reinitialize variables and materials on a face.
void updateBlockVariableDependency(SubdomainID id, std::set< MooseVariableFieldBase *> &needed_moose_vars, THREAD_ID tid=0) const
const std::string & getSubdomainName(SubdomainID subdomain_id) const
Return the name of a block given an id.
Definition: MooseMesh.C:1785
void reinitMaterialsFace(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase *> *reinit_mats=nullptr)
reinit materials on element faces
bool shouldComputeInternalSide(const Elem &elem, const Elem &neighbor) const override
Whether to compute the internal side for the provided element-neighbor pair.
Serves as a base class for DGKernel and ADDGKernel.
Definition: DGKernelBase.h:32
virtual void reinitElemNeighborAndLowerD(const Elem *elem, unsigned int side, const THREAD_ID tid) override
virtual void onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id, const Elem *lower_d_elem=nullptr) override
Called when doing boundary assembling.
virtual void accumulateNeighbor()=0
Add neighbor residual/Jacobian into assembly global data.
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
virtual void swapBackMaterialsFace(const THREAD_ID tid)
FVElemental is used for calculating residual contributions from volume integral terms of a PDE where ...
virtual void setActiveElementalMooseVariables(const std::set< MooseVariableFEBase *> &moose_vars, const THREAD_ID tid) override
Set the MOOSE variables to be reinited on each element.
const bool _has_active_objects
Whether there are any active residual objects; otherwise we will do an early return.
bool shouldPrintExecution(const THREAD_ID tid) const
Check whether the problem should output execution orders at this time.
MooseObjectWarehouse< HDGKernel > * _hdg_warehouse
This is the common base class for the three main kernel types implemented in MOOSE, Kernel, VectorKernel and ArrayKernel.
Definition: KernelBase.h:23
TheWarehouse & theWarehouse() const
void printBlockExecutionInformation() const override
Print list of specific objects executed on each block and in which order.
void reinitMaterialsNeighbor(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true, const std::deque< MaterialBase *> *reinit_mats=nullptr)
reinit materials on the neighboring element face
MooseObjectTagWarehouse< KernelBase > & _kernels
void reinitMaterialsNeighborOnBoundary(const BoundaryID boundary_id, const SubdomainID blk_id, const THREAD_ID tid, const bool swap_stateful=true, const std::deque< MaterialBase *> *const reinit_mats=nullptr)
reinit materials on neighbor element (usually faces) on a boundary (internal or external) This specif...
std::string formatString(std::string message, const std::string &prefix)
Add new lines and prefixes to a string for pretty display in output NOTE: This makes a copy of the st...
Definition: ConsoleUtils.C:583
boundary_id_type BoundaryID
virtual void computeOnElement()
bool _subdomain_has_hdg
Whether the subdomain has HDGKernels.
virtual std::string objectType() const
Return what the loops is meant to compute.
NonlinearThread(FEProblemBase &fe_problem)
void printGeneralExecutionInformation() const override
Print information about the loop, mostly order of execution of objects.
unsigned int number() const
Gets the number of this system.
Definition: SystemBase.C:1158
virtual void computeOnInterface(BoundaryID bnd_id)
NonlinearSystemBase & _nl
Reference to the underlying NonlinearSystemBase.
virtual void onExternalSide(const Elem *elem, unsigned int side) override
Called when iterating over external sides (no side neighbor)
virtual void postElement(const Elem *) override
Called after the element assembly is done (including surface assembling)
virtual void operator()(const RangeType &range, bool bypass_threading=false)
virtual void operator()(const ConstElemRange &range, bool bypass_threading=false) override
void updateBlockMatPropDependency(SubdomainID id, std::unordered_set< unsigned int > &needed_mat_props, THREAD_ID tid=0, const bool producer_only=false) const
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
void updateBoundaryMatPropDependency(std::unordered_set< unsigned int > &needed_mat_props, THREAD_ID tid=0, const bool producer_only=false) const
virtual void swapBackMaterialsNeighbor(const THREAD_ID tid)
virtual void onInternalSide(const Elem *elem, unsigned int side) override
Called when doing internal edge assembling.
virtual void computeOnInternalFace()=0
std::set< SubdomainID > _blocks_exec_printed
Keep track of which blocks were visited.
tbb::split split
MooseObjectWarehouse< IntegratedBCBase > * _ibc_warehouse
virtual void reinitLowerDElem(const Elem *lower_d_elem, const THREAD_ID tid, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr) override
const ConsoleStream & console() const
Return console handle.
Definition: Problem.h:48
virtual void swapBackMaterials(const THREAD_ID tid)
void updateBlockFEVariableCoupledVectorTagDependency(SubdomainID id, std::set< TagID > &needed_fe_var_vector_tags, THREAD_ID tid=0) const
std::set< BoundaryID > _boundaries_exec_printed
Keep track of which boundaries were visited.
virtual void subdomainSetup(SubdomainID subdomain, const THREAD_ID tid)
bool _should_execute_dg
Whether DG kernels should be executed for a given elem-neighbor pairing.
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse...
Definition: TheWarehouse.h:467
virtual void accumulateNeighborLower()=0
Add neighbor and lower residual/Jacobian into assembly global data.
MooseObjectTagWarehouse< InterfaceKernelBase > & _interface_kernels
Reference to interface kernel storage structure.
Base class for deriving any boundary condition of a integrated type.
void printBoundaryExecutionInformation(const unsigned int bid) const override
Print list of specific objects executed on each boundary and in which order.
virtual void onInterface(const Elem *elem, unsigned int side, BoundaryID bnd_id) override
Called when doing interface assembling.
void reinitElemFace(const Elem *elem, unsigned int side, BoundaryID, const THREAD_ID tid)
InterfaceKernelBase is the base class for all InterfaceKernel type classes.
virtual void determineObjectWarehouses()=0
Determine the objects we will actually compute based on vector/matrix tag information.
SubdomainID _subdomain
The subdomain for the current element.
MooseObjectWarehouse< KernelBase > * _tag_kernels
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
Returns a vector of boundary IDs for the requested element on the requested side. ...
MooseObjectWarehouse< DGKernelBase > * _dg_warehouse
virtual void reinitNeighbor(const Elem *elem, unsigned int side, const THREAD_ID tid) override
virtual void setActiveFEVariableCoupleableVectorTags(std::set< TagID > &vtags, const THREAD_ID tid) override
virtual void onElement(const Elem *elem) override
Assembly of the element (not including surface assembly)
void reinitMaterialsInterface(BoundaryID boundary_id, const THREAD_ID tid, bool swap_stateful=true)
void updateBoundaryVariableDependency(std::set< MooseVariableFieldBase *> &needed_moose_vars, THREAD_ID tid=0) const
std::vector< FVElementalKernel * > _fv_kernels
Current subdomain FVElementalKernels.
void prepareMaterials(const std::unordered_set< unsigned int > &consumer_needed_mat_props, const SubdomainID blk_id, const THREAD_ID tid)
Add the MooseVariables and the material properties that the current materials depend on to the depend...
virtual void reinitOffDiagScalars(const THREAD_ID tid) override
virtual void post() override
Called after the element range loop.
MooseObjectTagWarehouse< DGKernelBase > & _dg_kernels
Reference to DGKernel storage structure.
virtual ~NonlinearThread()
bool _subdomain_has_dg
Whether the subdomain has DGKernels.
virtual void subdomainChanged() override
Called every time the current subdomain changes (i.e.
The "SwapBackSentinel" class&#39;s destructor guarantees that FEProblemBase::swapBackMaterials{Face,Neighbor}() is called even when an exception is thrown from FEProblemBase::reinitMaterials{Face,Neighbor}.