DOFVectorView.hpp 4.04 KB
Newer Older
1 2
#pragma once

3
#include <amdis/GridFunctions.hpp>
4
#include <amdis/gridfunctions/DiscreteFunction.hpp>
5

6 7
namespace AMDiS
{
8
  /// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction
9
  template <class GB, class VT, class TP>
10
  class DOFVectorView
11
      : public DiscreteFunction<GB, VT, TP>
12
  {
13
    using Self = DOFVectorView;
14
    using Super = DiscreteFunction<GB, VT, TP>;
15

16 17
    using GlobalBasis = GB;
    using TreePath = TP;
18 19

  public:
20 21 22 23 24
    /// Constructor forwards to the treePath constructor, with empty TreePath
    DOFVectorView(DOFVector<GB,VT>& dofVector)
      : DOFVectorView{dofVector, Dune::TypeTree::hybridTreePath()}
    {}

25
    /// Constructor. Stores a pointer to the mutable `dofvector`.
26
    DOFVectorView(DOFVector<GB,VT>& dofVector, TP const& treePath)
27 28
      : Super(dofVector, treePath)
      , mutableDofVector_(&dofVector)
29 30
    {}

31 32 33
  public:
    /// \brief Interpolation of GridFunction to DOFVector, assuming that there is no
    /// reference to this DOFVector in the expression.
34 35 36
    /**
     * **Example:**
     * ```
Praetorius, Simon's avatar
Praetorius, Simon committed
37
     * auto v = makeDOFVectorView(prob.solutionVector(),0);
38 39 40
     * v.interpolate([](auto const& x) { return x[0]; });
     * ```
     **/
41 42
    template <class Expr>
    void interpolate_noalias(Expr&& expr)
43
    {
44 45
      auto const& basis = this->basis();
      auto const& treePath = this->treePath();
46

47
      auto&& gridFct = makeGridFunction(std::forward<Expr>(expr), basis.gridView());
48

49 50
      Dune::Functions::interpolate(basis, treePath, coefficients(),
        std::forward<decltype(gridFct)>(gridFct));
51 52
    }

53 54 55 56
    /// \brief Interpolation of GridFunction to DOFVector
    /**
     * **Example:**
     * ```
Praetorius, Simon's avatar
Praetorius, Simon committed
57
     * auto v = makeDOFVectorView(prob.solutionVector(),0);
58 59 60 61 62
     * 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.
     **/
63 64
    template <class Expr>
    void interpolate(Expr&& expr)
65
    {
66
      // create temporary copy of data
67
      DOFVector<GB,VT> tmp(coefficients());
68 69
      Self tmpView{tmp, this->treePath()};
      tmpView.interpolate_noalias(std::forward<Expr>(expr));
70

71 72
      // move data from temporary vector into stored DOFVector
      coefficients().vector() = std::move(tmp.vector());
73 74
    }

75 76 77
    /// \brief Interpolation of GridFunction to DOFVector, alias to \ref interpolate()
    template <class Expr>
    DOFVectorView& operator<<(Expr&& expr)
78
    {
79 80
      interpolate(expr);
      return *this;
81 82
    }

83
    /// \brief interpolate `(*this) + expr` to DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
84
    template <class Expr>
85
    DOFVectorView& operator+=(Expr&& expr)
86
    {
87
      interpolate((*this) + expr);
88 89
      return *this;
    }
90

91
    /// \brief interpolate `(*this) - expr` to DOFVector
92
    template <class Expr>
93
    DOFVectorView& operator-=(Expr&& expr)
94
    {
95 96
      interpolate((*this) - expr);
      return *this;
97 98
    }

99
    /// Return the mutable DOFVector
100
    DOFVector<GB,VT>& coefficients() { return *mutableDofVector_; }
101

102
    /// Return the const DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
103
    using Super::coefficients;
104

105
  protected:
106
    DOFVector<GB,VT>* mutableDofVector_;
107 108
  };

109

110 111 112 113 114 115 116
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
  // Deduction guide for DOFVectorView class
  template <class GlobalBasis, class ValueType>
  DOFVectorView(DOFVector<GlobalBasis, ValueType>& dofVector)
    -> DOFVectorView<GlobalBasis, ValueType, Dune::TypeTree::HybridTreePath<>>;
#endif

117
  /// A Generator for a mutable \ref DOFVectorView
118 119
  template <class GlobalBasis, class ValueType, class TreePath>
  auto makeDOFVectorView(DOFVector<GlobalBasis, ValueType>& dofVector, TreePath const& treePath)
120
  {
121
    return DOFVectorView<GlobalBasis, ValueType, TreePath>{dofVector, treePath};
122 123
  }

124
  /// A Generator for a mutable \ref DOFVectorView
125 126
  template <class GlobalBasis, class ValueType>
  auto makeDOFVectorView(DOFVector<GlobalBasis, ValueType>& dofVector)
127 128
  {
    auto treePath = Dune::TypeTree::hybridTreePath();
129
    return DOFVectorView<GlobalBasis, ValueType, Dune::TypeTree::HybridTreePath<>>{dofVector, treePath};
130 131
  }

132
} // end namespace AMDiS