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

3
#include <optional>
4
5
#include <vector>

6
7
#include <dune/common/ftraits.hh>
#include <dune/common/typeutilities.hh>
8
9
10
11
12
#include <dune/functions/common/defaultderivativetraits.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
13
#include <amdis/common/Tags.hpp>
14
#include <amdis/functions/NodeCache.hpp>
15
#include <amdis/linearalgebra/Access.hpp>
16
#include <amdis/typetree/FiniteElementType.hpp>
17
#include <amdis/typetree/RangeType.hpp>
18
#include <amdis/typetree/TreePath.hpp>
19
20
21

namespace AMDiS
{
22
  /// \class DiscreteFunction
23
24
  /// \brief A view on a subspace of a \ref DOFVector
  /**
25
26
  * \ingroup GridFunctions
  *
27
28
  * \tparam Coeff     Const or mutable coefficient vector
  * \tparam GB        The type of the global basis
Praetorius, Simon's avatar
Praetorius, Simon committed
29
  * \tparam TreePath  A realization of \ref Dune::TypeTree::HybridTreePath
30
  * \tparam Range     The range type for th evaluation of the discrete function
31
32
  *
  * **Requirements:**
33
  * - GB models \ref Concepts::GlobalBasis
34
  **/
35
  template <class Coeff, class GB, class TreePath, class Range = void>
36
37
  class DiscreteFunction;

38

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

    using Coefficients = Coeff;
    using GlobalBasis = GB;
49

Praetorius, Simon's avatar
Praetorius, Simon committed
50
51
  public:
    /// Constructor. Stores a pointer to the mutable `dofvector`.
52
    template <class... Path>
53
54
55
    DiscreteFunction(Coefficients& coefficients, GlobalBasis const& basis, Path... path)
      : Super(coefficients, basis, path...)
      , mutableCoeff_(&coefficients)
Praetorius, Simon's avatar
Praetorius, Simon committed
56
57
    {}

58
    template <class... Path>
59
60
    DiscreteFunction(Coefficients& coefficients, std::shared_ptr<GlobalBasis const> const& basis, Path... path)
      : DiscreteFunction(coefficients, *basis, path...)
61
62
    {}

63
64
    /// Construct a DiscreteFunction directly from a DOFVector
    template <class DV, class... Path,
65
      Dune::disableCopyMove<DiscreteFunction,DV> = 0,
66
      class Coeff_ = TYPEOF(std::declval<DV>().coefficients()),
67
68
69
      class GB_    = TYPEOF(std::declval<DV>().basis())>
    explicit DiscreteFunction(DV&& dofVector, Path... path)
      : DiscreteFunction(dofVector.coefficients(), dofVector.basis(), path...)
70
71
    {}

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

Praetorius, Simon's avatar
Praetorius, Simon committed
85
86
87
88
    /// \brief Interpolation of GridFunction to DOFVector
    /**
     * **Example:**
     * ```
89
     * auto v = valueOf(prob.solutionVector(),0);
Praetorius, Simon's avatar
Praetorius, Simon committed
90
91
92
     * v.interpolate(v + [](auto const& x) { return x[0]; });
     * ```
     * Allows to have a reference to the DOFVector in the expression, e.g. as
93
     * \ref DiscreteFunction or \ref gradientOf() of a DiscreteFunction.
Praetorius, Simon's avatar
Praetorius, Simon committed
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
121
122
     **/
    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
123
124
125
126
    Coefficients& coefficients()
    {
      return *mutableCoeff_;
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
127
128
129
130

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

131
    template <class Range = void, class... Indices>
132
    auto child(Indices... ii)
Praetorius, Simon's avatar
Praetorius, Simon committed
133
    {
134
      auto tp = cat(this->treePath_, makeTreePath(ii...));
135
      return DiscreteFunction<Coeff, GB, TYPEOF(makeTreePath(tp)), Range>{*mutableCoeff_, this->basis(), tp};
Praetorius, Simon's avatar
Praetorius, Simon committed
136
137
138
139
140
141
142
    }

    using Super::child;

  protected:
    Coefficients* mutableCoeff_;
  };
143
144

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

    using Coefficient = TYPEOF(std::declval<Traits::Access>()(std::declval<Coeff const>(), std::declval<typename GB::MultiIndex>()));
155
156
157

    using Tree = typename GlobalBasis::LocalView::Tree;
    using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
158

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

163
    /// Global coordinates of the EntitySet
164
165
    using Domain = typename EntitySet::GlobalCoordinate;

166
167
    /// Range type of this DiscreteFunction. If R=void deduce the Range automatically, using RangeType_t
    using Range = std::conditional_t<std::is_same_v<R,void>, RangeType_t<SubTree,Coefficient>, R>;
168

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

173
  private:
174
    /// A LocalFunction representing the localfunction and derivative of the DOFVector on a bound element
175
    template <class Type>
176
    class LocalFunction;
177
178
179

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

188
189
190
191
192
    template <class... Path>
    DiscreteFunction(Coefficients const& coefficients, std::shared_ptr<GlobalBasis const> const& basisPtr, Path... path)
      : DiscreteFunction(coefficients, *basisPtr, path...)
    {}

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

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

    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
206
    LocalFunction<tag::value> makeLocalFunction() const
207
    {
208
      return {std::make_shared<LocalView>(basis().localView()), treePath(), coefficients(), tag::value{}};
209
210
    }

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

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

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

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

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

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

249

250
251
  // deduction guides

252
  template <class C, class Basis, class... Indices,
253
    class GB = Underlying_t<Basis>,
254
    class TP = TYPEOF(makeTreePath(std::declval<Indices>()...)),
255
    REQUIRES(Concepts::GlobalBasis<GB>)>
256
257
  DiscreteFunction(C&, Basis const&, Indices...)
    -> DiscreteFunction<C,GB,TP>;
258

259
260
261
262
263
264
  template <class DV, class... Indices,
    class C  = decltype(std::declval<DV>().coefficients()),
    class GB = decltype(std::declval<DV>().basis()),
    class TP = TYPEOF(makeTreePath(std::declval<Indices>()...))>
  DiscreteFunction(DV&, Indices...)
    -> DiscreteFunction<std::remove_reference_t<C>,Underlying_t<GB>,TP>;
265

266
267
268
269
270

  // grid functions representing the DOFVector
  // -----------------------------------------

  /// A Generator for the childs of a mutable \ref DiscreteFunction
271
272
  template <class Range = void, class C, class GB, class TP, class R, class... Indices>
  auto valueOf(DiscreteFunction<C,GB,TP,R>& df, Indices... ii)
273
  {
274
    return df.template child<Range>(ii...);
275
276
277
  }

  /// A Generator for the childs of a const \ref DiscreteFunction
278
279
  template <class Range = void, class C, class GB, class TP, class R, class... Indices>
  auto valueOf(DiscreteFunction<C,GB,TP,R> const& df, Indices... ii)
280
  {
281
    return df.template child<Range>(ii...);
282
283
284
  }

  /// A Generator to transform a DOFVector into a \ref DiscreteFunction
285
286
287
288
  template <class Range = void, class DV, class... Indices,
    class C  = decltype(std::declval<DV>().coefficients()),
    class GB = decltype(std::declval<DV>().basis()),
    class TP = TYPEOF(makeTreePath(std::declval<Indices>()...))>
289
290
  auto valueOf(DV& dofVec, Indices... ii)
  {
291
292
    using DF = DiscreteFunction<std::remove_reference_t<C>,Underlying_t<GB>,TP,Range>;
    return DF{dofVec.coefficients(), dofVec.basis(), makeTreePath(ii...)};
293
294
  }

295
296
} // end namespace AMDiS

297
#include "DiscreteLocalFunction.inc.hpp"
298
#include "DiscreteFunction.inc.hpp"