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 _derivative_order(this->template getParam<unsigned
int>(
"derivative_order")),
37 _dmatvar_base(
"matpropautoderiv"),
47 auto additional_derivative_symbols =
48 this->
template getParam<std::vector<SymbolName>>(
"additional_derivative_symbols");
52 _derivative_symbol_table.reserve(_nargs + additional_derivative_symbols.size());
53 for (
unsigned i = 0; i < _nargs; ++i)
54 _derivative_symbol_table.push_back(i);
57 for (
auto & ads : additional_derivative_symbols)
60 auto it = std::find(_symbol_names.begin(), _symbol_names.end(), ads);
61 if (it == _symbol_names.end())
62 this->paramError(
"additional_derivative_symbols",
"Invalid symbol name '", ads,
"'.");
63 auto idx = std::distance(_symbol_names.begin(), it);
68 "additional_derivative_symbols",
71 "' is a coupled variable. Derivatives w.r.t. coupled variables are always taken " 72 "and they must not be specified again.");
77 additional_derivative_symbols.begin(), additional_derivative_symbols.end(), ads) > 1)
79 "additional_derivative_symbols",
"Symbol name '", ads,
"' was given more than once.");
82 _derivative_symbol_table.push_back(
idx);
89 assembleDerivatives();
92 for (
auto & mpd : _mat_prop_descriptors)
104 if (order > _derivative_order)
108 auto derivative_var = _derivative_symbol_table[var];
109 auto derivative_symbol = _symbol_names[derivative_var];
113 for (
const auto & parent_mpd : parent_mpd_list)
116 if (!parent_mpd.dependsOn(derivative_symbol))
124 std::string newvarname = _dmatvar_base +
Moose::stringify(_dmatvar_index++);
128 _bulk_rules.emplace_back(parent_mpd.getSymbolName(), derivative_symbol, newvarname);
131 mpd_list.push_back(mpd);
135 for (
const auto & mpd : mpd_list)
136 _mat_prop_descriptors.push_back(mpd);
139 for (
unsigned int i = var; i < _derivative_symbol_table.size(); ++i)
140 recurseMatProps(i, order + 1, mpd_list);
143 template <
bool is_ad>
150 if (order > _derivative_order)
154 auto derivative_var = _derivative_symbol_table[var];
155 auto derivative_symbol = _symbol_names[derivative_var];
162 current.
_darg_names.push_back(derivative_var < _nargs ? _arg_names[derivative_var]
163 : derivative_symbol);
165 current.
_F = std::make_shared<SymFunction>(*parent_derivative.
_F);
168 if (current.
_F->AutoDiff(derivative_symbol) != -1)
169 mooseError(
"Failed to take order ", order,
" derivative in material ", _name);
172 if (!_disable_fpoptimizer)
173 current.
_F->Optimize();
176 if (!current.
_F->isZero() || is_ad)
179 if (_enable_jit && !current.
_F->JITCompile())
180 mooseInfo(
"Failed to JIT compile expression, falling back to byte code interpretation.");
183 for (
unsigned int i = var; i < _derivative_symbol_table.size(); ++i)
184 recurseDerivative(i, order + 1, current);
188 &this->
template declarePropertyDerivative<Real, is_ad>(_F_name, current.
_darg_names);
191 _derivatives.push_back(current);
198 template <
bool is_ad>
203 if (_derivative_order < 1)
211 const MaterialWarehouse & material_warehouse = this->_fe_problem.getMaterialWarehouse();
214 MooseSharedPointer<DerivativeParsedMaterialHelperTempl> master =
219 for (
const auto & D : master->_derivatives)
223 &this->
template declarePropertyDerivative<Real, is_ad>(_F_name, D._darg_names);
224 newderivative.
_F = std::make_shared<SymFunction>(*D._F);
225 _derivatives.push_back(newderivative);
229 auto start = _mat_prop_descriptors.size();
230 for (MooseIndex(master->_mat_prop_descriptors) i = start;
231 i < master->_mat_prop_descriptors.size();
236 _mat_prop_descriptors.push_back(newdescriptor);
240 _func_params.resize(master->_func_params.size());
245 for (
unsigned int i = 0; i < _derivative_symbol_table.size(); ++i)
246 recurseMatProps(i, 1, _mat_prop_descriptors);
250 if (!_bulk_rules.empty())
252 std::string vars = _bulk_rules[0]._child;
253 for (MooseIndex(_bulk_rules) i = 1; i < _bulk_rules.size(); ++i)
254 vars +=
',' + _bulk_rules[i]._child;
255 _func_F->AddVariable(vars);
257 for (
const auto & rule : _bulk_rules)
258 _func_F->RegisterDerivative(rule._parent, rule._var, rule._child);
265 for (
unsigned int i = 0; i < _derivative_symbol_table.size(); ++i)
266 recurseDerivative(i, 1, root);
269 _func_params.resize(_nargs + _mat_prop_descriptors.size() + _postprocessor_values.size());
272 template <
bool is_ad>
276 computeQpProperties();
279 template <
bool is_ad>
286 for (
auto & D : _derivatives)
287 (*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)
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, VariableNameMappingMode map_mode=VariableNameMappingMode::USE_PARAM_NAMES)
void ErrorVector unsigned int
std::vector< FunctionMaterialPropertyDescriptor< is_ad > > MatPropDescriptorList
convenience typedef for the material property descriptors