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->getParam<std::string>("_object_name")),
50  _blk_dim(libMesh::invalid_uint)
51 {
52  if (initialize)
53  initializeBlockRestrictable(moose_object);
54 }
55 
56 // Dual restricted constructor
58  const std::set<BoundaryID> & boundary_ids)
59  : _blk_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
60  _blk_feproblem(moose_object->isParamValid("_fe_problem_base")
61  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
62  : NULL),
63  _blk_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
64  : NULL),
65  _boundary_ids(boundary_ids),
66  _blk_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
67  _blk_name(moose_object->getParam<std::string>("_object_name")),
68  _blk_dim(libMesh::invalid_uint)
69 {
70  initializeBlockRestrictable(moose_object);
71 }
72 
73 void
75 {
76  // If the mesh pointer is not defined, but FEProblemBase is, get it from there
77  if (_blk_feproblem != NULL && _blk_mesh == NULL)
79 
80  // Check that the mesh pointer was defined, it is required for this class to operate
81  if (_blk_mesh == NULL)
82  mooseError("The input parameters must contain a pointer to FEProblem via '_fe_problem' or a "
83  "pointer to the MooseMesh via '_mesh'");
84 
85  // Populate the MaterialData pointer
86  if (_blk_feproblem != NULL)
88 
89  // The 'block' input is defined
90  if (moose_object->isParamValid("block"))
91  {
92  // Extract the blocks from the input
93  _blocks = moose_object->getParam<std::vector<SubdomainName>>("block");
94 
95  // Store the IDs in a set, handling ANY_BLOCK_ID if supplied
96  if (std::find(_blocks.begin(), _blocks.end(), "ANY_BLOCK_ID") != _blocks.end())
98  else
99  {
100  // Get the IDs from the supplied names
102  _blk_ids.insert(_vec_ids.begin(), _vec_ids.end());
103  }
104  }
105 
106  // When 'blocks' is not set and there is a "variable", use the blocks from the variable
107  else if (moose_object->isParamValid("variable"))
108  {
109  std::string variable_name = moose_object->parameters().getMooseType("variable");
110  if (!variable_name.empty())
112  ->getVariable(_blk_tid,
113  variable_name,
116  .activeSubdomains();
117  }
118 
119  // Produce error if the object is not allowed to be both block and boundary restricted
120  if (!_blk_dual_restrictable && !_boundary_ids.empty() && !_boundary_ids.empty())
121  if (!_boundary_ids.empty() && _boundary_ids.find(Moose::ANY_BOUNDARY_ID) == _boundary_ids.end())
122  moose_object->paramError("block",
123  "Attempted to restrict the object '",
124  _blk_name,
125  "' to a block, but the object is already restricted by boundary");
126 
127  // If no blocks were defined above, specify that it is valid on all blocks
128  if (_blk_ids.empty() && !moose_object->isParamValid("boundary"))
129  {
131  _blocks = {"ANY_BLOCK_ID"};
132  }
133 
134  // If this object is block restricted, check that defined blocks exist on the mesh
135  if (_blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end())
136  {
137  const std::set<SubdomainID> & valid_ids = _blk_mesh->meshSubdomains();
138  std::vector<SubdomainID> diff;
139 
140  std::set_difference(_blk_ids.begin(),
141  _blk_ids.end(),
142  valid_ids.begin(),
143  valid_ids.end(),
144  std::back_inserter(diff));
145 
146  if (!diff.empty())
147  {
148  std::ostringstream msg;
149  auto sep = " ";
150  msg << "the following blocks (ids) do not exist on the mesh:";
151  for (const auto & id : diff)
152  {
153  if (_blk_name.size() > 0)
154  {
155  auto & name =
156  _blocks.at(std::find(_vec_ids.begin(), _vec_ids.end(), id) - _vec_ids.begin());
157  if (std::to_string(id) != name)
158  msg << sep << name << " (" << id << ")";
159  else
160  msg << sep << id;
161  }
162  else
163  msg << sep << id;
164  sep = ", ";
165  }
166  std::vector<SubdomainID> valid_ids_vec(valid_ids.begin(), valid_ids.end());
167  auto valid_names = _blk_mesh->getSubdomainNames(valid_ids_vec);
168  msg << "\nBlocks names (resp. ids) that do exist: " << Moose::stringify(valid_names) << " ("
169  << Moose::stringify(valid_ids) << ")";
170  moose_object->paramError("block", msg.str());
171  }
172  }
173 
174  // Get the mesh dimension for the blocks
175  if (blockRestricted())
177  else
179 }
180 
181 bool
183 {
184  return _blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end();
185 }
186 
187 const std::vector<SubdomainName> &
189 {
190  return _blocks;
191 }
192 
193 const std::set<SubdomainID> &
195 {
196  if (_blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
197  return _blk_mesh->meshSubdomains();
198  else
199  return _blk_ids;
200 }
201 
202 unsigned int
204 {
205  return (unsigned int)_blk_ids.size();
206 }
207 
208 bool
209 BlockRestrictable::hasBlocks(const SubdomainName & name) const
210 {
211  // Create a vector and utilize the getSubdomainIDs function, which
212  // handles the ANY_BLOCK_ID (getSubdomainID does not)
213  std::vector<SubdomainName> names(1);
214  names[0] = name;
215  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
216 }
217 
218 bool
219 BlockRestrictable::hasBlocks(const std::vector<SubdomainName> & names) const
220 {
221  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
222 }
223 
224 bool
225 BlockRestrictable::hasBlocks(const std::set<SubdomainName> & names) const
226 {
227  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
228 }
229 
230 bool
232 {
233  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
234  return true;
235  else
236  return _blk_ids.find(id) != _blk_ids.end();
237 }
238 
239 bool
240 BlockRestrictable::hasBlocks(const std::vector<SubdomainID> & ids) const
241 {
242  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
243  return hasBlocks(ids_set);
244 }
245 
246 bool
247 BlockRestrictable::hasBlocks(const std::set<SubdomainID> & ids) const
248 {
249  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
250  return true;
251  else
252  return std::includes(_blk_ids.begin(), _blk_ids.end(), ids.begin(), ids.end());
253 }
254 
255 bool
256 BlockRestrictable::isBlockSubset(const std::set<SubdomainID> & ids) const
257 {
258  // An empty input is assumed to be ANY_BLOCK_ID
259  if (ids.empty() || ids.find(Moose::ANY_BLOCK_ID) != ids.end())
260  return true;
261 
262  if (_blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
263  return std::includes(ids.begin(),
264  ids.end(),
265  _blk_mesh->meshSubdomains().begin(),
266  _blk_mesh->meshSubdomains().end());
267  else
268  return std::includes(ids.begin(), ids.end(), _blk_ids.begin(), _blk_ids.end());
269 }
270 
271 bool
272 BlockRestrictable::isBlockSubset(const std::vector<SubdomainID> & ids) const
273 {
274  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
275  return isBlockSubset(ids_set);
276 }
277 
278 const std::set<SubdomainID> &
280 {
281  return _blk_mesh->meshSubdomains();
282 }
283 
284 bool
286 {
287 
288  // Reference to MaterialWarehouse for testing and retrieving block ids
290 
291  // Complete set of ids that this object is active
292  const std::set<SubdomainID> & ids = blockRestricted() ? blockIDs() : meshBlockIDs();
293 
294  // Loop over each id for this object
295  for (const auto & id : ids)
296  {
297  // Storage of material properties that have been DECLARED on this id
298  std::set<std::string> declared_props;
299 
300  // If block materials exist, populated the set of properties that were declared
301  if (warehouse.hasActiveBlockObjects(id))
302  {
303  const std::vector<std::shared_ptr<MaterialBase>> & mats = warehouse.getActiveBlockObjects(id);
304  for (const auto & mat : mats)
305  {
306  const std::set<std::string> & mat_props = mat->getSuppliedItems();
307  declared_props.insert(mat_props.begin(), mat_props.end());
308  }
309  }
310 
311  // If the supplied property is not in the list of properties on the current id, return false
312  if (declared_props.find(prop_name) == declared_props.end())
313  return false;
314  }
315 
316  // If you get here the supplied property is defined on all blocks
317  return true;
318 }
319 
322 {
323  if (!_blk_mesh)
324  mooseError("No mesh available in BlockRestrictable::checkCoordSystem()");
325  if (!_blk_feproblem)
326  mooseError("No problem available in BlockRestrictable::checkCoordSystem()");
327 
328  const auto & subdomains = blockRestricted() ? blockIDs() : meshBlockIDs();
329 
330  if (subdomains.empty())
331  mooseError("No subdomains found in the problem.");
332 
333  // make sure all subdomains are using the same coordinate system
334  auto coord_system = _blk_feproblem->getCoordSystem(*subdomains.begin());
335  for (auto subdomain : subdomains)
336  if (_blk_feproblem->getCoordSystem(subdomain) != coord_system)
337  mooseError("This object requires all subdomains to have the same coordinate system.");
338 
339  return coord_system;
340 }
341 
342 void
344 {
345  // a variable defined on all internal sides does not need this check because
346  // it can be coupled with other variables in DG kernels
347  if (!_blk_mesh->interiorLowerDBlocks().empty() &&
349  return;
350 
351  if (!isBlockSubset(variable.activeSubdomains()))
352  {
353  std::string var_ids = Moose::stringify(variable.activeSubdomains(), ", ");
354  std::string obj_ids = Moose::stringify(blockRestricted() ? _blk_ids : meshBlockIDs(), ", ");
355  mooseError("The 'block' parameter of the object '",
356  _blk_name,
357  "' must be a subset of the 'block' parameter of the variable '",
358  variable.name(),
359  "':\n Object '",
360  _blk_name,
361  "': ",
362  obj_ids,
363  "\n Variable '",
364  variable.name(),
365  "': ",
366  var_ids);
367  }
368 }
369 
370 unsigned int
372 {
373  mooseAssert(_blk_dim != libMesh::invalid_uint, "Block restriction not initialized");
374  return _blk_dim;
375 }
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.
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:1403
bool hasActiveBlockObjects(THREAD_ID tid=0) const
const unsigned int invalid_uint
const std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
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:302
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.
const std::string & name() const override
Get the variable name.
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...
MaterialData & getMaterialData(Moose::MaterialDataType type, const THREAD_ID tid=0) const
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:1734
InputParameters emptyInputParameters()
static InputParameters validParams()
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
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.
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:28
virtual unsigned int dimension() const
Returns MeshBase::mesh_dimension(), (not MeshBase::spatial_dimension()!) of the underlying libMesh me...
Definition: MooseMesh.C:2923
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:88
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
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.
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 ...
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:1764
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:809
unsigned int getBlocksMaxDimension(const std::vector< SubdomainName > &blocks) const
Returns the maximum element dimension on the given blocks.
Definition: MooseMesh.C:2944
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.
const InputParameters & parameters() const
Get the parameters of the object.
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
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:3166