www.mooseframework.org
BlockRestrictable.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 "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 
20 template <>
23 {
24  // Create InputParameters object that will be appended to the parameters for the inheriting object
26 
27  // Add the user-facing 'block' input parameter
28  params.addParam<std::vector<SubdomainName>>(
29  "block", "The list of block ids (SubdomainID) that this object will be applied");
30 
31  // A parameter for disabling error message for objects restrictable by boundary and block,
32  // if the parameter is valid it was already set so don't do anything
33  if (!params.isParamValid("_dual_restrictable"))
34  params.addPrivateParam<bool>("_dual_restrictable", false);
35 
36  // Return the parameters
37  return params;
38 }
39 
40 // Standard constructor
42  : _blk_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
43  _blk_feproblem(moose_object->isParamValid("_fe_problem_base")
44  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
45  : NULL),
46  _blk_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
47  : NULL),
48  _boundary_ids(_empty_boundary_ids),
49  _blk_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
50  _blk_name(moose_object->getParam<std::string>("_object_name"))
51 {
52  initializeBlockRestrictable(moose_object);
53 }
54 
55 // Dual restricted constructor
57  const std::set<BoundaryID> & boundary_ids)
58  : _blk_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
59  _blk_feproblem(moose_object->isParamValid("_fe_problem_base")
60  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
61  : NULL),
62  _blk_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
63  : NULL),
64  _boundary_ids(boundary_ids),
65  _blk_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
66  _blk_name(moose_object->getParam<std::string>("_object_name"))
67 {
68  initializeBlockRestrictable(moose_object);
69 }
70 
71 void
73 {
74  // If the mesh pointer is not defined, but FEProblemBase is, get it from there
75  if (_blk_feproblem != NULL && _blk_mesh == NULL)
77 
78  // Check that the mesh pointer was defined, it is required for this class to operate
79  if (_blk_mesh == NULL)
80  mooseError("The input parameters must contain a pointer to FEProblem via '_fe_problem' or a "
81  "pointer to the MooseMesh via '_mesh'");
82 
83  // Populate the MaterialData pointer
84  if (_blk_feproblem != NULL)
86 
87  // The 'block' input is defined
88  if (moose_object->isParamValid("block"))
89  {
90  // Extract the blocks from the input
91  _blocks = moose_object->getParam<std::vector<SubdomainName>>("block");
92 
93  // Get the IDs from the supplied names
94  std::vector<SubdomainID> vec_ids = _blk_mesh->getSubdomainIDs(_blocks);
95 
96  // Store the IDs, handling ANY_BLOCK_ID if supplied
97  if (std::find(_blocks.begin(), _blocks.end(), "ANY_BLOCK_ID") != _blocks.end())
99  else
100  _blk_ids.insert(vec_ids.begin(), vec_ids.end());
101  }
102 
103  // When 'blocks' is not set and there is a "variable", use the blocks from the variable
104  else if (moose_object->isParamValid("variable"))
105  {
106  std::string variable_name = moose_object->parameters().getMooseType("variable");
107  if (!variable_name.empty())
109  ->getVariable(_blk_tid,
110  variable_name,
113  .activeSubdomains();
114  }
115 
116  // Produce error if the object is not allowed to be both block and boundary restricted
117  if (!_blk_dual_restrictable && !_boundary_ids.empty() && !_boundary_ids.empty())
118  if (!_boundary_ids.empty() && _boundary_ids.find(Moose::ANY_BOUNDARY_ID) == _boundary_ids.end())
119  mooseError("Attempted to restrict the object '",
120  _blk_name,
121  "' to a block, but the object is already restricted by boundary");
122 
123  // If no blocks were defined above, specify that it is valid on all blocks
124  if (_blk_ids.empty() && !moose_object->isParamValid("boundary"))
125  {
127  _blocks = {"ANY_BLOCK_ID"};
128  }
129 
130  // If this object is block restricted, check that defined blocks exist on the mesh
131  if (_blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end())
132  {
133  const std::set<SubdomainID> & valid_ids = _blk_mesh->meshSubdomains();
134  std::vector<SubdomainID> diff;
135 
136  std::set_difference(_blk_ids.begin(),
137  _blk_ids.end(),
138  valid_ids.begin(),
139  valid_ids.end(),
140  std::back_inserter(diff));
141 
142  if (!diff.empty())
143  {
144  std::ostringstream msg;
145  msg << "The object '" << _blk_name
146  << "' contains the following block ids that do not exist on the mesh:";
147  for (const auto & id : diff)
148  msg << " " << id;
149  mooseError(msg.str());
150  }
151  }
152 }
153 
154 bool
156 {
157  return _blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end();
158 }
159 
160 const std::vector<SubdomainName> &
162 {
163  return _blocks;
164 }
165 
166 const std::set<SubdomainID> &
168 {
169  return _blk_ids;
170 }
171 
172 unsigned int
174 {
175  return (unsigned int)_blk_ids.size();
176 }
177 
178 bool
179 BlockRestrictable::hasBlocks(const SubdomainName & name) const
180 {
181  // Create a vector and utilize the getSubdomainIDs function, which
182  // handles the ANY_BLOCK_ID (getSubdomainID does not)
183  std::vector<SubdomainName> names(1);
184  names[0] = name;
185  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
186 }
187 
188 bool
189 BlockRestrictable::hasBlocks(const std::vector<SubdomainName> & names) const
190 {
191  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
192 }
193 
194 bool
196 {
197  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
198  return true;
199  else
200  return _blk_ids.find(id) != _blk_ids.end();
201 }
202 
203 bool
204 BlockRestrictable::hasBlocks(const std::vector<SubdomainID> & ids) const
205 {
206  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
207  return hasBlocks(ids_set);
208 }
209 
210 bool
211 BlockRestrictable::hasBlocks(const std::set<SubdomainID> & ids) const
212 {
213  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
214  return true;
215  else
216  return std::includes(_blk_ids.begin(), _blk_ids.end(), ids.begin(), ids.end());
217 }
218 
219 bool
220 BlockRestrictable::isBlockSubset(const std::set<SubdomainID> & ids) const
221 {
222  // An empty input is assumed to be ANY_BLOCK_ID
223  if (ids.empty() || ids.find(Moose::ANY_BLOCK_ID) != ids.end())
224  return true;
225 
226  if (_blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
227  return std::includes(ids.begin(),
228  ids.end(),
229  _blk_mesh->meshSubdomains().begin(),
230  _blk_mesh->meshSubdomains().end());
231  else
232  return std::includes(ids.begin(), ids.end(), _blk_ids.begin(), _blk_ids.end());
233 }
234 
235 bool
236 BlockRestrictable::isBlockSubset(const std::vector<SubdomainID> & ids) const
237 {
238  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
239  return isBlockSubset(ids_set);
240 }
241 
242 const std::set<SubdomainID> &
244 {
245  return _blk_mesh->meshSubdomains();
246 }
247 
248 bool
250 {
251 
252  // Reference to MaterialWarehouse for testing and retrieving block ids
254 
255  // Complete set of ids that this object is active
256  const std::set<SubdomainID> & ids = blockRestricted() ? blockIDs() : meshBlockIDs();
257 
258  // Loop over each id for this object
259  for (const auto & id : ids)
260  {
261  // Storage of material properties that have been DECLARED on this id
262  std::set<std::string> declared_props;
263 
264  // If block materials exist, populated the set of properties that were declared
265  if (warehouse.hasActiveBlockObjects(id))
266  {
267  const std::vector<std::shared_ptr<Material>> & mats = warehouse.getActiveBlockObjects(id);
268  for (const auto & mat : mats)
269  {
270  const std::set<std::string> & mat_props = mat->getSuppliedItems();
271  declared_props.insert(mat_props.begin(), mat_props.end());
272  }
273  }
274 
275  // If the supplied property is not in the list of properties on the current id, return false
276  if (declared_props.find(prop_name) == declared_props.end())
277  return false;
278  }
279 
280  // If you get here the supplied property is defined on all blocks
281  return true;
282 }
283 
286 {
287  if (!_blk_mesh)
288  mooseError("No mesh available in BlockRestrictable::checkCoordSystem()");
289  if (!_blk_feproblem)
290  mooseError("No problem available in BlockRestrictable::checkCoordSystem()");
291 
292  const auto & subdomains = blockRestricted() ? blockIDs() : meshBlockIDs();
293 
294  if (subdomains.empty())
295  mooseError("No subdomains found in the problem.");
296 
297  // make sure all subdomains are using the same coordinate system
298  auto coord_system = _blk_feproblem->getCoordSystem(*subdomains.begin());
299  for (auto subdomain : subdomains)
300  if (_blk_feproblem->getCoordSystem(subdomain) != coord_system)
301  mooseError("This object requires all subdomains to have the same coordinate system.");
302 
303  return coord_system;
304 }
305 
306 void
308 {
309  if (!isBlockSubset(variable.activeSubdomains()))
310  {
311  std::string var_ids = Moose::stringify(variable.activeSubdomains(), ", ");
312  std::string obj_ids = Moose::stringify(blockRestricted() ? _blk_ids : meshBlockIDs(), ", ");
313  mooseError("The 'block' parameter of the object '",
314  _blk_name,
315  "' must be a subset of the 'block' parameter of the variable '",
316  variable.name(),
317  "':\n Object '",
318  _blk_name,
319  "': ",
320  obj_ids,
321  "\n Variable '",
322  variable.name(),
323  "': ",
324  var_ids);
325  }
326 }
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 numBlocks() const
Return the number of blocks for this object.
const bool _blk_dual_restrictable
Flag for allowing dual restriction.
bool hasActiveBlockObjects(THREAD_ID tid=0) const
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:207
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.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object.
virtual bool blockRestricted() const
Returns true if this object has been restricted to a boundary.
Material objects are special in that they have additional objects created automatically (see FEProble...
const MaterialWarehouse & getMaterialWarehouse() const
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()
std::shared_ptr< MaterialData > _blk_material_data
Pointer to the MaterialData class for this object.
virtual const std::set< SubdomainID > & activeSubdomains() const =0
The subdomains the variable is active on.
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.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:42
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseObject.h:65
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:74
BlockRestrictable(const MooseObject *moose_object)
Class constructor Populates the &#39;block&#39; input parameters, see the general class documentation for det...
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.
subdomain_id_type SubdomainID
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:60
InputParameters validParams< BlockRestrictable >()
CoordinateSystemType
Definition: MooseTypes.h:556
std::shared_ptr< MaterialData > getMaterialData(Moose::MaterialDataType type, THREAD_ID tid=0)
const SubdomainID ANY_BLOCK_ID
Definition: MooseTypes.C:15
const std::vector< SubdomainName > & blocks() const
Return the block names for this object.
const std::string & name() const
Get the variable name.
virtual Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) override
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 option parameter and a documentation string to the InputParameters object...
std::vector< SubdomainID > getSubdomainIDs(const std::vector< SubdomainName > &subdomain_name) const
Get the associated subdomainIDs for the subdomain names that are passed in.
Definition: MooseMesh.C:1090
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 reporting)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:89
void checkVariable(const MooseVariableFEBase &variable) const
Helper for checking that the ids for this object are in agreement with the variables on the supplied ...
const std::string & _blk_name
Name of the object.
MooseMesh * _blk_mesh
Pointer to Mesh.
const BoundaryID ANY_BOUNDARY_ID
Definition: MooseTypes.C:17
unsigned int THREAD_ID
Definition: MooseTypes.h:161
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
Definition: MooseMesh.C:2316
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.