https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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)
38 _reduction(getParam<MooseEnum>("reduction")),
39 _nfunctors(getParam<std::vector<MooseFunctorName>>("functors").size()),
40 _mesh_division(_fe_problem.getMeshDivision(getParam<MeshDivisionName>("mesh_division"), _tid))
41{
42 // Gather the functors
43 const auto & functor_names = getParam<std::vector<MooseFunctorName>>("functors");
44 for (const auto & functor_name : functor_names)
45 _functors.push_back(&getFunctor<Real>(functor_name));
46
47 // Set up reduction vectors
48 const auto ndiv = _mesh_division.getNumDivisions();
49 _volumes.resize(ndiv);
50 for (const auto & functor_name : functor_names)
51 {
52 auto & p = declareVector(functor_name);
53 p.resize(ndiv);
54 _functor_reductions.push_back(&p);
55 }
56}
57
58void
60{
61 for (auto & reduction : _functor_reductions)
62 {
64 std::fill(reduction->begin(), reduction->end(), 0);
66 std::fill(reduction->begin(), reduction->end(), std::numeric_limits<Real>::max());
68 std::fill(reduction->begin(), reduction->end(), std::numeric_limits<Real>::min());
69 else
70 mooseAssert(false, "Unknown reduction type");
71 }
72 std::fill(_volumes.begin(), _volumes.end(), 0);
73}
74
75void
77{
78 const auto state_arg = determineState();
79 if (hasBlocks(_current_elem->subdomain_id()))
80 {
81 const auto index = _mesh_division.divisionIndex(*_current_elem);
83 {
84 mooseWarning("Spatial value sampled outside of the mesh_division specified in element: " +
85 Moose::stringify(_current_elem->id()) + " of centroid " +
86 Moose::stringify(_current_elem->true_centroid()));
87 return;
88 }
89 for (const auto i : make_range(_nfunctors))
90 if (_functors[i]->hasBlocks(_current_elem->subdomain_id()))
91 for (const auto qp : make_range(_qrule->n_points()))
92 {
93 const Moose::ElemQpArg elem_qp = {_current_elem, qp, _qrule, _q_point[qp]};
94 const auto functor_value = (*_functors[i])(elem_qp, state_arg);
96 (*_functor_reductions[i])[index] += _JxW[qp] * _coord[qp] * functor_value;
98 {
99 if ((*_functor_reductions[i])[index] > functor_value)
100 (*_functor_reductions[i])[index] = functor_value;
101 }
102 else if (_reduction == ReductionEnum::MAX)
103 if ((*_functor_reductions[i])[index] < functor_value)
104 (*_functor_reductions[i])[index] = functor_value;
105
106 if (i == 0 && _reduction == ReductionEnum::AVERAGE)
107 _volumes[index] += _JxW[qp] * _coord[qp];
108 }
109 }
110}
111
112void
114{
115 for (auto & reduction : _functor_reductions)
117 gatherSum(*reduction);
118 else if (_reduction == ReductionEnum::MIN)
119 gatherMin(*reduction);
120 else if (_reduction == ReductionEnum::MAX)
121 gatherMax(*reduction);
122
124 {
126 for (const auto i_f : make_range(_nfunctors))
127 for (const auto i : index_range(*_functor_reductions[i_f]))
128 if (!MooseUtils::absoluteFuzzyEqual(_volumes[i], 0))
129 (*_functor_reductions[i_f])[i] /= _volumes[i];
130 else
131 (*_functor_reductions[i_f])[i] = 0;
132 }
133}
134
135void
137{
138 const auto & sibling = static_cast<const MeshDivisionFunctorReductionVectorPostprocessor &>(s);
139
140 for (const auto i_f : make_range(_nfunctors))
141 for (const auto i : index_range(*_functor_reductions[i_f]))
142 {
144 (*_functor_reductions[i_f])[i] += (*sibling._functor_reductions[i_f])[i];
145 else if (_reduction == ReductionEnum::MIN)
146 {
147 if ((*_functor_reductions[i_f])[i] > (*sibling._functor_reductions[i_f])[i])
148 (*_functor_reductions[i_f])[i] = (*sibling._functor_reductions[i_f])[i];
149 }
150 else if (_reduction == ReductionEnum::MAX)
151 if ((*_functor_reductions[i_f])[i] < (*sibling._functor_reductions[i_f])[i])
152 (*_functor_reductions[i_f])[i] = (*sibling._functor_reductions[i_f])[i];
153
154 // Average-reduction requires the reduction of the volume
155 if (i_f == 0 && _reduction == ReductionEnum::AVERAGE)
156 _volumes[i] += sibling._volumes[i];
157 }
158}
159
160Real
162{
163 if (_nfunctors > 1)
164 mooseError("The spatialValue user object interface was not conceived for objects that compute "
165 "multiple values for a given spatial point. Please specify only one functor");
166 const auto index = _mesh_division.divisionIndex(p);
168 mooseError("Spatial value sampled outside of the mesh_division specified at", p);
169 return (*_functor_reductions[0])[index];
170}
171
172bool
registerMooseObject("MooseApp", MeshDivisionFunctorReductionVectorPostprocessor)
void mooseWarning(Args &&... args)
Emit a warning message with the given stringified, concatenated args.
Definition MooseError.h:345
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
bool hasBlocks(const SubdomainName &name) const
Test if the supplied block name is valid for this object.
const QBase *const & _qrule
const Elem *const & _current_elem
The current element pointer (available during execute())
const MooseArray< Real > & _coord
const MooseArray< Real > & _JxW
const MooseArray< Point > & _q_point
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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...
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.
This MeshDivisionFunctorReductionVectorPostprocessor serves to integrate functors based on the index ...
const MeshDivision & _mesh_division
Mesh division providing the division.
std::vector< VectorPostprocessorValue * > _functor_reductions
Vectors holding functor reductions (integrals, averages, extrema..) over each mesh division.
std::vector< const Moose::Functor< Real > * > _functors
Functors that are evaluated to create the reduction.
const unsigned int _nfunctors
Number of functors to be integrated.
virtual void threadJoin(const UserObject &uo) override
Must override.
virtual Real spatialValue(const Point &p) const override
Optional interface function for "evaluating" a UserObject at a spatial position.
virtual void initialize() override
Called before execute() is ever called so that data can be cleared.
std::vector< Real > _volumes
Vectors holding the mesh division volumes.
virtual bool hasBlocks(SubdomainID sub) const override
Returns whether the functor is defined on this block.
unsigned int getNumDivisions() const
Return the number of divisions.
virtual unsigned int divisionIndex(const Point &pt) const =0
Return the index of the division to which the point belongs.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
Base class for creating a user object with the SpatialUserObject and Moose::Functor APIs.
static InputParameters validParams()
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
void gatherSum(T &value)
Gather the parallel sum of the variable passed in.
void gatherMin(T &value)
Gather the parallel min of the variable passed in.
void gatherMax(T &value)
Gather the parallel max of the variable passed in.
Base class for user-specific data.
Definition UserObject.h:20
VectorPostprocessorValue & declareVector(const std::string &vector_name)
Register a new vector to fill up.
unsigned int INVALID_DIVISION_INDEX
Invalid subdomain id to return when outside the mesh division.
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64
Argument for requesting functor evaluation at a quadrature point location in an element.