https://mooseframework.inl.gov
ComputeUserObjectsThread.h
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 #pragma once
11 
12 // MOOSE includes
13 #include "ThreadedElementLoop.h"
14 #include "ExecFlagEnum.h"
15 #include "AuxiliarySystem.h"
16 
17 #include "libmesh/elem_range.h"
18 
19 #include <map>
20 
22 class ElementUserObject;
25 class DomainUserObject;
26 
27 // libMesh forward declarations
28 namespace libMesh
29 {
30 template <typename T>
31 class NumericVector;
32 }
33 
37 class ComputeUserObjectsThread : public ThreadedElementLoop<ConstElemRange>
38 {
39 public:
41  // Splitting Constructor
43 
44  virtual ~ComputeUserObjectsThread();
45 
46  virtual void onElement(const Elem * elem) override;
47  virtual void onBoundary(const Elem * elem,
48  unsigned int side,
49  BoundaryID bnd_id,
50  const Elem * lower_d_elem = nullptr) override;
51  virtual void onInternalSide(const Elem * elem, unsigned int side) override;
52  virtual void onExternalSide(const Elem * elem, unsigned int side) override;
53  virtual void onInterface(const Elem * elem, unsigned int side, BoundaryID bnd_id) override;
54  virtual void post() override;
55  virtual void subdomainChanged() override;
56 
57  void join(const ComputeUserObjectsThread & /*y*/);
58 
59 protected:
61  void printGeneralExecutionInformation() const override;
62 
64  void printBlockExecutionInformation() const override;
65 
67  template <typename T>
68  void printVectorOrdering(std::vector<T *> uos, const std::string & name) const;
69 
70 private:
71  template <typename T>
72  void querySubdomain(Interfaces iface, std::vector<T> & results)
73  {
74  _query_subdomain.queryInto(results, _tid, _subdomain, iface);
75  }
76  template <typename T>
77  void queryBoundary(Interfaces iface, BoundaryID bnd, std::vector<T> & results)
78  {
79  _query_boundary.queryInto(results, _tid, std::make_tuple(bnd, false), iface);
80  }
81 
85  std::vector<InternalSideUserObject *> _internal_side_objs;
86  std::vector<InterfaceUserObject *> _interface_user_objects;
87  std::vector<ElementUserObject *> _element_objs;
88  std::vector<ShapeElementUserObject *> _shape_element_objs;
89  std::vector<DomainUserObject *> _domain_objs;
90  std::vector<DomainUserObject *> _all_domain_objs;
91 
93 };
94 
95 // determine when we need to run user objects based on whether any initial conditions or aux
96 // kernels depend on the user objects. If so we need to run them either before ics, before aux
97 // kernels, or after aux kernels (if nothing depends on them). Mark/store this information as
98 // attributes in the warehouse for later reference.
99 template <typename T>
100 void
102  AuxiliarySystem & aux,
103  const ExecFlagEnum & execute_flags,
104  const std::vector<T *> & objs,
105  const std::set<std::string> & ic_deps)
106 {
107  // These flags indicate when a user object will be executed for a given exec flag time.
108  // The attributes are set by this function and their values are queried in
109  // FEProblemBase::computeUserObjectsInternal(). If a UO is found to be in one of the
110  // three groups: PRE_IC, PRE_AUX, or POST_AUX, then that UO is executed with that group.
111  //
112  // PRE_IC objects are run before initial conditions during the "INITIAL" exec flag time.
113  // On any other exec flag time, they are run in POST_AUX by default or if there is
114  // an dependency for some exec flag or if force_preaux is set, they are run in
115  // PRE_AUX
116  //
117  // PRE_AUX objects are run before the dependent AuxKernels exec flag
118  //
119  // POST_AUX objects are run after AuxKernels on any given exec flag time, and is the
120  // default group for UOs. Dependencies that would otherwise move a UO into the
121  // PRE_AUX group can be overridden by specifying the parameter force_postaux
122  //
123  // This function attempts to sort a UO based on any ICs or AuxKernels which depend on
124  // it. Alternatively, a user may select which group to execute their object with by
125  // controlling the force_preic, force_preaux and force_postaux input parameters.
126  //
127 
128  std::map<T *, std::set<int>> pre_aux_dependencies;
129  std::map<T *, std::set<int>> post_aux_dependencies;
130  // This map is used to indicate, after all dependencies have
131  // been looked through, whether the UO has been flagged to
132  // execute on EXEC_INITIAL, either through a dependency or
133  // because force_preic was indicated. If neither of these
134  // are true, the UO needs to be run in POST_AUX for EXEC_INITIAL
135  std::map<T *, bool> is_pre_ic;
136 
137  for (const auto obj : objs)
138  is_pre_ic[obj] = false;
139 
140  for (const ExecFlagType & flag : execute_flags.items())
141  {
142  std::set<std::string> depend_objects_aux = aux.getDependObjects(flag);
143  for (const auto obj : objs)
144  {
145  if (depend_objects_aux.count(obj->name()) > 0)
146  {
147  pre_aux_dependencies[obj].insert(flag);
148  if (flag == EXEC_INITIAL)
149  is_pre_ic.at(obj) = true;
150  }
151  else if (flag != EXEC_INITIAL)
152  // default is for UO to be post_aux. If EXEC_INITIAL, check first if UO
153  // will be dependent on IC or have force_preic before deciding to put in
154  // post_aux
155  post_aux_dependencies[obj].insert(flag);
156  }
157  }
158 
159  for (const auto obj : objs)
160  {
161  if (ic_deps.count(obj->name()) > 0 ||
162  (obj->isParamValid("force_preic") && obj->template getParam<bool>("force_preic")))
163  {
164  w.update(obj, AttribPreIC(w, true));
165  is_pre_ic.at(obj) = true;
166  }
167 
168  if ((obj->isParamValid("force_preaux") && obj->template getParam<bool>("force_preaux")))
169  {
170  post_aux_dependencies[obj].clear();
171  for (const ExecFlagType & flag : execute_flags.items())
172  pre_aux_dependencies[obj].insert(flag);
173  }
174  else if (obj->isParamValid("force_postaux") && obj->template getParam<bool>("force_postaux"))
175  {
176  pre_aux_dependencies[obj].clear();
177  for (const ExecFlagType & flag : execute_flags.items())
178  post_aux_dependencies[obj].insert(flag);
179  }
180  else
181  {
182  // If at this point, then check if the UO has already been set to execute
183  // by either the force_preic param, an IC dependency, or a dependency
184  // already found for exec flage EXEC_INITIAL. If none of these are true,
185  // then is_pre_ic.at(obj) is false and the UO is added to the default
186  // post_aux group for the EXEC_INITIAL flag
187  if (!is_pre_ic.at(obj))
188  post_aux_dependencies[obj].insert(EXEC_INITIAL);
189  }
190  }
191 
192  for (auto & item : pre_aux_dependencies)
193  w.update(item.first, AttribPreAux(w, item.second));
194 
195  for (auto & item : post_aux_dependencies)
196  w.update(item.first, AttribPostAux(w, item.second));
197 }
std::string name(const ElemQuality q)
TheWarehouse::QueryCache< AttribThread, AttribSubdomains, AttribInterfaces > _query_subdomain
virtual void onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id, const Elem *lower_d_elem=nullptr) override
Called when doing boundary assembling.
Base class for assembly-like calculations.
virtual void post() override
Called after the element range loop.
std::vector< ElementUserObject * > _element_objs
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
std::vector< ShapeElementUserObject * > _shape_element_objs
void querySubdomain(Interfaces iface, std::vector< T > &results)
QueryCache is a convenient way to construct and pass around (possible partially constructed) warehous...
Definition: TheWarehouse.h:208
TheWarehouse::QueryCache< AttribThread, AttribBoundaries, AttribInterfaces > _query_boundary
void printBlockExecutionInformation() const override
Print information about the loop, mostly order of execution of particular objects.
void printGeneralExecutionInformation() const override
Print general information about the loop, like the ordering of class of objects.
void printVectorOrdering(std::vector< T *> uos, const std::string &name) const
Format output of vector of UOs.
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:311
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.
TODO: delete this later - it is a temporary hack for dealing with inter-system dependencies.
Definition: Attributes.h:313
void queryBoundary(Interfaces iface, BoundaryID bnd, std::vector< T > &results)
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
virtual void subdomainChanged() override
Called every time the current subdomain changes (i.e.
Interfaces
Definition: Attributes.h:20
This user object allows related evaluations on elements, boundaries, internal sides, interfaces in one single place.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
ComputeUserObjectsThread(FEProblemBase &problem, const TheWarehouse::Query &query)
TODO: delete this later - it is a temporary hack for dealing with inter-system dependencies.
Definition: Attributes.h:294
const std::set< ExecFlagType > & items() const
Reference the all the available items.
Definition: ExecFlagEnum.h:71
ElementUserObject class in which the _phi and _grad_phi shape function data is available and correctl...
boundary_id_type BoundaryID
virtual void onExternalSide(const Elem *elem, unsigned int side) override
Called when iterating over external sides (no side neighbor)
void groupUserObjects(TheWarehouse &w, AuxiliarySystem &aux, const ExecFlagEnum &execute_flags, const std::vector< T *> &objs, const std::set< std::string > &ic_deps)
const TheWarehouse::Query _query
std::vector< InterfaceUserObject * > _interface_user_objects
TheWarehouse is a container for MooseObjects that allows querying/filtering over various customizeabl...
Definition: TheWarehouse.h:185
void join(const ComputeUserObjectsThread &)
std::set< std::string > getDependObjects(ExecFlagType type)
Get a list of dependent UserObjects for this exec type.
TODO: delete this later - it is a temporary hack for dealing with inter-system dependencies.
Definition: Attributes.h:344
Base class for user objects executed on all element sides internal to one or more blocks...
query_obj query
void update(MooseObject *obj)
update updates the metadata/attribute-info stored for the given object obj that must already exists i...
Definition: TheWarehouse.C:154
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:18
Class for threaded computation of UserObjects.
virtual void onInternalSide(const Elem *elem, unsigned int side) override
Called when doing internal edge assembling.
std::vector< InternalSideUserObject * > _internal_side_objs
SubdomainID _subdomain
The subdomain for the current element.
Base class for implementing interface user objects.
std::vector< DomainUserObject * > _domain_objs
A system that holds auxiliary variables.
std::vector< DomainUserObject * > _all_domain_objs
ExecFlagEnum execute_flags
Storage for the registered execute flags.
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:28