AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
Assembler.hpp
1 #pragma once
2 
3 #include <list>
4 #include <memory>
5 
6 #include <amdis/ContextGeometry.hpp>
7 #include <amdis/BoundaryOperator.hpp>
8 #include <amdis/Operator.hpp>
9 #include <amdis/algorithm/Map.hpp>
10 
11 namespace AMDiS
12 {
13  namespace tag
14  {
15  template <class E> struct element_operator { using type = E; };
16  template <class I> struct intersection_operator { using type = I; };
17  }
18 
19  template <class GridView, class Container, class... Nodes>
21  {
22  using Element = typename GridView::template Codim<0>::Entity;
23  using Intersection = typename GridView::Intersection;
24 
25  using ElementTraits = Impl::OperatorTraits<GridView,Element,Container>;
26  using IntersectionTraits = Impl::OperatorTraits<GridView,Intersection,Container>;
27 
29  using ElementLocalOperator = LocalOperator<ElementTraits, Nodes...>;
30 
32  using IntersectionLocalOperator = LocalOperator<IntersectionTraits, Nodes...>;
33 
34  public:
36  LocalAssembler(std::vector<ElementLocalOperator> element,
37  std::vector<IntersectionLocalOperator> intersection,
39  : element_(std::move(element))
40  , intersection_(std::move(intersection))
41  , boundary_(std::move(boundary))
42  {}
43 
45  bool empty() const
46  {
47  return element_.empty() && boundary_.empty() && intersection_.empty();
48  }
49 
51  void bind(Element const& elem)
52  {
53  for (auto& lop : element_) lop.bind(elem);
54  for (auto& lop : intersection_) lop.bind(elem);
55  for (auto& lop : boundary_) lop.bind(elem);
56  }
57 
59  void unbind()
60  {
61  for (auto& lop : element_) lop.unbind();
62  for (auto& lop : intersection_) lop.unbind();
63  for (auto& lop : boundary_) lop.unbind();
64  assembled_ = true;
65  }
66 
68  void assemble(GlobalContext<GridView> const& context, Nodes const&... nodes,
69  Container& matVec) const
70  {
71  // do not assemble in case nothing to do
72  if ((assembled_ && !changing_) || empty())
73  return;
74 
75  // create a context for the element
76  ContextGeometry elementContext{context.element(), context.element(), context.geometry()};
77 
78  // assemble element operators
79  for (auto const& lop : element_)
80  lop.assemble(elementContext, nodes..., matVec);
81 
82  if (intersection_.empty() && (boundary_.empty() || !context.element().hasBoundaryIntersections()))
83  return;
84 
85  // assemble intersection operators
86  for (auto const& is : intersections(context.gridView(), context.element()))
87  {
88  // create a context for the intersection
89  ContextGeometry intersectionContext{is, context.element(), context.geometry()};
90 
91  if (is.boundary()) {
92  // assemble boundary operators
93  for (auto& lop : boundary_) {
94  lop.assemble(intersectionContext, nodes..., matVec);
95  }
96  } else {
97  // assemble intersection operators
98  for (auto& lop : intersection_)
99  lop.assemble(intersectionContext, nodes..., matVec);
100  }
101  }
102  }
103 
104  private:
106  std::vector<ElementLocalOperator> element_;
107 
109  std::vector<IntersectionLocalOperator> intersection_;
110 
112  std::vector<BoundaryLocalOperator<IntersectionLocalOperator,Intersection>> boundary_;
113 
115  bool assembled_ = false;
116 
118  bool changing_ = true;
119  };
120 
121 
130  template <class GridView, class Container, class... Nodes>
131  class Assembler
132  {
133  using Element = typename GridView::template Codim<0>::Entity;
134  using Intersection = typename GridView::Intersection;
135 
136  using ElementTraits = Impl::OperatorTraits<GridView,Element,Container>;
137  using IntersectionTraits = Impl::OperatorTraits<GridView,Intersection,Container>;
138 
140  using ElementOperator = Operator<ElementTraits, Nodes...>;
141 
143  using IntersectionOperator = Operator<IntersectionTraits, Nodes...>;
144 
145  public:
146  Assembler () = default;
147 
148  void update(GridView const& gridView)
149  {
150  for (auto& e : element_)
151  e.update(gridView);
152  for (auto& is : intersection_)
153  is.update(gridView);
154  for (auto& b : boundary_)
155  b.update(gridView);
156  }
157 
158  template <class Op>
159  void push(tag::element_operator<Element>, Op&& op)
160  {
161  element_.emplace_back(FWD(op));
162  }
163 
164  template <class Op>
165  void push(tag::intersection_operator<Intersection>, Op&& op)
166  {
167  intersection_.emplace_back(FWD(op));
168  }
169 
170  template <class Op>
171  void push(BoundarySubset<Intersection> b, Op&& op)
172  {
173  boundary_.push_back({FWD(op), std::move(b)});
174  }
175 
176  friend LocalAssembler<GridView,Container,Nodes...> localAssembler(Assembler const& a)
177  {
178  auto toLocalOperator = [](auto const& op) { return localOperator(op); };
179  return {Recursive::map(toLocalOperator, a.element_),
180  Recursive::map(toLocalOperator, a.intersection_),
181  Recursive::map(toLocalOperator, a.boundary_)};
182  }
183 
184  private:
186  std::vector<ElementOperator> element_{};
187 
189  std::vector<IntersectionOperator> intersection_{};
190 
192  std::vector<BoundaryOperator<IntersectionOperator,Intersection>> boundary_{};
193  };
194 
195 
196  template <class RowBasis, class ColBasis, class ElementMatrix>
197  using MatrixAssembler
198  = Assembler<typename RowBasis::GridView,ElementMatrix,
199  typename RowBasis::LocalView::TreeCache,
200  typename ColBasis::LocalView::TreeCache>;
201 
202  template <class Basis, class ElementVector>
203  using VectorAssembler
204  = Assembler<typename Basis::GridView,ElementVector,
205  typename Basis::LocalView::TreeCache>;
206 
207 } // end namespace AMDiS
LocalAssembler(std::vector< ElementLocalOperator > element, std::vector< IntersectionLocalOperator > intersection, std::vector< BoundaryLocalOperator< IntersectionLocalOperator, Intersection >> boundary)
List of operators to be assembled on grid elements.
Definition: Assembler.hpp:36
An Assembler is the main driver for building the local element matrices and vectors by assembling ope...
Definition: Assembler.hpp:131
GridView const & gridView() const
Return the GridView this context is bound to.
Definition: ContextGeometry.hpp:183
Definition: ContextGeometry.hpp:161
The base class for an operator to be used in an Assembler.
Definition: Operator.hpp:78
Definition: FieldMatVec.hpp:12
void unbind()
Unbind all operators from the element.
Definition: Assembler.hpp:59
Definition: AdaptBase.hpp:6
Geometry const & geometry() const
Return the geometry of the Element.
Definition: ContextGeometry.hpp:195
An adaptive container that stores a value per grid element.
Definition: ElementVector.hpp:21
void bind(Element const &elem)
Bind all operators to the grid element and geometry.
Definition: Assembler.hpp:51
The base class for a local operator to be used in a Assembler.
Definition: LocalOperator.hpp:73
void assemble(GlobalContext< GridView > const &context, Nodes const &... nodes, Container &matVec) const
Assemble all operators on an element.
Definition: Assembler.hpp:68
Wrapper class for element and geometry.
Definition: ContextGeometry.hpp:48
Definition: Assembler.hpp:20
Definition: Assembler.hpp:15
Definition: Assembler.hpp:16
The local operator associated to BoundaryOperator.
Definition: BoundaryOperator.hpp:10
Element const & element() const
Return the bound element (entity of codim 0)
Definition: ContextGeometry.hpp:189
bool empty() const
Return whether any operators are stored on the node.
Definition: Assembler.hpp:45