Provide a dune-functions-like wrapper around AdolC
Given a callback f
this allows to compute a differentiable function
in the sense of dune-functions where the derivative is provided using
automated differentiation via the AdolC library. The interface is very
close to makeDifferentiableFunctionFromCallables()
from dune-functions.
You only need to ensure that the passed callable is AdolC compatible
by carefully using deduced types as local variables.
Example:
// Define a function as generic lambda.
// By deducing the Field type from x, we ensure that
// this is AdolC-compatible.
auto f_raw = [](auto x) {
using Field = std::decay_t<decltype(x[0])>;
Field y = x[0]*x[0] + x[1]*x[2];
return y*y;
};
// Specify function signature explicitly
using Domain = Dune::FieldVector<double,3>;
using Range = double;
using SignatureTag = Dune::Functions::SignatureTag<Range(Domain)>;
// Create differentiable function
auto f = Dune::Fufem::makeAdolCFunction(SignatureTag(), f_raw);
// Obtain derivative
auto df = derivative(f);
// Obtain second derivative
auto ddf = derivative(df);
// Evaluate function (no AdolC-layer involved)
f(x);
// Evaluate derivative (this first lets AdolC tape f and then uses the tape to compute the Jacobian)
df(x);
// Evaluate second derivative (this first lets AdolC tape f and then uses the tape to compute the Hessian)
ddf(x);
To make this work as general as possible it can be customized for different domain-, range-, and Jacobian-types via specialization of certain helper templates.
Edited by Carsten Gräser