DiscreteFunction.hpp 7.54 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
20
21
  template <class GB, class VT>
  class DOFVector;
  
22
  /// \class DiscreteFunction
23
24
  /// \brief A view on a subspace of a \ref DOFVector
  /**
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  * \ingroup GridFunctions
  *
  * \tparam GB  Type of the global basis
  * \tparam VT  Coefficient type of the DOFVector
  * \tparam TP  A realization of \ref Dune::TypeTree::HybridTreePath
  * \tparam is_const  Specifies whether a const or mutable view is implemented.
  *
  * **Requirements:**
  * - GB models \ref Dune::Functions::Concept::GlobalBasis
  **/
  template <class GB, class VT, class TP, bool is_const>
  class DiscreteFunction;

#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
  // Deduction guide for DiscreteFunction class
  template <class GB, class VT>
  DiscreteFunction(DOFVector<GB, VT> const& dofVector)
    -> DiscreteFunction<GB, VT, Dune::TypeTree::HybridTreePath<>, true>;

  template <class GB, class VT>
  DiscreteFunction(DOFVector<GB, VT>& dofVector)
    -> DiscreteFunction<GB, VT, Dune::TypeTree::HybridTreePath<>, false>;
#endif


  /// A Generator for a const \ref DiscreteFunction
  template <class GlobalBasis, class ValueType,
            class PreTreePath = Dune::TypeTree::HybridTreePath<>>
  auto makeDiscreteFunction(DOFVector<GlobalBasis, ValueType> const& dofVector,
                            PreTreePath const& preTreePath = {})
55
  {
56
57
58
    auto treePath = makeTreePath(preTreePath);
    return DiscreteFunction<GlobalBasis, ValueType, decltype(treePath), true>{dofVector, treePath};
  }
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  /// A Generator for a mutable \ref DiscreteFunction
  template <class GlobalBasis, class ValueType,
            class PreTreePath = Dune::TypeTree::HybridTreePath<>>
  auto makeDiscreteFunction(DOFVector<GlobalBasis, ValueType>& dofVector,
                            PreTreePath const& preTreePath = {})
  {
    auto treePath = makeTreePath(preTreePath);
    return DiscreteFunction<GlobalBasis, ValueType, decltype(treePath), false>{dofVector, treePath};
  }



  /// A Const DiscreteFunction
  template <class GB, class VT, class TP>
  class DiscreteFunction<GB,VT,TP,true>
  {
76
77
78
  private:
    using GlobalBasis = GB;
    using TreePath = TP;
79
80
81
82
83
84
85

    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;

86
  public:
87
88
89
    /// Set of entities the DiscreteFunction is defined on
    using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;

90
    /// Global coordinates of the EntitySet
91
92
    using Domain = typename EntitySet::GlobalCoordinate;

93
94
    /// Range type of this DiscreteFunction
    using Range = RangeType_t<SubTree,VT>;
95

96
97
    /// \brief This GridFunction has no derivative function, it can be created
    /// by \ref DiscreteGridFunction.
98
99
    enum { hasDerivative = false };

100
101
  public:
    /// A LocalFunction representing the derivative of the DOFVector on a bound element
102
103
104
    template <class Type>
    class DerivativeLocalFunctionBase;

105
    class GradientLocalFunction;
106
107
    class PartialLocalFunction;
    class DivergenceLocalFunction;
108

109
    /// A LocalFunction representing the value the DOFVector on a bound element
110
    class LocalFunction;
111
112
113

  public:
    /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
114
    DiscreteFunction(DOFVector<GB,VT> const& dofVector, TP const& treePath = {})
115
116
      : dofVector_(&dofVector)
      , treePath_(treePath)
117
118
119
120
      , entitySet_(dofVector.basis()->gridView())
      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(*dofVector.basis(), treePath))
    {}

121
    /// \brief Evaluate DiscreteFunction in global coordinates. NOTE: expensive
122
123
124
    Range operator()(Domain const& x) const;

    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
125
    LocalFunction makeLocalFunction() const
126
    {
127
      return LocalFunction{*this};
128
129
    }

130
    /// \brief Return a \ref Dune::Functions::GridViewEntitySet
131
132
133
134
135
    EntitySet const& entitySet() const
    {
      return entitySet_;
    }

136
    /// \brief Return global basis bound to the DOFVector
137
    std::shared_ptr<GlobalBasis const> basis() const
138
139
140
141
    {
      return dofVector_->basis();
    }

142
    /// \brief Return treePath associated with this discrete function
143
144
145
146
147
    TreePath const& treePath() const
    {
      return treePath_;
    }

148
149
    /// \brief Return const coefficient vector
    DOFVector<GB,VT> const& coefficients() const
150
151
152
153
154
    {
      return *dofVector_;
    }

  protected:
155
156
    DOFVector<GB,VT> const* dofVector_;
    TreePath treePath_;
157
158
159
160
    EntitySet entitySet_;
    NodeToRangeEntry nodeToRangeEntry_;
  };

161
162


163
164
165
166
  /// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction
  template <class GB, class VT, class TP>
  class DiscreteFunction<GB,VT,TP,false>
      : public DiscreteFunction<GB, VT, TP, true>
167
  {
168
169
    using Self = DiscreteFunction<GB, VT, TP, false>;
    using Super = DiscreteFunction<GB, VT, TP, true>;
170

171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
    using GlobalBasis = GB;
    using TreePath = TP;

  public:
    /// Constructor. Stores a pointer to the mutable `dofvector`.
    DiscreteFunction(DOFVector<GB,VT>& dofVector, TP const& treePath = {})
      : Super(dofVector, treePath)
      , mutableDofVector_(&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 = {});

    /// \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
    DOFVector<GB,VT>& coefficients() { return *mutableDofVector_; }

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

  protected:
    DOFVector<GB,VT>* mutableDofVector_;
  };
240
241
242

} // end namespace AMDiS

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