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
11namespace 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>
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>
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
An Assembler is the main driver for building the local element matrices and vectors by assembling ope...
Definition: Assembler.hpp:132
The local operator associated to BoundaryOperator.
Definition: BoundaryOperator.hpp:11
An adaptive container that stores a value per grid element.
Definition: ElementVector.hpp:25
Definition: ContextGeometry.hpp:162
GridView const & gridView() const
Return the GridView this context is bound to.
Definition: ContextGeometry.hpp:183
Geometry const & geometry() const
Return the geometry of the Element.
Definition: ContextGeometry.hpp:195
Element const & element() const
Return the bound element (entity of codim 0)
Definition: ContextGeometry.hpp:189
Definition: Assembler.hpp:21
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
bool empty() const
Return whether any operators are stored on the node.
Definition: Assembler.hpp:45
void assemble(GlobalContext< GridView > const &context, Nodes const &... nodes, Container &matVec) const
Assemble all operators on an element.
Definition: Assembler.hpp:68
void bind(Element const &elem)
Bind all operators to the grid element and geometry.
Definition: Assembler.hpp:51
void unbind()
Unbind all operators from the element.
Definition: Assembler.hpp:59
The base class for a local operator to be used in a Assembler.
Definition: LocalOperator.hpp:75
The base class for an operator to be used in an Assembler.
Definition: Operator.hpp:80
Wrapper class for element and geometry.
Definition: ContextGeometry.hpp:49
Definition: Assembler.hpp:15
Definition: Assembler.hpp:16