www.mooseframework.org
BoundaryRestrictable.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
11 #include "BoundaryRestrictable.h"
12 #include "Material.h"
13 #include "MooseMesh.h"
14 #include "MooseObject.h"
15 
16 template <>
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 boundary IDs from the mesh where this boundary condition 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(_bnd_feproblem->getMaterialData(Moose::BOUNDARY_MATERIAL_DATA, _bnd_tid)),
46  _bnd_nodal(nodal)
47 {
48  initializeBoundaryRestrictable(moose_object);
49 }
50 
51 // Dual restricted constructor
53  const std::set<SubdomainID> & block_ids,
54  bool nodal)
55  : _bnd_feproblem(moose_object->isParamValid("_fe_problem_base")
56  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
57  : NULL),
58  _bnd_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
59  : NULL),
60  _bnd_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
61  _block_ids(block_ids),
62  _bnd_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
63  _bnd_material_data(_bnd_feproblem->getMaterialData(Moose::BOUNDARY_MATERIAL_DATA, _bnd_tid)),
64  _bnd_nodal(nodal)
65 {
66  initializeBoundaryRestrictable(moose_object);
67 }
68 
69 void
71 {
72  // The name and id of the object
73  const std::string & name = moose_object->getParam<std::string>("_object_name");
74 
75  // If the mesh pointer is not defined, but FEProblemBase is, get it from there
76  if (_bnd_feproblem != NULL && _bnd_mesh == NULL)
78 
79  // Check that the mesh pointer was defined, it is required for this class to operate
80  if (_bnd_mesh == NULL)
81  mooseError("The input parameters must contain a pointer to FEProblemBase via '_fe_problem' or "
82  "a pointer to the MooseMesh via '_mesh'");
83 
84  // If the user supplies boundary IDs
85  if (moose_object->isParamValid("boundary"))
86  {
87  // Extract the blocks from the input
88  _boundary_names = moose_object->getParam<std::vector<BoundaryName>>("boundary");
89 
90  // Get the IDs from the supplied names
91  std::vector<BoundaryID> vec_ids = _bnd_mesh->getBoundaryIDs(_boundary_names, true);
92 
93  // Store the IDs, handling ANY_BOUNDARY_ID if supplied
94  if (std::find(_boundary_names.begin(), _boundary_names.end(), "ANY_BOUNDARY_ID") !=
95  _boundary_names.end())
97  else
98  _bnd_ids.insert(vec_ids.begin(), vec_ids.end());
99  }
100 
101  // Produce error if the object is not allowed to be both block and boundary restricted
102  if (!_bnd_dual_restrictable && !_bnd_ids.empty() && !_block_ids.empty())
103  if (!_block_ids.empty() && _block_ids.find(Moose::ANY_BLOCK_ID) == _block_ids.end())
104  mooseError("Attempted to restrict the object '",
105  name,
106  "' to a boundary, but the object is already restricted by block(s)");
107 
108  // Store ANY_BOUNDARY_ID if empty
109  if (_bnd_ids.empty())
110  {
112  _boundary_names = {"ANY_BOUNDARY_ID"};
113  }
114 
115  // If this object is block restricted, check that defined blocks exist on the mesh
116  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) == _bnd_ids.end())
117  {
118  const std::set<BoundaryID> * valid_ids;
119 
120  if (_bnd_nodal)
121  valid_ids = &_bnd_mesh->meshNodesetIds();
122  else
123  valid_ids = &_bnd_mesh->meshSidesetIds();
124 
125  std::vector<BoundaryID> diff;
126 
127  std::set_difference(_bnd_ids.begin(),
128  _bnd_ids.end(),
129  valid_ids->begin(),
130  valid_ids->end(),
131  std::back_inserter(diff));
132 
133  if (!diff.empty())
134  {
135  std::ostringstream msg;
136  msg << "The object '" << name
137  << "' contains the following boundary ids that do not exist on the mesh:";
138  for (const auto & id : diff)
139  msg << " " << id;
140  mooseError(msg.str());
141  }
142  }
143 }
144 
146 
147 const std::set<BoundaryID> &
149 {
150  return _bnd_ids;
151 }
152 
153 const std::vector<BoundaryName> &
155 {
156  return _boundary_names;
157 }
158 
159 unsigned int
161 {
162  return (unsigned int)_bnd_ids.size();
163 }
164 
165 bool
167 {
169 }
170 
171 bool
172 BoundaryRestrictable::restricted(const std::set<BoundaryID> & ids)
173 {
174  return ids.find(Moose::ANY_BOUNDARY_ID) == ids.end();
175 }
176 
177 bool
178 BoundaryRestrictable::hasBoundary(const BoundaryName & name) const
179 {
180  // Create a vector and utilize the getBoundaryIDs function, which
181  // handles the ANY_BOUNDARY_ID (getBoundaryID does not)
182  return hasBoundary(_bnd_mesh->getBoundaryIDs({name}));
183 }
184 
185 bool
186 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryName> & names) const
187 {
188  return hasBoundary(_bnd_mesh->getBoundaryIDs(names));
189 }
190 
191 bool
193 {
194  if (_bnd_ids.empty() || _bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
195  return true;
196  else
197  return _bnd_ids.find(id) != _bnd_ids.end();
198 }
199 
200 bool
201 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryID> & ids, TEST_TYPE type) const
202 {
203  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
204  return hasBoundary(ids_set, type);
205 }
206 
207 bool
208 BoundaryRestrictable::hasBoundary(const std::set<BoundaryID> & ids, TEST_TYPE type) const
209 {
210  // An empty input is assumed to be ANY_BOUNDARY_ID
211  if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
212  return true;
213 
214  // All supplied IDs must match those of the object
215  else if (type == ALL)
216  {
217  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
218  return true;
219  else
220  return std::includes(_bnd_ids.begin(), _bnd_ids.end(), ids.begin(), ids.end());
221  }
222  // Any of the supplied IDs must match those of the object
223  else
224  {
225  // Loop through the supplied ids
226  for (const auto & id : ids)
227  {
228  // Test the current supplied id
229  bool test = hasBoundary(id);
230 
231  // If the id exists in the stored ids, then return true, otherwise
232  if (test)
233  return true;
234  }
235  return false;
236  }
237 }
238 
239 bool
240 BoundaryRestrictable::isBoundarySubset(const std::set<BoundaryID> & ids) const
241 {
242  // An empty input is assumed to be ANY_BOUNDARY_ID
243  if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
244  return true;
245 
246  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
247  return std::includes(ids.begin(),
248  ids.end(),
249  _bnd_mesh->meshBoundaryIds().begin(),
250  _bnd_mesh->meshBoundaryIds().end());
251  else
252  return std::includes(ids.begin(), ids.end(), _bnd_ids.begin(), _bnd_ids.end());
253 }
254 
255 bool
256 BoundaryRestrictable::isBoundarySubset(const std::vector<BoundaryID> & ids) const
257 {
258  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
259  return isBoundarySubset(ids_set);
260 }
261 
262 const std::set<BoundaryID> &
264 {
265  return _bnd_mesh->getBoundaryIDs();
266 }
267 
268 bool
270 {
271  // Reference to MaterialWarehouse for testing and retrieving boundary ids
273 
274  // Complete set of BoundaryIDs that this object is defined
275  const std::set<BoundaryID> & ids =
277 
278  // Loop over each BoundaryID for this object
279  for (const auto & id : ids)
280  {
281  // Storage of material properties that have been DECLARED on this BoundaryID
282  std::set<std::string> declared_props;
283 
284  // If boundary materials exist, populated the set of properties that were declared
285  if (warehouse.hasActiveBoundaryObjects(id))
286  {
287  const std::vector<std::shared_ptr<Material>> & mats = warehouse.getActiveBoundaryObjects(id);
288  for (const auto & mat : mats)
289  {
290  const std::set<std::string> & mat_props = mat->getSuppliedItems();
291  declared_props.insert(mat_props.begin(), mat_props.end());
292  }
293  }
294 
295  // If the supplied property is not in the list of properties on the current id, return false
296  if (declared_props.find(prop_name) == declared_props.end())
297  return false;
298  }
299 
300  // If you get here the supplied property is defined on all boundaries
301  return true;
302 }
const std::set< BoundaryID > & meshNodesetIds() const
Returns a read-only reference to the set of nodesets currently present in the Mesh.
Definition: MooseMesh.C:2334
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.
virtual bool boundaryRestricted() const
Returns true if this object has been restricted to a boundary.
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:2328
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
void initializeBoundaryRestrictable(const MooseObject *moose_object)
An initialization routine needed for dual constructors.
MooseMesh * _bnd_mesh
Point to mesh.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
Material objects are special in that they have additional objects created automatically (see FEProble...
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.
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseObject.h:191
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:2322
bool hasBoundaryMaterialPropertyHelper(const std::string &prop_name) const
A helper method to avoid circular #include problems.
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
InputParameters validParams< BoundaryRestrictable >()
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:42
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:74
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.
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
bool hasBoundary(const BoundaryName &name) const
Test if the supplied boundary name is valid for this object.
MatType type
const SubdomainID ANY_BLOCK_ID
Definition: MooseTypes.C:15
std::vector< BoundaryName > _boundary_names
Vector the the boundary names.
virtual MooseMesh & mesh() override
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. ...
Definition: MooseMesh.C:2153
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option 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.
Definition: Moose.h:112
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...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:89
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:17
unsigned int THREAD_ID
Definition: MooseTypes.h:161
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.