https://mooseframework.inl.gov
BoundaryRestrictable.C
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 // MOOSE includes
11 #include "BoundaryRestrictable.h"
12 #include "Material.h"
13 #include "MooseMesh.h"
14 #include "MooseObject.h"
15 
18 {
19 
20  // Create instance of InputParameters
22 
23  // Create user-facing 'boundary' input for restricting inheriting object to boundaries
24  params.addParam<std::vector<BoundaryName>>(
25  "boundary", "The list of boundaries (ids or names) from the mesh where this object applies");
26 
27  // A parameter for disabling error message for objects restrictable by boundary and block,
28  // if the parameter is valid it was already set so don't do anything
29  if (!params.isParamValid("_dual_restrictable"))
30  params.addPrivateParam<bool>("_dual_restrictable", false);
31 
32  return params;
33 }
34 
35 // Standard constructor
37  : _bnd_feproblem(moose_object->isParamValid("_fe_problem_base")
38  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
39  : NULL),
40  _bnd_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
41  : NULL),
42  _bnd_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
43  _block_ids(_empty_block_ids),
44  _bnd_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
45  _bnd_material_data(
46 #ifdef MOOSE_KOKKOS_ENABLED
47  moose_object->isKokkosObject()
48  ? _bnd_feproblem->getKokkosMaterialData(Moose::BOUNDARY_MATERIAL_DATA)
49  :
50 #endif
51  _bnd_feproblem->getMaterialData(Moose::BOUNDARY_MATERIAL_DATA, _bnd_tid)),
52  _bnd_nodal(nodal),
53  _moose_object(*moose_object)
54 {
56 }
57 
58 // Dual restricted constructor
60  const std::set<SubdomainID> & block_ids,
61  bool nodal)
62  : _bnd_feproblem(moose_object->isParamValid("_fe_problem_base")
63  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
64  : NULL),
65  _bnd_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
66  : NULL),
67  _bnd_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
68  _block_ids(block_ids),
69  _bnd_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
70  _bnd_material_data(
71 #ifdef MOOSE_KOKKOS_ENABLED
72  moose_object->isKokkosObject()
73  ? _bnd_feproblem->getKokkosMaterialData(Moose::BOUNDARY_MATERIAL_DATA)
74  :
75 #endif
76  _bnd_feproblem->getMaterialData(Moose::BOUNDARY_MATERIAL_DATA, _bnd_tid)),
77  _bnd_nodal(nodal),
78  _moose_object(*moose_object)
79 {
81 }
82 
83 void
85 {
86  // The name and id of the object
87  const std::string & name = _moose_object.name();
88 
89  // If the mesh pointer is not defined, but FEProblemBase is, get it from there
90  if (_bnd_feproblem != NULL && _bnd_mesh == NULL)
92 
93  // Check that the mesh pointer was defined, it is required for this class to operate
94  if (_bnd_mesh == NULL)
95  mooseError("The input parameters must contain a pointer to FEProblemBase via '_fe_problem' or "
96  "a pointer to the MooseMesh via '_mesh'");
97 
98  // If the user supplies boundary IDs
99  if (_moose_object.isParamValid("boundary"))
100  {
101  // Extract the blocks from the input
102  _boundary_names = _moose_object.getParam<std::vector<BoundaryName>>("boundary");
103 
104  // Get the IDs from the supplied names
106 
107  // Store the IDs, handling ANY_BOUNDARY_ID if supplied
108  if (std::find(_boundary_names.begin(), _boundary_names.end(), "ANY_BOUNDARY_ID") !=
109  _boundary_names.end())
111  else
112  _bnd_ids.insert(_vec_ids.begin(), _vec_ids.end());
113  }
114 
115  // Produce error if the object is not allowed to be both block and boundary restricted
116  if (!_bnd_dual_restrictable && !_bnd_ids.empty() && !_block_ids.empty())
117  if (!_block_ids.empty() && _block_ids.find(Moose::ANY_BLOCK_ID) == _block_ids.end())
118  _moose_object.paramError("boundary",
119  "Attempted to restrict the object '",
120  name,
121  "' to a boundary, but the object is already restricted by block(s)");
122 
123  // Store ANY_BOUNDARY_ID if empty
124  if (_bnd_ids.empty())
125  {
127  _boundary_names = {"ANY_BOUNDARY_ID"};
128  }
129 
130  // If this object is block restricted, check that defined blocks exist on the mesh
131  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) == _bnd_ids.end())
132  {
133  const std::set<BoundaryID> * valid_ids;
134  const char * message_ptr = nullptr;
135 
136  if (_bnd_nodal)
137  {
138  valid_ids = &_bnd_mesh->meshNodesetIds();
139  message_ptr = "node sets";
140  }
141  else
142  {
143  valid_ids = &_bnd_mesh->meshSidesetIds();
144  message_ptr = "side sets";
145  }
146 
147  std::vector<BoundaryID> diff;
148 
149  std::set_difference(_bnd_ids.begin(),
150  _bnd_ids.end(),
151  valid_ids->begin(),
152  valid_ids->end(),
153  std::back_inserter(diff));
154 
155  if (!diff.empty())
156  {
157  std::ostringstream msg;
158  auto sep = " ";
159  msg << "the following " << message_ptr << " (ids) do not exist on the mesh:";
160  for (const auto & id : diff)
161  {
162  if (_boundary_names.size() > 0)
163  {
164  auto & name = _boundary_names.at(std::find(_vec_ids.begin(), _vec_ids.end(), id) -
165  _vec_ids.begin());
166  if (std::to_string(id) != name)
167  msg << sep << name << " (" << id << ")";
168  else
169  msg << sep << id;
170  }
171  else
172  msg << sep << id;
173  sep = ", ";
174  }
175  if (!_bnd_nodal)
176  // Diagnostic message
177  msg << "\n\nMOOSE distinguishes between \"node sets\" and \"side sets\" depending on "
178  "whether\nyou are using \"Nodal\" or \"Integrated\" BCs respectively. Node sets "
179  "corresponding\nto your side sets are constructed for you by default.\n\n"
180  "Try setting \"Mesh/construct_side_list_from_node_list=true\" if you see this "
181  "error.\n"
182  "Note: If you are running with adaptivity you should prefer using side sets.";
183 
184  _moose_object.paramError("boundary", msg.str());
185  }
186  }
187 
188 #ifdef MOOSE_KOKKOS_ENABLED
192 #endif
193 }
194 
196 
197 const std::set<BoundaryID> &
199 {
200  return _bnd_ids;
201 }
202 
203 const std::vector<BoundaryName> &
205 {
206  return _boundary_names;
207 }
208 
209 unsigned int
211 {
212  return (unsigned int)_bnd_ids.size();
213 }
214 
215 bool
217 {
219 }
220 
221 bool
222 BoundaryRestrictable::restricted(const std::set<BoundaryID> & ids)
223 {
224  return ids.find(Moose::ANY_BOUNDARY_ID) == ids.end();
225 }
226 
227 bool
228 BoundaryRestrictable::hasBoundary(const BoundaryName & name) const
229 {
230  // Create a vector and utilize the getBoundaryIDs function, which
231  // handles the ANY_BOUNDARY_ID (getBoundaryID does not)
232  return hasBoundary(_bnd_mesh->getBoundaryIDs({name}));
233 }
234 
235 bool
236 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryName> & names) const
237 {
238  return hasBoundary(_bnd_mesh->getBoundaryIDs(names));
239 }
240 
241 bool
243 {
244  if (_bnd_ids.empty() || _bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
245  return true;
246  else
247  return _bnd_ids.find(id) != _bnd_ids.end();
248 }
249 
250 bool
251 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryID> & ids, TEST_TYPE type) const
252 {
253  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
254  return hasBoundary(ids_set, type);
255 }
256 
257 bool
258 BoundaryRestrictable::hasBoundary(const std::set<BoundaryID> & ids, TEST_TYPE type) const
259 {
260  // An empty input is assumed to be ANY_BOUNDARY_ID
261  if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
262  return true;
263 
264  // All supplied IDs must match those of the object
265  else if (type == ALL)
266  {
267  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
268  return true;
269  else
270  return std::includes(_bnd_ids.begin(), _bnd_ids.end(), ids.begin(), ids.end());
271  }
272  // Any of the supplied IDs must match those of the object
273  else
274  {
275  // Loop through the supplied ids
276  for (const auto & id : ids)
277  {
278  // Test the current supplied id
279  bool test = hasBoundary(id);
280 
281  // If the id exists in the stored ids, then return true, otherwise
282  if (test)
283  return true;
284  }
285  return false;
286  }
287 }
288 
289 bool
290 BoundaryRestrictable::isBoundarySubset(const std::set<BoundaryID> & ids) const
291 {
292  // An empty input is assumed to be ANY_BOUNDARY_ID
293  if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
294  return true;
295 
296  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
297  return std::includes(ids.begin(),
298  ids.end(),
299  _bnd_mesh->meshBoundaryIds().begin(),
300  _bnd_mesh->meshBoundaryIds().end());
301  else
302  return std::includes(ids.begin(), ids.end(), _bnd_ids.begin(), _bnd_ids.end());
303 }
304 
305 bool
306 BoundaryRestrictable::isBoundarySubset(const std::vector<BoundaryID> & ids) const
307 {
308  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
309  return isBoundarySubset(ids_set);
310 }
311 
312 const std::set<BoundaryID> &
314 {
315  return _bnd_mesh->getBoundaryIDs();
316 }
317 
318 bool
320 {
321  // Reference to MaterialWarehouse for testing and retrieving boundary ids
323 
324  // Complete set of BoundaryIDs that this object is defined
325  const std::set<BoundaryID> & ids =
327 
328  // Loop over each BoundaryID for this object
329  for (const auto & id : ids)
330  {
331  // Storage of material properties that have been DECLARED on this BoundaryID
332  std::set<std::string> declared_props;
333 
334  // If boundary materials exist, populated the set of properties that were declared
335  if (warehouse.hasActiveBoundaryObjects(id))
336  {
337  const std::vector<std::shared_ptr<MaterialBase>> & mats =
338  warehouse.getActiveBoundaryObjects(id);
339  for (const auto & mat : mats)
340  {
341  const std::set<std::string> & mat_props = mat->getSuppliedItems();
342  declared_props.insert(mat_props.begin(), mat_props.end());
343  }
344  }
345 
346  // If the supplied property is not in the list of properties on the current id, return false
347  if (declared_props.find(prop_name) == declared_props.end())
348  return false;
349  }
350 
351  // If you get here the supplied property is defined on all boundaries
352  return true;
353 }
std::string name(const ElemQuality q)
const std::set< BoundaryID > & meshNodesetIds() const
Returns a read-only reference to the set of nodesets currently present in the Mesh.
Definition: MooseMesh.C:3316
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:40
virtual ~BoundaryRestrictable()
Empty class destructor.
bool isBoundarySubset(const std::set< BoundaryID > &ids) const
Test if the class boundary ids are a subset of the supplied objects.
void initializeBoundaryRestrictable()
An initialization routine needed for dual constructors.
virtual bool boundaryRestricted() const
Returns true if this object has been restricted to a boundary.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition: MooseBase.h:467
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseBase.h:416
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
const std::set< BoundaryID > & meshSidesetIds() const
Returns a read-only reference to the set of sidesets currently present in the Mesh.
Definition: MooseMesh.C:3310
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:311
bool isKokkosObject() const
Get whether this object is a Kokkos functor The parameter MooseBase::kokkos_object_param is set by th...
Definition: MooseObject.h:63
MooseMesh * _bnd_mesh
Point to mesh.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
MaterialBase objects are special in that they have additional objects created automatically (see FEPr...
const MaterialWarehouse & getMaterialWarehouse() const
const bool _bnd_dual_restrictable
Flag for allowing dual restriction with BlockRestrictable.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
InputParameters emptyInputParameters()
const std::set< BoundaryID > & meshBoundaryIds() const
Returns a read-only reference to the set of boundary IDs currently present in the Mesh...
Definition: MooseMesh.C:3304
bool hasBoundaryMaterialPropertyHelper(const std::string &prop_name) const
A helper method to avoid circular #include problems.
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
static bool restricted(const std::set< BoundaryID > &ids)
Helper for determining if the object is boundary restricted.
void addKokkosMeshInitializationHook(std::function< void()> function)
Add a function hook that needs to be called after Kokkos mesh initialization.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:28
boundary_id_type BoundaryID
std::set< BoundaryID > _bnd_ids
Set of the boundary ids.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:93
const std::set< BoundaryID > & meshBoundaryIDs() const
Returns the set of all boundary ids for the entire mesh.
unsigned int numBoundaryIDs() const
Return the number of boundaries for this object.
TEST_TYPE
A flag changing the behavior of hasBoundary.
bool _bnd_nodal
Whether or not this object is restricted to nodesets.
static InputParameters validParams()
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
std::vector< BoundaryID > _vec_ids
Vector of the boundary ids.
bool hasBoundary(const BoundaryName &name) const
Test if the supplied boundary name is valid for this object.
const MooseObject & _moose_object
The moose object that this is an interface for.
const SubdomainID ANY_BLOCK_ID
Definition: MooseTypes.C:19
std::vector< BoundaryName > _boundary_names
Vector the the boundary names.
virtual MooseMesh & mesh() override
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
const std::set< SubdomainID > & _block_ids
Reference to the block_ids, defaults to an empty set if not provided.
FEProblemBase * _bnd_feproblem
Pointer to FEProblemBase.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:209
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
Returns a vector of boundary IDs for the requested element on the requested side. ...
BoundaryRestrictable(const MooseObject *moose_object, bool nodal)
Class constructor Populates the _bnd_ids for the given boundary names supplied with the &#39;boundary&#39; in...
const std::vector< BoundaryName > & boundaryNames() const
Return the boundary names for this object.
virtual const std::set< BoundaryID > & boundaryIDs() const
Return the boundary IDs for this object.
void initializeKokkosBoundaryRestrictable()
const BoundaryID ANY_BOUNDARY_ID
Definition: MooseTypes.C:21
unsigned int THREAD_ID
Definition: MooseTypes.h:237
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.