DiscreteFunction.hpp 7.48 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
#pragma once

#include <vector>

#include <dune/common/std/optional.hh>
#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
29
30
  *
  * **Requirements:**
  * - GB models \ref Dune::Functions::Concept::GlobalBasis
  **/
Praetorius, Simon's avatar
Praetorius, Simon committed
31
  template <class Coeff, class GB, class TreePath = Dune::TypeTree::HybridTreePath<>>
32
33
34
  class DiscreteFunction;

#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
Praetorius, Simon's avatar
Praetorius, Simon committed
35
  template <class Coeff, class GB, class TreePath = RootTreePath>
Praetorius, Simon's avatar
Praetorius, Simon committed
36
  DiscreteFunction(Coeff&, GB const&, TreePath = {})
Praetorius, Simon's avatar
Praetorius, Simon committed
37
    -> DiscreteFunction<Coeff, GB, TreePath_t<TreePath>>;
38
39
#endif

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

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

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

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

Praetorius, Simon's avatar
Praetorius, Simon committed
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
112
113
114
115
116
117
118
119
    /// \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
120
121
122
123
    Coefficients& coefficients()
    {
      return *mutableCoeff_;
    }
Praetorius, Simon's avatar
Praetorius, Simon committed
124
125
126
127
128
129
130

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

    template <class Path = RootTreePath>
    auto child(Path const& path = {})
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
131
132
      auto tp = cat(this->treePath_, makeTreePath(path));
      return makeDiscreteFunction(*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.
Praetorius, Simon's avatar
Praetorius, Simon committed
183
184
    template <class Path = TreePath>
    DiscreteFunction(Coefficients const& coefficients, GlobalBasis const& basis, Path const& path = {})
Praetorius, Simon's avatar
Praetorius, Simon committed
185
186
      : coefficients_(&coefficients)
      , basis_(&basis)
Praetorius, Simon's avatar
Praetorius, Simon committed
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
    /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
193
194
195
    Range operator()(Domain const& x) const;

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

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

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

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

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

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

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

} // end namespace AMDiS

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