DiscreteFunction.hpp 8.32 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
57
    template <class... Path>
    DiscreteFunction(Coefficients& dofVector, GlobalBasis const& basis, Path... path)
      : Super(dofVector, basis, path...)
Praetorius, Simon's avatar
Praetorius, Simon committed
58
59
60
      , mutableCoeff_(&dofVector)
    {}

61
62
63
64
65
66
67
68
    /// Construct a DiscreteFunction directly from a DOFVector
    template <class DV, class... Path,
      class Coeff_ = TYPEOF(std::declval<DV>().coefficients()),
      class GB_    = TYPEOF(*std::declval<DV>().basis())>
    DiscreteFunction(DV&& dofVector, Path... path)
      : DiscreteFunction(dofVector.coefficients(), *dofVector.basis(), path...)
    {}

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

Praetorius, Simon's avatar
Praetorius, Simon committed
82
83
84
85
    /// \brief Interpolation of GridFunction to DOFVector
    /**
     * **Example:**
     * ```
86
     * auto v = discreteFunction(prob.solutionVector(),0);
Praetorius, Simon's avatar
Praetorius, Simon committed
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
     * 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
120
121
122
123
    Coefficients& coefficients()
    {
      return *mutableCoeff_;
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
124
125
126
127

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

128
129
    template <class... Indices>
    auto child(Indices... ii)
Praetorius, Simon's avatar
Praetorius, Simon committed
130
    {
131
132
      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
133
134
135
136
137
138
139
    }

    using Super::child;

  protected:
    Coefficients* mutableCoeff_;
  };
140
141

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

    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;

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

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

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

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

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

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

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

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

192
193
194
195
196
197
198
199
200
    /// Construct a DiscreteFunction directly from a DOFVector
    template <class DV, class... Path,
      class Coeff_ = TYPEOF(std::declval<DV>().coefficients()),
      class GB_    = TYPEOF(*std::declval<DV>().basis())>
    DiscreteFunction(DV const& dofVector, Path... path)
      : DiscreteFunction(dofVector.coefficients(), *dofVector.basis(), path...)
    {}


201
    /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
202
203
204
    Range operator()(Domain const& x) const;

    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
205
    LocalFunction makeLocalFunction() const
206
    {
207
      return LocalFunction{*this};
208
209
    }

210
    /// \brief Return a \ref Dune::Functions::GridViewEntitySet
211
212
213
214
215
    EntitySet const& entitySet() const
    {
      return entitySet_;
    }

216
    /// \brief Return global basis bound to the DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
217
    GlobalBasis const& basis() const
218
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
219
      return *basis_;
220
221
    }

222
    /// \brief Return treePath associated with this discrete function
223
224
225
226
227
    TreePath const& treePath() const
    {
      return treePath_;
    }

228
    /// \brief Return const coefficient vector
Praetorius, Simon's avatar
Praetorius, Simon committed
229
    Coefficients const& coefficients() const
230
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
231
      return *coefficients_;
232
233
    }

234
235
    template <class... Indices>
    auto child(Indices... ii) const
236
    {
237
238
      auto tp = cat(this->treePath_, makeTreePath(ii...));
      return DiscreteFunction<Coeff const, GB, TYPEOF(makeTreePath(tp))>{*coefficients_, *basis_, tp};
239
240
    }

241
  protected:
Praetorius, Simon's avatar
Praetorius, Simon committed
242
243
    Coefficients const* coefficients_;
    GlobalBasis const* basis_;
244
    TreePath treePath_;
245
246
247
248
    EntitySet entitySet_;
    NodeToRangeEntry nodeToRangeEntry_;
  };

249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
  // deduction guides

  template <class Coeff, class GB, class... Path,
    class TP = TYPEOF(makeTreePath(std::declval<Path>()...)),
    REQUIRES(Concepts::GlobalBasis<GB>)>
  DiscreteFunction(Coeff&, GB const&, Path...)
    -> DiscreteFunction<Coeff,GB,TP>;

  template <class DV, class... Path,
    class Coeff = decltype(std::declval<DV>().coefficients()),
    class GB    = decltype(*std::declval<DV>().basis()),
    class TP    = TYPEOF(makeTreePath(std::declval<Path>()...))>
  DiscreteFunction(DV&, Path...)
    -> DiscreteFunction<std::remove_reference_t<Coeff>,std::decay_t<GB>,TP>;

264
265
} // end namespace AMDiS

266
#include "DiscreteLocalFunction.inc.hpp"
267
#include "DiscreteFunction.inc.hpp"