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

#include <list>
#include <memory>

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

namespace AMDiS
{
12
13
14
15
  namespace tag
  {
    template <class E> struct element_operator { using type = E; };
    template <class I> struct intersection_operator { using type = I; };
16
    template <class I> struct boundary_operator : public BoundarySubset<I>
17
18
    {
      using type = I;
19
      using BoundarySubset<I>::BoundarySubset;
20
    };
21
22
  }

23
  template <class GridView, class Container>
24
25
26
27
28
  class OperatorLists
  {
    using Element = typename GridView::template Codim<0>::Entity;
    using Intersection = typename GridView::Intersection;

29
    template <class Op>
30
31
    struct DataElement
    {
32
      std::shared_ptr<Op> op;
33
      BoundarySubset<Intersection> bs;
34
35
    };

36
    /// Lists of \ref DataElement on the Element, BoundaryIntersection, and InteriorIntersections
37
38
39
40
41
42
    template <class... Nodes>
    struct Data
    {
      /// Return whether any operators are stored on the node
      bool empty() const
      {
Praetorius, Simon's avatar
Praetorius, Simon committed
43
        return element_.empty() && boundary_.empty() && intersection_.empty();
44
45
46
      }

      /// Test whether to assemble on the node
47
      bool doAssemble() const
48
      {
Praetorius, Simon's avatar
Praetorius, Simon committed
49
50
51
52
53
54
        return !assembled_ || changing_;
      }

      operator bool() const
      {
        return doAssemble() && !empty();
55
56
57
58
59
60
      }

      /// Bind all operators to the grid element and geometry
      template <class Geo>
      void bind(Element const& elem, Geo const& geo)
      {
61
62
        for (auto& op : element_) op->bind(elem,geo);
        for (auto& op : intersection_) op->bind(elem,geo);
63
        for (auto& data : boundary_) data.op->bind(elem,geo);
64
65
66
67
68
      }

      /// Unbind all operators from the element
      void unbind()
      {
69
70
        for (auto& op : element_) op->unbind();
        for (auto& op : intersection_) op->unbind();
71
        for (auto& data : boundary_) data.op->unbind();
Praetorius, Simon's avatar
Praetorius, Simon committed
72
        assembled_ = true;
73
74
      }

75

76
77
      template <class Op>
      void push(tag::element_operator<Element>, Op&& op)
78
      {
79
        element_.emplace_back(FWD(op));
80
81
      }

82
83
      template <class Op>
      void push(tag::intersection_operator<Intersection>, Op&& op)
84
      {
85
        intersection_.emplace_back(FWD(op));
86
87
      }

88
89
      template <class Op>
      void push(tag::boundary_operator<Intersection> b, Op&& op)
90
      {
91
        boundary_.push_back({FWD(op), b});
92
93
94
      }


Praetorius, Simon's avatar
Praetorius, Simon committed
95
96
97
98
99
100
      auto&       onElement()       { return element_; }
      auto const& onElement() const { return element_; }

      auto&       onIntersection()       { return intersection_; }
      auto const& onIntersection() const { return intersection_; }

101
102
103
      auto&       onBoundary()       { return boundary_; }
      auto const& onBoundary() const { return boundary_; }

Praetorius, Simon's avatar
Praetorius, Simon committed
104
    private:
105
106
107
      using ElementTraits = DefaultAssemblerTraits<Element,Container>;
      using IntersectionTraits = DefaultAssemblerTraits<Intersection,Container>;

Praetorius, Simon's avatar
Praetorius, Simon committed
108
      /// The type of local operators associated with grid elements
109
      using ElementAssembler = AssemblerInterface<ElementTraits, Nodes...>;
Praetorius, Simon's avatar
Praetorius, Simon committed
110
111

      /// The type of local operators associated with grid intersections
112
      using IntersectionAssembler = AssemblerInterface<IntersectionTraits, Nodes...>;
Praetorius, Simon's avatar
Praetorius, Simon committed
113

114
      /// List of operators to be assembled on grid elements
115
      std::vector<std::shared_ptr<ElementAssembler>> element_;
116
117

      /// List of operators to be assembled on interior intersections
118
      std::vector<std::shared_ptr<IntersectionAssembler>> intersection_;
Praetorius, Simon's avatar
Praetorius, Simon committed
119

120
      /// List of operators to be assembled on boundary intersections
121
      std::vector<DataElement<IntersectionAssembler>> boundary_;
Praetorius, Simon's avatar
Praetorius, Simon committed
122

123
      /// if false, do reassemble of all operators
Praetorius, Simon's avatar
Praetorius, Simon committed
124
      bool assembled_ = false;
125
126

      /// if true, or \ref assembled false, do reassemble of all operators
Praetorius, Simon's avatar
Praetorius, Simon committed
127
      bool changing_ = true;
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    };

  public:

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

    /// List of operators associated with vector blocks [Node]
    template <class Node>
    using VecData = Data<Node>;
  };


142
  template <class RowBasis, class ColBasis, class ElementMatrix>
143
  using MatrixOperators
144
    = TypeTree::TreeMatrix<
145
        OperatorLists<typename RowBasis::GridView,ElementMatrix>::template MatData,
146
147
        typename RowBasis::LocalView::TreeCache,
        typename ColBasis::LocalView::TreeCache>;
148

149
  template <class Basis, class ElementVector>
150
  using VectorOperators
151
    = TypeTree::TreeContainer<
152
        OperatorLists<typename Basis::GridView,ElementVector>::template VecData,
153
        typename Basis::LocalView::TreeCache>;
154
155

} // end namespace AMDiS