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

3 4 5 6
#include <vector>

#include <dune/common/std/optional.hh>
#include <dune/functions/common/defaultderivativetraits.hh>
7
#include <dune/functions/common/treedata.hh>
8 9 10 11 12
#include <dune/functions/functionspacebases/defaultnodetorangemap.hh>
#include <dune/functions/functionspacebases/flatvectorbackend.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/typetree/childextraction.hh>

13 14
#include <amdis/GridFunctions.hpp>
#include <amdis/utility/FiniteElementType.hpp>
15

16 17
namespace AMDiS
{
18 19 20 21 22
  /**
    * \addtogroup GridFunctions
    * @{
    **/

23
  template <class Traits, class TreePathType>
Praetorius, Simon's avatar
Praetorius, Simon committed
24
  class DOFVectorConstView
25 26
  {
  public:
27
    using GlobalBasis = typename Traits::GlobalBasis;
28
    using TreePath = TreePathType;
29
    using Vector = DOFVector<Traits>;
30 31

    using Tree = typename GlobalBasis::LocalView::Tree;
32 33
    using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
    using NodeToRangeEntry = Dune::Functions::DefaultNodeToRangeMap<SubTree>;
34 35

    using GridView = typename GlobalBasis::GridView;
36
    using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;
37 38

    using Domain = typename EntitySet::GlobalCoordinate;
39
    using Range = RangeType_t<SubTree>;
40

41 42
    using RawSignature = typename Dune::Functions::SignatureTraits<Range(Domain)>::RawSignature;
    using DerivativeTraits = Dune::Functions::DefaultDerivativeTraits<RawSignature>;
43 44
    using DerivativeRange = typename DerivativeTraits::Range;

45 46
    using LocalDomain = typename EntitySet::LocalCoordinate;
    using Element = typename EntitySet::Element;
47 48 49 50 51
    using Geometry = typename Element::Geometry;

    template <class Block>
    using Flat = Dune::Functions::FlatVectorBackend<Block>;

Praetorius, Simon's avatar
Praetorius, Simon committed
52

53 54
  public: // a local view on the gradients

55
    /// A LocalFunction representing the derivative of the DOFVector
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    class GradientLocalFunction
    {
    public:
      using Domain = LocalDomain;
      using Range = DerivativeRange;

    private:
      using LocalBasisView = typename GlobalBasis::LocalView;
      using LocalIndexSet = typename GlobalBasis::LocalIndexSet;

      template <class LeafNode>
      using LocalBasisJacobian = typename LeafNode::FiniteElement::Traits::LocalBasisType::Traits::JacobianType;

      template <class Node>
      using NodeData = typename std::vector<LocalBasisJacobian<Node>>;

      using ReferenceGradientContainer = Dune::Functions::TreeData<SubTree, NodeData, true>;

    public:
Praetorius, Simon's avatar
Praetorius, Simon committed
75
      GradientLocalFunction(DOFVectorConstView const& globalFunction)
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
        : globalFunction_(&globalFunction)
        , localBasisView_(globalFunction_->basis().localView())
        , localIndexSet_(globalFunction_->basis().localIndexSet())
        , subTree_(&Dune::TypeTree::child(localBasisView_.tree(), globalFunction_->treePath()))
      {
        referenceGradientContainer_.init(*subTree_);
      }

      void bind(Element const& element)
      {
        localBasisView_.bind(element);
        localIndexSet_.bind(localBasisView_);
        geometry_.emplace(element.geometry());
        bound_ = true;
      }

      void unbind()
      {
        localIndexSet_.unbind();
        localBasisView_.unbind();
        geometry_.reset();
        bound_ = false;
      }

      /// Evaluate Gradient at bound element in local coordinates
      Range operator()(Domain const& x) const;

103 104 105
      friend int order(GradientLocalFunction const& self)
      {
        assert( self.bound_ );
106
        return std::max(0, polynomialDegree(*self.subTree_)-1);
107 108
      }

109 110 111 112 113 114 115 116
      /// Return the bound element
      Element const& localContext() const
      {
        assert( bound_ );
        return localBasisView_.element();
      }

    private:
Praetorius, Simon's avatar
Praetorius, Simon committed
117
      DOFVectorConstView const* globalFunction_;
118 119 120 121 122 123 124 125 126 127 128 129
      LocalBasisView localBasisView_;
      LocalIndexSet localIndexSet_;

      SubTree const* subTree_;
      mutable ReferenceGradientContainer referenceGradientContainer_;

      Dune::Std::optional<Geometry> geometry_;
      bool bound_ = false;
    };


  public: // a local view on the values
130

131
    /// A LocalFunction, i.e., an element local view on the DOFVector
132 133 134
    class LocalFunction
    {
    public:
Praetorius, Simon's avatar
Praetorius, Simon committed
135 136
      using Domain = typename DOFVectorConstView::LocalDomain;
      using Range = typename DOFVectorConstView::Range;
137

138
    private:
139 140 141 142
      using LocalBasisView = typename GlobalBasis::LocalView;
      using LocalIndexSet = typename GlobalBasis::LocalIndexSet;

      template <class LeafNode>
143 144
      using LocalBasisRange = RangeType_t<LeafNode>;
        // = typename LeafNode::FiniteElement::Traits::LocalBasisType::Traits::RangeType;
145 146 147 148 149 150 151

      template <class Node>
      using NodeData = typename std::vector<LocalBasisRange<Node>>;

      using ShapeFunctionValueContainer = Dune::Functions::TreeData<SubTree, NodeData, true>;

    public:
Praetorius, Simon's avatar
Praetorius, Simon committed
152
      LocalFunction(DOFVectorConstView const& globalFunction)
153 154 155
        : globalFunction_(&globalFunction)
        , localBasisView_(globalFunction_->basis().localView())
        , localIndexSet_(globalFunction_->basis().localIndexSet())
156
        , subTree_(&Dune::TypeTree::child(localBasisView_.tree(), globalFunction_->treePath()))
157
      {
158
        shapeFunctionValueContainer_.init(*subTree_);
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
      }

      void bind(Element const& element)
      {
        localBasisView_.bind(element);
        localIndexSet_.bind(localBasisView_);
        bound_ = true;
      }

      void unbind()
      {
        localIndexSet_.unbind();
        localBasisView_.unbind();
        bound_ = false;
      }

175
      /// Evaluate LocalFunction at bound element in local coordinates
176 177
      Range operator()(Domain const& x) const;

178
      /// \brief Create a LocalFunction representing the gradient. \relates GradientLocalFunction
179 180
      friend GradientLocalFunction derivative(LocalFunction const& localFunction)
      {
181
        static_assert(isValidRange<DerivativeTraits>(),"Derivative of DOFVector not defined.");
182 183 184
        return GradientLocalFunction{*localFunction.globalFunction_};
      }

185 186 187
      friend int order(LocalFunction const& self)
      {
        assert( self.bound_ );
188
        return polynomialDegree(*self.subTree_);
189 190
      }

191
      /// Return the bound element
192 193
      Element const& localContext() const
      {
194
        assert( bound_ );
195 196 197 198
        return localBasisView_.element();
      }

    private:
Praetorius, Simon's avatar
Praetorius, Simon committed
199
      DOFVectorConstView const* globalFunction_;
200 201
      LocalBasisView localBasisView_;
      LocalIndexSet localIndexSet_;
202
      SubTree const* subTree_;
203 204 205 206 207 208

      mutable ShapeFunctionValueContainer shapeFunctionValueContainer_;

      bool bound_ = false;
    };

209

210
  public:
211
    /// Constructor. Stores a pointer to the dofVector and a copy of the treePath.
212
    DOFVectorConstView(DOFVector<Traits> const& dofVector, TreePath const& treePath)
213
      : dofVector_(&dofVector)
214
      , treePath_(treePath)
215 216
      , entitySet_(dofVector.getFeSpace().gridView())
      , nodeToRangeEntry_(Dune::Functions::makeDefaultNodeToRangeMap(dofVector.getFeSpace(), treePath))
217 218
    {}

219
    /// Evaluate the view on this DOFVector in global coordinates
220 221 222 223 224 225
    Range operator()(Domain const& x) const
    {
      error_exit("Not implemented.");
      return Range(0);
    }

226
    /// \brief Create a local function for this view on the DOFVector. \relates LocalFunction
Praetorius, Simon's avatar
Praetorius, Simon committed
227
    friend LocalFunction localFunction(DOFVectorConstView const& self)
228
    {
229 230 231
      return LocalFunction{self};
    }

232 233 234 235 236 237
    EntitySet const& entitySet() const
    {
      return entitySet_;
    }

  public:
238 239 240 241 242 243 244 245 246 247 248 249 250
    /// Return global basis
    GlobalBasis const& basis() const
    {
      return dofVector_->getFeSpace();
    }

    /// Return treePath associated with this view
    TreePath const& treePath() const
    {
      return treePath_;
    }

    /// Return const coefficient vector
251
    DOFVector<Traits> const& coefficients() const
252 253 254 255 256
    {
      return *dofVector_;
    }

  protected:
257
    DOFVector<Traits> const* dofVector_;
258 259 260 261 262 263 264 265
    TreePath const treePath_;

    EntitySet entitySet_;
    NodeToRangeEntry nodeToRangeEntry_;
  };


  // A mutable version of DOFVectorView
266
  template <class Traits, class TreePathType>
Praetorius, Simon's avatar
Praetorius, Simon committed
267
  class DOFVectorMutableView
268
      : public DOFVectorConstView<Traits, TreePathType>
269
  {
270
    using Super = DOFVectorConstView<Traits, TreePathType>;
271

272
    using GlobalBasis = typename Traits::GlobalBasis;
273 274 275 276
    using TreePath = TreePathType;

  public:
    /// Constructor. Stores a pointer to the mutable `dofvector`.
277
    DOFVectorMutableView(DOFVector<Traits>& dofVector, TreePath const& treePath)
Praetorius, Simon's avatar
Praetorius, Simon committed
278
      : Super(dofVector, treePath)
279 280 281 282
      , mutableDofVector_(&dofVector)
    {}

  public:
Praetorius, Simon's avatar
Praetorius, Simon committed
283 284
    /// Interpolation of GridFunction to DOFVector
    template <class Expr>
Praetorius, Simon's avatar
Praetorius, Simon committed
285
    DOFVectorMutableView& interpolate(Expr&& expr)
286
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
287 288
      auto const& basis = Super::basis();
      auto const& treePath = Super::treePath();
289

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

292
      DOFVector<Traits> tmp(basis, "tmp");
293
      Dune::Functions::interpolate(basis, treePath, tmp, std::forward<decltype(gridFct)>(gridFct));
294

295 296 297 298
      // move data from temporary vector into stored DOFVector
      mutableDofVector_->getVector() = std::move(tmp.getVector());
      return *this;
    }
299

300
    /// Return the mutable DOFVector
301
    DOFVector<Traits>& coefficients() { return *mutableDofVector_; }
302

303
    /// Return the const DOFVector
Praetorius, Simon's avatar
Praetorius, Simon committed
304
    using Super::coefficients;
305

306
  protected:
307
    DOFVector<Traits>* mutableDofVector_;
308 309
  };

310 311
  /** @} **/

312

313
#ifndef DOXYGEN
314
  // A Generator for a const \ref DOFVectorView.
315 316
  template <class Traits, class TreePath>
  auto makeDOFVectorView(DOFVector<Traits> const& dofVector, TreePath const& treePath)
317
  {
318
    return DOFVectorConstView<Traits, TreePath>{dofVector, treePath};
319 320 321
  }

  // A Generator for a mutable \ref DOFVectorView.
322 323
  template <class Traits, class TreePath>
  auto makeDOFVectorView(DOFVector<Traits>& dofVector, TreePath const& treePath)
324
  {
325
    return DOFVectorMutableView<Traits, TreePath>{dofVector, treePath};
326 327 328 329
  }


  // A Generator for a const \ref DOFVectorView.
330 331
  template <class Traits>
  auto makeDOFVectorView(DOFVector<Traits> const& dofVector)
332 333
  {
    auto treePath = Dune::TypeTree::hybridTreePath();
334
    return DOFVectorConstView<Traits, decltype(treePath)>{dofVector, treePath};
335 336 337
  }

  // A Generator for a mutable \ref DOFVectorView.
338 339
  template <class Traits>
  auto makeDOFVectorView(DOFVector<Traits>& dofVector)
340 341
  {
    auto treePath = Dune::TypeTree::hybridTreePath();
342
    return DOFVectorMutableView<Traits, decltype(treePath)>{dofVector, treePath};
343
  }
344
#endif
345

346 347 348
} // end namespace AMDiS

#include "DOFVectorView.inc.hpp"