12 #include "libmesh/quadrature.h" 22 params.
addParam<
bool>(
"error_on_missing_material_properties",
24 "Throw an error if any explicitly requested material property does not " 25 "exist. Otherwise assume it to be zero.");
30 "Special symbols, like point coordinates, time, and timestep size.");
31 params.
addParam<std::vector<MaterialName>>(
33 std::vector<MaterialName>(),
34 "List of upstream material properties that must be evaluated when compute=false");
42 const std::optional<std::string> & function_param_name )
45 _symbol_names(_nargs),
46 _extra_symbols(this->template getParam<
MultiMooseEnum>(
"extra_symbols")
50 _function_param_name(function_param_name),
51 _upstream_mat_names(this->template getParam<
std::vector<MaterialName>>(
"upstream_materials")),
52 _error_on_missing_material_properties(
53 this->template getParam<bool>(
"error_on_missing_material_properties")),
58 "Does not have parameter");
65 for (
const auto symbol : _extra_symbols)
69 reserved_names.insert(
"x");
72 reserved_names.insert(
"y");
75 reserved_names.insert(
"z");
78 reserved_names.insert(
"t");
80 case ExtraSymbols::dt:
81 reserved_names.insert(
"dt");
90 const std::vector<std::string> empty_string_vector;
91 functionParse(function_expression, empty_string_vector, empty_string_vector);
97 const std::vector<std::string> & constant_names,
98 const std::vector<std::string> & constant_expressions)
100 const std::vector<std::string> empty_string_vector;
101 const std::vector<Real> empty_real_vector;
102 functionParse(function_expression,
104 constant_expressions,
110 template <
bool is_ad>
113 const std::vector<std::string> & constant_names,
114 const std::vector<std::string> & constant_expressions,
115 const std::vector<std::string> & mat_prop_expressions,
116 const std::vector<std::string> & tol_names,
117 const std::vector<Real> & tol_values)
119 const std::vector<PostprocessorName> empty_pp_name_vector;
120 functionParse(function_expression,
122 constant_expressions,
123 mat_prop_expressions,
124 empty_pp_name_vector,
129 template <
bool is_ad>
132 const std::string & function_expression,
133 const std::vector<std::string> & constant_names,
134 const std::vector<std::string> & constant_expressions,
135 const std::vector<std::string> & mat_prop_expressions,
136 const std::vector<PostprocessorName> & postprocessor_names,
137 const std::vector<std::string> & tol_names,
138 const std::vector<Real> & tol_values)
140 const std::vector<MooseFunctorName> empty_functor_vector;
141 const std::vector<std::string> empty_string_vector;
142 functionParse(function_expression,
144 constant_expressions,
145 mat_prop_expressions,
149 empty_functor_vector,
150 empty_string_vector);
153 template <
bool is_ad>
156 const std::string & function_expression,
157 const std::vector<std::string> & constant_names,
158 const std::vector<std::string> & constant_expressions,
159 const std::vector<std::string> & mat_prop_expressions,
160 const std::vector<PostprocessorName> & postprocessor_names,
161 const std::vector<std::string> & tol_names,
162 const std::vector<Real> & tol_values,
163 const std::vector<MooseFunctorName> & functor_names,
164 const std::vector<std::string> & functor_symbols)
167 _func_F = std::make_shared<SymFunction>();
170 setParserFeatureFlags(_func_F);
173 addFParserConstants(_func_F, constant_names, constant_expressions);
176 if (_map_mode == VariableNameMappingMode::USE_PARAM_NAMES)
177 for (
const auto & acd : _arg_constant_defaults)
178 if (!_func_F->AddConstant(acd, this->_pars.defaultCoupledValue(acd)))
179 _params.mooseError(
"Invalid constant name in parsed function object");
184 case VariableNameMappingMode::USE_MOOSE_NAMES:
185 for (
unsigned int i = 0; i < _nargs; ++i)
186 _symbol_names[i] = _arg_names[i];
189 case VariableNameMappingMode::USE_PARAM_NAMES:
190 for (
unsigned i = 0; i < _nargs; ++i)
192 if (_arg_param_numbers[i] < 0)
193 _symbol_names[i] = _arg_param_names[i];
195 _symbol_names[i] = _arg_param_names[i] + std::to_string(_arg_param_numbers[i]);
200 _params.mooseError(
"Unknown variable mapping mode.");
204 if (tol_names.size() != tol_values.size())
205 _params.mooseError(
"The parameter vectors tol_names and tol_values must have equal length.");
215 if (_symbol_names[i] == tol_names[j])
217 _tol[i] = tol_values[j];
223 unsigned int nmat_props = mat_prop_expressions.size();
227 _mat_prop_descriptors.emplace_back(
228 mat_prop_expressions[i],
this, _error_on_missing_material_properties);
231 _symbol_names.push_back(_mat_prop_descriptors.back().getSymbolName());
235 for (
const auto & pp : postprocessor_names)
237 _postprocessor_values.push_back(&this->getPostprocessorValueByName(pp));
238 _symbol_names.push_back(pp);
242 for (
const auto symbol : _extra_symbols)
245 case ExtraSymbols::x:
246 _symbol_names.push_back(
"x");
248 case ExtraSymbols::y:
249 _symbol_names.push_back(
"y");
251 case ExtraSymbols::z:
252 _symbol_names.push_back(
"z");
254 case ExtraSymbols::t:
255 _symbol_names.push_back(
"t");
257 case ExtraSymbols::dt:
258 _symbol_names.push_back(
"dt");
263 if (!functor_symbols.empty() && functor_symbols.size() != functor_names.size())
265 "The parameter vector functor_symbols must be of same length as functor_names, if " 267 _functors.resize(functor_names.size());
270 if (functor_symbols.empty())
272 auto functor_name = functor_names[i];
273 _symbol_names.push_back(functor_name);
274 _functors[i] = &FunctorInterface::getFunctor<Real>(functor_name);
278 auto functor_name = functor_names[i];
279 auto symbol_name = functor_symbols[i];
280 _symbol_names.push_back(symbol_name);
281 _functors[i] = &FunctorInterface::getFunctor<Real>(functor_name);
289 if (_func_F->Parse(function_expression, variables) >= 0)
290 parseError(
"Invalid parsed material function \"" + function_expression +
291 "\" with variables \"" + variables +
"\"; " + _func_F->ErrorMsg());
294 _func_params.resize(_nargs + nmat_props + _postprocessor_values.size() + _extra_symbols.size() +
295 functor_names.size());
300 if (_communicator.rank() != 0)
301 _communicator.barrier();
303 functionsPostParse();
306 if (_communicator.rank() == 0)
307 _communicator.barrier();
310 template <
bool is_ad>
314 functionsOptimize(_func_F);
317 for (
auto & mpd : _mat_prop_descriptors)
321 template <
bool is_ad>
325 _upstream_mat.resize(_upstream_mat_names.size());
326 for (
const auto i :
make_range(_upstream_mat_names.size()))
327 _upstream_mat[i] = &this->getMaterialByName(_upstream_mat_names[i]);
330 template <
bool is_ad>
334 computeQpProperties();
337 template <
bool is_ad>
341 if (!(this->_compute))
343 for (
const auto i :
make_range(_upstream_mat_names.size()))
344 _upstream_mat[i]->computePropertiesAtQp(_qp);
351 _func_params[i] = (*_args[i])[_qp];
354 auto a = (*_args[i])[_qp];
355 _func_params[i] = a < _tol[i] ? _tol[i] : (a > 1.0 - _tol[i] ? 1.0 - _tol[i] : a);
358 auto offset = _nargs;
361 for (
const auto i :
index_range(_mat_prop_descriptors))
362 _func_params[i + offset] = _mat_prop_descriptors[i].
value(_qp);
363 offset += _mat_prop_descriptors.size();
366 auto npps = _postprocessor_values.size();
367 for (MooseIndex(_postprocessor_values) i = 0; i < npps; ++i)
368 _func_params[i + offset] = *_postprocessor_values[i];
369 offset += _postprocessor_values.size();
374 const auto j = offset + i;
375 switch (_extra_symbols[i])
377 case ExtraSymbols::x:
378 _func_params[j] = _q_point[_qp](0);
380 case ExtraSymbols::y:
381 _func_params[j] = _q_point[_qp](1);
383 case ExtraSymbols::z:
384 _func_params[j] = _q_point[_qp](2);
386 case ExtraSymbols::t:
387 _func_params[j] = _t;
389 case ExtraSymbols::dt:
390 _func_params[j] = _dt;
394 offset += _extra_symbols.size();
398 const Moose::ElemQpArg qp_arg = {_current_elem, _qp, _qrule, _q_point[_qp]};
400 _func_params[offset + i] = (*_functors[i])(qp_arg, state);
404 (*_prop_F)[_qp] =
evaluate(_func_F, _name);
407 template <
bool is_ad>
411 if (_function_param_name)
412 _params.paramError(*_function_param_name, message);
414 _params.mooseError(message);
void insertReservedNames(std::set< std::string > &reserved_names)
Populates the given set with names not to be used as user-defined symbol (e.g.
virtual void initialSetup() override final
Gets called at the beginning of the simulation before this object is asked to do its job...
ParsedMaterialHelper(const InputParameters ¶meters, const VariableNameMappingMode map_mode, const std::optional< std::string > &function_param_name={})
void computeQpProperties() override
Users must override this method.
Material base class, central to all Materials that provide a Function as a material property value...
Moose::StateArg determineState() const
Create a functor state argument that corresponds to the implicit state of this object.
const InputParameters & _params
The underlying parameters.
static InputParameters validParams()
static InputParameters validParams()
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void parseError(const std::string &message) const
Helper for reporting a parse error with a much as context as possible.
Argument for requesting functor evaluation at a quadrature point location in an element.
T evaluate(Real, const Point &)
The general evaluation method is not defined.
void initQpStatefulProperties() override
Initialize stateful properties at quadrature points.
std::string stringify(const T &t)
conversion to string
Helper class to perform the parsing and optimization of the function expression.
IntRange< T > make_range(T beg, T end)
static InputParameters validParams()
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
auto index_range(const T &sizable)
virtual void functionsPostParse()
void functionParse(const std::string &function_expression)
This method sets up and parses the function string given by the user.
const std::optional< std::string > _function_param_name
Optional parameter name that represents the function to associate errors with.