15 #include "libmesh/quadrature.h" 23 params.
addParam<
unsigned int>(
"derivative_order", 3,
"Maximum order of derivatives taken");
24 params.
addParam<std::vector<SymbolName>>(
25 "additional_derivative_symbols",
27 "A list of additional (non-variable) symbols (such as material property or postprocessor " 28 "names) to take derivatives w.r.t.");
36 const std::optional<std::string> & function_param_name )
38 _derivative_order(this->template getParam<unsigned
int>(
"derivative_order")),
39 _dmatvar_base(
"matpropautoderiv"),
49 auto additional_derivative_symbols =
50 this->
template getParam<std::vector<SymbolName>>(
"additional_derivative_symbols");
54 _derivative_symbol_table.reserve(_nargs + additional_derivative_symbols.size());
55 for (
unsigned i = 0; i < _nargs; ++i)
56 _derivative_symbol_table.push_back(i);
59 for (
auto & ads : additional_derivative_symbols)
62 auto it = std::find(_symbol_names.begin(), _symbol_names.end(), ads);
63 if (it == _symbol_names.end())
64 this->paramError(
"additional_derivative_symbols",
"Invalid symbol name '", ads,
"'.");
65 auto idx = std::distance(_symbol_names.begin(), it);
70 "additional_derivative_symbols",
73 "' is a coupled variable. Derivatives w.r.t. coupled variables are always taken " 74 "and they must not be specified again.");
79 additional_derivative_symbols.begin(), additional_derivative_symbols.end(), ads) > 1)
81 "additional_derivative_symbols",
"Symbol name '", ads,
"' was given more than once.");
84 _derivative_symbol_table.push_back(
idx);
91 assembleDerivatives();
94 for (
auto & mpd : _mat_prop_descriptors)
100 template <
bool is_ad>
106 if (order > _derivative_order)
110 auto derivative_var = _derivative_symbol_table[var];
111 auto derivative_symbol = _symbol_names[derivative_var];
115 for (
const auto & parent_mpd : parent_mpd_list)
118 if (!parent_mpd.dependsOn(derivative_symbol))
126 std::string newvarname = _dmatvar_base +
Moose::stringify(_dmatvar_index++);
130 _bulk_rules.emplace_back(parent_mpd.getSymbolName(), derivative_symbol, newvarname);
133 mpd_list.push_back(mpd);
137 for (
const auto & mpd : mpd_list)
138 _mat_prop_descriptors.push_back(mpd);
141 for (
unsigned int i = var; i < _derivative_symbol_table.size(); ++i)
142 recurseMatProps(i, order + 1, mpd_list);
145 template <
bool is_ad>
152 if (order > _derivative_order)
156 auto derivative_var = _derivative_symbol_table[var];
157 auto derivative_symbol = _symbol_names[derivative_var];
164 current.
_darg_names.push_back(derivative_var < _nargs ? _arg_names[derivative_var]
165 : derivative_symbol);
167 current.
_F = std::make_shared<SymFunction>(*parent_derivative.
_F);
170 if (current.
_F->AutoDiff(derivative_symbol) != -1)
171 mooseError(
"Failed to take order ", order,
" derivative in material ", _name);
174 if (!_disable_fpoptimizer)
175 current.
_F->Optimize();
178 if (!current.
_F->isZero() || is_ad)
181 if (_enable_jit && !current.
_F->JITCompile())
182 mooseInfo(
"Failed to JIT compile expression, falling back to byte code interpretation.");
185 for (
unsigned int i = var; i < _derivative_symbol_table.size(); ++i)
186 recurseDerivative(i, order + 1, current);
190 &this->
template declarePropertyDerivative<Real, is_ad>(_F_name, current.
_darg_names);
193 _derivatives.push_back(current);
200 template <
bool is_ad>
205 if (_derivative_order < 1)
213 const MaterialWarehouse & material_warehouse = this->_fe_problem.getMaterialWarehouse();
216 MooseSharedPointer<DerivativeParsedMaterialHelperTempl> master =
221 for (
const auto & D : master->_derivatives)
225 &this->
template declarePropertyDerivative<Real, is_ad>(_F_name, D._darg_names);
226 newderivative.
_F = std::make_shared<SymFunction>(*D._F);
227 _derivatives.push_back(newderivative);
231 auto start = _mat_prop_descriptors.size();
232 for (MooseIndex(master->_mat_prop_descriptors) i = start;
233 i < master->_mat_prop_descriptors.size();
238 _mat_prop_descriptors.push_back(newdescriptor);
242 _func_params.resize(master->_func_params.size());
247 for (
unsigned int i = 0; i < _derivative_symbol_table.size(); ++i)
248 recurseMatProps(i, 1, _mat_prop_descriptors);
252 if (!_bulk_rules.empty())
254 std::string
vars = _bulk_rules[0]._child;
255 for (MooseIndex(_bulk_rules) i = 1; i < _bulk_rules.size(); ++i)
256 vars +=
',' + _bulk_rules[i]._child;
257 _func_F->AddVariable(
vars);
259 for (
const auto & rule : _bulk_rules)
260 _func_F->RegisterDerivative(rule._parent, rule._var, rule._child);
267 for (
unsigned int i = 0; i < _derivative_symbol_table.size(); ++i)
268 recurseDerivative(i, 1, root);
271 _func_params.resize(_nargs + _mat_prop_descriptors.size() + _postprocessor_values.size() +
272 _extra_symbols.size() + _functors.size());
275 template <
bool is_ad>
279 computeQpProperties();
282 template <
bool is_ad>
289 for (
auto & D : _derivatives)
290 (*D._mat_prop)[_qp] =
evaluate(D._F, _name);
std::string name(const ElemQuality q)
Material properties get fully described using this structure, including their dependent variables and...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
void computeQpProperties() override
Users must override this method.
void computeQpProperties() override
Users must override this method.
void assembleDerivatives()
Perform construction of all requested derivatives.
virtual void functionsOptimize(SymFunctionPtr &parsed_function)
run FPOptimizer on the parsed function
void setSymbolName(const std::string &n)
set the fparser symbol name
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
void addDerivative(const SymbolName &symbol)
take another derivative
MaterialBase objects are special in that they have additional objects created automatically (see FEPr...
Helper class to perform the auto derivative taking.
static InputParameters validParams()
void recurseMatProps(unsigned int var, unsigned int order, const MatPropDescriptorList &parent_mpd)
void mooseInfo(Args &&... args)
Emit an informational message with the given stringified, concatenated args.
std::shared_ptr< T > getActiveObject(const std::string &name, THREAD_ID tid=0) const
GenericMaterialProperty< Real, is_ad > * _mat_prop
T evaluate(Real, const Point &)
The general evaluation method is not defined.
void functionsPostParse() override
std::string stringify(const T &t)
conversion to string
static InputParameters validParams()
Helper class to perform the parsing and optimization of the function expression.
void recurseDerivative(unsigned int var, unsigned int order, const Derivative &parent_derivative)
void initQpStatefulProperties() override
Initialize stateful properties at quadrature points.
std::vector< SymbolName > _darg_names
DerivativeParsedMaterialHelperTempl(const InputParameters ¶meters, const VariableNameMappingMode map_mode=VariableNameMappingMode::USE_PARAM_NAMES, const std::optional< std::string > &function_param_name={})
void ErrorVector unsigned int
std::vector< FunctionMaterialPropertyDescriptor< is_ad > > MatPropDescriptorList
convenience typedef for the material property descriptors