DiscreteFunction.hpp 7.42 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
  **/
Praetorius, Simon's avatar
Praetorius, Simon committed
31
  template <class Coeff, class GB, class TreePath = Dune::TypeTree::HybridTreePath<>>
32
33
  class DiscreteFunction;

34
35

  // deduction guide
Praetorius, Simon's avatar
Praetorius, Simon committed
36
  template <class Coeff, class GB, class TreePath = RootTreePath>
Praetorius, Simon's avatar
Praetorius, Simon committed
37
  DiscreteFunction(Coeff&, GB const&, TreePath = {})
Praetorius, Simon's avatar
Praetorius, Simon committed
38
    -> DiscreteFunction<Coeff, GB, TreePath_t<TreePath>>;
39

40

Praetorius, Simon's avatar
Praetorius, Simon committed
41
  /// A Generator for a mutable \ref DiscreteFunction
Praetorius, Simon's avatar
Praetorius, Simon committed
42
  template <class Coeff, class GB, class Path = RootTreePath,
Praetorius, Simon's avatar
Praetorius, Simon committed
43
    class = void_t<decltype(std::declval<GB>().localView())> >
Praetorius, Simon's avatar
Praetorius, Simon committed
44
  auto makeDiscreteFunction(Coeff& coefficients, GB const& basis, Path const& path = {})
45
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
46
    return DiscreteFunction<Coeff, GB, TreePath_t<Path>>{coefficients, basis, path};
47
  }
48

Praetorius, Simon's avatar
Praetorius, Simon committed
49
50
51
52
53

  /// 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>
54
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
55
56
57
58
59
60
    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;
61

Praetorius, Simon's avatar
Praetorius, Simon committed
62
63
  public:
    /// Constructor. Stores a pointer to the mutable `dofvector`.
Praetorius, Simon's avatar
Praetorius, Simon committed
64
65
66
    template <class Path = TreePath>
    DiscreteFunction(Coefficients& dofVector, GlobalBasis const& basis, Path const& path = {})
      : Super(dofVector, basis, path)
Praetorius, Simon's avatar
Praetorius, Simon committed
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
      , mutableCoeff_(&dofVector)
    {}

  public:
    /// \brief Interpolation of GridFunction to DOFVector, assuming that there is no
    /// reference to this DOFVector in the expression.
    /**
     * **Example:**
     * ```
     * auto v = makeDiscreteFunction(prob.solutionVector(),0);
     * v.interpolate_noalias([](auto const& x) { return x[0]; });
     * ```
     **/
    template <class Expr, class Tag = tag::average>
    void interpolate_noalias(Expr&& expr, Tag strategy = {});
82

Praetorius, Simon's avatar
Praetorius, Simon committed
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
112
113
114
115
116
117
118
119
120
    /// \brief Interpolation of GridFunction to DOFVector
    /**
     * **Example:**
     * ```
     * auto v = makeDiscreteFunction(prob.solutionVector(),0);
     * 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
121
122
123
124
    Coefficients& coefficients()
    {
      return *mutableCoeff_;
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
125
126
127
128
129
130
131

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

    template <class Path = RootTreePath>
    auto child(Path const& path = {})
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
132
133
      auto tp = cat(this->treePath_, makeTreePath(path));
      return makeDiscreteFunction(*mutableCoeff_, this->basis(), tp);
Praetorius, Simon's avatar
Praetorius, Simon committed
134
135
136
137
138
139
140
    }

    using Super::child;

  protected:
    Coefficients* mutableCoeff_;
  };
141
142

  /// A Const DiscreteFunction
Praetorius, Simon's avatar
Praetorius, Simon committed
143
144
  template <class Coeff, class GB, class TreePath>
  class DiscreteFunction<Coeff const,GB,TreePath>
145
  {
146
  private:
Praetorius, Simon's avatar
Praetorius, Simon committed
147
    using Coefficients = std::remove_const_t<Coeff>;
148
    using GlobalBasis = GB;
Praetorius, Simon's avatar
Praetorius, Simon committed
149
    using ValueType = typename Coefficients::value_type;
150
151
152
153
154
155

    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;

156
  public:
157
158
159
    /// Set of entities the DiscreteFunction is defined on
    using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;

160
    /// Global coordinates of the EntitySet
161
162
    using Domain = typename EntitySet::GlobalCoordinate;

163
    /// Range type of this DiscreteFunction
Praetorius, Simon's avatar
Praetorius, Simon committed
164
    using Range = RangeType_t<SubTree,ValueType>;
165

166
167
    /// \brief This GridFunction has no derivative function, it can be created
    /// by \ref DiscreteGridFunction.
168
169
    enum { hasDerivative = false };

170
171
  public:
    /// A LocalFunction representing the derivative of the DOFVector on a bound element
172
173
174
    template <class Type>
    class DerivativeLocalFunctionBase;

175
    class GradientLocalFunction;
176
177
    class PartialLocalFunction;
    class DivergenceLocalFunction;
178

179
    /// A LocalFunction representing the value the DOFVector on a bound element
180
    class LocalFunction;
181
182
183

  public:
    /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
Praetorius, Simon's avatar
Praetorius, Simon committed
184
185
    template <class Path = TreePath>
    DiscreteFunction(Coefficients const& coefficients, GlobalBasis const& basis, Path const& path = {})
Praetorius, Simon's avatar
Praetorius, Simon committed
186
187
      : coefficients_(&coefficients)
      , basis_(&basis)
Praetorius, Simon's avatar
Praetorius, Simon committed
188
      , treePath_(makeTreePath(path))
Praetorius, Simon's avatar
Praetorius, Simon committed
189
      , entitySet_(basis_->gridView())
Praetorius, Simon's avatar
Praetorius, Simon committed
190
      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(*basis_, treePath_))
191
192
    {}

193
    /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
194
195
196
    Range operator()(Domain const& x) const;

    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
197
    LocalFunction makeLocalFunction() const
198
    {
199
      return LocalFunction{*this};
200
201
    }

202
    /// \brief Return a \ref Dune::Functions::GridViewEntitySet
203
204
205
206
207
    EntitySet const& entitySet() const
    {
      return entitySet_;
    }

208
    /// \brief Return global basis bound to the DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
209
    GlobalBasis const& basis() const
210
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
211
      return *basis_;
212
213
    }

214
    /// \brief Return treePath associated with this discrete function
215
216
217
218
219
    TreePath const& treePath() const
    {
      return treePath_;
    }

220
    /// \brief Return const coefficient vector
Praetorius, Simon's avatar
Praetorius, Simon committed
221
    Coefficients const& coefficients() const
222
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
223
      return *coefficients_;
224
225
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
226
227
    template <class Path = RootTreePath>
    auto child(Path const& path = {}) const
228
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
229
230
      auto tp = cat(this->treePath_, makeTreePath(path));
      return makeDiscreteFunction(*coefficients_, *basis_, tp);
231
232
    }

233
  protected:
Praetorius, Simon's avatar
Praetorius, Simon committed
234
235
    Coefficients const* coefficients_;
    GlobalBasis const* basis_;
236
    TreePath treePath_;
237
238
239
240
241
242
    EntitySet entitySet_;
    NodeToRangeEntry nodeToRangeEntry_;
  };

} // end namespace AMDiS

243
#include "DiscreteLocalFunction.inc.hpp"
244
#include "DiscreteFunction.inc.hpp"