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