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.");
29 "Special symbols, like point coordinates, time, and timestep size.");
30 params.
addParam<std::vector<MaterialName>>(
32 std::vector<MaterialName>(),
33 "List of upstream material properties that must be evaluated when compute=false");
40 const VariableNameMappingMode map_mode,
41 const std::optional<std::string> & function_param_name )
44 _symbol_names(_nargs),
45 _extra_symbols(this->template getParam<
MultiMooseEnum>(
"extra_symbols")
46 .template getSetValueIDs<ExtraSymbols>()),
49 _function_param_name(function_param_name),
50 _upstream_mat_names(this->template getParam<
std::vector<MaterialName>>(
"upstream_materials")),
51 _error_on_missing_material_properties(
52 this->template getParam<bool>(
"error_on_missing_material_properties")),
57 "Does not have parameter");
64 for (
const auto symbol : _extra_symbols)
68 reserved_names.insert(
"x");
71 reserved_names.insert(
"y");
74 reserved_names.insert(
"z");
77 reserved_names.insert(
"t");
79 case ExtraSymbols::dt:
80 reserved_names.insert(
"dt");
89 const std::vector<std::string> empty_string_vector;
90 functionParse(function_expression, empty_string_vector, empty_string_vector);
96 const std::vector<std::string> & constant_names,
97 const std::vector<std::string> & constant_expressions)
99 const std::vector<std::string> empty_string_vector;
100 const std::vector<Real> empty_real_vector;
101 functionParse(function_expression,
103 constant_expressions,
109 template <
bool is_ad>
112 const std::vector<std::string> & constant_names,
113 const std::vector<std::string> & constant_expressions,
114 const std::vector<std::string> & mat_prop_expressions,
115 const std::vector<std::string> & tol_names,
116 const std::vector<Real> & tol_values)
118 const std::vector<PostprocessorName> empty_pp_name_vector;
119 functionParse(function_expression,
121 constant_expressions,
122 mat_prop_expressions,
123 empty_pp_name_vector,
128 template <
bool is_ad>
131 const std::string & function_expression,
132 const std::vector<std::string> & constant_names,
133 const std::vector<std::string> & constant_expressions,
134 const std::vector<std::string> & mat_prop_expressions,
135 const std::vector<PostprocessorName> & postprocessor_names,
136 const std::vector<std::string> & tol_names,
137 const std::vector<Real> & tol_values)
139 const std::vector<MooseFunctorName> empty_functor_vector;
140 const std::vector<std::string> empty_string_vector;
141 functionParse(function_expression,
143 constant_expressions,
144 mat_prop_expressions,
148 empty_functor_vector,
149 empty_string_vector);
152 template <
bool is_ad>
155 const std::string & function_expression,
156 const std::vector<std::string> & constant_names,
157 const std::vector<std::string> & constant_expressions,
158 const std::vector<std::string> & mat_prop_expressions,
159 const std::vector<PostprocessorName> & postprocessor_names,
160 const std::vector<std::string> & tol_names,
161 const std::vector<Real> & tol_values,
162 const std::vector<MooseFunctorName> & functor_names,
163 const std::vector<std::string> & functor_symbols)
166 _func_F = std::make_shared<SymFunction>();
169 setParserFeatureFlags(_func_F);
172 addFParserConstants(_func_F, constant_names, constant_expressions);
175 if (_map_mode == VariableNameMappingMode::USE_PARAM_NAMES)
176 for (
const auto & acd : _arg_constant_defaults)
177 if (!_func_F->AddConstant(acd, this->_pars.defaultCoupledValue(acd)))
178 _params.mooseError(
"Invalid constant name in parsed function object");
183 case VariableNameMappingMode::USE_MOOSE_NAMES:
184 for (
unsigned int i = 0; i < _nargs; ++i)
185 _symbol_names[i] = _arg_names[i];
188 case VariableNameMappingMode::USE_PARAM_NAMES:
189 for (
unsigned i = 0; i < _nargs; ++i)
191 if (_arg_param_numbers[i] < 0)
192 _symbol_names[i] = _arg_param_names[i];
194 _symbol_names[i] = _arg_param_names[i] + std::to_string(_arg_param_numbers[i]);
199 _params.mooseError(
"Unknown variable mapping mode.");
203 if (tol_names.size() != tol_values.size())
204 _params.mooseError(
"The parameter vectors tol_names and tol_values must have equal length.");
214 if (_symbol_names[i] == tol_names[j])
216 _tol[i] = tol_values[j];
222 unsigned int nmat_props = mat_prop_expressions.size();
226 _mat_prop_descriptors.emplace_back(
227 mat_prop_expressions[i],
this, _error_on_missing_material_properties);
230 _symbol_names.push_back(_mat_prop_descriptors.back().getSymbolName());
234 for (
const auto & pp : postprocessor_names)
236 _postprocessor_values.push_back(&this->getPostprocessorValueByName(pp));
237 _symbol_names.push_back(pp);
241 for (
const auto symbol : _extra_symbols)
244 case ExtraSymbols::x:
245 _symbol_names.push_back(
"x");
247 case ExtraSymbols::y:
248 _symbol_names.push_back(
"y");
250 case ExtraSymbols::z:
251 _symbol_names.push_back(
"z");
253 case ExtraSymbols::t:
254 _symbol_names.push_back(
"t");
256 case ExtraSymbols::dt:
257 _symbol_names.push_back(
"dt");
262 if (!functor_symbols.empty() && functor_symbols.size() != functor_names.size())
264 "The parameter vector functor_symbols must be of same length as functor_names, if " 266 _functors.resize(functor_names.size());
269 if (functor_symbols.empty())
271 auto functor_name = functor_names[i];
272 _symbol_names.push_back(functor_name);
273 _functors[i] = &FunctorInterface::getFunctor<Real>(functor_name);
277 auto functor_name = functor_names[i];
278 auto symbol_name = functor_symbols[i];
279 _symbol_names.push_back(symbol_name);
280 _functors[i] = &FunctorInterface::getFunctor<Real>(functor_name);
288 if (_func_F->Parse(function_expression, variables) >= 0)
289 parseError(
"Invalid parsed material function \"" + function_expression +
290 "\" with variables \"" + variables +
"\"; " + _func_F->ErrorMsg());
293 _func_params.resize(_nargs + nmat_props + _postprocessor_values.size() + _extra_symbols.size() +
294 functor_names.size());
299 if (_communicator.rank() != 0)
300 _communicator.barrier();
302 functionsPostParse();
305 if (_communicator.rank() == 0)
306 _communicator.barrier();
309 template <
bool is_ad>
313 functionsOptimize(_func_F);
316 for (
auto & mpd : _mat_prop_descriptors)
320 template <
bool is_ad>
324 _upstream_mat.resize(_upstream_mat_names.size());
325 for (
const auto i :
make_range(_upstream_mat_names.size()))
326 _upstream_mat[i] = &this->getMaterialByName(_upstream_mat_names[i]);
329 template <
bool is_ad>
333 computeQpProperties();
336 template <
bool is_ad>
340 if (!(this->_compute))
342 for (
const auto i :
make_range(_upstream_mat_names.size()))
343 _upstream_mat[i]->computePropertiesAtQp(_qp);
350 _func_params[i] = (*_args[i])[_qp];
353 auto a = (*_args[i])[_qp];
354 _func_params[i] = a < _tol[i] ? _tol[i] : (a > 1.0 - _tol[i] ? 1.0 - _tol[i] : a);
357 auto offset = _nargs;
360 for (
const auto i :
index_range(_mat_prop_descriptors))
361 _func_params[i + offset] = _mat_prop_descriptors[i].
value(_qp);
362 offset += _mat_prop_descriptors.size();
365 auto npps = _postprocessor_values.size();
366 for (MooseIndex(_postprocessor_values) i = 0; i < npps; ++i)
367 _func_params[i + offset] = *_postprocessor_values[i];
368 offset += _postprocessor_values.size();
373 const auto j = offset + i;
374 switch (_extra_symbols[i])
376 case ExtraSymbols::x:
377 _func_params[j] = _q_point[_qp](0);
379 case ExtraSymbols::y:
380 _func_params[j] = _q_point[_qp](1);
382 case ExtraSymbols::z:
383 _func_params[j] = _q_point[_qp](2);
385 case ExtraSymbols::t:
386 _func_params[j] = _t;
388 case ExtraSymbols::dt:
389 _func_params[j] = _dt;
393 offset += _extra_symbols.size();
397 const Moose::ElemQpArg qp_arg = {_current_elem, _qp, _qrule, _q_point[_qp]};
399 _func_params[offset + i] = (*_functors[i])(qp_arg, state);
403 (*_prop_F)[_qp] =
evaluate(_func_F, _name);
406 template <
bool is_ad>
410 if (_function_param_name)
411 _params.paramError(*_function_param_name, message);
413 _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.