DiscreteFunction.hpp 7.02 KB
Newer Older
1
2
#pragma once

3
#include <optional>
4
5
6
7
8
9
10
11
#include <vector>

#include <dune/functions/common/defaultderivativetraits.hh>
#include <dune/functions/functionspacebases/defaultnodetorangemap.hh>
#include <dune/functions/functionspacebases/flatvectorview.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/typetree/childextraction.hh>

Praetorius, Simon's avatar
Praetorius, Simon committed
12
#include <amdis/common/Tags.hpp>
13
#include <amdis/typetree/FiniteElementType.hpp>
14
#include <amdis/typetree/RangeType.hpp>
15
#include <amdis/typetree/TreePath.hpp>
16
17
18

namespace AMDiS
{
19
  /// \class DiscreteFunction
20
21
  /// \brief A view on a subspace of a \ref DOFVector
  /**
22
23
  * \ingroup GridFunctions
  *
Praetorius, Simon's avatar
Praetorius, Simon committed
24
25
26
  * \tparam Coeff     Const or mutable coefficient type of the DOFVector
  * \tparam GB        Thy type of the global basis
  * \tparam TreePath  A realization of \ref Dune::TypeTree::HybridTreePath
27
28
  *
  * **Requirements:**
29
  * - GB models \ref Concepts::GlobalBasis
30
  **/
31
  template <class Coeff, class GB, class TreePath>
32
33
  class DiscreteFunction;

34
35

  // deduction guide
36
37
38
  template <class Coeff, class GB, class Path>
  DiscreteFunction(Coeff&, GB const&, Path const& path)
    -> DiscreteFunction<Coeff, GB, TYPEOF(makeTreePath(path))>;
39

Praetorius, Simon's avatar
Praetorius, Simon committed
40
41
42
43
44

  /// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction
  template <class Coeff, class GB, class TreePath>
  class DiscreteFunction
      : public DiscreteFunction<Coeff const,GB,TreePath>
45
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
46
47
48
49
50
51
    using Self = DiscreteFunction<Coeff,GB,TreePath>;
    using Super = DiscreteFunction<Coeff const,GB,TreePath>;

    using Coefficients = Coeff;
    using GlobalBasis = GB;
    using ValueType = typename Coeff::value_type;
52

Praetorius, Simon's avatar
Praetorius, Simon committed
53
54
  public:
    /// Constructor. Stores a pointer to the mutable `dofvector`.
55
56
    template <class Path>
    DiscreteFunction(Coefficients& dofVector, GlobalBasis const& basis, Path const& path)
Praetorius, Simon's avatar
Praetorius, Simon committed
57
      : Super(dofVector, basis, path)
Praetorius, Simon's avatar
Praetorius, Simon committed
58
59
60
61
62
63
64
65
66
      , mutableCoeff_(&dofVector)
    {}

  public:
    /// \brief Interpolation of GridFunction to DOFVector, assuming that there is no
    /// reference to this DOFVector in the expression.
    /**
     * **Example:**
     * ```
67
     * auto v = discreteFunction(prob.solutionVector(),0);
Praetorius, Simon's avatar
Praetorius, Simon committed
68
69
70
71
72
     * v.interpolate_noalias([](auto const& x) { return x[0]; });
     * ```
     **/
    template <class Expr, class Tag = tag::average>
    void interpolate_noalias(Expr&& expr, Tag strategy = {});
73

Praetorius, Simon's avatar
Praetorius, Simon committed
74
75
76
77
    /// \brief Interpolation of GridFunction to DOFVector
    /**
     * **Example:**
     * ```
78
     * auto v = discreteFunction(prob.solutionVector(),0);
Praetorius, Simon's avatar
Praetorius, Simon committed
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
     * v.interpolate(v + [](auto const& x) { return x[0]; });
     * ```
     * Allows to have a reference to the DOFVector in the expression, e.g. as
     * \ref DiscreteFunction or \ref gradientAtQP() of a DiscreteFunction.
     **/
    template <class Expr, class Tag = tag::average>
    void interpolate(Expr&& expr, Tag strategy = {});

    /// \brief Interpolation of GridFunction to DOFVector, alias to \ref interpolate()
    template <class Expr>
    Self& operator<<(Expr&& expr)
    {
      interpolate(FWD(expr));
      return *this;
    }

    /// \brief interpolate `(*this) + expr` to DOFVector
    template <class Expr>
    Self& operator+=(Expr&& expr)
    {
      interpolate((*this) + expr);
      return *this;
    }

    /// \brief interpolate `(*this) - expr` to DOFVector
    template <class Expr>
    Self& operator-=(Expr&& expr)
    {
      interpolate((*this) - expr);
      return *this;
    }

    /// Return the mutable DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
112
113
114
115
    Coefficients& coefficients()
    {
      return *mutableCoeff_;
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
116
117
118
119

    /// Return the const DOFVector
    using Super::coefficients;

120
121
    template <class... Indices>
    auto child(Indices... ii)
Praetorius, Simon's avatar
Praetorius, Simon committed
122
    {
123
124
      auto tp = cat(this->treePath_, makeTreePath(ii...));
      return DiscreteFunction<Coeff, GB, TYPEOF(makeTreePath(tp))>{*mutableCoeff_, this->basis(), tp};
Praetorius, Simon's avatar
Praetorius, Simon committed
125
126
127
128
129
130
131
    }

    using Super::child;

  protected:
    Coefficients* mutableCoeff_;
  };
132
133

  /// A Const DiscreteFunction
Praetorius, Simon's avatar
Praetorius, Simon committed
134
135
  template <class Coeff, class GB, class TreePath>
  class DiscreteFunction<Coeff const,GB,TreePath>
136
  {
137
  private:
Praetorius, Simon's avatar
Praetorius, Simon committed
138
    using Coefficients = std::remove_const_t<Coeff>;
139
    using GlobalBasis = GB;
Praetorius, Simon's avatar
Praetorius, Simon committed
140
    using ValueType = typename Coefficients::value_type;
141
142
143
144
145
146

    using Tree = typename GlobalBasis::LocalView::Tree;
    using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
    using NodeToRangeEntry = Dune::Functions::DefaultNodeToRangeMap<SubTree>;
    using GridView = typename GlobalBasis::GridView;

147
  public:
148
149
150
    /// Set of entities the DiscreteFunction is defined on
    using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;

151
    /// Global coordinates of the EntitySet
152
153
    using Domain = typename EntitySet::GlobalCoordinate;

154
    /// Range type of this DiscreteFunction
Praetorius, Simon's avatar
Praetorius, Simon committed
155
    using Range = RangeType_t<SubTree,ValueType>;
156

157
158
    /// \brief This GridFunction has no derivative function, it can be created
    /// by \ref DiscreteGridFunction.
159
160
    enum { hasDerivative = false };

161
162
  public:
    /// A LocalFunction representing the derivative of the DOFVector on a bound element
163
164
165
    template <class Type>
    class DerivativeLocalFunctionBase;

166
    class GradientLocalFunction;
167
168
    class PartialLocalFunction;
    class DivergenceLocalFunction;
169

170
    /// A LocalFunction representing the value the DOFVector on a bound element
171
    class LocalFunction;
172
173
174

  public:
    /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
175
176
    template <class Path>
    DiscreteFunction(Coefficients const& coefficients, GlobalBasis const& basis, Path const& path)
Praetorius, Simon's avatar
Praetorius, Simon committed
177
178
      : coefficients_(&coefficients)
      , basis_(&basis)
Praetorius, Simon's avatar
Praetorius, Simon committed
179
      , treePath_(makeTreePath(path))
Praetorius, Simon's avatar
Praetorius, Simon committed
180
      , entitySet_(basis_->gridView())
Praetorius, Simon's avatar
Praetorius, Simon committed
181
      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(*basis_, treePath_))
182
183
    {}

184
    /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
185
186
187
    Range operator()(Domain const& x) const;

    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
188
    LocalFunction makeLocalFunction() const
189
    {
190
      return LocalFunction{*this};
191
192
    }

193
    /// \brief Return a \ref Dune::Functions::GridViewEntitySet
194
195
196
197
198
    EntitySet const& entitySet() const
    {
      return entitySet_;
    }

199
    /// \brief Return global basis bound to the DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
200
    GlobalBasis const& basis() const
201
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
202
      return *basis_;
203
204
    }

205
    /// \brief Return treePath associated with this discrete function
206
207
208
209
210
    TreePath const& treePath() const
    {
      return treePath_;
    }

211
    /// \brief Return const coefficient vector
Praetorius, Simon's avatar
Praetorius, Simon committed
212
    Coefficients const& coefficients() const
213
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
214
      return *coefficients_;
215
216
    }

217
218
    template <class... Indices>
    auto child(Indices... ii) const
219
    {
220
221
      auto tp = cat(this->treePath_, makeTreePath(ii...));
      return DiscreteFunction<Coeff const, GB, TYPEOF(makeTreePath(tp))>{*coefficients_, *basis_, tp};
222
223
    }

224
  protected:
Praetorius, Simon's avatar
Praetorius, Simon committed
225
226
    Coefficients const* coefficients_;
    GlobalBasis const* basis_;
227
    TreePath treePath_;
228
229
230
231
232
233
    EntitySet entitySet_;
    NodeToRangeEntry nodeToRangeEntry_;
  };

} // end namespace AMDiS

234
#include "DiscreteLocalFunction.inc.hpp"
235
#include "DiscreteFunction.inc.hpp"