16#include "libmesh/libmesh_exceptions.h"
17#include "libmesh/elem.h"
25template <
typename RangeType>
35 virtual void operator()(
const RangeType & range,
bool bypass_threading =
false);
79 const Elem * lower_d_elem =
nullptr);
92 const Elem * lower_d_elem =
nullptr);
207template <
typename RangeType>
212template <
typename RangeType>
219template <
typename RangeType>
224template <
typename RangeType>
233 _tid = bypass_threading ? 0 : puid.
id;
236 printGeneralExecutionInformation();
240 typename RangeType::const_iterator el = range.begin();
241 for (el = range.begin(); el != range.end(); ++el)
246 const Elem * elem = *el;
250 _old_subdomain = _subdomain;
251 _subdomain = elem->subdomain_id();
252 if (_subdomain != _old_subdomain)
255 printBlockExecutionInformation();
260 if (_mesh.interiorLowerDBlocks().count(elem->subdomain_id()) > 0 ||
261 _mesh.boundaryLowerDBlocks().count(elem->subdomain_id()) > 0)
267 const auto elem_boundary_ids = _mesh.getBoundaryIDs(elem);
268 for (
unsigned int side = 0; side < elem->n_sides(); side++)
270 const auto & boundary_ids = elem_boundary_ids[side];
271 const Elem * lower_d_elem = _mesh.getLowerDElem(elem, side);
273 for (
const auto bnd_id : boundary_ids)
275 preBoundary(elem, side, bnd_id, lower_d_elem);
276 printBoundaryExecutionInformation(bnd_id);
277 onBoundary(elem, side, bnd_id, lower_d_elem);
280 const Elem * neighbor = elem->neighbor_ptr(side);
283 preInternalSide(elem, side);
285 _old_neighbor_subdomain = _neighbor_subdomain;
286 _neighbor_subdomain = neighbor->subdomain_id();
287 if (_neighbor_subdomain != _old_neighbor_subdomain)
288 neighborSubdomainChanged();
290 if (shouldComputeInternalSide(*elem, *neighbor))
291 onInternalSide(elem, side);
293 for (
const auto bnd_id : boundary_ids)
294 onInterface(elem, side, bnd_id);
296 postInternalSide(elem, side);
299 onExternalSide(elem, side);
306 resetExecPrintedSets();
308 catch (MetaPhysicL::LogicError & e)
312 catch (std::exception & e)
316 if (!strstr(e.what(),
"Jacobian") && !strstr(e.what(),
"singular") &&
317 !strstr(e.what(),
"det != 0"))
320 mooseException(
"We caught a libMesh degeneracy exception in ThreadedElementLoopBase:\n",
326 caughtMooseException(e);
330template <
typename RangeType>
336template <
typename RangeType>
342template <
typename RangeType>
348template <
typename RangeType>
354template <
typename RangeType>
360template <
typename RangeType>
369template <
typename RangeType>
378template <
typename RangeType>
384template <
typename RangeType>
390template <
typename RangeType>
396template <
typename RangeType>
402template <
typename RangeType>
410template <
typename RangeType>
416template <
typename RangeType>
422template <
typename RangeType>
425 const Elem & neighbor)
const
432 mooseAssert(elem.active(),
"This method should never be called with an inactive element");
433 if (!neighbor.active())
441 const auto elem_level = elem.level(), neighbor_level = neighbor.level();
442 if (elem_level != neighbor_level)
443 return elem_level > neighbor_level;
445 const auto elem_p_level = elem.p_level(), neighbor_p_level = neighbor.p_level();
446 if (elem_p_level != neighbor_p_level)
447 return elem_p_level > neighbor_p_level;
449 return elem.id() < neighbor.id();
452template <
typename RangeType>
456 _blocks_exec_printed.clear();
457 _boundaries_exec_printed.clear();
boundary_id_type BoundaryID
Provides a way for users to bail out of the current solve.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Base class for assembly-like calculations.
virtual void onExternalSide(const Elem *elem, unsigned int side)
Called when iterating over external sides (no side neighbor)
ThreadedElementLoopBase(ThreadedElementLoopBase &x, Threads::split split)
virtual void caughtMooseException(MooseException &)
Called if a MooseException is caught anywhere during the computation.
virtual void onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id, const Elem *lower_d_elem=nullptr)
Called when doing boundary assembling.
virtual void printBoundaryExecutionInformation(const unsigned int) const
Print information about the particular ordering of objects on each boundary.
virtual void neighborSubdomainChanged()
Called every time the neighbor subdomain changes (i.e.
virtual void printGeneralExecutionInformation() const
Print information about the loop ordering.
virtual void onInterface(const Elem *elem, unsigned int side, BoundaryID bnd_id)
Called when doing interface assembling.
virtual bool keepGoing()
Whether or not the loop should continue.
ThreadedElementLoopBase(MooseMesh &mesh)
void resetExecPrintedSets() const
Resets the set of blocks and boundaries visited.
SubdomainID _old_subdomain
The subdomain for the last element.
virtual void preInternalSide(const Elem *elem, unsigned int side)
Called before evaluations on an element internal side.
virtual void operator()(const RangeType &range, bool bypass_threading=false)
virtual void postInternalSide(const Elem *elem, unsigned int side)
Called after evaluations on an element internal side.
virtual void subdomainChanged()
Called every time the current subdomain changes (i.e.
virtual void onInternalSide(const Elem *elem, unsigned int side)
Called when doing internal edge assembling.
virtual void preBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id, const Elem *lower_d_elem=nullptr)
Called before the boundary assembly.
virtual void onElement(const Elem *elem)
Assembly of the element (not including surface assembly)
virtual void postElement(const Elem *elem)
Called after the element assembly is done (including surface assembling)
virtual void preElement(const Elem *elem)
Called before the element assembly.
SubdomainID _old_neighbor_subdomain
The subdomain for the last neighbor.
SubdomainID _subdomain
The subdomain for the current element.
virtual ~ThreadedElementLoopBase()
SubdomainID _neighbor_subdomain
The subdomain for the current neighbor.
std::set< BoundaryID > _boundaries_exec_printed
Keep track of which boundaries were visited.
virtual void printBlockExecutionInformation() const
Print information about the particular ordering of objects on each block.
virtual void post()
Called after the element range loop.
virtual void pre()
Called before the element range loop.
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.
const SubdomainID INVALID_BLOCK_ID
void translateMetaPhysicLError(const MetaPhysicL::LogicError &)
emit a relatively clear error message when we catch a MetaPhysicL logic error