FiniteElementSpaces.hpp 3.68 KB
Newer Older
1
2
3
4
#pragma once

#include <dune/amdis/common/TupleUtility.hpp>
#include <dune/amdis/common/IndexSeq.hpp>
5
#include <dune/amdis/common/Loops.hpp>
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

namespace AMDiS
{
  template <class FeSpace>
  struct LocalView
  {
    using type = typename FeSpace::LocalView;
  };

  template <class FeSpace>
  struct LocalIndexSet
  {
    using type = typename FeSpace::LocalIndexSet;
  };


  template <class FeSpaces>
  class FiniteElementSpaces
  {
    template <std::size_t I>
    using FeSpace = std::tuple_element_t<I, FeSpaces>;

    static constexpr int nComponents = std::tuple_size<FeSpaces>::value;

    static_assert( nComponents > 0, "" );

    using LocalViews = MapTuple_t<LocalView, FeSpaces>;
    using LocalIndexSets = MapTuple_t<LocalIndexSet, FeSpaces>;

    /// The grid view the global FE basis lives on
    using GridView = typename FeSpace<0>::GridView;

    /// Type of the grid element we are bound to
    using Element = typename GridView::template Codim<0>::Entity;

  public:
42
    explicit FiniteElementSpaces(std::shared_ptr<FeSpaces> const& feSpaces)
43
44
45
      : feSpaces_(feSpaces)
      , localViews_(mapTuple([](auto const& basis) { return basis.localView(); }, *feSpaces))
      , localIndexSets_(mapTuple([](auto const& basis) { return basis.localIndexSet(); }, *feSpaces))
46
47
    {}

48
49
50
51
52
53
54
55
56
57
58
    /// Update all global bases. This will update the indexing information of the global basis.
    /// NOTE: It must be called if the grid has changed.
    void update(GridView const& gv)
    {
      forEach(range_<0, nComponents>, [&,this](auto const _i)
      {
        static const int I = decltype(_i)::value;
        std::get<I>(*feSpaces_).update(gv);
      });
    }

59
60
61
62
63
64
    /// Bind the \ref localViews and \ref localIndexSets to a grid element
    void bind(Element const& element)
    {
      forEach(range_<0, nComponents>, [&,this](auto const _i)
      {
        static const int I = decltype(_i)::value;
65
66
67
68
69
70

        auto& localView = std::get<I>(localViews_);
        localView.bind(element);

        auto& localIndexSet = std::get<I>(localIndexSets_);
        localIndexSet.bind(localView);
71
72
      });
      // NOTE: maybe create element-geometry here
73
      bound_ = true;
74
75
76
77
78
79
80
81
82
83
84
    }

    /// Unbind from the current element
    void unbind()
    {
      forEach(range_<0, nComponents>, [&,this](auto const _i)
      {
        static const int I = decltype(_i)::value;
        std::get<I>(localIndexSets_).unbind();
        std::get<I>(localViews_).unbind();
      });
85
      bound_ = false;
86
87
    }

88
    template <std::size_t I>
89
    auto const& feSpace(const index_t<I> _i = {}) const
90
91
92
93
    {
      return std::get<I>(*feSpaces_);
    }

94
95
96
    template <std::size_t I>
    auto const& localView(const index_t<I> _i = {}) const
    {
97
      assert( bound_ && "localViews must be bound to an element." );
98
99
100
101
102
103
      return std::get<I>(localViews_);
    }

    template <std::size_t I>
    auto const& localIndexSet(const index_t<I> _i = {}) const
    {
104
      assert( bound_ && "localIndexSets must be bound to a localView." );
105
106
107
      return std::get<I>(localIndexSets_);
    }

108
109
110
111
112
113
    auto const& element() const
    {
      assert( bound_ && "localViews must be bound to an element." );
      return std::get<0>(localViews_).element();
    }

114
115
    auto const& gridView() const
    {
116
      return std::get<0>(*feSpaces_).gridView();
117
118
119
    }

  private:
120
    /// Tuple of global functionspace bases
121
122
    std::shared_ptr<FeSpaces> feSpaces_;

123
    /// Tuple of localView objects, obtained from the tuple of global bases
124
125
    LocalViews localViews_;

126
    /// Tuple of localIndexSet objects, obtained from the tuple of global bases
127
    LocalIndexSets localIndexSets_;
128
129
130

    /// True, if localViews and localIndexSets are bound to an element
    bool bound_ = false;
131
132
133
  };

} // end namespace AMDiS