https://mooseframework.inl.gov
ElementMaterialSampler.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 #include "ElementMaterialSampler.h"
11 #include "Material.h"
12 #include "IndirectSort.h"
13 #include "MooseMesh.h"
14 
15 #include "libmesh/quadrature.h"
16 
17 #include <numeric>
18 
21  MaterialVectorPostprocessor,
22  "06/30/2025 24:00",
24 
27 {
29  params.addClassDescription("Records all Real-valued material properties of a material object, "
30  "or Real-valued material properties of the supplied property names "
31  "on quadrature points on elements at the indicated execution points.");
32  params.addParam<MaterialName>("material", "Material for which all properties will be recorded.");
33  params.addParam<std::vector<MaterialPropertyName>>(
34  "property", "Material property names that will be recorded.");
35  params.addParam<std::vector<dof_id_type>>(
36  "elem_ids",
37  "Subset of element IDs to print data for. If omitted, all elements will be printed.");
38  return params;
39 }
40 
42  : ElementVectorPostprocessor(parameters),
43  _elem_ids(declareVector("elem_id")),
44  _qp_ids(declareVector("qp_id")),
45  _x_coords(declareVector("x")),
46  _y_coords(declareVector("y")),
47  _z_coords(declareVector("z"))
48 {
49  // Check either "material" or "property" was set but not both
50  if (parameters.isParamValid("material") && parameters.isParamValid("property"))
51  mooseError("Setting both 'material' and 'property' is not allowed. Use one or the other.");
52  if (!parameters.isParamValid("material") && !parameters.isParamValid("property"))
53  mooseError("Either 'material' and 'property' needs to be set.");
54 
55  // List of property names to collect
56  std::vector<MaterialName> prop_names;
57 
58  // Get list of elements from user
59  if (parameters.isParamValid("elem_ids"))
60  {
61  const auto & ids = getParam<std::vector<dof_id_type>>("elem_ids");
62  _elem_filter = std::set<dof_id_type>(ids.begin(), ids.end());
63  }
64 
65  // If Material is used, get all properties.
66  if (parameters.isParamValid("material"))
67  {
68  auto & mat = getMaterialByName(getParam<MaterialName>("material"), true);
69  if (mat.isBoundaryMaterial())
70  mooseError(name(), ": boundary materials (i.e. ", mat.name(), ") cannot be used");
71 
72  // Get property names from the Material
73  auto & props = mat.getSuppliedItems(); // returns std::set
74  prop_names = std::vector<MaterialName>(props.begin(), props.end());
75 
76  // Check requested materials are available
77  if (_elem_filter)
78  {
79  for (const auto & id : *_elem_filter)
80  {
81  auto el = _mesh.getMesh().query_elem_ptr(id);
82 
83  // We'd better have found the requested element on *some*
84  // processor.
85  bool found_elem = (el != nullptr);
86  this->comm().max(found_elem);
87 
88  // We might not have el on this processor in a distributed mesh,
89  // but it should be somewhere and it ought to have a material
90  // defined for its subdomain
91  if (!found_elem || (el && !mat.hasBlocks(el->subdomain_id())))
92  mooseError(name(), ": material ", mat.name(), " is not defined on element ", id);
93  }
94  }
95  }
96  else
97  {
98 
99  // Properties supplied by user
100  auto & props = getParam<std::vector<MaterialPropertyName>>("property");
101  prop_names = std::vector<MaterialName>(props.begin(), props.end());
102  }
103 
104  // Check properties are valid and store references
105  for (auto & prop : prop_names)
106  {
107  if (hasMaterialProperty<Real>(prop))
108  _prop_refs.push_back(&getMaterialProperty<Real>(prop));
109  else if (hasMaterialProperty<unsigned int>(prop))
110  _prop_refs.push_back(&getMaterialProperty<unsigned int>(prop));
111  else if (hasMaterialProperty<int>(prop))
112  _prop_refs.push_back(&getMaterialProperty<int>(prop));
113  else
114  {
115  mooseWarning("property " + prop +
116  " is of unsupported type and skipped by ElementMaterialSampler");
117  continue;
118  }
119  _prop_vecs.push_back(&declareVector(prop));
120  _prop_names.push_back(prop);
121  }
122 }
123 
124 void
126 {
128  {
129  _elem_ids.clear();
130  _qp_ids.clear();
131  _x_coords.clear();
132  _y_coords.clear();
133  _z_coords.clear();
134  for (auto vec : _prop_vecs)
135  vec->clear();
136  }
137 }
138 
139 void
141 {
142  // skip execution if element not in filter, assuming filter was used
143  const auto elem_id = _current_elem->id();
144  if (_elem_filter && !_elem_filter->count(elem_id))
145  return;
146 
147  unsigned int nqp = _qrule->n_points();
148  for (unsigned int qp = 0; qp < nqp; qp++)
149  {
150  _elem_ids.push_back(elem_id);
151  _qp_ids.push_back(qp);
152  _x_coords.push_back(_q_point[qp](0));
153  _y_coords.push_back(_q_point[qp](1));
154  _z_coords.push_back(_q_point[qp](2));
155  }
156 
157  for (unsigned int i = 0; i < _prop_names.size(); i++)
158  {
159  auto prop_name = _prop_names[i];
160  auto prop = _prop_vecs[i];
161  std::vector<Real> vals;
162  if (hasMaterialProperty<Real>(prop_name))
163  {
164  auto vals = dynamic_cast<const MaterialProperty<Real> *>(_prop_refs[i]);
165  for (unsigned int qp = 0; qp < nqp; qp++)
166  prop->push_back((*vals)[qp]);
167  }
168  else if (hasMaterialProperty<unsigned int>(prop_name))
169  {
170  auto vals = dynamic_cast<const MaterialProperty<unsigned int> *>(_prop_refs[i]);
171  for (unsigned int qp = 0; qp < nqp; qp++)
172  prop->push_back((*vals)[qp]);
173  }
174  else if (hasMaterialProperty<int>(prop_name))
175  {
176  auto vals = dynamic_cast<const MaterialProperty<int> *>(_prop_refs[i]);
177  for (unsigned int qp = 0; qp < nqp; qp++)
178  prop->push_back((*vals)[qp]);
179  }
180  }
181 }
182 
183 void
185 {
186  // collect all processor data
187  comm().gather(0, _elem_ids);
188  comm().gather(0, _qp_ids);
189  comm().gather(0, _x_coords);
190  comm().gather(0, _y_coords);
191  comm().gather(0, _z_coords);
192  for (auto vec : _prop_vecs)
193  comm().gather(0, *vec);
194  sortVecs();
195 }
196 
197 void
199 {
200  const auto & vpp = static_cast<const ElementMaterialSampler &>(y);
201  _elem_ids.insert(_elem_ids.end(), vpp._elem_ids.begin(), vpp._elem_ids.end());
202  _qp_ids.insert(_qp_ids.end(), vpp._qp_ids.begin(), vpp._qp_ids.end());
203  _x_coords.insert(_x_coords.end(), vpp._x_coords.begin(), vpp._x_coords.end());
204  _y_coords.insert(_y_coords.end(), vpp._y_coords.begin(), vpp._y_coords.end());
205  _z_coords.insert(_z_coords.end(), vpp._z_coords.begin(), vpp._z_coords.end());
206 
207  for (unsigned int i = 0; i < _prop_vecs.size(); i++)
208  {
209  auto & vec = *_prop_vecs[i];
210  auto & othervec = *vpp._prop_vecs[i];
211  vec.insert(vec.end(), othervec.begin(), othervec.end());
212  }
213  sortVecs();
214 }
215 
216 void
218 {
219  std::vector<size_t> ind;
220  ind.resize(_elem_ids.size());
221  std::iota(ind.begin(), ind.end(), 0);
222  std::sort(ind.begin(),
223  ind.end(),
224  [&](size_t a, size_t b) -> bool
225  {
226  if (_elem_ids[a] == _elem_ids[b])
227  {
228  return _qp_ids[a] < _qp_ids[b];
229  }
230  return _elem_ids[a] < _elem_ids[b];
231  });
232 
238  for (auto vec : _prop_vecs)
239  Moose::applyIndices(*vec, ind);
240 }
std::optional< std::set< dof_id_type > > _elem_filter
Element ids to record material properties for.
VectorPostprocessorValue & _qp_ids
Column of quadrature point indices.
virtual void finalize() override
Finalize.
VectorPostprocessorValue & _x_coords
Columns of quadrature point coordinates.
const MooseArray< Point > & _q_point
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
std::vector< const PropertyValue * > _prop_refs
Reference to each material property - used to retrieve the actual property values at every execution ...
void sortVecs()
Sorts all data in the VectorPostProcessorValue objects so that output from this postprocessor is orde...
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
void applyIndices(T &container, const std::vector< size_t > &indices)
Uses indices created by the indirectSort function to sort the given container (which must support ran...
Definition: IndirectSort.h:108
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
void mooseWarning(Args &&... args) const
Emits a warning prefixed with object name and type.
bool containsCompleteHistory() const
Return whether or not this VectorPostprocessor contains complete history.
VectorPostprocessorValue & _y_coords
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3443
ElementMaterialSampler(const InputParameters &parameters)
This postprocessor records all scalar material properties of the specified material object on specifi...
VectorPostprocessorValue & declareVector(const std::string &vector_name)
Register a new vector to fill up.
virtual void execute() override
Execute method.
registerMooseObject("MooseApp", ElementMaterialSampler)
registerMooseObjectRenamed("MooseApp", MaterialVectorPostprocessor, "06/30/2025 24:00", ElementMaterialSampler)
MaterialBase & getMaterialByName(const std::string &name, bool no_warn=false)
const QBase *const & _qrule
std::vector< std::string > _prop_names
Names for every property in the material - used for determining if properties are scalar or not...
const Elem *const & _current_elem
The current element pointer (available during execute())
void max(const T &r, T &o, Request &req) const
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
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...
static InputParameters validParams()
static InputParameters validParams()
std::vector< VectorPostprocessorValue * > _prop_vecs
Columns for each (scalar) property of the material.
virtual void threadJoin(const UserObject &y) override
Must override.
VectorPostprocessorValue & _elem_ids
Column of element id info.
Base class for user-specific data.
Definition: UserObject.h:40
VectorPostprocessorValue & _z_coords
bool isParamValid(const std::string &name) const
This method returns parameters that have been initialized in one fashion or another, i.e.