27#include "libmesh/numeric_vector.h"
33 _query_subdomain(_query),
34 _query_boundary(_query),
35 _aux_sys(problem.getAuxiliarySystem())
43 _query_subdomain(x._query_subdomain),
44 _query_boundary(x._query_boundary),
55 std::vector<UserObject *> objs;
65 std::vector<UserObject *> side_objs;
69 .queryInto(side_objs);
71 objs.insert(objs.begin(), side_objs.begin(), side_objs.end());
76 std::set<MooseVariableFEBase *> needed_moose_vars;
77 std::unordered_set<unsigned int> needed_mat_props;
78 std::set<TagID> needed_fe_var_vector_tags;
79 for (
const auto obj : objs)
85 needed_moose_vars.insert(v_deps.begin(), v_deps.end());
92 needed_mat_props.insert(m_deps.begin(), m_deps.end());
99 needed_fe_var_vector_tags.insert(tag_deps.begin(), tag_deps.end());
102 obj->subdomainSetup();
133 if (uo->hasWritableCoupledVariables())
134 for (
auto * var : uo->getWritableCoupledVariables())
140 uo->preExecuteOnElement();
141 uo->executeOnElement();
149 for (
const auto & jvar : jacobian_moose_vars)
151 unsigned int jvar_id = jvar->number();
152 auto && dof_indices = jvar->dofIndices();
156 uo->executeJacobianWrapper(jvar_id, dof_indices);
165 const auto cache_key = std::make_pair(bnd_id, subdomain_id);
167 auto & cache = cache_it->second;
174 std::vector<UserObject *> userobjs;
177 std::vector<const MaterialPropertyInterface *> material_consumers;
178 material_consumers.reserve(userobjs.size() +
_domain_objs.size());
180 const auto add_material_consumers = [&material_consumers](
const auto & objects)
182 for (
const auto *
const object : objects)
184 material_consumers.push_back(consumer);
187 add_material_consumers(userobjs);
190 material_consumers, bnd_id, subdomain_id, cache.face_materials, cache.boundary_materials);
198 const auto cache_key = std::make_pair(subdomain_id, neighbor_subdomain_id);
200 auto & cache = cache_it->second;
205 std::vector<const MaterialPropertyInterface *> material_consumers;
207 const auto add_material_consumer = [&material_consumers](
const auto *
const object)
210 material_consumers.push_back(consumer);
214 if (!uo->blockRestricted() || uo->hasBlocks(neighbor_subdomain_id))
215 add_material_consumer(uo);
218 if (!uo->blockRestricted() || uo->hasBlocks(neighbor_subdomain_id))
219 add_material_consumer(uo);
225 if (face_materials.hasActiveBlockObjects(subdomain_id,
_tid))
227 material_consumers, face_materials.getActiveBlockObjects(subdomain_id,
_tid),
true);
230 if (neighbor_materials.hasActiveBlockObjects(neighbor_subdomain_id,
_tid))
233 neighbor_materials.getActiveBlockObjects(neighbor_subdomain_id,
_tid),
244 const std::vector<UserObject *> & interface_objs)
246 const auto cache_key = std::make_tuple(bnd_id, subdomain_id, neighbor_subdomain_id);
248 auto & cache = cache_it->second;
253 std::vector<const MaterialPropertyInterface *> material_consumers;
254 material_consumers.reserve(interface_objs.size() +
_all_domain_objs.size());
255 const auto add_material_consumer = [&material_consumers](
const auto *
const object)
258 material_consumers.push_back(consumer);
261 for (
const auto *
const uo : interface_objs)
262 add_material_consumer(uo);
265 if (uo->shouldExecuteOnInterface())
266 add_material_consumer(uo);
271 if (interface_materials.hasActiveBoundaryObjects(bnd_id,
_tid))
272 for (
const auto & material : interface_materials.getActiveBoundaryObjects(bnd_id,
_tid))
273 add_material_consumer(material.get());
276 material_consumers, bnd_id, subdomain_id, cache.face_materials, cache.boundary_materials);
278 const auto & neighbor_materials =
280 if (neighbor_materials.hasActiveBlockObjects(neighbor_subdomain_id,
_tid))
283 neighbor_materials.getActiveBlockObjects(neighbor_subdomain_id,
_tid),
293 const Elem * lower_d_elem )
295 std::vector<UserObject *> userobjs;
315 bnd_id, elem->subdomain_id(),
_tid,
true, &required_mats.face_materials);
318 for (
const auto & uo : userobjs)
323 uo->preExecuteOnBoundary();
324 uo->executeOnBoundary();
328 std::vector<ShapeSideUserObject *> shapers;
334 for (
const auto & jvar : jacobian_moose_vars)
336 unsigned int jvar_id = jvar->number();
337 auto && dof_indices = jvar->dofIndices();
341 for (
const auto & uo : shapers)
342 uo->executeJacobianWrapper(jvar_id, dof_indices);
351 const Elem * neighbor = elem->neighbor_ptr(side);
359 const auto & required_mats =
369 neighbor->subdomain_id(),
_tid,
true, &required_mats.neighbor_materials);
372 if (!uo->blockRestricted() || uo->hasBlocks(neighbor->subdomain_id()))
376 if (!uo->blockRestricted() || uo->hasBlocks(neighbor->subdomain_id()))
378 uo->preExecuteOnInternalSide();
379 uo->executeOnInternalSide();
390 uo->executeOnExternalSide(elem, side);
397 const Elem * neighbor = elem->neighbor_ptr(side);
398 if (!(neighbor->active()))
401 std::vector<UserObject *> interface_objs;
404 bool has_domain_objs =
false;
408 if (domain_uo->shouldExecuteOnInterface())
410 has_domain_objs =
true;
416 if (interface_objs.empty() && !has_domain_objs)
423 bnd_id, elem->subdomain_id(), neighbor->subdomain_id(), interface_objs);
430 bnd_id, elem->subdomain_id(),
_tid,
true, &required_mats.face_materials);
435 neighbor->subdomain_id(),
_tid,
true, &required_mats.neighbor_materials);
442 for (
const auto & uo : interface_objs)
446 if (uo->shouldExecuteOnInterface())
448 uo->preExecuteOnInterface();
449 uo->executeOnInterface();
472 console <<
"[DBG] Computing elemental user objects on " << execute_on << std::endl;
473 mooseDoOnce(console <<
"[DBG] Execution order of objects types on each element then its sides:"
476 console <<
"[DBG] - element user objects" << std::endl;
477 console <<
"[DBG] - domain user objects" << std::endl;
478 console <<
"[DBG] - element user objects contributing to the Jacobian" << std::endl;
481 console <<
"[DBG] - side user objects" << std::endl;
482 console <<
"[DBG] - domain user objects executing on sides" << std::endl;
483 console <<
"[DBG] - side user objects contributing to the Jacobian" << std::endl;
486 console <<
"[DBG] - internal side user objects" << std::endl;
487 console <<
"[DBG] - domain user objects executing on internal sides" << std::endl;
490 console <<
"[DBG] - interface user objects" << std::endl;
491 console <<
"[DBG] - domain user objects executing at interfaces" << std::endl;);
504 std::vector<ShapeSideUserObject *> shapers;
508 std::vector<SideUserObject *> side_uos;
512 std::vector<InterfaceUserObject *> interface_objs;
516 std::vector<const DomainUserObject *> domain_interface_uos;
518 if (domain_uo->shouldExecuteOnInterface())
519 domain_interface_uos.push_back(domain_uo);
524 interface_objs.size() + domain_interface_uos.size();
534 console <<
"[DBG] Ordering of User Objects on block " <<
_subdomain << std::endl;
536 printExecutionOrdering<ElementUserObject>(
_element_objs,
"element user objects");
537 printExecutionOrdering<DomainUserObject>(
_domain_objs,
"domain user objects");
539 printExecutionOrdering<ShapeElementUserObject>(
541 printExecutionOrdering<SideUserObject>(side_uos,
"side user objects");
543 printExecutionOrdering<ShapeSideUserObject>(shapers,
544 "side user objects contributing to the Jacobian");
546 "internal side user objects");
547 printExecutionOrdering<InterfaceUserObject>(interface_objs,
"interface user objects");
548 console <<
"[DBG] Only user objects active on local element/sides are executed" << std::endl;
551 console <<
"[DBG] No User Objects on block " <<
_subdomain <<
" on " << execute_on.name()
boundary_id_type BoundaryID
subdomain_id_type SubdomainID
Class for threaded computation of UserObjects.
std::vector< DomainUserObject * > _all_domain_objs
std::vector< ElementUserObject * > _element_objs
const InterfaceMaterialReinitCache & getInterfaceMaterialReinitCache(BoundaryID bnd_id, SubdomainID subdomain_id, SubdomainID neighbor_subdomain_id, const std::vector< UserObject * > &interface_objs)
Return the face, boundary, and neighbor materials required while executing on this interface.
virtual void post() override
Called after the element range loop.
virtual void onInternalSide(const Elem *elem, unsigned int side) override
Called when doing internal edge assembling.
const TheWarehouse::Query _query
virtual void onElement(const Elem *elem) override
Assembly of the element (not including surface assembly)
virtual void onInterface(const Elem *elem, unsigned int side, BoundaryID bnd_id) override
Called when doing interface assembling.
virtual void onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id, const Elem *lower_d_elem=nullptr) override
Called when doing boundary assembling.
void printBlockExecutionInformation() const override
Print information about the loop, mostly order of execution of particular objects.
const InternalSideMaterialReinitCache & getInternalSideMaterialReinitCache(SubdomainID subdomain_id, SubdomainID neighbor_subdomain_id)
Return the face and neighbor materials required while executing on this internal side.
void queryBoundary(Interfaces iface, BoundaryID bnd, std::vector< T > &results)
ComputeUserObjectsThread(FEProblemBase &problem, const TheWarehouse::Query &query)
void printGeneralExecutionInformation() const override
Print general information about the loop, like the ordering of class of objects.
void join(const ComputeUserObjectsThread &)
const BoundaryMaterialReinitCache & getBoundaryMaterialReinitCache(BoundaryID bnd_id, SubdomainID subdomain_id)
Return the exact face and boundary materials required while executing on this boundary.
virtual ~ComputeUserObjectsThread()
AuxiliarySystem & _aux_sys
std::map< std::pair< BoundaryID, SubdomainID >, BoundaryMaterialReinitCache > _boundary_material_reinit_cache
virtual void onExternalSide(const Elem *elem, unsigned int side) override
Called when iterating over external sides (no side neighbor)
std::vector< ShapeElementUserObject * > _shape_element_objs
std::map< std::pair< SubdomainID, SubdomainID >, InternalSideMaterialReinitCache > _internal_side_material_reinit_cache
void querySubdomain(Interfaces iface, std::vector< T > &results)
std::vector< DomainUserObject * > _domain_objs
std::map< std::tuple< BoundaryID, SubdomainID, SubdomainID >, InterfaceMaterialReinitCache > _interface_material_reinit_cache
virtual void subdomainChanged() override
Called every time the current subdomain changes (i.e.
std::vector< InternalSideUserObject * > _internal_side_objs
Interface for objects that needs coupling capabilities.
std::set< TagID > & getFEVariableCoupleableVectorTags()
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const MaterialWarehouse & getInterfaceMaterialsWarehouse() const
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
virtual void prepareFaceShapes(unsigned int var, const THREAD_ID tid) override
virtual void prepareShapes(unsigned int var, const THREAD_ID tid) override
virtual void reinitElem(const Elem *elem, const THREAD_ID tid) override
virtual void swapBackMaterialsFace(const THREAD_ID tid)
const std::vector< const MooseVariableFEBase * > & getUserObjectJacobianVariables(const THREAD_ID tid) const
const MaterialWarehouse & getMaterialWarehouse() const
void reinitMaterials(SubdomainID blk_id, const THREAD_ID tid, bool swap_stateful=true)
const MaterialWarehouse & getRegularMaterialsWarehouse() const
virtual void prepare(const Elem *elem, 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 clearActiveMaterialProperties(const THREAD_ID tid)
Clear the active material properties.
virtual void clearActiveElementalMooseVariables(const THREAD_ID tid) override
Clear the active elemental MooseVariableFEBase.
virtual void prepareFace(const Elem *elem, const THREAD_ID tid) override
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.
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 void subdomainSetup(SubdomainID subdomain, const THREAD_ID tid)
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
static std::deque< MaterialBase * > buildRequiredMaterials(const Consumers &mat_consumers, const std::vector< std::shared_ptr< MaterialBase > > &mats, const bool allow_stateful)
Build the materials required by a set of consumer objects.
An interface for accessing Materials.
virtual const std::unordered_set< unsigned int > & getMatPropDependencies() const
Retrieve the set of material properties that this object depends on.
void updateBlockFEVariableCoupledVectorTagDependency(SubdomainID id, std::set< TagID > &needed_fe_var_vector_tags, THREAD_ID tid=0) const
const std::set< MooseVariableFieldBase * > & getMooseVariableDependencies() const
Retrieve the set of MooseVariableFieldBase that this object depends on.
const ConsoleStream & console() const
Return console handle.
const bool & currentlyComputingJacobian() const
Returns true if the problem is in the process of computing the Jacobian.
The "SwapBackSentinel" class's destructor guarantees that FEProblemBase::swapBackMaterials{Face,...
NumericVector< Number > & solution()
QueryCache is a convenient way to construct and pass around (possible partially constructed) warehous...
QueryCache & condition(Args &&... args)
Adds a new condition to the query.
QueryCache clone() const
clone creates and returns an independent copy of the query in its current state.
SubdomainID _subdomain
The subdomain for the current element.
std::set< SubdomainID > _blocks_exec_printed
Keep track of which blocks were visited.
Base class for assembly-like calculations.
FEProblemBase & _fe_problem
void getRequiredBoundaryMaterials(const std::vector< const MaterialPropertyInterface * > &material_consumers, BoundaryID bnd_id, SubdomainID subdomain_id, std::deque< MaterialBase * > &required_face_materials, std::deque< MaterialBase * > &required_boundary_materials) const
Determine the face and boundary materials required by material property consumers.
const BoundaryID ANY_BOUNDARY_ID