www.mooseframework.org
BlockRestrictable.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 // MOOSE Includes
16 #include "BlockRestrictable.h"
17 
18 #include "FEProblem.h"
19 #include "Material.h"
20 #include "MooseMesh.h"
21 #include "MooseVariable.h"
22 #include "SystemBase.h"
23 #include "Conversion.h"
24 #include "MooseVariableInterface.h"
25 
26 template <>
29 {
30  // Create InputParameters object that will be appended to the parameters for the inheriting object
32 
33  // Add the user-facing 'block' input parameter
34  params.addParam<std::vector<SubdomainName>>(
35  "block", "The list of block ids (SubdomainID) that this object will be applied");
36 
37  // A parameter for disabling error message for objects restrictable by boundary and block,
38  // if the parameter is valid it was already set so don't do anything
39  if (!params.isParamValid("_dual_restrictable"))
40  params.addPrivateParam<bool>("_dual_restrictable", false);
41 
42  // Return the parameters
43  return params;
44 }
45 
46 // Standard constructor
48  : _blk_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
49  _blk_feproblem(moose_object->isParamValid("_fe_problem_base")
50  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
51  : NULL),
52  _blk_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
53  : NULL),
54  _boundary_ids(_empty_boundary_ids),
55  _blk_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
56  _blk_name(moose_object->getParam<std::string>("_object_name"))
57 {
58  initializeBlockRestrictable(moose_object);
59 }
60 
61 // Dual restricted constructor
63  const std::set<BoundaryID> & boundary_ids)
64  : _blk_dual_restrictable(moose_object->getParam<bool>("_dual_restrictable")),
65  _blk_feproblem(moose_object->isParamValid("_fe_problem_base")
66  ? moose_object->getParam<FEProblemBase *>("_fe_problem_base")
67  : NULL),
68  _blk_mesh(moose_object->isParamValid("_mesh") ? moose_object->getParam<MooseMesh *>("_mesh")
69  : NULL),
70  _boundary_ids(boundary_ids),
71  _blk_tid(moose_object->isParamValid("_tid") ? moose_object->getParam<THREAD_ID>("_tid") : 0),
72  _blk_name(moose_object->getParam<std::string>("_object_name"))
73 {
74  initializeBlockRestrictable(moose_object);
75 }
76 
77 void
79 {
80  // If the mesh pointer is not defined, but FEProblemBase is, get it from there
81  if (_blk_feproblem != NULL && _blk_mesh == NULL)
83 
84  // Check that the mesh pointer was defined, it is required for this class to operate
85  if (_blk_mesh == NULL)
86  mooseError("The input parameters must contain a pointer to FEProblem via '_fe_problem' or a "
87  "pointer to the MooseMesh via '_mesh'");
88 
89  // Populate the MaterialData pointer
90  if (_blk_feproblem != NULL)
92 
93  // The 'block' input is defined
94  if (moose_object->isParamValid("block"))
95  {
96  // Extract the blocks from the input
97  _blocks = moose_object->getParam<std::vector<SubdomainName>>("block");
98 
99  // Get the IDs from the supplied names
100  std::vector<SubdomainID> vec_ids = _blk_mesh->getSubdomainIDs(_blocks);
101 
102  // Store the IDs, handling ANY_BLOCK_ID if supplied
103  if (std::find(_blocks.begin(), _blocks.end(), "ANY_BLOCK_ID") != _blocks.end())
105  else
106  _blk_ids.insert(vec_ids.begin(), vec_ids.end());
107  }
108 
109  // When 'blocks' is not set and there is a "variable", use the blocks from the variable
110  else if (moose_object->isParamValid("variable"))
111  {
112  std::string variable_name = moose_object->parameters().getMooseType("variable");
113  if (!variable_name.empty())
115  }
116 
117  // Produce error if the object is not allowed to be both block and boundary restricted
118  if (!_blk_dual_restrictable && !_boundary_ids.empty() && !_boundary_ids.empty())
119  if (!_boundary_ids.empty() && _boundary_ids.find(Moose::ANY_BOUNDARY_ID) == _boundary_ids.end())
120  mooseError("Attempted to restrict the object '",
121  _blk_name,
122  "' to a block, but the object is already restricted by boundary");
123 
124  // If no blocks were defined above, specify that it is valid on all blocks
125  if (_blk_ids.empty() && !moose_object->isParamValid("boundary"))
126  {
128  _blocks = {"ANY_BLOCK_ID"};
129  }
130 
131  // If this object is block restricted, check that defined blocks exist on the mesh
132  if (_blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end())
133  {
134  const std::set<SubdomainID> & valid_ids = _blk_mesh->meshSubdomains();
135  std::vector<SubdomainID> diff;
136 
137  std::set_difference(_blk_ids.begin(),
138  _blk_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  msg << "The object '" << _blk_name
147  << "' contains the following block ids that do not exist on the mesh:";
148  for (const auto & id : diff)
149  msg << " " << id;
150  mooseError(msg.str());
151  }
152  }
153 }
154 
155 bool
157 {
158  return _blk_ids.find(Moose::ANY_BLOCK_ID) == _blk_ids.end();
159 }
160 
161 const std::vector<SubdomainName> &
163 {
164  return _blocks;
165 }
166 
167 const std::set<SubdomainID> &
169 {
170  return _blk_ids;
171 }
172 
173 unsigned int
175 {
176  return (unsigned int)_blk_ids.size();
177 }
178 
179 bool
180 BlockRestrictable::hasBlocks(const SubdomainName & name) const
181 {
182  // Create a vector and utilize the getSubdomainIDs function, which
183  // handles the ANY_BLOCK_ID (getSubdomainID does not)
184  std::vector<SubdomainName> names(1);
185  names[0] = name;
186  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
187 }
188 
189 bool
190 BlockRestrictable::hasBlocks(const std::vector<SubdomainName> & names) const
191 {
192  return hasBlocks(_blk_mesh->getSubdomainIDs(names));
193 }
194 
195 bool
197 {
198  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
199  return true;
200  else
201  return _blk_ids.find(id) != _blk_ids.end();
202 }
203 
204 bool
205 BlockRestrictable::hasBlocks(const std::vector<SubdomainID> & ids) const
206 {
207  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
208  return hasBlocks(ids_set);
209 }
210 
211 bool
212 BlockRestrictable::hasBlocks(const std::set<SubdomainID> & ids) const
213 {
214  if (_blk_ids.empty() || _blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
215  return true;
216  else
217  return std::includes(_blk_ids.begin(), _blk_ids.end(), ids.begin(), ids.end());
218 }
219 
220 bool
221 BlockRestrictable::isBlockSubset(const std::set<SubdomainID> & ids) const
222 {
223  // An empty input is assumed to be ANY_BLOCK_ID
224  if (ids.empty() || ids.find(Moose::ANY_BLOCK_ID) != ids.end())
225  return true;
226 
227  if (_blk_ids.find(Moose::ANY_BLOCK_ID) != _blk_ids.end())
228  return std::includes(ids.begin(),
229  ids.end(),
230  _blk_mesh->meshSubdomains().begin(),
231  _blk_mesh->meshSubdomains().end());
232  else
233  return std::includes(ids.begin(), ids.end(), _blk_ids.begin(), _blk_ids.end());
234 }
235 
236 bool
237 BlockRestrictable::isBlockSubset(const std::vector<SubdomainID> & ids) const
238 {
239  std::set<SubdomainID> ids_set(ids.begin(), ids.end());
240  return isBlockSubset(ids_set);
241 }
242 
243 const std::set<SubdomainID> &
245 {
246  return _blk_mesh->meshSubdomains();
247 }
248 
249 bool
251 {
252 
253  // Reference to MaterialWarehouse for testing and retrieving block ids
255 
256  // Complete set of ids that this object is active
257  const std::set<SubdomainID> & ids = blockRestricted() ? blockIDs() : meshBlockIDs();
258 
259  // Loop over each id for this object
260  for (const auto & id : ids)
261  {
262  // Storage of material properties that have been DECLARED on this id
263  std::set<std::string> declared_props;
264 
265  // If block materials exist, populated the set of properties that were declared
266  if (warehouse.hasActiveBlockObjects(id))
267  {
268  const std::vector<std::shared_ptr<Material>> & mats = warehouse.getActiveBlockObjects(id);
269  for (const auto & mat : mats)
270  {
271  const std::set<std::string> & mat_props = mat->getSuppliedItems();
272  declared_props.insert(mat_props.begin(), mat_props.end());
273  }
274  }
275 
276  // If the supplied property is not in the list of properties on the current id, return false
277  if (declared_props.find(prop_name) == declared_props.end())
278  return false;
279  }
280 
281  // If you get here the supplied property is defined on all blocks
282  return true;
283 }
284 
287 {
288  if (!_blk_mesh)
289  mooseError("No mesh available in BlockRestrictable::checkCoordSystem()");
290  if (!_blk_feproblem)
291  mooseError("No problem available in BlockRestrictable::checkCoordSystem()");
292 
293  const auto & subdomains = blockRestricted() ? blockIDs() : meshBlockIDs();
294 
295  if (subdomains.empty())
296  mooseError("No subdomains found in the problem.");
297 
298  // make sure all subdomains are using the same coordinate system
299  auto coord_system = _blk_feproblem->getCoordSystem(*subdomains.begin());
300  for (auto subdomain : subdomains)
301  if (_blk_feproblem->getCoordSystem(subdomain) != coord_system)
302  mooseError("This object requires all subdomains to have the same coordinate system.");
303 
304  return coord_system;
305 }
306 
307 void
309 {
310  if (!isBlockSubset(variable.activeSubdomains()))
311  {
312  std::string var_ids = Moose::stringify(variable.activeSubdomains(), ", ");
313  std::string obj_ids = Moose::stringify(blockRestricted() ? _blk_ids : meshBlockIDs(), ", ");
314  mooseError("The 'block' parameter of the object '",
315  _blk_name,
316  "' must be a subset of the 'block' parameter of the variable '",
317  variable.name(),
318  "':\n Object '",
319  _blk_name,
320  "': ",
321  obj_ids,
322  "\n Variable '",
323  variable.name(),
324  "': ",
325  var_ids);
326  }
327 }
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object.
bool isBlockSubset(const std::set< SubdomainID > &ids) const
Test if the class block ids are a subset of the supplied objects.
const bool _blk_dual_restrictable
Flag for allowing dual restriction.
Class for stuff related to variables.
Definition: MooseVariable.h:43
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...
subdomain_id_type SubdomainID
Definition: MooseTypes.h:77
const std::vector< SubdomainName > & blocks() const
Return the block names for this object.
const std::set< SubdomainID > & meshBlockIDs() const
Return all of the SubdomainIDs for the mesh.
const std::set< SubdomainID > & meshSubdomains() const
Returns a read-only reference to the set of subdomains currently present in the Mesh.
Definition: MooseMesh.C:2104
void mooseError(Args &&...args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:182
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...
Material objects are special in that they have additional objects created automatically (see FEProble...
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
const std::string & name() const
Get the variable name.
InputParameters emptyInputParameters()
const std::set< SubdomainID > & activeSubdomains() const
std::shared_ptr< MaterialData > _blk_material_data
Pointer to the MaterialData class for this object.
void initializeBlockRestrictable(const MooseObject *moose_object)
An initialization routine needed for dual constructors.
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:36
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.
unsigned int numBlocks() const
Return the number of blocks for this object.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:67
bool hasBlocks(const SubdomainName &name) const
Test if the supplied block name is valid for this object.
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:66
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseObject.h:122
std::string getMooseType(const std::string &name) const
Utility functions for retrieving one of the MooseTypes variables into the common "string" base class...
InputParameters validParams< BlockRestrictable >()
CoordinateSystemType
Definition: MooseTypes.h:212
std::shared_ptr< MaterialData > getMaterialData(Moose::MaterialDataType type, THREAD_ID tid=0)
const std::map< SubdomainID, std::vector< std::shared_ptr< T > > > & getActiveBlockObjects(THREAD_ID tid=0) const
const MaterialWarehouse & getMaterialWarehouse()
const SubdomainID ANY_BLOCK_ID
Definition: MooseTypes.h:117
void checkVariable(const MooseVariable &variable) const
Helper for checking that the ids for this object are in agreement with the variables on the supplied ...
virtual Moose::CoordinateSystemType getCoordSystem(SubdomainID sid) override
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseObject.h:53
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...
bool hasActiveBlockObjects(THREAD_ID tid=0) const
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:1012
std::set< SubdomainID > _blk_ids
Set of block ids supplied by the user via the input file (for error reporting)
virtual MooseVariable & getVariable(THREAD_ID tid, const std::string &var_name) override
Returns the variable reference for requested variable which may be in any system. ...
const std::string & _blk_name
Name of the object.
MooseMesh * _blk_mesh
Pointer to Mesh.
const BoundaryID ANY_BOUNDARY_ID
Definition: MooseTypes.h:119
unsigned int THREAD_ID
Definition: MooseTypes.h:79
virtual bool blockRestricted() const
Returns true if this object has been restricted to a boundary.