The version of the *Function Parser* library that ships with MOOSE contains an automatic differentiation feature that is not present in the upstream version.

Include the automatic differentiation module (which also adds just in time compilation support) with

```
#include "libmesh/fparser_ad.hh"
```

The module provides the class

FunctionParserADBase<Real>

which derives from

FunctionParserBase<Real>

and provides the additional method

int AutoDiff(const std::string& var);

where `var`

is the name of the variable to take the derivative with respect to. The `AutoDiff`

method must be called on an initialized and parsed (but not optimized) Function Parser object.

The automatic differentiation system transforms the compiled bytecode of the parsed function into the bytecode of the derivative. The `AutoDiff`

method can be called multiple times to generate high order derivatives.

The helper method

bool isZero();

can be called after optimizing the Function Parser object to check if the function is a constant zero (i.e. the bytecode consists only of a `push 0`

command).

Almost all FParser opcodes are supported, *except* `PCall`

and `FCall`

, which are function calls to other FParser objects and calls to custom functions.

The automatic differentiation will currently complain when taking derivatives of functions that are not differentiable in a countable infinite number of points (such as `int()`

), it will however take derivatives of functions like the absolute value `abs()`

that are not differentiable in only a single point. This limitation is arbitrary and may be changed in future versions.

The current version of the AD module *does* support differentiationg FParser objects that have been previously optimized.

The following code snippet illustrates how to compute and evaluate a derivative:

FunctionParserADBase<Real> fparser; std::string func = "sin(a*x)+x^2*(3+sin(3*x))+a"; // Parse the input expression into bytecode fparser.Parse(func, "x,a"); // transform F -> dF/dx fparser.AutoDiff("x"); // run optimizer to simplify the derivative fparser.Optimize(); // evaluate the derivative (method from FParserBase<Real>) Real params[2] = {0.1, 1.7}; std::cout << fparser.Eval(params) << std::endl; // print byte code of the derivative (needs debugging enabled) fparser.PrintByteCode(std::cout);

Not that optimizing the FParser object using `.Optimize()`

after taking the derivative is *highly* recommended, as the automatic differentiation generates lots of trivial terms. For example the derivative of `2*x`

is `0*x+2*1`

, which will be optimized to `2`

.

- DerivativeParsedMaterial - automatic differentiation for MOOSE end users
- ExpressionBuilder - building FParser expressions at compile time using operator overloading