https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
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
83void
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
176 const auto & other_ids =
178 std::vector<BoundaryID> other_boundary_ids;
179 std::set_intersection(diff.begin(),
180 diff.end(),
181 other_ids.begin(),
182 other_ids.end(),
183 std::back_inserter(other_boundary_ids));
184 if (!other_boundary_ids.empty())
185 {
186 msg << "\n\nThe following boundary ";
187 if (other_boundary_ids.size() == 1)
188 msg << "id exists";
189 else
190 msg << "ids exist";
191 if (other_boundary_ids.size() == 1)
192 msg << " as " << (_bnd_nodal ? "a side set" : "a node set")
193 << " but is being requested as " << (_bnd_nodal ? "a node set" : "a side set") << ":";
194 else
195 msg << " as " << (_bnd_nodal ? "side sets" : "node sets")
196 << " but are being requested as " << (_bnd_nodal ? "node sets" : "side sets") << ":";
197
198 sep = " ";
199 for (const auto id : other_boundary_ids)
200 {
201 msg << sep << id;
202 sep = ", ";
203 }
204
205 if (!_bnd_nodal)
206 msg << "\n\nTry setting Mesh/construct_side_list_from_node_list=true if you want side "
207 "sets constructed from node sets.";
208 }
209
210 _moose_object.paramError("boundary", msg.str());
211 }
212 }
213
214#ifdef MOOSE_KOKKOS_ENABLED
218#endif
219}
220
222
223const std::set<BoundaryID> &
225{
226 return _bnd_ids;
227}
228
229const std::vector<BoundaryName> &
234
235unsigned int
237{
238 return (unsigned int)_bnd_ids.size();
239}
240
241bool
246
247bool
248BoundaryRestrictable::restricted(const std::set<BoundaryID> & ids)
249{
250 return ids.find(Moose::ANY_BOUNDARY_ID) == ids.end();
251}
252
253bool
254BoundaryRestrictable::hasBoundary(const BoundaryName & name) const
255{
256 // Create a vector and utilize the getBoundaryIDs function, which
257 // handles the ANY_BOUNDARY_ID (getBoundaryID does not)
258 return hasBoundary(_bnd_mesh->getBoundaryIDs({name}));
259}
260
261bool
262BoundaryRestrictable::hasBoundary(const std::vector<BoundaryName> & names) const
263{
264 return hasBoundary(_bnd_mesh->getBoundaryIDs(names));
265}
266
267bool
269{
270 if (_bnd_ids.empty() || _bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
271 return true;
272 else
273 return _bnd_ids.find(id) != _bnd_ids.end();
274}
275
276bool
277BoundaryRestrictable::hasBoundary(const std::vector<BoundaryID> & ids, TEST_TYPE type) const
278{
279 std::set<BoundaryID> ids_set(ids.begin(), ids.end());
280 return hasBoundary(ids_set, type);
281}
282
283bool
284BoundaryRestrictable::hasBoundary(const std::set<BoundaryID> & ids, TEST_TYPE type) const
285{
286 // An empty input is assumed to be ANY_BOUNDARY_ID
287 if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
288 return true;
289
290 // All supplied IDs must match those of the object
291 else if (type == ALL)
292 {
293 if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
294 return true;
295 else
296 return std::includes(_bnd_ids.begin(), _bnd_ids.end(), ids.begin(), ids.end());
297 }
298 // Any of the supplied IDs must match those of the object
299 else
300 {
301 // Loop through the supplied ids
302 for (const auto & id : ids)
303 {
304 // Test the current supplied id
305 bool test = hasBoundary(id);
306
307 // If the id exists in the stored ids, then return true, otherwise
308 if (test)
309 return true;
310 }
311 return false;
312 }
313}
314
315bool
316BoundaryRestrictable::isBoundarySubset(const std::set<BoundaryID> & ids) const
317{
318 // An empty input is assumed to be ANY_BOUNDARY_ID
319 if (ids.empty() || ids.find(Moose::ANY_BOUNDARY_ID) != ids.end())
320 return true;
321
322 if (_bnd_ids.find(Moose::ANY_BOUNDARY_ID) != _bnd_ids.end())
323 return std::includes(ids.begin(),
324 ids.end(),
325 _bnd_mesh->meshBoundaryIds().begin(),
326 _bnd_mesh->meshBoundaryIds().end());
327 else
328 return std::includes(ids.begin(), ids.end(), _bnd_ids.begin(), _bnd_ids.end());
329}
330
331bool
332BoundaryRestrictable::isBoundarySubset(const std::vector<BoundaryID> & ids) const
333{
334 std::set<BoundaryID> ids_set(ids.begin(), ids.end());
335 return isBoundarySubset(ids_set);
336}
337
338const std::set<BoundaryID> &
343
344bool
346{
347 // Reference to MaterialWarehouse for testing and retrieving boundary ids
349
350 // Complete set of BoundaryIDs that this object is defined
351 const std::set<BoundaryID> & ids =
353
354 // Loop over each BoundaryID for this object
355 for (const auto & id : ids)
356 {
357 // Storage of material properties that have been DECLARED on this BoundaryID
358 std::set<std::string> declared_props;
359
360 // If boundary materials exist, populated the set of properties that were declared
361 if (warehouse.hasActiveBoundaryObjects(id))
362 {
363 const std::vector<std::shared_ptr<MaterialBase>> & mats =
364 warehouse.getActiveBoundaryObjects(id);
365 for (const auto & mat : mats)
366 {
367 const std::set<std::string> & mat_props = mat->getSuppliedItems();
368 declared_props.insert(mat_props.begin(), mat_props.end());
369 }
370 }
371
372 // If the supplied property is not in the list of properties on the current id, return false
373 if (declared_props.find(prop_name) == declared_props.end())
374 return false;
375 }
376
377 // If you get here the supplied property is defined on all boundaries
378 return true;
379}
boundary_id_type BoundaryID
InputParameters emptyInputParameters()
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
unsigned int THREAD_ID
Definition MooseTypes.h:237
const bool _bnd_dual_restrictable
Flag for allowing dual restriction with BlockRestrictable.
FEProblemBase * _bnd_feproblem
Pointer to FEProblemBase.
MooseMesh * _bnd_mesh
Point to mesh.
BoundaryRestrictable(const MooseObject *moose_object, bool nodal)
Class constructor Populates the _bnd_ids for the given boundary names supplied with the 'boundary' in...
void initializeKokkosBoundaryRestrictable()
bool hasBoundary(const BoundaryName &name) const
Test if the supplied boundary name is valid for this object.
std::set< BoundaryID > _bnd_ids
Set of the boundary ids.
virtual ~BoundaryRestrictable()
Empty class destructor.
const std::set< SubdomainID > & _block_ids
Reference to the block_ids, defaults to an empty set if not provided.
bool hasBoundaryMaterialPropertyHelper(const std::string &prop_name) const
A helper method to avoid circular #include problems.
bool isBoundarySubset(const std::set< BoundaryID > &ids) const
Test if the class boundary ids are a subset of the supplied objects.
static bool restricted(const std::set< BoundaryID > &ids)
Helper for determining if the object is boundary restricted.
bool _bnd_nodal
Whether or not this object is restricted to nodesets.
const std::vector< BoundaryName > & boundaryNames() const
Return the boundary names for this object.
TEST_TYPE
A flag changing the behavior of hasBoundary.
virtual bool boundaryRestricted() const
Returns true if this object has been restricted to a boundary.
const std::set< BoundaryID > & meshBoundaryIDs() const
Returns the set of all boundary ids for the entire mesh.
const MooseObject & _moose_object
The moose object that this is an interface for.
static InputParameters validParams()
std::vector< BoundaryID > _vec_ids
Vector of the boundary ids.
std::vector< BoundaryName > _boundary_names
Vector the the boundary names.
virtual const std::set< BoundaryID > & boundaryIDs() const
Return the boundary IDs for this object.
void initializeBoundaryRestrictable()
An initialization routine needed for dual constructors.
unsigned int numBoundaryIDs() const
Return the number of boundaries for this object.
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const MaterialWarehouse & getMaterialWarehouse() const
void addKokkosMeshInitializationHook(std::function< void()> function)
Add a function hook that needs to be called after Kokkos mesh initialization.
virtual MooseMesh & mesh() override
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
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...
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another,...
MaterialBase objects are special in that they have additional objects created automatically (see FEPr...
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
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:457
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition MooseBase.h:406
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
const std::set< BoundaryID > & meshNodesetIds() const
Returns a read-only reference to the set of nodesets currently present in the Mesh.
Definition MooseMesh.C:3290
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:3278
const std::set< BoundaryID > & meshSidesetIds() const
Returns a read-only reference to the set of sidesets currently present in the Mesh.
Definition MooseMesh.C:3284
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:3027
const std::map< BoundaryID, std::vector< std::shared_ptr< T > > > & getActiveBoundaryObjects(THREAD_ID tid=0) const
bool hasActiveBoundaryObjects(THREAD_ID tid=0) const
Every object that can be built by the factory should be derived from this class.
Definition MooseObject.h:31
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
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const SubdomainID ANY_BLOCK_ID
Definition MooseTypes.C:19
const BoundaryID ANY_BOUNDARY_ID
Definition MooseTypes.C:21