DiscreteFunction.hpp 7.44 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>

12
#include <amdis/LinearAlgebra.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
36
37
  template <class Coeff, class GB, class TreePath = Dune::TypeTree::HybridTreePath<>>
  DiscreteFunction(Coeff&, GB const&, TreePath = {})
    -> DiscreteFunction<Coeff, GB, TreePath>;
38
39
#endif

Praetorius, Simon's avatar
Praetorius, Simon committed
40
41
42
43
  /// A Generator for a mutable \ref DiscreteFunction
  template <class Coeff, class GB, class Path,
    class = void_t<decltype(std::declval<GB>().localView())> >
  auto makeDiscreteFunction(Coeff& coefficients, GB const& basis, Path const& path)
44
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
45
46
    auto treePath = makeTreePath(path);
    return DiscreteFunction<Coeff, GB, decltype(treePath)>{coefficients, basis, treePath};
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  public:
    /// Constructor. Stores a pointer to the mutable `dofvector`.
    DiscreteFunction(Coefficients& dofVector, GlobalBasis const& basis, TreePath const& treePath = {})
      : Super(dofVector, basis, treePath)
      , 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    /// \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
    Coefficients& coefficients() { return *mutableCoeff_; }

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

    template <class Path = RootTreePath>
    auto child(Path const& path = {})
    {
      auto&& tp = makeTreePath(path);
      return makeDiscreteFunction(*mutableCoeff_, this->basis(), cat(this->treePath_,tp));
    }

    using Super::child;

  protected:
    Coefficients* mutableCoeff_;
  };
137
138

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

    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;

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

156
    /// Global coordinates of the EntitySet
157
158
    using Domain = typename EntitySet::GlobalCoordinate;

159
    /// Range type of this DiscreteFunction
Praetorius, Simon's avatar
Praetorius, Simon committed
160
    using Range = RangeType_t<SubTree,ValueType>;
161

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

166
167
  public:
    /// A LocalFunction representing the derivative of the DOFVector on a bound element
168
169
170
    template <class Type>
    class DerivativeLocalFunctionBase;

171
    class GradientLocalFunction;
172
173
    class PartialLocalFunction;
    class DivergenceLocalFunction;
174

175
    /// A LocalFunction representing the value the DOFVector on a bound element
176
    class LocalFunction;
177
178
179

  public:
    /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
Praetorius, Simon's avatar
Praetorius, Simon committed
180
181
182
    DiscreteFunction(Coefficients const& coefficients, GlobalBasis const& basis, TreePath const& treePath = {})
      : coefficients_(&coefficients)
      , basis_(&basis)
183
      , treePath_(treePath)
Praetorius, Simon's avatar
Praetorius, Simon committed
184
185
      , entitySet_(basis_->gridView())
      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(*basis_, treePath))
186
187
    {}

188
    /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
189
190
191
    Range operator()(Domain const& x) const;

    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
192
    LocalFunction makeLocalFunction() const
193
    {
194
      return LocalFunction{*this};
195
196
    }

197
    /// \brief Return a \ref Dune::Functions::GridViewEntitySet
198
199
200
201
202
    EntitySet const& entitySet() const
    {
      return entitySet_;
    }

203
    /// \brief Return global basis bound to the DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
204
    GlobalBasis const& basis() const
205
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
206
      return *basis_;
207
208
    }

209
    /// \brief Return treePath associated with this discrete function
210
211
212
213
214
    TreePath const& treePath() const
    {
      return treePath_;
    }

215
    /// \brief Return const coefficient vector
Praetorius, Simon's avatar
Praetorius, Simon committed
216
    Coefficients const& coefficients() const
217
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
218
      return *coefficients_;
219
220
    }

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

228
  protected:
Praetorius, Simon's avatar
Praetorius, Simon committed
229
230
    Coefficients const* coefficients_;
    GlobalBasis const* basis_;
231
    TreePath treePath_;
232
233
234
235
236
237
    EntitySet entitySet_;
    NodeToRangeEntry nodeToRangeEntry_;
  };

} // end namespace AMDiS

238
#include "DiscreteLocalFunction.inc.hpp"
239
#include "DiscreteFunction.inc.hpp"