Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
MeshDivisionFunctorReductionVectorPostprocessor.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 
11 #include "MeshDivision.h"
12 #include "MooseMesh.h"
13 #include "MooseMeshUtils.h"
14 #include "FEProblemBase.h"
15 
16 #include "libmesh/mesh_base.h"
17 
19 
22 {
24  MooseEnum reduction("integral average min max");
25  params.addRequiredParam<MooseEnum>("reduction", reduction, "Reduction operation to apply");
26  params.addRequiredParam<std::vector<MooseFunctorName>>("functors",
27  "Functors to apply the reduction on");
28  params.addRequiredParam<MeshDivisionName>(
29  "mesh_division",
30  "Mesh division object which dictates the elements to perform the reduction with");
31  params.addClassDescription("Perform reductions on functors based on a per-mesh-division basis");
32  return params;
33 }
34 
36  const InputParameters & parameters)
39  _reduction(getParam<MooseEnum>("reduction")),
40  _nfunctors(getParam<std::vector<MooseFunctorName>>("functors").size()),
41  _mesh_division(_fe_problem.getMeshDivision(getParam<MeshDivisionName>("mesh_division"), _tid))
42 {
43  // Gather the functors
44  const auto & functor_names = getParam<std::vector<MooseFunctorName>>("functors");
45  for (const auto & functor_name : functor_names)
46  _functors.push_back(&getFunctor<Real>(functor_name));
47 
48  // Set up reduction vectors
49  const auto ndiv = _mesh_division.getNumDivisions();
50  _volumes.resize(ndiv);
51  for (const auto & functor_name : functor_names)
52  {
53  auto & p = declareVector(functor_name);
54  p.resize(ndiv);
55  _functor_reductions.push_back(&p);
56  }
57 }
58 
59 void
61 {
62  for (auto & reduction : _functor_reductions)
63  {
64  if (_reduction == ReductionEnum::INTEGRAL || _reduction == ReductionEnum::AVERAGE)
65  std::fill(reduction->begin(), reduction->end(), 0);
66  else if (_reduction == ReductionEnum::MIN)
67  std::fill(reduction->begin(), reduction->end(), std::numeric_limits<Real>::max());
68  else if (_reduction == ReductionEnum::MAX)
69  std::fill(reduction->begin(), reduction->end(), std::numeric_limits<Real>::min());
70  else
71  mooseAssert(false, "Unknown reduction type");
72  }
73  std::fill(_volumes.begin(), _volumes.end(), 0);
74 }
75 
76 void
78 {
79  const auto state_arg = determineState();
80  if (hasBlocks(_current_elem->subdomain_id()))
81  {
82  const auto index = _mesh_division.divisionIndex(*_current_elem);
84  {
85  mooseWarning("Spatial value sampled outside of the mesh_division specified in element: " +
86  Moose::stringify(_current_elem->id()) + " of centroid " +
87  Moose::stringify(_current_elem->true_centroid()));
88  return;
89  }
90  for (const auto i : make_range(_nfunctors))
91  if (_functors[i]->hasBlocks(_current_elem->subdomain_id()))
92  for (const auto qp : make_range(_qrule->n_points()))
93  {
94  const Moose::ElemQpArg elem_qp = {_current_elem, qp, _qrule, _q_point[qp]};
95  const auto functor_value = (*_functors[i])(elem_qp, state_arg);
96  if (_reduction == ReductionEnum::INTEGRAL || _reduction == ReductionEnum::AVERAGE)
97  (*_functor_reductions[i])[index] += _JxW[qp] * _coord[qp] * functor_value;
98  else if (_reduction == ReductionEnum::MIN)
99  {
100  if ((*_functor_reductions[i])[index] > functor_value)
101  (*_functor_reductions[i])[index] = functor_value;
102  }
103  else if (_reduction == ReductionEnum::MAX)
104  if ((*_functor_reductions[i])[index] < functor_value)
105  (*_functor_reductions[i])[index] = functor_value;
106 
107  if (i == 0 && _reduction == ReductionEnum::AVERAGE)
108  _volumes[index] += _JxW[qp] * _coord[qp];
109  }
110  }
111 }
112 
113 void
115 {
116  for (auto & reduction : _functor_reductions)
117  if (_reduction == ReductionEnum::INTEGRAL || _reduction == ReductionEnum::AVERAGE)
118  gatherSum(*reduction);
119  else if (_reduction == ReductionEnum::MIN)
120  gatherMin(*reduction);
121  else if (_reduction == ReductionEnum::MAX)
122  gatherMax(*reduction);
123 
124  if (_reduction == ReductionEnum::AVERAGE)
125  {
127  for (const auto i_f : make_range(_nfunctors))
128  for (const auto i : index_range(*_functor_reductions[i_f]))
130  (*_functor_reductions[i_f])[i] /= _volumes[i];
131  else
132  (*_functor_reductions[i_f])[i] = 0;
133  }
134 }
135 
136 void
138 {
139  const auto & sibling = static_cast<const MeshDivisionFunctorReductionVectorPostprocessor &>(s);
140 
141  for (const auto i_f : make_range(_nfunctors))
142  for (const auto i : index_range(*_functor_reductions[i_f]))
143  {
144  if (_reduction == ReductionEnum::INTEGRAL || _reduction == ReductionEnum::AVERAGE)
145  (*_functor_reductions[i_f])[i] += (*sibling._functor_reductions[i_f])[i];
146  else if (_reduction == ReductionEnum::MIN)
147  {
148  if ((*_functor_reductions[i_f])[i] > (*sibling._functor_reductions[i_f])[i])
149  (*_functor_reductions[i_f])[i] = (*sibling._functor_reductions[i_f])[i];
150  }
151  else if (_reduction == ReductionEnum::MAX)
152  if ((*_functor_reductions[i_f])[i] < (*sibling._functor_reductions[i_f])[i])
153  (*_functor_reductions[i_f])[i] = (*sibling._functor_reductions[i_f])[i];
154 
155  // Average-reduction requires the reduction of the volume
156  if (i_f == 0 && _reduction == ReductionEnum::AVERAGE)
157  _volumes[i] += sibling._volumes[i];
158  }
159 }
160 
161 Real
163 {
164  if (_nfunctors > 1)
165  mooseError("The spatialValue user object interface was not conceived for objects that compute "
166  "multiple values for a given spatial point. Please specify only one functor");
167  const auto index = _mesh_division.divisionIndex(p);
169  mooseError("Spatial value sampled outside of the mesh_division specified at", p);
170  return (*_functor_reductions[0])[index];
171 }
172 
173 bool
175 {
176  return BlockRestrictable::hasBlocks(sub);
177 }
An interface for accessing Moose::Functors for systems that do not care about automatic differentiati...
virtual unsigned int divisionIndex(const Point &pt) const =0
Return the index of the division to which the point belongs.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:368
const MooseArray< Point > & _q_point
const MooseArray< Real > & _coord
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
void gatherMax(T &value)
Gather the parallel max of the variable passed in.
Definition: UserObject.h:136
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
std::vector< const Moose::Functor< Real > * > _functors
Functors that are evaluated to create the reduction.
void gatherMin(T &value)
Gather the parallel min of the variable passed in.
Definition: UserObject.h:148
registerMooseObject("MooseApp", MeshDivisionFunctorReductionVectorPostprocessor)
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...
auto max(const L &left, const R &right)
const MeshDivision & _mesh_division
Mesh division providing the division.
This MeshDivisionFunctorReductionVectorPostprocessor serves to integrate functors based on the index ...
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
void gatherSum(T &value)
Gather the parallel sum of the variable passed in.
Definition: UserObject.h:124
std::vector< Real > _volumes
Vectors holding the mesh division volumes.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
virtual bool hasBlocks(SubdomainID sub) const override
Returns whether the functor is defined on this block.
Argument for requesting functor evaluation at a quadrature point location in an element.
VectorPostprocessorValue & declareVector(const std::string &vector_name)
Register a new vector to fill up.
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
const MooseEnum _reduction
Reduction operation to be performed.
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
Definition: MeshDivision.h:28
unsigned int getNumDivisions() const
Return the number of divisions.
Definition: MeshDivision.h:56
virtual void threadJoin(const UserObject &uo) override
Must override.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const QBase *const & _qrule
const Elem *const & _current_elem
The current element pointer (available during execute())
const MooseArray< Real > & _JxW
const unsigned int _nfunctors
Number of functors to be integrated.
IntRange< T > make_range(T beg, T end)
virtual Real spatialValue(const Point &p) const override
Optional interface function for "evaluating" a UserObject at a spatial position.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
Base class for creating a user object with the SpatialUserObject and Moose::Functor APIs...
static InputParameters validParams()
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...
bool hasBlocks(const SubdomainName &name) const
Test if the supplied block name is valid for this object.
auto min(const L &left, const R &right)
std::vector< VectorPostprocessorValue * > _functor_reductions
Vectors holding functor reductions (integrals, averages, extrema..) over each mesh division...
auto index_range(const T &sizable)
Base class for user-specific data.
Definition: UserObject.h:39