7#ifndef DUNE_FUFEM_FUNCTIONS_ADOLCFUNCTION_HH
8#define DUNE_FUFEM_FUNCTIONS_ADOLCFUNCTION_HH
16#include <adolc/adolc.h>
17#include <adolc/drivers/drivers.h>
18#include <adolc/taping.h>
60struct AdolCConversion;
73using AdolCActiveType =
typename AdolCConversion<T>::ActiveType;
98struct AdolCConstVectorDataHandle;
128struct AdolCMutableMatrixDataHandle;
155template<
class Signature,
class F,
class D>
156auto adolCTapeFunction(
short int tapeTag, F&& f,
const D& xp)
165 AdolCActiveType<Domain> x;
166 AdolCActiveType<Range> y;
168 AdolCConversion<Domain>::toActiveType(xp, x);
170 AdolCConversion<Range>::fromActiveType(y, yp);
194template<
class DerivativeSignature,
class D,
class R>
195auto adolCJacobian(
short int tapeTag,
const D& x,
const R&y)
200 auto J = DerivativeRange();
202 auto x_data_handle = AdolCConstVectorDataHandle<const Domain>(x);
203 auto J_data_handle = AdolCMutableMatrixDataHandle<DerivativeRange>(J);
204 J_data_handle.resizeTo(y, x);
206 int n = J_data_handle.N();
207 int m = J_data_handle.M();
208 assert(m == x_data_handle.size());
210 jacobian(tapeTag, n, m, x_data_handle.data(), J_data_handle.data());
227template<
class SecondDerivativeSignature,
class D>
228auto adolCHessian(
short int tapeTag,
const D& x)
232 auto H = SecondDerivativeRange();
234 auto x_data_handle = AdolCConstVectorDataHandle<const D>(x);
235 auto H_data_handle = AdolCMutableMatrixDataHandle<SecondDerivativeRange>(H);
236 H_data_handle.resizeTo(x, x);
238 int n = H_data_handle.N();
243 auto x_data_pointer =
const_cast<double*
>(x_data_handle.data());
244 hessian(tapeTag, n, x_data_pointer, H_data_handle.data());
247 for(
auto i :
range(n))
248 for(auto j :
range(i+1,n))
249 H_data_handle.
data()[i][j] = H_data_handle.
data()[j][i];
261struct AdolCConversion<double>
263 using PassiveType = double;
264 using ActiveType = adouble;
266 static void toActiveType(
const PassiveType& px, ActiveType& x) {
270 static void fromActiveType(ActiveType& y, PassiveType& py) {
278template<
class K,
int n>
279struct AdolCConversion<
std::array<K,n>>
284 static void toActiveType(
const PassiveType& px, ActiveType& x) {
285 for(
auto i : range(px.
size()))
286 AdolCConversion<K>::toActiveType(px[i], x[i]);
289 static void fromActiveType(ActiveType& y, PassiveType& py) {
290 for(
auto i : range(y.
size()))
291 AdolCConversion<K>::fromActiveType(y[i], py[i]);
299struct AdolCConversion<
std::vector<K>>
304 static void toActiveType(
const PassiveType& px, ActiveType& x) {
306 for(
auto i : range(px.
size()))
307 AdolCConversion<K>::toActiveType(px[i], x[i]);
310 static void fromActiveType(ActiveType& y, PassiveType& py) {
312 for(
auto i : range(y.
size()))
313 AdolCConversion<K>::fromActiveType(y[i], py[i]);
321struct AdolCConversion<
Dune::FieldVector<double,n>>
326 static void toActiveType(
const PassiveType& px, ActiveType& x) {
327 for(
auto i : range(px.
size()))
328 AdolCConversion<double>::toActiveType(px[i], x[i]);
331 static void fromActiveType(ActiveType& y, PassiveType& py) {
332 for(
auto i : range(y.
size()))
333 AdolCConversion<double>::fromActiveType(y[i], py[i]);
340template<
class K,
int n,
int m>
341struct AdolCConversion<
Dune::FieldMatrix<K,n, m>>
346 static void toActiveType(
const PassiveType& px, ActiveType& x) {
347 for(
auto i : range(px.
N()))
348 for(auto j : range(px.
M()))
349 AdolCConversion<K>::toActiveType(px[i][j], x[i][j]);
352 static void fromActiveType(ActiveType& y, PassiveType& py) {
353 for(
auto i : range(y.
N()))
354 for(auto j : range(y.
M()))
355 AdolCConversion<K>::fromActiveType(y[i][j], py[i][j]);
368 static void toActiveType(
const PassiveType& px, ActiveType& x) {
369 x.resize(px.N(), px.M());
370 for(
auto row : range(px.
N()))
371 for(auto
col : range(px.
M()))
372 AdolCConversion<K>::toActiveType(px[row][
col], x[row][
col]);
375 static void fromActiveType(
const ActiveType& y, PassiveType& py) {
376 py.resize(y.N(), y.M());
377 for(
auto row : range(y.
N()))
378 for(auto
col : range(y.
M()))
379 AdolCConversion<K>::fromActiveType(y[row][
col], py[row][
col]);
391struct AdolCConstVectorDataHandle
393 AdolCConstVectorDataHandle(
const T& t) : t_(t) {}
394 int size()
const {
return t_.size(); }
395 const double*
data()
const {
return t_.data(); }
400struct AdolCConstVectorDataHandle<const double>
402 AdolCConstVectorDataHandle(
const double& t) : tp_(&t) {}
403 int size()
const {
return 1; }
404 const double*
data()
const {
return tp_; }
415struct AdolCMutableMatrixDataHandle
417 AdolCMutableMatrixDataHandle(T& t) : t_(t), data_(t_.
data()) {}
418 int N()
const {
return 1; }
419 int M()
const {
return t_.size(); }
420 double**
data() {
return &data_; }
422 template<
class RowVector,
class ColVector>
423 void resizeTo(
const RowVector& rowVector,
const ColVector& colVector) {}
430struct AdolCMutableMatrixDataHandle<double>
432 AdolCMutableMatrixDataHandle(
double& t) : data_(&t) {}
433 int N()
const {
return 1; }
434 int M()
const {
return 1; }
435 double**
data() {
return &data_; }
437 template<
class RowVector,
class ColVector>
438 void resizeTo(
const RowVector& rowVector,
const ColVector& colVector) {}
443template<
int n,
int m>
444struct AdolCMutableMatrixDataHandle<
Dune::FieldMatrix<double,n,m>>
448 for(
auto i : range(n))
449 data_[i] = t[i].
data();
451 int N()
const {
return n; }
452 int M()
const {
return m; }
453 double**
data() {
return data_.data(); }
455 template<
class RowVector,
class ColVector>
456 void resizeTo(
const RowVector& rowVector,
const ColVector& colVector) {}
462struct AdolCMutableMatrixDataHandle<
std::vector<double>>
465 AdolCMutableMatrixDataHandle(T& t) : t_(t), data_(t_.
data()) {}
466 int N()
const {
return 1; }
467 int M()
const {
return t_.size(); }
468 double**
data() {
return &data_; }
470 template<
class RowVector>
471 void resizeTo(
const RowVector& rowVector,
const T& colVector) {
472 t_.resize(colVector.size());
481struct AdolCMutableMatrixDataHandle<
Dune::
Matrix<double>>
486 data_.resize(matrix_.N());
487 for(
auto i : range(
matrix.
N()))
488 data_[i] = &matrix_[i][0];
490 int N()
const {
return matrix_.N(); }
491 int M()
const {
return matrix_.M(); }
492 double**
data() {
return data_.data(); }
494 template<
class RowVector,
class ColVector>
495 void resizeTo(
const RowVector& rowVector,
const ColVector& colVector) {
496 matrix_.setSize(rowVector.size(), colVector.size());
497 data_.resize(matrix_.N());
498 for(
auto i : range(matrix_.
N()))
499 data_[i] = &matrix_[i][0];
540template<
class Signature,
template<
class>
class DerivativeTraits,
class F>
545 using DerivativeRange =
typename DerivativeTraits<Signature>::Range;
546 using DerivativeSignature = DerivativeRange(Domain);
548 using SecondDerivativeRange =
typename DerivativeTraits<DerivativeSignature>::Range;
549 using SecondDerivativeSignature = SecondDerivativeRange(Domain);
551 auto df = [f, tapeTag](
const Domain& x) {
552 auto y = Dune::Fufem::Impl::adolCTapeFunction<Signature>(tapeTag, f, x);
553 return Dune::Fufem::Impl::adolCJacobian<DerivativeSignature>(tapeTag, x, y);
562 auto ddf = [f, tapeTag](
const Domain& x) {
563 [[maybe_unused]]
auto y = Dune::Fufem::Impl::adolCTapeFunction<Signature>(tapeTag, f, x);
564 return Dune::Fufem::Impl::adolCHessian<SecondDerivativeSignature>(tapeTag, x);
Dune::BCRSMatrix< FieldMatrix< T, n, m >, TA > Matrix
OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
DifferentiableFunctionFromCallables< Signature, DerivativeTraits, F... > makeDifferentiableFunctionFromCallables(const SignatureTag< Signature, DerivativeTraits > &signatureTag, F &&... f)
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
static constexpr size_type M()
static constexpr size_type N()
auto jacobian(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the jacobian of an operator.
Definition userfunctions.hh:1063
Definition dunefunctionsboundaryfunctionalassembler.hh:29