www.mooseframework.org
ComputeUserObjectsThread.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
11 #include "Problem.h"
12 #include "SystemBase.h"
13 #include "ElementUserObject.h"
14 #include "ShapeElementUserObject.h"
15 #include "SideUserObject.h"
16 #include "InterfaceUserObject.h"
17 #include "ShapeSideUserObject.h"
18 #include "InternalSideUserObject.h"
19 #include "NodalUserObject.h"
20 #include "SwapBackSentinel.h"
21 #include "FEProblem.h"
22 
23 #include "libmesh/numeric_vector.h"
24 
26  SystemBase & sys,
27  const TheWarehouse::Query & query)
28  : ThreadedElementLoop<ConstElemRange>(problem), _soln(*sys.currentSolution()), _query(query)
29 {
30 }
31 
32 // Splitting Constructor
34  : ThreadedElementLoop<ConstElemRange>(x._fe_problem), _soln(x._soln), _query(x._query)
35 {
36 }
37 
39 
40 void
42 {
43  // for the current thread get block objects for the current subdomain and *all* side objects
44  std::vector<UserObject *> objs;
47  objs);
48 
49  std::vector<UserObject *> side_objs;
50  _query.clone()
52  .condition<AttribInterfaces>(Interfaces::SideUserObject)
53  .queryInto(side_objs);
54 
55  objs.insert(objs.begin(), side_objs.begin(), side_objs.end());
56 
57  // collect dependenciesand run subdomain setup
59 
60  std::set<MooseVariableFEBase *> needed_moose_vars;
61  std::set<unsigned int> needed_mat_props;
62  for (const auto obj : objs)
63  {
64  auto v_obj = dynamic_cast<MooseVariableDependencyInterface *>(obj);
65  if (!v_obj)
66  mooseError("robert wrote broken code");
67  const auto & v_deps = v_obj->getMooseVariableDependencies();
68  needed_moose_vars.insert(v_deps.begin(), v_deps.end());
69 
70  auto m_obj = dynamic_cast<MaterialPropertyInterface *>(obj);
71  if (!m_obj)
72  mooseError("robert wrote broken code again");
73  auto & m_deps = m_obj->getMatPropDependencies();
74  needed_mat_props.insert(m_deps.begin(), m_deps.end());
75 
76  obj->subdomainSetup();
77  }
78 
80  _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid);
82 
87 }
88 
89 void
91 {
92  _fe_problem.prepare(elem, _tid);
94 
95  // Set up Sentinel class so that, even if reinitMaterials() throws, we
96  // still remember to swap back during stack unwinding.
99 
100  for (const auto & uo : _element_objs)
101  uo->execute();
102 
103  // UserObject Jacobians
105  {
106  // Prepare shape functions for ShapeElementUserObjects
107  std::vector<MooseVariableFEBase *> jacobian_moose_vars =
109  for (auto & jvar : jacobian_moose_vars)
110  {
111  unsigned int jvar_id = jvar->number();
112  auto && dof_indices = jvar->dofIndices();
113 
114  _fe_problem.prepareShapes(jvar_id, _tid);
115  for (const auto uo : _shape_element_objs)
116  uo->executeJacobianWrapper(jvar_id, dof_indices);
117  }
118  }
119 }
120 
121 void
122 ComputeUserObjectsThread::onBoundary(const Elem * elem, unsigned int side, BoundaryID bnd_id)
123 {
124  std::vector<UserObject *> userobjs;
125  queryBoundary(Interfaces::SideUserObject, bnd_id, userobjs);
126  if (userobjs.size() == 0)
127  return;
128 
129  _fe_problem.reinitElemFace(elem, side, bnd_id, _tid);
130 
131  // Set up Sentinel class so that, even if reinitMaterialsFace() throws, we
132  // still remember to swap back during stack unwinding.
136 
137  for (const auto & uo : userobjs)
138  uo->execute();
139 
140  // UserObject Jacobians
141  std::vector<ShapeSideUserObject *> shapers;
143  if (_fe_problem.currentlyComputingJacobian() && shapers.size() > 0)
144  {
145  // Prepare shape functions for ShapeSideUserObjects
146  std::vector<MooseVariableFEBase *> jacobian_moose_vars =
148  for (auto & jvar : jacobian_moose_vars)
149  {
150  unsigned int jvar_id = jvar->number();
151  auto && dof_indices = jvar->dofIndices();
152 
154 
155  for (const auto & uo : shapers)
156  uo->executeJacobianWrapper(jvar_id, dof_indices);
157  }
158  }
159 }
160 
161 void
162 ComputeUserObjectsThread::onInternalSide(const Elem * elem, unsigned int side)
163 {
164  // Pointer to the neighbor we are currently working on.
165  const Elem * neighbor = elem->neighbor_ptr(side);
166 
167  // Get the global id of the element and the neighbor
168  const dof_id_type elem_id = elem->id(), neighbor_id = neighbor->id();
169 
170  if (_internal_side_objs.size() == 0)
171  return;
172  if (!((neighbor->active() && (neighbor->level() == elem->level()) && (elem_id < neighbor_id)) ||
173  (neighbor->level() < elem->level())))
174  return;
175 
177  _fe_problem.reinitNeighbor(elem, side, _tid);
178 
179  // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
180  // still remember to swap back during stack unwinding.
182  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
183 
185  _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
186 
187  for (const auto & uo : _internal_side_objs)
188  if (!uo->blockRestricted() || uo->hasBlocks(neighbor->subdomain_id()))
189  uo->execute();
190 }
191 
192 void
193 ComputeUserObjectsThread::onInterface(const Elem * elem, unsigned int side, BoundaryID bnd_id)
194 {
195  // Pointer to the neighbor we are currently working on.
196  const Elem * neighbor = elem->neighbor_ptr(side);
197 
198  std::vector<UserObject *> userobjs;
200  if (_interface_user_objects.size() == 0)
201  return;
202  if (!(neighbor->active()))
203  return;
204 
206  _fe_problem.reinitNeighbor(elem, side, _tid);
207 
208  // Set up Sentinels so that, even if one of the reinitMaterialsXXX() calls throws, we
209  // still remember to swap back during stack unwinding.
211  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
212 
214  _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
215 
216  for (const auto & uo : userobjs)
217  uo->execute();
218 }
219 
220 void
222 {
225 }
226 
227 void
229 {
230 }
virtual void prepare(const Elem *elem, THREAD_ID tid) override
Base class for assembly-like calculations.
virtual void post() override
Called after the element range loop.
std::vector< ElementUserObject * > _element_objs
std::vector< ShapeElementUserObject * > _shape_element_objs
void querySubdomain(Interfaces iface, std::vector< T > &results)
virtual void prepareFace(const Elem *elem, THREAD_ID tid) override
virtual void prepareMaterials(SubdomainID blk_id, THREAD_ID tid)
Add the MooseVariables that the current materials depend on to the dependency list.
virtual void setActiveElementalMooseVariables(const std::set< MooseVariableFEBase *> &moose_vars, THREAD_ID tid) override
Set the MOOSE variables to be reinited on each element.
virtual const bool & currentlyComputingJacobian() const
Returns true if the problem is in the process of computing Jacobian.
Definition: SubProblem.h:569
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
virtual void reinitMaterialsNeighbor(SubdomainID blk_id, THREAD_ID tid, bool swap_stateful=true)
virtual void onBoundary(const Elem *elem, unsigned int side, BoundaryID bnd_id) override
Called when doing boundary assembling.
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.
void queryBoundary(Interfaces iface, BoundaryID bnd, std::vector< T > &results)
virtual void subdomainChanged() override
Called every time the current subdomain changes (i.e.
static PetscErrorCode Vec x
Base class for a system (of equations)
Definition: SystemBase.h:92
virtual void reinitElem(const Elem *elem, THREAD_ID tid) override
virtual void reinitMaterials(SubdomainID blk_id, THREAD_ID tid, bool swap_stateful=true)
virtual void reinitMaterialsBoundary(BoundaryID boundary_id, THREAD_ID tid, bool swap_stateful=true)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual void setActiveMaterialProperties(const std::set< unsigned int > &mat_prop_ids, THREAD_ID tid) override
Record and set the material properties required by the current computing thread.
virtual void subdomainSetup(SubdomainID subdomain, THREAD_ID tid)
Query & condition(Args &&... args)
Adds a new condition to the query.
Definition: TheWarehouse.h:157
std::vector< std::string > split(const std::string &str, const std::string &delimiter)
Python like split function for strings.
Definition: MooseUtils.C:736
const std::vector< MooseVariableFEBase * > & getUserObjectJacobianVariables(THREAD_ID tid) const
boundary_id_type BoundaryID
virtual void clearActiveMaterialProperties(THREAD_ID tid) override
Clear the active material properties.
const TheWarehouse::Query _query
std::vector< InterfaceUserObject * > _interface_user_objects
void join(const ComputeUserObjectsThread &)
virtual void swapBackMaterials(THREAD_ID tid)
virtual void swapBackMaterialsNeighbor(THREAD_ID tid)
ComputeUserObjectsThread(FEProblemBase &problem, SystemBase &sys, const TheWarehouse::Query &query)
virtual void reinitElemFace(const Elem *elem, unsigned int side, BoundaryID bnd_id, THREAD_ID tid) override
An interface for accessing Materials.
Class for threaded computation of UserObjects.
virtual void reinitMaterialsFace(SubdomainID blk_id, THREAD_ID tid, bool swap_stateful=true)
Query clone() const
clone creates and returns an independent copy of the query in its current state.
Definition: TheWarehouse.h:164
virtual void onInternalSide(const Elem *elem, unsigned int side) override
Called when doing internal edge assembling.
std::vector< InternalSideUserObject * > _internal_side_objs
virtual void prepareFaceShapes(unsigned int var, THREAD_ID tid) override
virtual void reinitNeighbor(const Elem *elem, unsigned int side, THREAD_ID tid) override
virtual void prepareShapes(unsigned int var, THREAD_ID tid) override
SubdomainID _subdomain
The subdomain for the current element.
Query is a convenient way to construct and pass around (possible partially constructed) warehouse que...
Definition: TheWarehouse.h:128
virtual void swapBackMaterialsFace(THREAD_ID tid)
virtual void clearActiveElementalMooseVariables(THREAD_ID tid) override
Clear the active elemental MooseVariableFEBase.
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}.