www.mooseframework.org
ComputeElemAuxBcsThread.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 
10 // MOOSE includes
12 #include "AuxiliarySystem.h"
13 #include "FEProblem.h"
14 #include "DisplacedProblem.h"
15 #include "Assembly.h"
16 #include "AuxKernel.h"
17 #include "SwapBackSentinel.h"
18 
19 #include "libmesh/threads.h"
20 
21 template <typename AuxKernelType>
23  FEProblemBase & fe_problem,
25  bool need_materials)
26  : _fe_problem(fe_problem),
27  _aux_sys(fe_problem.getAuxiliarySystem()),
28  _storage(storage),
29  _need_materials(need_materials)
30 {
31 }
32 
33 // Splitting Constructor
34 template <typename AuxKernelType>
36  Threads::split /*split*/)
37  : _fe_problem(x._fe_problem),
38  _aux_sys(x._aux_sys),
39  _storage(x._storage),
40  _need_materials(x._need_materials)
41 {
42 }
43 
44 template <typename AuxKernelType>
45 void
47 {
48  ParallelUniqueId puid;
49  _tid = puid.id;
50 
51  // Reference to all boundary restricted AuxKernels for the current thread
52  const auto & boundary_kernels = _storage.getActiveBoundaryObjects(_tid);
53 
54  printGeneralExecutionInformation();
55 
56  for (const auto & belem : range)
57  {
58  const Elem * elem = belem->_elem;
59  unsigned short int side = belem->_side;
60  BoundaryID boundary_id = belem->_bnd_id;
61  SubdomainID last_did = Elem::invalid_subdomain_id;
62 
63  // need to update the boundary ID in assembly
64  _fe_problem.setCurrentBoundaryID(boundary_id, _tid);
65 
66  if (elem->processor_id() == _fe_problem.processor_id())
67  {
68  // Locate the AuxKernel objects for the current BoundaryID
69  const auto iter = boundary_kernels.find(boundary_id);
70 
71  if (iter != boundary_kernels.end() && !(iter->second.empty()))
72  {
73  printBoundaryExecutionInformation(boundary_id, iter->second);
74  auto did = elem->subdomain_id();
75  if (did != last_did)
76  {
77  _fe_problem.subdomainSetup(did, _tid);
78  last_did = did;
79  }
80  _fe_problem.setCurrentSubdomainID(elem, _tid);
81  _fe_problem.prepare(elem, _tid);
82  _fe_problem.reinitElemFace(elem, side, boundary_id, _tid);
83 
84  const Elem * lower_d_elem = _fe_problem.mesh().getLowerDElem(elem, side);
85  _fe_problem.setCurrentLowerDElem(lower_d_elem, _tid);
86  if (lower_d_elem)
87  _fe_problem.reinitLowerDElem(lower_d_elem, _tid);
88 
89  const Elem * neighbor = elem->neighbor_ptr(side);
90 
91  // The last check here is absolutely necessary otherwise we will attempt to evaluate
92  // neighbor materials on neighbor elements that aren't evaluable, e.g. don't have algebraic
93  // ghosting
94  bool compute_interface =
95  neighbor && neighbor->active() &&
96  _fe_problem.getInterfaceMaterialsWarehouse().hasActiveBoundaryObjects(boundary_id,
97  _tid);
98 
99  // Set up Sentinel class so that, even if reinitMaterialsFace() throws, we
100  // still remember to swap back during stack unwinding.
101  SwapBackSentinel sentinel(_fe_problem, &FEProblem::swapBackMaterialsFace, _tid);
102  SwapBackSentinel neighbor_sentinel(
103  _fe_problem, &FEProblem::swapBackMaterialsNeighbor, _tid, compute_interface);
104 
105  if (_need_materials)
106  {
107  std::unordered_set<unsigned int> needed_mat_props;
108  for (const auto & aux : iter->second)
109  {
110  const auto & mp_deps = aux->getMatPropDependencies();
111  needed_mat_props.insert(mp_deps.begin(), mp_deps.end());
112  }
113  _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid);
114 
115  _fe_problem.reinitMaterialsFace(elem->subdomain_id(), _tid);
116 
117  _fe_problem.reinitMaterialsBoundary(boundary_id, _tid);
118 
119  if (compute_interface)
120  {
121  _fe_problem.reinitNeighbor(elem, side, _tid);
122  _fe_problem.reinitMaterialsNeighbor(neighbor->subdomain_id(), _tid);
123  _fe_problem.reinitMaterialsInterface(boundary_id, _tid);
124  }
125  }
126 
127  for (const auto & aux : iter->second)
128  {
129  aux->compute();
130  aux->insert();
131  }
132 
133  if (_need_materials)
134  _fe_problem.clearActiveMaterialProperties(_tid);
135  }
136  }
137  }
138 }
139 
140 template <typename AuxKernelType>
141 void
143 {
144 }
145 
146 template <typename AuxKernelType>
147 void
149 {
150  if (_fe_problem.shouldPrintExecution(_tid) && _storage.hasActiveObjects())
151  {
152  const auto & console = _fe_problem.console();
153  const auto & execute_on = _fe_problem.getCurrentExecuteOnFlag();
154  console << "[DBG] Executing boundary restricted auxkernels on boundary elements on "
155  << execute_on << std::endl;
156  }
157 }
158 
159 template <typename AuxKernelType>
160 void
162  unsigned int boundary_id, const std::vector<std::shared_ptr<AuxKernelType>> & kernels) const
163 {
164  if (!_fe_problem.shouldPrintExecution(_tid) || !_storage.hasActiveObjects() ||
165  _boundaries_exec_printed.count(boundary_id))
166  return;
167 
168  const auto & console = _fe_problem.console();
169  console << "[DBG] Ordering on boundary " << boundary_id << std::endl;
170  std::vector<MooseObject *> objs_ptrs;
171  for (auto & kernel_ptr : kernels)
172  if (kernel_ptr->hasBoundary(boundary_id))
173  objs_ptrs.push_back(dynamic_cast<MooseObject *>(kernel_ptr.get()));
174  std::string list_kernels = ConsoleUtils::mooseObjectVectorToString(objs_ptrs);
175  console << ConsoleUtils::formatString(list_kernels, "[DBG]") << std::endl;
176  _boundaries_exec_printed.insert(boundary_id);
177 }
178 
void operator()(const ConstBndElemRange &range)
std::string mooseObjectVectorToString(const std::vector< MooseObject *> &objs, const std::string &sep=" ")
Routine to output the name of MooseObjects in a string.
Definition: ConsoleUtils.C:452
void printGeneralExecutionInformation() const
Print list of object types executed and in which order.
void printBoundaryExecutionInformation(unsigned int boundary_id, const std::vector< std::shared_ptr< AuxKernelType >> &kernels) const
Print list of specific objects executed and in which order.
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > ConstBndElemRange
Definition: MooseMesh.h:2027
void join(const ComputeElemAuxBcsThread &)
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
virtual void swapBackMaterialsFace(const THREAD_ID tid)
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...
Definition: ConsoleUtils.C:436
boundary_id_type BoundaryID
virtual void swapBackMaterialsNeighbor(const THREAD_ID tid)
ComputeElemAuxBcsThread(FEProblemBase &fe_problem, const MooseObjectWarehouse< AuxKernelType > &storage, bool need_materials)
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}.