https://mooseframework.inl.gov
BlockRestrictable.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 "BlockRestrictable.h"
12 
13 #include "FEProblem.h"
14 #include "Material.h"
15 #include "MooseMesh.h"
16 #include "MooseVariableFE.h"
17 #include "SystemBase.h"
18 #include "Conversion.h"
19 
22 {
23  // Create InputParameters object that will be appended to the parameters for the inheriting object
25 
26  // Add the user-facing 'block' input parameter
27  params.addParam<std::vector<SubdomainName>>(
28  "block", "The list of blocks (ids or names) that this object will be applied");
29 
30  // A parameter for disabling error message for objects restrictable by boundary and block,
31  // if the parameter is valid it was already set so don't do anything
32  if (!params.have_parameter<bool>("_dual_restrictable"))
33  params.addPrivateParam<bool>("_dual_restrictable", false);
34 
35  // Return the parameters
36  return params;
37 }
38 
39 // Standard constructor
40 BlockRestrictable::BlockRestrictable(const MooseObject * moose_object, bool initialize /*=true*/)
41  : _blk_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
42  _blk_feproblem(moose_object->isParamValid("_fe_problem_base")
43  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
44  : NULL),
45  _blk_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
46  : NULL),
47  _boundary_ids(_empty_boundary_ids),
48  _blk_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
49  _blk_name(moose_object->name()),
50  _blk_dim(libMesh::invalid_uint),
51  _moose_object(moose_object)
52 {
53  if (initialize)
55 }
56 
57 // Dual restricted constructor
59  const std::set<BoundaryID> & boundary_ids)
60  : _blk_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
61  _blk_feproblem(moose_object->isParamValid("_fe_problem_base")
62  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
63  : NULL),
64  _blk_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
65  : NULL),
66  _boundary_ids(boundary_ids),
67  _blk_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
68  _blk_name(moose_object->name()),
69  _blk_dim(libMesh::invalid_uint),
70  _moose_object(moose_object)
71 {
73 }
74 
75 void
77 {
78  // If the mesh pointer is not defined, but FEProblemBase is, get it from there
79  if (_blk_feproblem != NULL && _blk_mesh == NULL)
81 
82  // Check that the mesh pointer was defined, it is required for this class to operate
83  if (_blk_mesh == NULL)
84  mooseError("The input parameters must contain a pointer to FEProblem via '_fe_problem' or a "
85  "pointer to the MooseMesh via '_mesh'");
86 
87  // Populate the MaterialData pointer
88  if (_blk_feproblem != NULL)
89  {
90 #ifdef MOOSE_KOKKOS_ENABLED
93  else
94 #endif
96  }
97 
98  // The 'block' input is defined
99  if (moose_object->isParamValid("block"))
100  {
101  // Extract the blocks from the input
102  _blocks = moose_object->getParam<std::vector<SubdomainName>>("block");
103 
104  // Store the IDs in a set, handling ANY_BLOCK_ID if supplied
105  if (std::find(_blocks.begin(), _blocks.end(), "ANY_BLOCK_ID") != _blocks.end())
107  else
108  {
109  // Get the IDs from the supplied names
111  _blk_ids.insert(_vec_ids.begin(), _vec_ids.end());
112  }
113  }
114 
115  // When 'blocks' is not set and there is a "variable", use the blocks from the variable
116  else if (moose_object->isParamValid("variable"))
117  {
118  std::string variable_name = moose_object->parameters().getMooseType("variable");
119  if (!variable_name.empty())
121  ->getVariable(_blk_tid,
122  variable_name,
125  .activeSubdomains();
126  }
127 
128  // Produce error if the object is not allowed to be both block and boundary restricted
129  if (!_blk_dual_restrictable && !_boundary_ids.empty() && !_boundary_ids.empty())
130  if (!_boundary_ids.empty() && _boundary_ids.find(Moose::ANY_BOUNDARY_ID) == _boundary_ids.end())
131  moose_object->paramError("block",
132  "Attempted to restrict the object '",
133  _blk_name,
134  "' to a block, but the object is already restricted by boundary");
135 
136  // If no blocks were defined above, specify that it is valid on all blocks
137  if (_blk_ids.empty() && !moose_object->isParamValid("boundary"))
138  {
140  _blocks = {"ANY_BLOCK_ID"};
141  }
142 
143  // If this object is block restricted, check that defined blocks exist on the mesh
144  if (_blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end())
145  {
146  const std::set<SubdomainID> & valid_ids = _blk_mesh->meshSubdomains();
147  std::vector<SubdomainID> diff;
148 
149  std::set_difference(_blk_ids.begin(),
150  _blk_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 blocks (ids) do not exist on the mesh:";
160  for (const auto & id : diff)
161  {
162  if (_blk_name.size() > 0)
163  {
164  auto & name =
165  _blocks.at(std::find(_vec_ids.begin(), _vec_ids.end(), id) - _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  std::vector<SubdomainID> valid_ids_vec(valid_ids.begin(), valid_ids.end());
176  auto valid_names = _blk_mesh->getSubdomainNames(valid_ids_vec);
177  msg << "\nBlocks names (resp. ids) that do exist: " << Moose::stringify(valid_names) << " ("
178  << Moose::stringify(valid_ids) << ")";
179  moose_object->paramError("block", msg.str());
180  }
181  }
182 
183  // Get the mesh dimension for the blocks
184  if (blockRestricted())
186  else
188 
189 #ifdef MOOSE_KOKKOS_ENABLED
190  if (moose_object->isKokkosObject({}))
192 #endif
193 }
194 
195 bool
197 {
198  return _blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end();
199 }
200 
201 const std::vector<SubdomainName> &
203 {
204  return _blocks;
205 }
206 
207 const std::set<SubdomainID> &
209 {
210  if (_blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
211  return _blk_mesh->meshSubdomains();
212  else
213  return _blk_ids;
214 }
215 
216 unsigned int
218 {
219  return (unsigned int)_blk_ids.size();
220 }
221 
222 bool
223 BlockRestrictable::hasBlocks(const SubdomainName & name) const
224 {
225  // Create a vector and utilize the getSubdomainIDs function, which
226  // handles the ANY_BLOCK_ID (getSubdomainID does not)
227  std::vector<SubdomainName> names(1);
228  names[0] = name;
229  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
230 }
231 
232 bool
233 BlockRestrictable::hasBlocks(const std::vector<SubdomainName> & names) const
234 {
235  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
236 }
237 
238 bool
239 BlockRestrictable::hasBlocks(const std::set<SubdomainName> & names) const
240 {
241  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
242 }
243 
244 bool
246 {
247  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
248  return true;
249  else
250  return _blk_ids.find(id) != _blk_ids.end();
251 }
252 
253 bool
254 BlockRestrictable::hasBlocks(const std::vector<SubdomainID> & ids) const
255 {
256  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
257  return hasBlocks(ids_set);
258 }
259 
260 bool
261 BlockRestrictable::hasBlocks(const std::set<SubdomainID> & ids) const
262 {
263  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
264  return true;
265  else
266  return std::includes(_blk_ids.begin(), _blk_ids.end(), ids.begin(), ids.end());
267 }
268 
269 bool
270 BlockRestrictable::isBlockSubset(const std::set<SubdomainID> & ids) const
271 {
272  // An empty input is assumed to be ANY_BLOCK_ID
273  if (ids.empty() || ids.find(Moose::ANY_BLOCK_ID) != ids.end())
274  return true;
275 
276  if (_blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
277  return std::includes(ids.begin(),
278  ids.end(),
279  _blk_mesh->meshSubdomains().begin(),
280  _blk_mesh->meshSubdomains().end());
281  else
282  return std::includes(ids.begin(), ids.end(), _blk_ids.begin(), _blk_ids.end());
283 }
284 
285 bool
286 BlockRestrictable::isBlockSubset(const std::vector<SubdomainID> & ids) const
287 {
288  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
289  return isBlockSubset(ids_set);
290 }
291 
292 const std::set<SubdomainID> &
294 {
295  return _blk_mesh->meshSubdomains();
296 }
297 
298 bool
300 {
301 
302  // Reference to MaterialWarehouse for testing and retrieving block ids
304 
305  // Complete set of ids that this object is active
306  const std::set<SubdomainID> & ids = blockRestricted() ? blockIDs() : meshBlockIDs();
307 
308  // Loop over each id for this object
309  for (const auto & id : ids)
310  {
311  // Storage of material properties that have been DECLARED on this id
312  std::set<std::string> declared_props;
313 
314  // If block materials exist, populated the set of properties that were declared
315  if (warehouse.hasActiveBlockObjects(id))
316  {
317  const std::vector<std::shared_ptr<MaterialBase>> & mats = warehouse.getActiveBlockObjects(id);
318  for (const auto & mat : mats)
319  {
320  const std::set<std::string> & mat_props = mat->getSuppliedItems();
321  declared_props.insert(mat_props.begin(), mat_props.end());
322  }
323  }
324 
325  // If the supplied property is not in the list of properties on the current id, return false
326  if (declared_props.find(prop_name) == declared_props.end())
327  return false;
328  }
329 
330  // If you get here the supplied property is defined on all blocks
331  return true;
332 }
333 
336 {
337  if (!_blk_mesh)
338  mooseError("No mesh available in BlockRestrictable::checkCoordSystem()");
339  if (!_blk_feproblem)
340  mooseError("No problem available in BlockRestrictable::checkCoordSystem()");
341 
342  const auto & subdomains = blockRestricted() ? blockIDs() : meshBlockIDs();
343 
344  if (subdomains.empty())
345  mooseError("No subdomains found in the problem.");
346 
347  // make sure all subdomains are using the same coordinate system
348  auto coord_system = _blk_feproblem->getCoordSystem(*subdomains.begin());
349  for (auto subdomain : subdomains)
350  if (_blk_feproblem->getCoordSystem(subdomain) != coord_system)
351  mooseError("This object requires all subdomains to have the same coordinate system.");
352 
353  return coord_system;
354 }
355 
356 void
358 {
359  // a variable defined on all internal sides does not need this check because
360  // it can be coupled with other variables in DG kernels
361  if (!_blk_mesh->interiorLowerDBlocks().empty() &&
363  return;
364 
365  if (!isBlockSubset(variable.activeSubdomains()))
366  {
367  std::string var_ids = Moose::stringify(variable.activeSubdomains(), ", ");
368  std::string obj_ids = Moose::stringify(blockRestricted() ? _blk_ids : meshBlockIDs(), ", ");
369  mooseError("The 'block' parameter of the object '",
370  _blk_name,
371  "' must be a subset of the 'block' parameter of the variable '",
372  variable.name(),
373  "':\n Object '",
374  _blk_name,
375  "': ",
376  obj_ids,
377  "\n Variable '",
378  variable.name(),
379  "': ",
380  var_ids);
381  }
382 }
383 
384 unsigned int
386 {
387  mooseAssert(_blk_dim != libMesh::invalid_uint, "Block restriction not initialized");
388  return _blk_dim;
389 }
std::string name(const ElemQuality q)
unsigned int blocksMaxDimension() const
Return the largest mesh dimension of the elements in the blocks for this object.
std::string getMooseType(const std::string &name) const
Utility functions for retrieving one of the MooseTypes variables into the common "string" base class...
unsigned int _blk_dim
Largest mesh dimension of the elements in the blocks for this object.
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
unsigned int numBlocks() const
Return the number of blocks for this object.
const bool _blk_dual_restrictable
Flag for allowing dual restriction.
const std::set< SubdomainID > & interiorLowerDBlocks() const
Definition: MooseMesh.h:1429
bool hasActiveBlockObjects(THREAD_ID tid=0) const
const unsigned int invalid_uint
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 std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
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...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:131
Moose::CoordinateSystemType getBlockCoordSystem()
Check if the blocks this object operates on all have the same coordinate system, and if so return it...
FEProblemBase * _blk_feproblem
Pointer to FEProblemBase.
virtual void checkVariable(const MooseVariableFieldBase &variable) const
Helper for checking that the ids for this object are in agreement with the variables on the supplied ...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const MooseObject * _moose_object
Pointer to the MOOSE object.
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted, this function returns all mesh subdomain ids.
virtual bool blockRestricted() const
Returns true if this object has been restricted to a block.
MaterialBase objects are special in that they have additional objects created automatically (see FEPr...
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const MaterialWarehouse & getMaterialWarehouse() const
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
void initialize(EquationSystems &es, const std::string &system_name)
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_names) const
Get the associated subdomainIDs for the subdomain names that are passed in.
Definition: MooseMesh.C:1775
InputParameters emptyInputParameters()
static InputParameters validParams()
const Moose::Kokkos::Mesh * getKokkosMesh() const
Accessor for Kokkos mesh object.
Definition: MooseMesh.h:674
bool isBlockSubset(const std::set< SubdomainID > &ids) const
Test if the class block ids are a subset of the supplied objects.
void initializeBlockRestrictable(const MooseObject *moose_object)
An initialization routine needed for dual constructors.
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:103
bool activeOnSubdomains(const std::set< SubdomainID > &subdomains) const
Is the variable active on the subdomains?
std::vector< SubdomainID > _vec_ids
Vector of block ids supplied by the user via the input file (for error reporting) ...
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:27
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
Definition: MooseMesh.C:2968
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:92
void initializeKokkosBlockRestrictable(const Moose::Kokkos::Mesh *mesh)
THREAD_ID _blk_tid
Thread id for this object.
std::vector< SubdomainName > _blocks
Vector the block names supplied by the user via the input file.
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
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
std::vector< SubdomainName > getSubdomainNames(const std::vector< SubdomainID > &subdomain_ids) const
Get the associated subdomainNames for the subdomain ids that are passed in.
Definition: MooseMesh.C:1807
MaterialData & getMaterialData(Moose::MaterialDataType type, const THREAD_ID tid=0, const MooseObject *object=nullptr) const
MaterialData & getKokkosMaterialData(Moose::MaterialDataType type, const MooseObject *object=nullptr) const
const MooseMesh * _blk_mesh
Pointer to Mesh.
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
const std::set< SubdomainID > & activeSubdomains() const
The subdomains the variable is active on.
const SubdomainID ANY_BLOCK_ID
Definition: MooseTypes.C:19
const std::vector< SubdomainName > & blocks() const
Return the block names for this object.
CoordinateSystemType
Definition: MooseTypes.h:810
unsigned int getBlocksMaxDimension(const std::vector< SubdomainName > &blocks) const
Returns the maximum element dimension on the given blocks.
Definition: MooseMesh.C:2989
const MaterialData * _blk_material_data
Pointer to the MaterialData class for this object.
const std::set< SubdomainID > & meshBlockIDs() const
Return all of the SubdomainIDs for the mesh.
virtual MooseMesh & mesh() override
virtual bool hasBlockMaterialPropertyHelper(const std::string &prop_name)
A helper method to allow the Material object to specialize the behavior of hasBlockMaterialProperty.
const std::set< BoundaryID > & _boundary_ids
Reference to the boundary_ids, defaults to an empty set if not provided.
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...
Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) const
Definition: SubProblem.C:1278
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:199
BlockRestrictable(const MooseObject *moose_object, bool initialize=true)
Class constructor Populates the &#39;block&#39; input parameters, see the general class documentation for det...
bool hasBlocks(const SubdomainName &name) const
Test if the supplied block name is valid for this object.
std::set< SubdomainID > _blk_ids
Set of block ids supplied by the user via the input file (for error checking)
const std::string & _blk_name
Name of the object.
const BoundaryID ANY_BOUNDARY_ID
Definition: MooseTypes.C:21
unsigned int THREAD_ID
Definition: MooseTypes.h:209
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
Definition: MooseMesh.C:3211