https://mooseframework.inl.gov
Loading...
Searching...
No Matches
ParsedDownSelectionPositions.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{
22 // Might as well offer block restriction as an additional down-selection criterion
25
26 params.addRequiredParam<std::vector<PositionsName>>(
27 "input_positions",
28 "Positions object(s) that will be down-selected by this object. The order of the "
29 "down-selected positions is kept the same");
30
31 // Parsed expression parameters
32 params.addRequiredCustomTypeParam<std::string>(
33 "expression",
34 "FunctionExpression",
35 "Parsed function expression to compute the selection criterion. Note that x,y,z and t can be "
36 "used in the expression without being declared as functors.");
37 params.addParam<std::vector<MooseFunctorName>>(
38 "functor_names", {}, "Functors to use in the parsed expression");
39 params.addParam<std::vector<std::string>>(
40 "functor_symbols",
41 {},
42 "Symbolic name to use for each functor in 'functor_names' in the parsed expression. If not "
43 "provided, then the actual functor names will be used in the parsed expression.");
44
45 // We need to preserve the order of the positions from the input_positions objects
46 params.set<bool>("auto_sort") = false;
47 // We already perform a custom synchronization, because the functors cannot be evaluated on every
48 // domain
49 params.set<bool>("auto_broadcast") = false;
50
51 // Keep as up-to-date as possible given the generality of functors
52 params.set<ExecFlagEnum>("execute_on") = {EXEC_LINEAR, EXEC_TIMESTEP_BEGIN};
53
54 params.addClassDescription("Examines input positions object(s) to find all positions matching a "
55 "user-specifed parsed expression criterion. The order of the "
56 "positions in the input is kept.");
57 return params;
58}
59
61 : Positions(parameters),
64 FunctionParserUtils(parameters),
65 _expression(getParam<std::string>("expression")),
66 _xyzt({"x", "y", "z", "t"}),
67 _functor_names(getParam<std::vector<MooseFunctorName>>("functor_names")),
68 _n_functors(_functor_names.size()),
69 _functor_symbols(getParam<std::vector<std::string>>("functor_symbols"))
70{
71 if (getParam<ExecFlagEnum>("execute_on").contains(EXEC_NONE))
72 paramError("execute_on",
73 "NONE execution flag not supported. Most functors (functions, variables, spatial "
74 "user objects for example) are not initialized at construction.");
75
76 // sanity checks
77 if (!_functor_symbols.empty() && (_functor_symbols.size() != _n_functors))
78 paramError("functor_symbols", "functor_symbols must be the same length as functor_names.");
79
80 // Make sure functors are not x, y, z, or t
81 for (const auto & name : _functor_symbols)
82 if (std::find(_xyzt.begin(), _xyzt.end(), name) != _xyzt.end())
83 paramError("functor_symbols", "x, y, z, and t cannot be used in 'functor_symbols'.");
84 for (const auto & name : _functor_names)
85 if (std::find(_xyzt.begin(), _xyzt.end(), name) != _xyzt.end())
86 paramError("functor_names",
87 "x, y, z, and t cannot be used in 'functor_names'. Use functor_symbols to "
88 "disambiguate by using a different symbol in the expression.");
89
90 // build variables argument
91 std::string variables;
92
93 // adding functors to the expression
94 if (_functor_symbols.size())
95 for (const auto & symbol : _functor_symbols)
96 variables += (variables.empty() ? "" : ",") + symbol;
97 else
98 for (const auto & name : _functor_names)
99 variables += (variables.empty() ? "" : ",") + name;
100
101 // xyz and t are likely useful here
102 for (auto & v : _xyzt)
103 variables += (variables.empty() ? "" : ",") + v;
104
105 // Create parsed function
106 _func_F = std::make_shared<SymFunction>();
107 parsedFunctionSetup(_func_F, _expression, variables, {}, {}, comm());
108
109 // reserve storage for parameter passing buffer
110 _func_params.resize(_n_functors + 4);
111
112 // keep pointers to the functors
113 for (const auto & name : _functor_names)
114 _functors.push_back(&getFunctor<Real>(name));
115}
116
117void
119{
120 if (!_initialized)
121 {
122 // Retrieve the input positions
123 const auto & base_names = getParam<std::vector<PositionsName>>("input_positions");
124 for (const auto & base_name : base_names)
125 if (_fe_problem.hasUserObject(base_name))
126 _positions_ptrs.push_back(&_fe_problem.getPositionsObject(base_name));
127
128 // Check execute-ons
129 for (const auto pos_ptr : _positions_ptrs)
130 if (!pos_ptr->getExecuteOnEnum().contains(_fe_problem.getCurrentExecuteOnFlag()))
131 mooseInfo("Positions '",
132 pos_ptr->name(),
133 "' is not executing on ",
135 ". This could mean this position is not updated when down-selecting.");
136 }
137
139 const bool initial = _fe_problem.getCurrentExecuteOnFlag() == EXEC_INITIAL;
140
141 // Pre-allocate for performance
142 unsigned int n_points = 0;
143 for (const auto pos_ptr : _positions_ptrs)
144 n_points += pos_ptr->getNumPositions(initial);
145 _positions.reserve(n_points);
146 mooseAssert(comm().verify(n_points), "Input positions should be synchronized");
147
148 // Rather than synchronize all ranks at every point, we will figure out whether to keep (2),
149 // discard (1) or error (0, due to no ranks having made the decision) for each position
150 std::vector<short> keep_positions(n_points, PositionSelection::Error);
151
152 const auto state = determineState();
153 auto pl = _fe_problem.mesh().getMesh().sub_point_locator();
154 pl->enable_out_of_mesh_mode();
155
156 // Loop over the positions, find them in the mesh to form the adequate functor arguments
157 // Note that every positions object is assumed replicated over every rank already
158 unsigned int i_pos, counter = 0;
159 for (const auto & pos_ptr : _positions_ptrs)
160 for (const auto & pos : pos_ptr->getPositions(initial))
161 {
162 counter++;
163 i_pos = counter - 1;
164 // Get all possible elements the position may be in
165 std::set<const Elem *> candidate_elements;
166 (*pl)(pos, candidate_elements);
167
168 for (const auto elem : candidate_elements)
169 {
170 // Check block restriction
171 // Dont exclude a point we already chose to keep. This 'inclusivity' means that a position
172 // at a node can be included if at least one element it borders is in the block restriction
173 if (!hasBlocks(elem->subdomain_id()) && (keep_positions[i_pos] != PositionSelection::Keep))
174 {
175 keep_positions[i_pos] = PositionSelection::Discard;
176 continue;
177 }
178
179 // We can't guarantee we have enough algebraic ghosting for variable functors. Might as well
180 // skip, another process will take care of it
181 if (elem->processor_id() != processor_id())
182 continue;
183
184 // Form a functor argument
185 const Moose::ElemPointArg elem_arg = {elem, pos, false};
186
187 // Fill arguments to the parsed expression
188 // Functors
189 for (const auto i : index_range(_functors))
190 _func_params[i] = (*_functors[i])(elem_arg, state);
191
192 // Positions and time
193 for (const auto j : make_range(Moose::dim))
194 _func_params[_n_functors + j] = pos(j);
196
197 // Evaluate parsed expression
198 const auto value = evaluate(_func_F);
199
200 // Keep points matching the criterion
201 if (value > 0)
202 keep_positions[i_pos] = PositionSelection::Keep;
203 // Dont exclude a point we already chose to keep. This 'inclusivity'
204 // means that a position at an interface between elements can get included if the functor
205 // evaluates greater than 0 for any of the elements used in forming ElemPointArgs
206 else if (keep_positions[i_pos] != PositionSelection::Keep)
207 keep_positions[i_pos] = PositionSelection::Discard;
208 }
209 }
210
211 // Synchronize which positions to keep across all ranks
212 comm().max(keep_positions);
213 i_pos = 0;
214 for (const auto & pos_ptr : _positions_ptrs)
215 for (const auto & pos : pos_ptr->getPositions(initial))
216 {
217 if (keep_positions[i_pos] == PositionSelection::Keep)
218 _positions.push_back(pos);
219 else if (keep_positions[i_pos] == PositionSelection::Error)
221 "No process has made a decision on whether position '",
222 pos,
223 "' from Positions object '" + pos_ptr->name() +
224 "' should be discarded or kept during down-selection. This usually means this "
225 "position is outside the mesh!");
226 i_pos++;
227 }
228
229 _initialized = true;
230}
void mooseInfo(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
Definition MooseError.h:401
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
const ExecFlagType EXEC_TIMESTEP_BEGIN
Definition Moose.C:37
const ExecFlagType EXEC_INITIAL
Definition Moose.C:30
const ExecFlagType EXEC_LINEAR
Definition Moose.C:31
const ExecFlagType EXEC_NONE
Definition Moose.C:29
registerMooseObject("MooseApp", ParsedDownSelectionPositions)
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
An interface that restricts an object to subdomains via the 'blocks' input parameter.
bool hasBlocks(const SubdomainName &name) const
Test if the supplied block name is valid for this object.
static InputParameters validParams()
A MultiMooseEnum object to hold "execute_on" flags.
const Positions & getPositionsObject(const std::string &name) const
Get the Positions object by its name.
bool hasUserObject(const std::string &name) const
Check if there if a user object of given name.
const ExecFlagType & getCurrentExecuteOnFlag() const
Return/set the current execution flag.
virtual MooseMesh & mesh() override
std::vector< GenericReal< is_ad > > _func_params
Array to stage the parameters passed to the functions when calling Eval.
GenericReal< is_ad > evaluate(SymFunctionPtr &, const std::string &object_name="")
Evaluate FParser object and check EvalError.
static InputParameters validParams()
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
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.
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 addRequiredCustomTypeParam(const std::string &name, const std::string &custom_type, const std::string &doc_string)
These methods add an option parameter and with a customer type to the InputParameters object.
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.
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
An interface for accessing Moose::Functors for systems that do not care about automatic differentiati...
static InputParameters validParams()
Positions of the centroids of all elements meeting the parsed expression criterion.
ParsedDownSelectionPositions(const InputParameters &parameters)
const unsigned int _n_functors
Number of functors.
SymFunctionPtr _func_F
function parser object for the local value of the expression
std::vector< const Moose::Functor< Real > * > _functors
Vector of pointers to functors.
std::vector< const Positions * > _positions_ptrs
Vector of pointers to positions objects.
void initialize() override
In charge of computing / loading the positions.
Positions objects are under the hood Reporters.
Definition Positions.h:21
void clearPositions()
Clear all positions vectors.
Definition Positions.C:154
std::vector< Point > & _positions
For now, only the 1D vector will be shared across all ranks.
Definition Positions.h:92
static InputParameters validParams()
Definition Positions.C:15
bool _initialized
Whether the positions object has been initialized. This must be set by derived objects.
Definition Positions.h:116
void max(const T &r, T &o, Request &req) const
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
FEProblemBase & _fe_problem
Reference to the FEProblemBase for this user object.
processor_id_type processor_id() const
const Parallel::Communicator & comm() const
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition Moose.h:165
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64
std::string name(const ElemQuality q)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
A structure that is used to evaluate Moose functors at an arbitrary physical point contained within a...