DerivativeGridFunction.hpp 3.59 KB
Newer Older
1
2
3
4
5
6
#pragma once

#include <type_traits>

#include <dune/functions/common/defaultderivativetraits.hh>

7
#include <amdis/gridfunctions/GridFunctionConcepts.hpp>
Praetorius, Simon's avatar
Praetorius, Simon committed
8

9
10
11
namespace AMDiS
{
  /**
Praetorius, Simon's avatar
Praetorius, Simon committed
12
    * \addtogroup GridFunctions
13
14
15
    * @{
    **/

16
17
18
19
20
21
22
23
24
25
26
  /// \brief A Gridfunction that returns the derivative when calling localFunction.
  /**
   * Wrapps the GridFunction so that \ref localFunction returns a LocalFunction
   * representing the derivative of the LocalFunction of the GridFunction.
   *
   * \tparam GridFunction The GridFunction that is wrapped.
   *
   * **Requirements:**
   * - `GridFunction` models \ref Concepts::GridFunction and the LocalFunction has a derivative.
   **/
  template <class GridFunction>
27
28
  class DerivativeGridFunction
  {
29
30
31
    using GridFctRange = typename GridFunction::Range;
    using GridFctDomain = typename GridFunction::Domain;
    using RawSignature = typename Dune::Functions::SignatureTraits<GridFctRange(GridFctDomain)>::RawSignature;
32
    using DerivativeTraits = Dune::Functions::DefaultDerivativeTraits<RawSignature>;
33
    using LocalFunction = std::decay_t<decltype(derivative(localFunction(std::declval<GridFunction>())))>;
34
35

  public:
36
    /// The Range of the derivative of the GridFunction
37
38
    using Range = typename DerivativeTraits::Range;

39
    /// The domain of the GridFunction
40
    using Domain = GridFctDomain;
41

42
43
    /// The EntitySet of the GridFunction
    using EntitySet = typename GridFunction::EntitySet;
44
45

  public:
46
47
    /// Constructor. Stores a copy of gridFct.
    explicit DerivativeGridFunction(GridFunction const& gridFct)
48
      : gridFct_(gridFct)
49
50
51
    {
      static_assert(isValidRange<DerivativeTraits>(), "Derivative of GridFunction not defined");
    }
52

53
    /// NOTE: no global derivative available
54
55
56
57
58
59
    Range operator()(Domain const& x) const
    {
      error_exit("Not implemented");
      return Range(0);
    }

60
    /// Return the derivative-localFunction of the GridFunction.
61
62
    friend LocalFunction localFunction(DerivativeGridFunction const& gf)
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
63
64
65
      return derivative(localFunction(gf.gridFct_));
    }

66
    /// Return the \ref EntitySet of the \ref GridFunction.
67
68
69
70
71
72
    EntitySet const& entitySet() const
    {
      return gridFct_.entitySet();
    }

  private:
73
    GridFunction gridFct_;
74
75
  };

76
77

#ifndef DOXYGEN
Praetorius, Simon's avatar
Praetorius, Simon committed
78
  template <class GridFct,
79
    REQUIRES(not Concepts::HasDerivative<GridFct> &&
80
                Concepts::HasLocalFunctionDerivative<GridFct>)>
Praetorius, Simon's avatar
Praetorius, Simon committed
81
  auto derivative(GridFct const& gridFct)
82
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
83
    return DerivativeGridFunction<GridFct>{gridFct};
84
85
  }

86
87
88
89
90
91
92
93
94
95
96
97
98

  template <class Expr>
  struct DerivativePreGridFunction
  {
    Expr expr;
  };

  namespace Traits
  {
    template <class Expr>
    struct IsPreGridFunction<DerivativePreGridFunction<Expr>>
      : std::true_type {};
  }
99
#endif
100
101


102
103
104
105
106
107
108
109
  /// \brief Generator function for DerivativeGridFunction expressions. \relates DerivativeGridFunction
  /**
   * Generates a derivative of a GridFunction. See \ref DerivativeGridFunction.
   *
   * **Examples:**
   * - `gradientAtQP(prob.getSolution(_0))`
   * - `gradientAtQP(X(0) + X(1) + prob.getSolution(_0))`
   **/
110
111
112
113
114
115
  template <class Expr>
  auto gradientAtQP(Expr const& expr)
  {
    return DerivativePreGridFunction<Expr>{expr};
  }

116
117
  /** @} **/

118
119
120
121
122
123
124
125
126
127
  namespace Impl
  {
    /// Generator function for \ref AnalyticGridFunction expressions from \ref AnalyticPreGridFunction.
    template <class Expr, class GridView>
    auto makeGridFunctionImpl(DerivativePreGridFunction<Expr> const& pre, GridView const& gridView, Dune::PriorityTag<3>)
    {
      return derivative(Impl::makeGridFunctionImpl(pre.expr, gridView, Dune::PriorityTag<10>{}));
    }

  } // end namespace Impl
128
} // end namespace AMDiS