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 
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(_bnd_feproblem->getMaterialData(Moose::BOUNDARY_MATERIAL_DATA, _bnd_tid)),
46  _bnd_nodal(nodal),
47  _moose_object(*moose_object)
48 {
50 }
51 
52 // Dual restricted constructor
54  const std::set<SubdomainID> & block_ids,
55  bool nodal)
56  : _bnd_feproblem(moose_object->isParamValid("_fe_problem_base")
57  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
58  : NULL),
59  _bnd_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
60  : NULL),
61  _bnd_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
62  _block_ids(block_ids),
63  _bnd_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
64  _bnd_material_data(_bnd_feproblem->getMaterialData(Moose::BOUNDARY_MATERIAL_DATA, _bnd_tid)),
65  _bnd_nodal(nodal),
66  _moose_object(*moose_object)
67 {
69 }
70 
71 void
73 {
74  // The name and id of the object
75  const std::string & name = _moose_object.getParam<std::string>("_object_name");
76 
77  // If the mesh pointer is not defined, but FEProblemBase is, get it from there
78  if (_bnd_feproblem != NULL && _bnd_mesh == NULL)
80 
81  // Check that the mesh pointer was defined, it is required for this class to operate
82  if (_bnd_mesh == NULL)
83  mooseError("The input parameters must contain a pointer to FEProblemBase via '_fe_problem' or "
84  "a pointer to the MooseMesh via '_mesh'");
85 
86  // If the user supplies boundary IDs
87  if (_moose_object.isParamValid("boundary"))
88  {
89  // Extract the blocks from the input
90  _boundary_names = _moose_object.getParam<std::vector<BoundaryName>>("boundary");
91 
92  // Get the IDs from the supplied names
94 
95  // Store the IDs, handling ANY_BOUNDARY_ID if supplied
96  if (std::find(_boundary_names.begin(), _boundary_names.end(), "ANY_BOUNDARY_ID") !=
97  _boundary_names.end())
99  else
100  _bnd_ids.insert(_vec_ids.begin(), _vec_ids.end());
101  }
102 
103  // Produce error if the object is not allowed to be both block and boundary restricted
104  if (!_bnd_dual_restrictable && !_bnd_ids.empty() && !_block_ids.empty())
105  if (!_block_ids.empty() && _block_ids.find(Moose::ANY_BLOCK_ID) == _block_ids.end())
106  _moose_object.paramError("boundary",
107  "Attempted to restrict the object '",
108  name,
109  "' to a boundary, but the object is already restricted by block(s)");
110 
111  // Store ANY_BOUNDARY_ID if empty
112  if (_bnd_ids.empty())
113  {
115  _boundary_names = {"ANY_BOUNDARY_ID"};
116  }
117 
118  // If this object is block restricted, check that defined blocks exist on the mesh
119  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) == _bnd_ids.end())
120  {
121  const std::set<BoundaryID> * valid_ids;
122  const char * message_ptr = nullptr;
123 
124  if (_bnd_nodal)
125  {
126  valid_ids = &_bnd_mesh->meshNodesetIds();
127  message_ptr = "node sets";
128  }
129  else
130  {
131  valid_ids = &_bnd_mesh->meshSidesetIds();
132  message_ptr = "side sets";
133  }
134 
135  std::vector<BoundaryID> diff;
136 
137  std::set_difference(_bnd_ids.begin(),
138  _bnd_ids.end(),
139  valid_ids->begin(),
140  valid_ids->end(),
141  std::back_inserter(diff));
142 
143  if (!diff.empty())
144  {
145  std::ostringstream msg;
146  auto sep = " ";
147  msg << "the following " << message_ptr << " (ids) do not exist on the mesh:";
148  for (const auto & id : diff)
149  {
150  if (_boundary_names.size() > 0)
151  {
152  auto & name = _boundary_names.at(std::find(_vec_ids.begin(), _vec_ids.end(), id) -
153  _vec_ids.begin());
154  if (std::to_string(id) != name)
155  msg << sep << name << " (" << id << ")";
156  else
157  msg << sep << id;
158  }
159  else
160  msg << sep << id;
161  sep = ", ";
162  }
163  if (!_bnd_nodal)
164  // Diagnostic message
165  msg << "\n\nMOOSE distinguishes between \"node sets\" and \"side sets\" depending on "
166  "whether \nyou are using \"Nodal\" or \"Integrated\" BCs respectively. Node sets "
167  "corresponding \nto your side sets are constructed for you by default.\n\n"
168  "Try setting \"Mesh/construct_side_list_from_node_list=true\" if you see this "
169  "error.\n"
170  "Note: If you are running with adaptivity you should prefer using side sets.";
171 
172  _moose_object.paramError("boundary", msg.str());
173  }
174  }
175 }
176 
178 
179 const std::set<BoundaryID> &
181 {
182  return _bnd_ids;
183 }
184 
185 const std::vector<BoundaryName> &
187 {
188  return _boundary_names;
189 }
190 
191 unsigned int
193 {
194  return (unsigned int)_bnd_ids.size();
195 }
196 
197 bool
199 {
201 }
202 
203 bool
204 BoundaryRestrictable::restricted(const std::set<BoundaryID> & ids)
205 {
206  return ids.find(Moose::ANY_BOUNDARY_ID) == ids.end();
207 }
208 
209 bool
210 BoundaryRestrictable::hasBoundary(const BoundaryName & name) const
211 {
212  // Create a vector and utilize the getBoundaryIDs function, which
213  // handles the ANY_BOUNDARY_ID (getBoundaryID does not)
214  return hasBoundary(_bnd_mesh->getBoundaryIDs({name}));
215 }
216 
217 bool
218 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryName> & names) const
219 {
220  return hasBoundary(_bnd_mesh->getBoundaryIDs(names));
221 }
222 
223 bool
225 {
226  if (_bnd_ids.empty() || _bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
227  return true;
228  else
229  return _bnd_ids.find(id) != _bnd_ids.end();
230 }
231 
232 bool
233 BoundaryRestrictable::hasBoundary(const std::vector<BoundaryID> & ids, TEST_TYPE type) const
234 {
235  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
236  return hasBoundary(ids_set, type);
237 }
238 
239 bool
240 BoundaryRestrictable::hasBoundary(const std::set<BoundaryID> & ids, TEST_TYPE type) 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  // All supplied IDs must match those of the object
247  else if (type == ALL)
248  {
249  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
250  return true;
251  else
252  return std::includes(_bnd_ids.begin(), _bnd_ids.end(), ids.begin(), ids.end());
253  }
254  // Any of the supplied IDs must match those of the object
255  else
256  {
257  // Loop through the supplied ids
258  for (const auto & id : ids)
259  {
260  // Test the current supplied id
261  bool test = hasBoundary(id);
262 
263  // If the id exists in the stored ids, then return true, otherwise
264  if (test)
265  return true;
266  }
267  return false;
268  }
269 }
270 
271 bool
272 BoundaryRestrictable::isBoundarySubset(const std::set<BoundaryID> & ids) const
273 {
274  // An empty input is assumed to be ANY_BOUNDARY_ID
275  if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
276  return true;
277 
278  if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
279  return std::includes(ids.begin(),
280  ids.end(),
281  _bnd_mesh->meshBoundaryIds().begin(),
282  _bnd_mesh->meshBoundaryIds().end());
283  else
284  return std::includes(ids.begin(), ids.end(), _bnd_ids.begin(), _bnd_ids.end());
285 }
286 
287 bool
288 BoundaryRestrictable::isBoundarySubset(const std::vector<BoundaryID> & ids) const
289 {
290  std::set<BoundaryID> ids_set(ids.begin(), ids.end());
291  return isBoundarySubset(ids_set);
292 }
293 
294 const std::set<BoundaryID> &
296 {
297  return _bnd_mesh->getBoundaryIDs();
298 }
299 
300 bool
302 {
303  // Reference to MaterialWarehouse for testing and retrieving boundary ids
305 
306  // Complete set of BoundaryIDs that this object is defined
307  const std::set<BoundaryID> & ids =
309 
310  // Loop over each BoundaryID for this object
311  for (const auto & id : ids)
312  {
313  // Storage of material properties that have been DECLARED on this BoundaryID
314  std::set<std::string> declared_props;
315 
316  // If boundary materials exist, populated the set of properties that were declared
317  if (warehouse.hasActiveBoundaryObjects(id))
318  {
319  const std::vector<std::shared_ptr<MaterialBase>> & mats =
320  warehouse.getActiveBoundaryObjects(id);
321  for (const auto & mat : mats)
322  {
323  const std::set<std::string> & mat_props = mat->getSuppliedItems();
324  declared_props.insert(mat_props.begin(), mat_props.end());
325  }
326  }
327 
328  // If the supplied property is not in the list of properties on the current id, return false
329  if (declared_props.find(prop_name) == declared_props.end())
330  return false;
331  }
332 
333  // If you get here the supplied property is defined on all boundaries
334  return true;
335 }
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:2939
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 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:2933
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
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:2927
bool hasBoundaryMaterialPropertyHelper(const std::string &prop_name) const
A helper method to avoid circular #include problems.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
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:33
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:88
const std::set< BoundaryID > & meshBoundaryIDs() const
Returns the set of all boundary ids for the entire mesh.
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
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.
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 ...
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
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:2719
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.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
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.
const BoundaryID ANY_BOUNDARY_ID
Definition: MooseTypes.C:23
unsigned int THREAD_ID
Definition: MooseTypes.h:198
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.