OperatorList.hpp 7.15 KB
Newer Older
1
2
3
4
5
#pragma once

#include <list>
#include <memory>

6
#include <amdis/BoundarySubset.hpp>
7
8
#include <amdis/ContextGeometry.hpp>
#include <amdis/Operator.hpp>
9
#include <amdis/typetree/TreeContainer.hpp>
10
11
12

namespace AMDiS
{
13
14
15
16
  namespace tag
  {
    template <class E> struct element_operator { using type = E; };
    template <class I> struct intersection_operator { using type = I; };
17
18
19
20

    template <class I>
    struct boundary_operator
        : public BoundarySubset<I>
21
22
    {
      using type = I;
23
24
25
26
27

      boundary_operator(BoundarySubset<I> const& bs)
        : BoundarySubset<I>{bs}
      {}

28
      using BoundarySubset<I>::BoundarySubset;
29
    };
30
31
  }

32
  template <class GridView, class Container>
33
34
35
36
37
  class OperatorLists
  {
    using Element = typename GridView::template Codim<0>::Entity;
    using Intersection = typename GridView::Intersection;

38
39
40
    using ElementTraits = Impl::OperatorTraits<GridView,Element,Container>;
    using IntersectionTraits = Impl::OperatorTraits<GridView,Intersection,Container>;

41
    template <class Op>
42
43
    struct DataElement
    {
44
      Op op;
45
      BoundarySubset<Intersection> bs;
46
47
48
49
50

      friend auto localOperator(DataElement const& de)
      {
        return DataElement<decltype(localOperator(de.op))>{localOperator(de.op), de.bs};
      }
51
52
    };

53
54
    /// Lists of \ref DataElement on the Element, BoundaryIntersection, and
    /// InteriorIntersections
55
    template <class... Nodes>
56
    struct LocalData
57
58
59
60
    {
      /// Return whether any operators are stored on the node
      bool empty() const
      {
Praetorius, Simon's avatar
Praetorius, Simon committed
61
        return element_.empty() && boundary_.empty() && intersection_.empty();
62
63
      }

64
65
      /// Bind all operators to the grid element and geometry
      void bind(Element const& elem)
66
      {
67
68
69
        for (auto& op : element_) op.bind(elem);
        for (auto& op : intersection_) op.bind(elem);
        for (auto& data : boundary_) data.op.bind(elem);
Praetorius, Simon's avatar
Praetorius, Simon committed
70
71
      }

72
73
      /// Unbind all operators from the element
      void unbind()
Praetorius, Simon's avatar
Praetorius, Simon committed
74
      {
75
76
77
78
        for (auto& op : element_) op.unbind();
        for (auto& op : intersection_) op.unbind();
        for (auto& data : boundary_) data.op.unbind();
        assembled_ = true;
79
80
      }

81
82
83
      /// Assemble all operators on an element
      void assemble(GlobalContext<GridView> const& context, Nodes const&... nodes,
                    Container& matVec) const
84
      {
85
        // do not assemble in case nothing to do
86
        if ((assembled_ && !changing_) || empty())
87
88
89
          return;

        // create a context for the element
90
        ContextGeometry elementContext{context.element(), context.element(), context.geometry()};
91
92
93
94
95

        // assemble element operators
        for (auto const& op : element_)
          op.assemble(elementContext, nodes..., matVec);

96
97
98
99
100
        if (intersection_.empty() && (boundary_.empty() || !context.element().hasBoundaryIntersections()))
          return;

        // assemble intersection operators
        for (auto const& is : intersections(context.gridView(), context.element()))
101
        {
102
          // create a context for the intersection
103
          ContextGeometry intersectionContext{is, context.element(), context.geometry()};
104
105
106
107
108
109

          if (is.boundary()) {
            // assemble boundary operators
            for (auto& data : boundary_) {
              if (data.bs(is))
                data.op.assemble(intersectionContext, nodes..., matVec);
110
            }
111
112
113
114
          } else {
            // assemble intersection operators
            for (auto& op : intersection_)
              op.assemble(intersectionContext, nodes..., matVec);
115
116
          }
        }
117
118
      }

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
      /// The type of local operators associated with grid elements
      using ElementOperator = LocalOperator<ElementTraits, Nodes...>;

      /// The type of local operators associated with grid intersections
      using IntersectionOperator = LocalOperator<IntersectionTraits, Nodes...>;

      /// List of operators to be assembled on grid elements
      std::vector<ElementOperator> element_;

      /// List of operators to be assembled on interior intersections
      std::vector<IntersectionOperator> intersection_;

      /// List of operators to be assembled on boundary intersections
      std::vector<DataElement<IntersectionOperator>> boundary_;

      /// if false, do reassemble of all operators
      bool assembled_ = false;

      /// if true, or \ref assembled false, do reassemble of all operators
      bool changing_ = true;
    };


    template <class... Nodes>
    struct Data
    {
      void update(GridView const& gridView)
146
      {
147
148
149
150
151
152
        for (auto& e : element_)
          e.update(gridView);
        for (auto& is : intersection_)
          is.update(gridView);
        for (auto& b : boundary_)
          b.op.update(gridView);
153
154
      }

155
156
      template <class Op>
      void push(tag::element_operator<Element>, Op&& op)
157
      {
158
        element_.emplace_back(FWD(op));
159
160
      }

161
162
      template <class Op>
      void push(tag::intersection_operator<Intersection>, Op&& op)
163
      {
164
        intersection_.emplace_back(FWD(op));
165
166
      }

167
168
      template <class Op>
      void push(tag::boundary_operator<Intersection> b, Op&& op)
169
      {
170
        boundary_.push_back({FWD(op), b});
171
172
      }

173
174
175
176
177
178
179
180
181
182
183
      friend LocalData<Nodes...> localOperator(Data const& d)
      {
        LocalData<Nodes...> data;
        for (auto const& e : d.element_)
          data.element_.push_back(localOperator(e));
        for (auto const& is : d.intersection_)
          data.intersection_.push_back(localOperator(is));
        for (auto const& b : d.boundary_)
          data.boundary_.push_back(localOperator(b));
        return data;
      }
184

Praetorius, Simon's avatar
Praetorius, Simon committed
185
      /// The type of local operators associated with grid elements
186
      using ElementOperator = Operator<ElementTraits, Nodes...>;
Praetorius, Simon's avatar
Praetorius, Simon committed
187
188

      /// The type of local operators associated with grid intersections
189
      using IntersectionOperator = Operator<IntersectionTraits, Nodes...>;
Praetorius, Simon's avatar
Praetorius, Simon committed
190

191
      /// List of operators to be assembled on grid elements
192
      std::vector<ElementOperator> element_;
193
194

      /// List of operators to be assembled on interior intersections
195
      std::vector<IntersectionOperator> intersection_;
Praetorius, Simon's avatar
Praetorius, Simon committed
196

197
      /// List of operators to be assembled on boundary intersections
198
      std::vector<DataElement<IntersectionOperator>> boundary_;
199
200
201
202
203
204
205
206
    };

  public:

    /// List of operators associated with matrix blocks (RowNode, ColNode)
    template <class RowNode, class ColNode>
    using MatData = Data<RowNode, ColNode>;

207
208
209
    template <class RowNode, class ColNode>
    using LocalMatData = LocalData<RowNode, ColNode>;

210
211
212
    /// List of operators associated with vector blocks [Node]
    template <class Node>
    using VecData = Data<Node>;
213
214
215

    template <class Node>
    using LocalVecData = LocalData<Node>;
216
217
218
  };


219
  template <class RowBasis, class ColBasis, class ElementMatrix>
220
  using MatrixOperators
221
    = TypeTree::TreeMatrix<
222
        OperatorLists<typename RowBasis::GridView,ElementMatrix>::template MatData,
223
224
        typename RowBasis::LocalView::TreeCache,
        typename ColBasis::LocalView::TreeCache>;
225

226
  template <class Basis, class ElementVector>
227
  using VectorOperators
228
    = TypeTree::TreeContainer<
229
        OperatorLists<typename Basis::GridView,ElementVector>::template VecData,
230
        typename Basis::LocalView::TreeCache>;
231
232

} // end namespace AMDiS