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 {
55  initializeBoundaryRestrictable();
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 {
80  initializeBoundaryRestrictable();
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
191 #endif
192 }
193 
195 
196 const std::set<BoundaryID> &
198 {
199  return _bnd_ids;
200 }
201 
202 const std::vector<BoundaryName> &
204 {
205  return _boundary_names;
206 }
207 
208 unsigned int
210 {
211  return (unsigned int)_bnd_ids.size();
212 }
213 
214 bool
216 {
218 }
219 
220 bool
221 BoundaryRestrictable::restricted(const std::set<BoundaryID> & ids)
222 {
223  return ids.find(Moose::ANY_BOUNDARY_ID) == ids.end();
224 }
225 
226 bool
227 BoundaryRestrictable::hasBoundary(const BoundaryName & name) const
228 {
229  // Create a vector and utilize the getBoundaryIDs function, which
230  // handles the ANY_BOUNDARY_ID (getBoundaryID does not)
231  return hasBoundary(_bnd_mesh->getBoundaryIDs({name}));
232 }
233 
234 bool
235 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryName> & names) const
236 {
237  return hasBoundary(_bnd_mesh->getBoundaryIDs(names));
238 }
239 
240 bool
242 {
243  if (_bnd_ids.empty() || _bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
244  return true;
245  else
246  return _bnd_ids.find(id) != _bnd_ids.end();
247 }
248 
249 bool
250 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryID> & ids, TEST_TYPE type) const
251 {
252  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
253  return hasBoundary(ids_set, type);
254 }
255 
256 bool
257 BoundaryRestrictable::hasBoundary(const std::set<BoundaryID> & ids, TEST_TYPE type) const
258 {
259  // An empty input is assumed to be ANY_BOUNDARY_ID
260  if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
261  return true;
262 
263  // All supplied IDs must match those of the object
264  else if (type == ALL)
265  {
266  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
267  return true;
268  else
269  return std::includes(_bnd_ids.begin(), _bnd_ids.end(), ids.begin(), ids.end());
270  }
271  // Any of the supplied IDs must match those of the object
272  else
273  {
274  // Loop through the supplied ids
275  for (const auto & id : ids)
276  {
277  // Test the current supplied id
278  bool test = hasBoundary(id);
279 
280  // If the id exists in the stored ids, then return true, otherwise
281  if (test)
282  return true;
283  }
284  return false;
285  }
286 }
287 
288 bool
289 BoundaryRestrictable::isBoundarySubset(const std::set<BoundaryID> & ids) const
290 {
291  // An empty input is assumed to be ANY_BOUNDARY_ID
292  if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
293  return true;
294 
295  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
296  return std::includes(ids.begin(),
297  ids.end(),
298  _bnd_mesh->meshBoundaryIds().begin(),
299  _bnd_mesh->meshBoundaryIds().end());
300  else
301  return std::includes(ids.begin(), ids.end(), _bnd_ids.begin(), _bnd_ids.end());
302 }
303 
304 bool
305 BoundaryRestrictable::isBoundarySubset(const std::vector<BoundaryID> & ids) const
306 {
307  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
308  return isBoundarySubset(ids_set);
309 }
310 
311 const std::set<BoundaryID> &
313 {
314  return _bnd_mesh->getBoundaryIDs();
315 }
316 
317 bool
319 {
320  // Reference to MaterialWarehouse for testing and retrieving boundary ids
322 
323  // Complete set of BoundaryIDs that this object is defined
324  const std::set<BoundaryID> & ids =
326 
327  // Loop over each BoundaryID for this object
328  for (const auto & id : ids)
329  {
330  // Storage of material properties that have been DECLARED on this BoundaryID
331  std::set<std::string> declared_props;
332 
333  // If boundary materials exist, populated the set of properties that were declared
334  if (warehouse.hasActiveBoundaryObjects(id))
335  {
336  const std::vector<std::shared_ptr<MaterialBase>> & mats =
337  warehouse.getActiveBoundaryObjects(id);
338  for (const auto & mat : mats)
339  {
340  const std::set<std::string> & mat_props = mat->getSuppliedItems();
341  declared_props.insert(mat_props.begin(), mat_props.end());
342  }
343  }
344 
345  // If the supplied property is not in the list of properties on the current id, return false
346  if (declared_props.find(prop_name) == declared_props.end())
347  return false;
348  }
349 
350  // If you get here the supplied property is defined on all boundaries
351  return true;
352 }
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:3229
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:30
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:439
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseBase.h:388
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:3223
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
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:3217
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.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:27
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:92
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.
bool isKokkosObject(IsKokkosObjectKey &&) const
Get whether this object is a Kokkos functor The parameter is set by the Kokkos base classes: ...
Definition: MooseObject.h:72
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:199
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...
void initializeKokkosBoundaryRestrictable(MooseMesh *mesh)
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.
const BoundaryID ANY_BOUNDARY_ID
Definition: MooseTypes.C:21
unsigned int THREAD_ID
Definition: MooseTypes.h:209
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.