https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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 "AuxiliarySystem.h"
12#include "NonlinearSystem.h"
13#include "Problem.h"
14#include "FEProblem.h"
15#include "KernelBase.h"
16#include "IntegratedBCBase.h"
17#include "DGKernelBase.h"
18#include "InterfaceKernelBase.h"
19#include "Material.h"
20#include "TimeKernel.h"
21#include "SwapBackSentinel.h"
22#include "FVTimeKernel.h"
24#include "Assembly.h"
25
26#include "libmesh/threads.h"
27#include "libmesh/elem.h"
28#include "libmesh/fe_map.h"
29
31 : ThreadedElementLoop<ConstElemRange>(fe_problem),
32 _nl(fe_problem.currentNonlinearSystem()),
33 _num_cached(0),
34 _integrated_bcs(_nl.getIntegratedBCWarehouse()),
35 _dg_kernels(_nl.getDGKernelWarehouse()),
36 _interface_kernels(_nl.getInterfaceKernelWarehouse()),
37 _kernels(_nl.getKernelWarehouse()),
38 _hdg_kernels(_nl.getHDGKernelWarehouse()),
39 _has_active_objects(_integrated_bcs.hasActiveObjects() || _dg_kernels.hasActiveObjects() ||
40 _interface_kernels.hasActiveObjects() || _kernels.hasActiveObjects() ||
41 _fe_problem.haveFV()),
42 _should_execute_dg(false)
43{
44}
45
46// Splitting Constructor
48 : ThreadedElementLoop<ConstElemRange>(x, split),
49 _nl(x._nl),
50 _num_cached(x._num_cached),
51 _integrated_bcs(x._integrated_bcs),
52 _dg_kernels(x._dg_kernels),
53 _interface_kernels(x._interface_kernels),
54 _kernels(x._kernels),
55 _tag_kernels(x._tag_kernels),
56 _hdg_kernels(x._hdg_kernels),
57 _has_active_objects(x._has_active_objects),
58 _should_execute_dg(x._should_execute_dg)
59{
60}
61
63
64void
65NonlinearThread::operator()(const ConstElemRange & range, bool bypass_threading)
66{
69}
70
71void
73{
74 // This should come first to setup the residual objects before we do dependency determination of
75 // material properties and variables
77
79
80 // Update variable Dependencies
81 std::set<MooseVariableFEBase *> needed_moose_vars;
86
87 // Update FE variable coupleable vector tags
88 std::set<TagID> needed_fe_var_vector_tags;
90 _subdomain, needed_fe_var_vector_tags, _tid);
92 _subdomain, needed_fe_var_vector_tags, _tid);
94 _subdomain, needed_fe_var_vector_tags, _tid);
95
96 // Update material dependencies
97 std::unordered_set<unsigned int> needed_mat_props;
102
103 if (_fe_problem.haveFV())
104 {
105 // Re-query the finite volume elemental kernels
106 _fv_kernels.clear();
108 .query()
109 .template condition<AttribSysNum>(_nl.number())
110 .template condition<AttribSystem>("FVElementalKernel")
111 .template condition<AttribSubdomains>(_subdomain)
112 .template condition<AttribThread>(_tid)
114 for (const auto fv_kernel : _fv_kernels)
116 const auto & fv_mv_deps = fv_kernel->getMooseVariableDependencies();
117 needed_moose_vars.insert(fv_mv_deps.begin(), fv_mv_deps.end());
118 const auto & fv_mp_deps = fv_kernel->getMatPropDependencies();
119 needed_mat_props.insert(fv_mp_deps.begin(), fv_mp_deps.end());
120 }
121 }
122
123 // Cache these to avoid computing them on every side
126
128 _fe_problem.setActiveFEVariableCoupleableVectorTags(needed_fe_var_vector_tags, _tid);
129 _fe_problem.prepareMaterials(needed_mat_props, _subdomain, _tid);
130}
131
132void
133NonlinearThread::onElement(const Elem * const elem)
134{
135 // Set up Sentinel class so that, even if reinitMaterials() throws in prepareElement, we
136 // still remember to swap back during stack unwinding.
138
139 prepareElement(elem);
140
141 if (dynamic_cast<ComputeJacobianThread *>(this))
142 if (_nl.getScalarVariables(_tid).size() > 0)
144
146}
147
148void
150{
152 {
153 const auto & kernels = _tag_kernels->getActiveBlockObjects(_subdomain, _tid);
154 for (const auto & kernel : kernels)
155 compute(*kernel);
156 }
157
158 if (_fe_problem.haveFV())
159 for (auto kernel : _fv_kernels)
160 compute(*kernel);
161}
162
163void
164NonlinearThread::onBoundary(const Elem * const elem,
165 const unsigned int side,
166 const BoundaryID bnd_id,
167 const Elem * const lower_d_elem /*=nullptr*/)
168{
170 {
171 // Set up Sentinel class so that, after we swap in reinitMaterialsFace in prepareFace, even if
172 // one of our callees throws we remember to swap back during stack unwinding. We put our
173 // sentinel here as opposed to in prepareFace because we certainly don't want our materials
174 // swapped back before we proceed to residual/Jacobian computation
176
177 prepareFace(elem, side, bnd_id, lower_d_elem);
178 computeOnBoundary(bnd_id, lower_d_elem);
179
180 if (lower_d_elem)
182 }
183}
184
185void
186NonlinearThread::computeOnBoundary(BoundaryID bnd_id, const Elem * /*lower_d_elem*/)
187{
188 const auto & bcs = _ibc_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
189 for (const auto & bc : bcs)
190 if (bc->shouldApply())
191 compute(*bc);
192}
193
194void
195NonlinearThread::onInterface(const Elem * elem, unsigned int side, BoundaryID bnd_id)
196{
198 {
199
200 // Pointer to the neighbor we are currently working on.
201 const Elem * neighbor = elem->neighbor_ptr(side);
202
203 if (neighbor->active())
204 {
205 _fe_problem.reinitNeighbor(elem, side, _tid);
206
207 // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
208 // still remember to swap back during stack unwinding. Note that face, boundary, and interface
209 // all operate with the same MaterialData object
211 _fe_problem.reinitMaterialsFaceOnBoundary(bnd_id, elem->subdomain_id(), _tid);
213
215 _fe_problem.reinitMaterialsNeighborOnBoundary(bnd_id, neighbor->subdomain_id(), _tid);
216
217 // Has to happen after face and neighbor properties have been computed. Note that we don't use
218 // a sentinel here because FEProblem::swapBackMaterialsFace is going to handle face materials,
219 // boundary materials, and interface materials (e.g. it queries the boundary material data
220 // with the current element and side
222
223 computeOnInterface(bnd_id);
224
226 }
227 else
228 {
229 // elem's neighbor across this side is an inactive ancestor: elem is on the coarser side of
230 // an interface with h-refinement on the other side.
231 // The real geometric neighbors are the active children of this ancestor, so visit each of
232 // them individually instead of silently skipping the whole face.
233 std::vector<const Elem *> fine_neighbors;
234 neighbor->active_family_tree_by_neighbor(fine_neighbors, elem);
235 for (const Elem * fine_neighbor : fine_neighbors)
236 onInterfaceWithHRefinementMismatch(elem, side, bnd_id, fine_neighbor);
237 }
238 }
239}
240
241void
243 unsigned int side,
244 BoundaryID bnd_id,
245 const Elem * fine_neighbor)
246{
248 mooseError("InterfaceKernel '",
249 _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid)[0]->name(),
250 "' is defined on boundary ",
251 bnd_id,
252 ", whose primary (boundary-tagged) side is coarser than its paired side. This "
253 "case is not supported with a displaced mesh problem: the displaced problem's "
254 "assembly is not reinitialized on these faces, and the borrowed integration "
255 "weight used to handle the mismatched refinement is not AD-differentiable with "
256 "respect to mesh displacement.");
257
258 const unsigned int fine_side = fine_neighbor->which_neighbor_am_i(elem);
259
260 // Measure the fine neighbor's own natural face quadrature: these physical points and weights
261 // are the correct integration measure for the portion of elem's face that fine_neighbor
262 // actually covers. Call this directly on the Assembly object (not through FEProblemBase) so no
263 // variable/dof binding happens for fine_neighbor in the "elem" role.
265 current_assembly.reinitElemFaceRef(fine_neighbor, fine_side, TOLERANCE, nullptr, nullptr);
266 const auto fine_phys_points = current_assembly.qPointsFace().stdVector();
267 const auto fine_phys_JxW = current_assembly.JxWFace().stdVector();
268
269 // Find elem's own side-local reference coordinates for those same physical points.
270 const Elem & elem_side_elem = _elem_side_builder(*elem, side);
271 std::vector<Point> elem_side_ref_points;
273 elem_side_elem.dim(), &elem_side_elem, fine_phys_points, elem_side_ref_points);
274
275 // Measure elem's own local Jacobian at those points using dummy unit weights, then rescale so
276 // that elem's face JxW, once bound for real below, exactly matches fine_neighbor's physical
277 // weight computed above.
278 current_assembly.reinitElemFaceRef(elem, side, TOLERANCE, &elem_side_ref_points, nullptr);
279 const auto elem_dummy_JxW = current_assembly.JxWFace().stdVector();
280 std::vector<Real> elem_ref_weights(fine_phys_JxW.size());
281 for (const auto qp : index_range(elem_ref_weights))
282 elem_ref_weights[qp] = fine_phys_JxW[qp] / elem_dummy_JxW[qp];
283
284 // Bind elem's (primary side) variable to its own dofs, with the face reinitialized at the
285 // corrected points/weights above. elem's residual/Jacobian contribution must accumulate
286 // additively across every fine neighbor of this (elem, side) visit, since each one only covers
287 // a fraction of elem's face; that local storage was already correctly prepared and zeroed
288 // exactly once for this element by FEProblemBase::prepare() before this side loop ever started.
289 // The loop below calls Assembly::reinitElemFaceRef() directly rather than the
290 // FEProblemBase/SubProblem method of the same name: that convenience bundle also calls
291 // Assembly::prepareResidual()/prepareJacobianBlock(), which would unconditionally re-zero elem's
292 // local residual/Jacobian storage, discarding the prior fine neighbors' contributions as well as
293 // every contribution already accumulated earlier in this element's visit (volumetric Kernels,
294 // IntegratedBCs and InterfaceKernels on other sides, etc.). elem's dof indices don't change
295 // across fine neighbors, so reinitializing the face at the new points/weights and recomputing
296 // variable values from them is all that is needed; no further dof preparation step is required.
297 for (const auto sys_num : make_range(_fe_problem.numNonlinearSystems()))
298 {
299 _fe_problem.assembly(_tid, sys_num)
300 .reinitElemFaceRef(elem, side, TOLERANCE, &elem_side_ref_points, &elem_ref_weights);
302 }
303 // Auxiliary variables use the system 0 assembly reinitialized above
305
307 _fe_problem.reinitMaterialsFaceOnBoundary(bnd_id, elem->subdomain_id(), _tid);
309
310 // Bind the neighbor variable to fine_neighbor's own dofs at the matching physical points.
312 _fe_problem.reinitNeighborPhys(fine_neighbor, fine_side, fine_phys_points, _tid);
313
315 _fe_problem.reinitMaterialsNeighborOnBoundary(bnd_id, fine_neighbor->subdomain_id(), _tid);
316
318
319 computeOnInterface(bnd_id);
320
322}
323
324void
326{
327 const auto & int_ks = _ik_warehouse->getActiveBoundaryObjects(bnd_id, _tid);
328 for (const auto & interface_kernel : int_ks)
329 compute(*interface_kernel);
330}
331
332void
333NonlinearThread::onInternalSide(const Elem * elem, unsigned int side)
334{
336 {
337 // Pointer to the neighbor we are currently working on.
338 const Elem * neighbor = elem->neighbor_ptr(side);
339
341
342 // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
343 // still remember to swap back during stack unwinding.
345 _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
346
348 _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
349
350 computeOnInternalFace(neighbor);
351
353 }
355 {
356 // Set up Sentinel class so that, after we swap in reinitMaterialsFace in prepareFace, even if
357 // one of our callees throws we remember to swap back during stack unwinding. We put our
358 // sentinel here as opposed to in prepareFace because we certainly don't want our materials
359 // swapped back before we proceed to residual/Jacobian computation
361
362 prepareFace(elem, side, Moose::INVALID_BOUNDARY_ID, nullptr);
364 }
365}
366
367void
368NonlinearThread::onExternalSide(const Elem * elem, unsigned int side)
369{
370 // Check that we don't have any interface kernels defined on this boundary
371 const auto boundary_ids = _mesh.getBoundaryIDs(elem, side);
372
373 bool has_interface_kernels = false;
374 for (const auto bid : boundary_ids)
376 has_interface_kernels = true;
377
378 if (has_interface_kernels)
379 mooseError("Element ",
380 elem->id(),
381 " on side ",
382 side,
383 " is missing a neighbor (hence identified as an external side) but "
384 "has interface kernel(s) defined on the boundary.");
385}
386
387void
389{
390 const auto & dgks = _dg_warehouse->getActiveBlockObjects(_subdomain, _tid);
391 for (const auto & dg_kernel : dgks)
392 if (dg_kernel->hasBlocks(neighbor->subdomain_id()))
393 compute(*dg_kernel, neighbor);
394}
395
396void
398{
399 compute(cast_ref<ResidualObject &>(kernel));
400}
401
402void
404{
405 compute(cast_ref<ResidualObject &>(kernel));
406}
407
408void
410{
411 compute(cast_ref<ResidualObject &>(bc));
412}
413
414void
415NonlinearThread::compute(DGKernelBase & dg, const Elem * /*neighbor*/)
416{
417 compute(cast_ref<ResidualObject &>(dg));
418}
419
420void
422{
423 compute(cast_ref<ResidualObject &>(ik));
424}
425
426void
427NonlinearThread::postElement(const Elem * /*elem*/)
428{
429 accumulate();
430}
431
432void
437
438void
440{
442 {
443 const auto & console = _fe_problem.console();
444 const auto execute_on = _fe_problem.getCurrentExecuteOnFlag();
445 console << "[DBG] Beginning elemental loop to compute " + objectType() + " on " << execute_on
446 << std::endl;
447 mooseDoOnce(
448 console << "[DBG] Execution order on each element:" << std::endl;
449 console << "[DBG] - kernels on element quadrature points" << std::endl;
450 console << "[DBG] - finite volume elemental kernels on element" << std::endl;
451 console << "[DBG] - integrated boundary conditions on element side quadrature points"
452 << std::endl;
453 console << "[DBG] - DG kernels on element side quadrature points" << std::endl;
454 console << "[DBG] - interface kernels on element side quadrature points" << std::endl;);
455 }
456}
457
458void
460{
461 // Number of objects executing is approximated by size of warehouses
462 const int num_objects = _kernels.size() + _fv_kernels.size() + _integrated_bcs.size() +
464 const auto & console = _fe_problem.console();
465 const auto block_name = _mesh.getSubdomainName(_subdomain);
466
467 if (_fe_problem.shouldPrintExecution(_tid) && num_objects > 0)
468 {
470 return;
471 console << "[DBG] Ordering of " + objectType() + " Objects on block " << block_name << " ("
472 << _subdomain << ")" << std::endl;
474 {
475 console << "[DBG] Ordering of kernels:" << std::endl;
476 console << _kernels.activeObjectsToFormattedString() << std::endl;
477 }
478 if (_fv_kernels.size())
479 {
480 console << "[DBG] Ordering of FV elemental kernels:" << std::endl;
481 std::string fvkernels =
482 std::accumulate(_fv_kernels.begin() + 1,
483 _fv_kernels.end(),
484 _fv_kernels[0]->name(),
485 [](const std::string & str_out, FVElementalKernel * kernel)
486 { return str_out + " " + kernel->name(); });
487 console << ConsoleUtils::formatString(fvkernels, "[DBG]") << std::endl;
488 }
490 {
491 console << "[DBG] Ordering of DG kernels:" << std::endl;
492 console << _dg_kernels.activeObjectsToFormattedString() << std::endl;
493 }
494 }
495 else if (_fe_problem.shouldPrintExecution(_tid) && num_objects == 0 &&
497 console << "[DBG] No Active " + objectType() + " Objects on block " << block_name << " ("
498 << _subdomain << ")" << std::endl;
499
501}
502
503void
505{
509 return;
510
511 const auto & console = _fe_problem.console();
512 const auto b_name = _mesh.getBoundaryName(bid);
513 console << "[DBG] Ordering of " + objectType() + " Objects on boundary " << b_name << " (" << bid
514 << ")" << std::endl;
515
517 {
518 console << "[DBG] Ordering of integrated boundary conditions:" << std::endl;
519 console << _integrated_bcs.activeObjectsToFormattedString() << std::endl;
520 }
521
522 // We have not checked if we have a neighbor. This could be premature for saying we are executing
523 // interface kernels. However, we should assume the execution will happen on another side of the
524 // same boundary
526 {
527 console << "[DBG] Ordering of interface kernels:" << std::endl;
528 console << _interface_kernels.activeObjectsToFormattedString() << std::endl;
529 }
530
531 _boundaries_exec_printed.insert(bid);
532}
533
534void
535NonlinearThread::prepareFace(const Elem * const elem,
536 const unsigned int side,
537 const BoundaryID bnd_id,
538 const Elem * const lower_d_elem)
539{
540 _fe_problem.reinitElemFace(elem, side, _tid);
541
542 // Needed to use lower-dimensional variables on Materials
543 if (lower_d_elem)
544 _fe_problem.reinitLowerDElem(lower_d_elem, _tid);
545
546 if (bnd_id != Moose::INVALID_BOUNDARY_ID)
547 {
548 _fe_problem.reinitMaterialsFaceOnBoundary(bnd_id, elem->subdomain_id(), _tid);
550 }
551 // Currently only used by HDG
552 else
553 _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
554}
555
556bool
557NonlinearThread::shouldComputeInternalSide(const Elem & elem, const Elem & neighbor) const
558{
559 // ThreadedElementLoop<ConstElemRange>::shouldComputeInternalSide gets expensive on high
560 // h-refinement cases so we avoid it if possible
561 _should_execute_dg = false;
566}
boundary_id_type BoundaryID
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Keeps track of stuff related to assembling.
Definition Assembly.h:102
void reinitElemFaceRef(const Elem *elem, unsigned int elem_side, Real tolerance, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)
Reinitialize FE data for the given element on the given side, optionally with a given set of referenc...
Definition Assembly.C:2058
const MooseArray< Point > & qPointsFace() const
Returns the reference to the current quadrature being used.
Definition Assembly.h:337
const MooseArray< Real > & JxWFace() const
Returns the reference to the transformed jacobian weights on a current face.
Definition Assembly.h:343
virtual void reinitElemFace(const Elem *elem, unsigned int side, THREAD_ID tid) override
Reinit assembly info for a side of an element.
Serves as a base class for DGKernel and ADDGKernel.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual void reinitNeighborPhys(const Elem *neighbor, unsigned int neighbor_side, const std::vector< Point > &physical_points, const THREAD_ID tid) override
virtual bool haveFV() const override
returns true if this problem includes/needs finite volume functionality.
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
AuxiliarySystem & getAuxiliarySystem()
virtual void reinitOffDiagScalars(const THREAD_ID tid) override
virtual std::size_t numNonlinearSystems() const override
virtual void swapBackMaterialsFace(const THREAD_ID tid)
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
const MaterialWarehouse & getMaterialWarehouse() const
virtual void reinitElemNeighborAndLowerD(const Elem *elem, unsigned int side, const THREAD_ID tid) override
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
virtual void swapBackMaterialsNeighbor(const THREAD_ID tid)
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...
void reinitElemFace(const Elem *elem, unsigned int side, BoundaryID, const THREAD_ID tid)
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 ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
virtual unsigned int currentNlSysNum() const override
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...
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
virtual void setActiveElementalMooseVariables(const std::set< MooseVariableFEBase * > &moose_vars, const THREAD_ID tid) override
Set the MOOSE variables to be reinited on each element.
virtual void swapBackMaterials(const THREAD_ID tid)
virtual void setActiveFEVariableCoupleableVectorTags(std::set< TagID > &vtags, const THREAD_ID tid) override
bool shouldPrintExecution(const THREAD_ID tid) const
Check whether the problem should output execution orders at this time.
virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num) override
TheWarehouse & theWarehouse() const
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
virtual void subdomainSetup(SubdomainID subdomain, const THREAD_ID tid)
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...
void reinitMaterialsInterface(BoundaryID boundary_id, const THREAD_ID tid, bool swap_stateful=true)
virtual void reinitNeighbor(const Elem *elem, unsigned int side, const THREAD_ID tid) override
virtual void setNeighborSubdomainID(const Elem *elem, unsigned int side, const THREAD_ID tid) override
FVElemental is used for calculating residual contributions from volume integral terms of a PDE where ...
Base class for deriving any boundary condition of a integrated type.
InterfaceKernelBase is the base class for all InterfaceKernel type classes.
This is the common base class for the three main kernel types implemented in MOOSE,...
Definition KernelBase.h:29
std::vector< T > stdVector() const
Extremely inefficient way to produce a std::vector from a MooseArray!
Definition MooseArray.h:344
const std::string & getBoundaryName(const BoundaryID boundary_id) const
Return the name of the boundary given the id.
Definition MooseMesh.C:1743
const std::string & getSubdomainName(SubdomainID subdomain_id) const
Return the name of a block given an id.
Definition MooseMesh.C:1714
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.
Definition MooseMesh.C:2990
unsigned int size(THREAD_ID tid=0) const
Return how many kernels we store in the current warehouse.
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.
const std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
void updateBlockMatPropDependency(SubdomainID id, std::unordered_set< unsigned int > &needed_mat_props, THREAD_ID tid=0, const bool producer_only=false) const
void updateBlockFEVariableCoupledVectorTagDependency(SubdomainID id, std::set< TagID > &needed_fe_var_vector_tags, THREAD_ID tid=0) const
void updateBoundaryVariableDependency(std::set< MooseVariableFieldBase * > &needed_moose_vars, THREAD_ID tid=0) const
void updateBlockVariableDependency(SubdomainID id, std::set< MooseVariableFieldBase * > &needed_moose_vars, THREAD_ID tid=0) const
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
bool hasActiveBlockObjects(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
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
MooseObjectTagWarehouse< KernelBase > & _kernels
virtual std::string objectType() const
Return what the loops is meant to compute.
virtual void onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id, const Elem *lower_d_elem=nullptr) override
Called when doing boundary assembling.
bool shouldComputeInternalSide(const Elem &elem, const Elem &neighbor) const override
Whether to compute the internal side for the provided element-neighbor pair.
virtual void onInternalSide(const Elem *elem, unsigned int side) override
Called when doing internal edge assembling.
NonlinearThread(FEProblemBase &fe_problem)
void onInterfaceWithHRefinementMismatch(const Elem *elem, unsigned int side, BoundaryID bnd_id, const Elem *fine_neighbor)
Compute and accumulate the interface kernel contribution from a single active fine neighbor when elem...
MooseObjectTagWarehouse< IntegratedBCBase > & _integrated_bcs
Reference to BC storage structures.
virtual void accumulateNeighbor()=0
Add neighbor residual/Jacobian into assembly global data.
virtual void operator()(const ConstElemRange &range, bool bypass_threading=false) override
virtual void determineObjectWarehouses()=0
Determine the objects we will actually compute based on vector/matrix tag information.
virtual void computeOnInterface(BoundaryID bnd_id)
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.
MooseObjectWarehouse< InterfaceKernelBase > * _ik_warehouse
bool _subdomain_has_dg
Whether the subdomain has DGKernels.
virtual void computeOnBoundary(BoundaryID bnd_id, const Elem *lower_d_elem)
MooseObjectTagWarehouse< DGKernelBase > & _dg_kernels
Reference to DGKernel storage structure.
virtual void post() override
Called after the element range loop.
virtual void accumulateNeighborLower()=0
Add neighbor and lower residual/Jacobian into assembly global data.
void printBlockExecutionInformation() const override
Print list of specific objects executed on each block and in which order.
virtual void accumulate()=0
Add element residual/Jacobian into assembly global data.
virtual void onExternalSide(const Elem *elem, unsigned int side) override
Called when iterating over external sides (no side neighbor)
virtual void compute(ResidualObject &ro)=0
Will dispatch to computeResidual/computeJacobian/computeResidualAndJacobian based on the derived clas...
virtual void computeOnElement()
virtual void computeOnInternalFace()=0
std::vector< FVElementalKernel * > _fv_kernels
Current subdomain FVElementalKernels.
bool _subdomain_has_hdg
Whether the subdomain has HDGKernels.
NonlinearSystemBase & _nl
Reference to the underlying NonlinearSystemBase.
void printBoundaryExecutionInformation(const unsigned int bid) const override
Print list of specific objects executed on each boundary and in which order.
virtual void subdomainChanged() override
Called every time the current subdomain changes (i.e.
libMesh::ElemSideBuilder _elem_side_builder
Builds (and caches) the side element for elem/side pairs in onInterfaceWithHRefinementMismatch.
const bool _has_active_objects
Whether there are any active residual objects; otherwise we will do an early return.
MooseObjectWarehouse< DGKernelBase > * _dg_warehouse
MooseObjectWarehouse< HDGKernel > * _hdg_warehouse
MooseObjectWarehouse< KernelBase > * _tag_kernels
void printGeneralExecutionInformation() const override
Print information about the loop, mostly order of execution of objects.
virtual ~NonlinearThread()
MooseObjectTagWarehouse< InterfaceKernelBase > & _interface_kernels
Reference to interface kernel storage structure.
virtual void accumulateLower()=0
Add lower-d residual/Jacobian into assembly global data.
virtual void onInterface(const Elem *elem, unsigned int side, BoundaryID bnd_id) override
Called when doing interface assembling.
virtual void postElement(const Elem *) override
Called after the element assembly is done (including surface assembling)
MooseObjectWarehouse< IntegratedBCBase > * _ibc_warehouse
bool _should_execute_dg
Whether DG kernels should be executed for a given elem-neighbor pairing.
virtual void onElement(const Elem *elem) override
Assembly of the element (not including surface assembly)
const ConsoleStream & console() const
Return console handle.
Definition Problem.h:48
The "SwapBackSentinel" class's destructor guarantees that FEProblemBase::swapBackMaterials{Face,...
unsigned int number() const
Gets the number of this system.
virtual void reinitElemFace(const Elem *elem, unsigned int side, THREAD_ID tid)
Reinit assembly info for a side of an element.
Definition SystemBase.C:368
const std::vector< MooseVariableScalar * > & getScalarVariables(THREAD_ID tid)
Definition SystemBase.h:789
std::vector< T * > & queryInto(std::vector< T * > &results, Args &&... args)
queryInto executes the query and stores the results in the given vector.
Query query()
query creates and returns an initialized a query object for querying objects from the warehouse.
virtual void operator()(const RangeType &range, bool bypass_threading=false)
SubdomainID _subdomain
The subdomain for the current element.
std::set< BoundaryID > _boundaries_exec_printed
Keep track of which boundaries were visited.
virtual bool shouldComputeInternalSide(const Elem &elem, const Elem &neighbor) const
Whether to compute the internal side for the provided element-neighbor pair.
std::set< SubdomainID > _blocks_exec_printed
Keep track of which blocks were visited.
Base class for assembly-like calculations.
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
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...
const BoundaryID INVALID_BOUNDARY_ID
Definition MooseTypes.C:22