https://mooseframework.inl.gov
FunctorExtremaPositions.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 "libmesh/parallel.h"
12 #include "libmesh/parallel_algebra.h"
13 #include "libmesh/vector_value.h"
14 
16 
19 {
23 
24  params.addRequiredParam<MooseFunctorName>(
25  "functor", "Functor of which the extremas are going to form the list of positions");
26  params.addParam<MooseEnum>("extrema_type",
27  MooseEnum("max=0 min=1 max_abs=2", "max"),
28  "Type of extreme value to return. 'max' "
29  "returns the location(s) of the maximum value(s). 'min' returns "
30  "the location(s) of the minimum value(s). 'max_abs' returns the "
31  "locations of the maximum(a) of the absolute value.");
32  params.addParam<unsigned int>("num_extrema", 1, "Number of extrema to look for");
33 
34  // Future arguments we could conceive:
35  // - min_dist to force a certain distance between extrema
36  // - functor argument type. We use elements, we could do nodes, qps, sides, ...
37 
38  // Use user-provided ordering
39  params.set<bool>("auto_sort") = false;
40  params.suppressParameter<bool>("auto_sort");
41  // The broadcasting has to be custom to preserve the order of the extremas
42  params.set<bool>("auto_broadcast") = false;
43  params.suppressParameter<bool>("auto_broadcast");
44 
45  // Keep as up-to-date as possible given the generality of functors
46  params.set<ExecFlagEnum>("execute_on") = {EXEC_LINEAR, EXEC_TIMESTEP_BEGIN};
47 
48  params.addClassDescription("Searches the geometry for the extrema of the functors");
49  return params;
50 }
51 
53  : Positions(parameters),
55  BlockRestrictable(this),
56  _functor(getFunctor<Real>("functor")),
57  _n_extrema(getParam<unsigned int>("num_extrema")),
58  _type(getParam<MooseEnum>("extrema_type").getEnum<ExtremeType>()),
59  _positions_values(declareValueByName<std::vector<Real>, ReporterVectorContext<Real>>(
60  "functor_extrema", REPORTER_MODE_REPLICATED))
61 {
62  // Constants and postprocessors are not interesting here
63  const auto & functor_name = getParam<MooseFunctorName>("functor");
64  if (_fe_problem.hasPostprocessorValueByName(functor_name) ||
65  MooseUtils::parsesToReal(functor_name))
66  paramError(
67  "functor",
68  "Postprocessors and constants do not have extrema, they are constant over the domain.");
69 
70  if (getParam<ExecFlagEnum>("execute_on").contains(EXEC_NONE))
71  paramError("execute_on",
72  "NONE execution flag not supported. Most functors (functions, variables, spatial "
73  "user objects for example) are not initialized at construction.");
74 }
75 
76 void
78 {
80  _positions.resize(_n_extrema);
82 
83  std::list<Real> extrema;
84  std::list<Point> extrema_locs;
86  extrema.resize(_n_extrema, -std::numeric_limits<Real>::max());
87  else
88  extrema.resize(_n_extrema, std::numeric_limits<Real>::max());
89  extrema_locs.resize(_n_extrema);
90 
91  const auto time_arg = determineState();
92 
93  // Loop over the local mesh, keep track of all extrema
94  for (const auto & elem :
95  _fe_problem.mesh().getMesh().active_local_subdomain_set_element_ptr_range(blockIDs()))
96  {
97  const Moose::ElemArg elem_arg = {elem, false};
98  auto value = _functor(elem_arg, time_arg);
99 
100  auto extremum = extrema.begin();
101  auto extremum_loc = extrema_locs.begin();
102 
103  for (const auto i : make_range(_n_extrema))
104  {
105  libmesh_ignore(i);
106  bool extrema_found = false;
107  switch (_type)
108  {
110  value = std::abs(value);
111  // fallthrough
112  case ExtremeType::MAX:
113  {
114  if (value > *extremum)
115  extrema_found = true;
116  break;
117  }
118  case ExtremeType::MIN:
119  {
120  if (value < *extremum)
121  extrema_found = true;
122  break;
123  }
124  }
125  if (extrema_found)
126  {
127  // Move the extrema down the list of extrema
128  extrema.insert(extremum, value);
129  extrema_locs.insert(extremum_loc, elem->true_centroid());
130  extrema.pop_back();
131  extrema_locs.pop_back();
132  // Found an extremum, filled the extrema vector, done
133  break;
134  }
135  // Consider the next extremum
136  std::advance(extremum, 1);
137  std::advance(extremum_loc, 1);
138  }
139  }
140 
141  // Synchronize across all ranks
142  auto current_candidate = extrema.begin();
143  auto current_candidate_loc = extrema_locs.begin();
144  for (const auto i : make_range(_n_extrema))
145  {
146  unsigned int rank;
147  // dont modify the extremum, it might be the global n-th extremum in a later call
148  auto copy = *current_candidate;
150  comm().maxloc(copy, rank);
151  else
152  comm().minloc(copy, rank);
153 
154  RealVectorValue extreme_point(0., 0., 0.);
155  if (rank == processor_id())
156  {
157  extreme_point = *current_candidate_loc;
158  // Our candidate for ith max got accepted, move on to offering the next extremal one
159  std::advance(current_candidate, 1);
160  std::advance(current_candidate_loc, 1);
161  }
162 
163  // Send the position
164  // The broadcast and scatter are for root 0 sending to all. The sum works just as well
165  comm().sum(extreme_point);
166  _positions[i] = extreme_point;
167  _positions_values[i] = copy;
168  }
169  mooseAssert(comm().verify(_positions_values),
170  "Positions extrema should be the same across all MPI processes.");
171  _initialized = true;
172 }
An interface for accessing Moose::Functors for systems that do not care about automatic differentiati...
bool parsesToReal(const std::string &input)
Check if the input string can be parsed into a Real.
Definition: MooseUtils.C:89
MetaPhysicL::DualNumber< V, D, asd > abs(const MetaPhysicL::DualNumber< V, D, asd > &a)
Definition: EigenADReal.h:42
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
static InputParameters validParams()
Definition: Positions.C:15
std::vector< Real > & _positions_values
Values of the functor at the extrema.
This context is specific for vector types of reporters, mainly for declaring a vector of the type fro...
void minloc(T &r, unsigned int &min_id) const
void clearPositions()
Clear all positions vectors.
Definition: Positions.C:154
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
const ExecFlagType EXEC_NONE
Definition: Moose.C:27
Positions objects are under the hood Reporters.
Definition: Positions.h:20
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
void initialize() override
In charge of computing / loading the positions.
ExtremeType
Type of extreme value we are going to compute.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
virtual const std::set< SubdomainID > & blockIDs() const
Return the block subdomain ids for this object Note, if this is not block restricted, this function returns all mesh subdomain ids.
const Moose::Functor< Real > & _functor
Functor providing the value.
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)
bool _initialized
Whether the positions object has been initialized. This must be set by derived objects.
Definition: Positions.h:116
static InputParameters validParams()
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn&#39;t required or valid in the derived class...
void libmesh_ignore(const Args &...)
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3443
const ExecFlagType EXEC_TIMESTEP_BEGIN
Definition: Moose.C:35
const unsigned int _n_extrema
Number of extrema to keep track of.
std::vector< Point > & _positions
For now, only the 1D vector will be shared across all ranks.
Definition: Positions.h:92
bool hasPostprocessorValueByName(const PostprocessorName &name) const
Whether or not a Postprocessor value exists by a given name.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
A structure that is used to evaluate Moose functors logically at an element/cell center.
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
void maxloc(T &r, unsigned int &max_id) const
FunctorExtremaPositions(const InputParameters &parameters)
const ExecFlagType EXEC_LINEAR
Definition: Moose.C:29
static InputParameters validParams()
registerMooseObject("MooseApp", FunctorExtremaPositions)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
Definition: UserObject.h:211
An interface that restricts an object to subdomains via the &#39;blocks&#39; input parameter.
IntRange< T > make_range(T beg, T end)
virtual MooseMesh & mesh() override
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...
static InputParameters validParams()
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...
const ReporterMode REPORTER_MODE_REPLICATED
Positions from the extrema of a functor.
processor_id_type processor_id() const
enum FunctorExtremaPositions::ExtremeType _type
void ErrorVector unsigned int