Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
localsumassembler.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_FORMS_LOCALSUMASSEMBLER_HH
8#define DUNE_FUFEM_FORMS_LOCALSUMASSEMBLER_HH
9
10#include <type_traits>
11#include <tuple>
12#include <utility>
13
15
16#include <dune/assembler/assemblerconcepts.hh>
17
19
20
21namespace Dune::Fufem::Forms {
22
23 namespace Impl {
24
25 template <class LocalAssembler, class Element>
26 concept HasAssembleElementMatrix =
27 requires(LocalAssembler la, Element e, Dune::Assembler::Concepts::Archetypes::Matrix& localMatrix, Dune::Assembler::Concepts::Archetypes::LocalMatrixPattern& localPattern)
28 {
29 la.assembleElementMatrix(e,localMatrix);
30 la.assembleElementMatrixPattern(e,localPattern);
31 };
32
33 template <class LocalAssembler, class Intersection>
34 concept HasAssembleBoundaryIntersectionMatrix =
35 requires(LocalAssembler la, Intersection is, Dune::Assembler::Concepts::Archetypes::Matrix& localMatrix, Dune::Assembler::Concepts::Archetypes::LocalMatrixPattern& localPattern)
36 {
37 la.assembleBoundaryIntersectionMatrix(is, localMatrix);
38 la.assembleBoundaryIntersectionMatrixPattern(is, localPattern);
39 };
40
41 template <class LocalAssembler, class Intersection>
42 concept HasAssembleInteriorIntersectionMatrix =
43 requires(
44 LocalAssembler la,
45 Intersection is,
48 )
49 {
50 la.assembleInteriorIntersectionMatrix(is, localMatrix);
51 la.assembleInteriorIntersectionMatrixPattern(is, localPattern);
52 };
53
54 template <class LocalAssembler, class Element>
55 concept HasAssembleElementVector =
56 requires(LocalAssembler la, Element e, Dune::Assembler::Concepts::Archetypes::Vector& localVector)
57 {
58 la.assembleElementVector(e, localVector);
59 };
60
61 template <class LocalAssembler, class Intersection>
62 concept HasAssembleBoundaryIntersectionVector =
63 requires(LocalAssembler la, Intersection is, Dune::Assembler::Concepts::Archetypes::Vector& localVector)
64 {
65 la.assembleBoundaryIntersectionVector(is, localVector);
66 };
67
68 template <class LocalAssembler, class Intersection>
69 concept HasAssembleInteriorIntersectionVector =
70 requires(LocalAssembler la, Intersection is, Dune::Assembler::Concepts::Archetypes::Vector& localVector)
71 {
72 la.assembleInteriorIntersectionVector(is, localVector);
73 };
74
75 }
76
77
78
79 template<class T>
81
82
83
99 template<class... LocalAssemblers>
101 {
102
103 // SFINAE expression check for preprocess() method of local assembler
104 template <class LocalAssembler, class TestLocalView, class AnsatzLocalView>
105 using LocalAssemblerBinaryPreprocess = decltype(std::declval<LocalAssembler>().preprocess(std::declval<TestLocalView>(), std::declval<AnsatzLocalView>()));
106
107 // SFINAE expression check for preprocess() method of local assembler
108 template <class LocalAssembler, class TestLocalView>
109 using LocalAssemblerUnaryPreprocess = decltype(std::declval<LocalAssembler>().preprocess(std::declval<TestLocalView>()));
110
111 public:
112
113 LocalSumAssembler(const LocalAssemblers&... localAssemblers) :
114 localAssemblers_(localAssemblers...)
115 {}
116
117 // Dune::Assembler assembler interface
118
119 template<class Element>
120 void bindElement (const Element& element)
121 {
122 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
123 localAssembler.bindElement(element);
124 });
125 }
126
127 // Dune::Assembler matrix-assembler interface
128
129 template<class TestRootLocalView, class AnsatzRootLocalView>
130 void bindLocalViews (const TestRootLocalView& testLocalView, const AnsatzRootLocalView& ansatzLocalView)
131 requires (Dune::Assembler::Concepts::BindableToLocalViews<LocalAssemblers, TestRootLocalView, AnsatzRootLocalView> || ...)
132 {
133 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
134 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
135 if constexpr (Dune::Assembler::Concepts::BindableToLocalViews<LocalAssembler, TestRootLocalView, AnsatzRootLocalView>)
136 localAssembler.bindLocalViews(testLocalView, ansatzLocalView);
137 });
138 }
139
140 template<class TestRootLocalView, class AnsatzRootLocalView>
141 void bindOutsideLocalViews (const TestRootLocalView& testLocalView, const AnsatzRootLocalView& ansatzLocalView)
142 requires (Dune::Assembler::Concepts::BindableToOutsideLocalViews<LocalAssemblers, TestRootLocalView, AnsatzRootLocalView> || ...)
143 {
144 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
145 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
146 if constexpr (Dune::Assembler::Concepts::BindableToOutsideLocalViews<LocalAssembler, TestRootLocalView, AnsatzRootLocalView>)
147 localAssembler.bindOutsideLocalViews(testLocalView, ansatzLocalView);
148 });
149 }
150
151 template<class Element, class LocalMatrix>
152 void assembleElementMatrix (const Element& element, LocalMatrix& localMatrix)
153 requires (Impl::HasAssembleElementMatrix<LocalAssemblers, Element> || ...)
154 {
155 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
156 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
157 if constexpr (Impl::HasAssembleElementMatrix<LocalAssembler, Element>)
158 localAssembler.assembleElementMatrix(element, localMatrix);
159 });
160 }
161
162 template<class Element, class LocalPattern>
163 void assembleElementMatrixPattern(const Element& element, LocalPattern& localPattern)
164 requires (Impl::HasAssembleElementMatrix<LocalAssemblers, Element> || ...)
165 {
166 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
167 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
168 if constexpr (Impl::HasAssembleElementMatrix<LocalAssembler, Element>)
169 localAssembler.assembleElementMatrixPattern(element, localPattern);
170 });
171 }
172
173 template<class Intersection, class LocalMatrix>
174 void assembleBoundaryIntersectionMatrix(const Intersection& intersection, LocalMatrix& localMatrix)
175 requires (Impl::HasAssembleBoundaryIntersectionMatrix<LocalAssemblers, Intersection> || ...)
176 {
177 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
178 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
179 if constexpr (Impl::HasAssembleBoundaryIntersectionMatrix<LocalAssembler, Intersection>)
180 localAssembler.assembleBoundaryIntersectionMatrix(intersection, localMatrix);
181 });
182 }
183
184 template<class Intersection, class LocalPattern>
185 void assembleBoundaryIntersectionMatrixPattern(const Intersection& intersection, LocalPattern& localPattern)
186 requires (Impl::HasAssembleBoundaryIntersectionMatrix<LocalAssemblers, Intersection> || ...)
187 {
188 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
189 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
190 if constexpr (Impl::HasAssembleBoundaryIntersectionMatrix<LocalAssembler, Intersection>)
191 localAssembler.assembleBoundaryIntersectionMatrixPattern(intersection, localPattern);
192 });
193 }
194
195 template<class Intersection, class LocalMatrix>
196 void assembleInteriorIntersectionMatrix(const Intersection& intersection, LocalMatrix& localMatrix)
197 requires (Impl::HasAssembleInteriorIntersectionMatrix<LocalAssemblers, Intersection> || ...)
198 {
199 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
200 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
201 if constexpr (Impl::HasAssembleInteriorIntersectionMatrix<LocalAssembler, Intersection>)
202 localAssembler.assembleInteriorIntersectionMatrix(intersection, localMatrix);
203 });
204 }
205
206 template<class Intersection, class LocalPattern>
207 void assembleInteriorIntersectionMatrixPattern(const Intersection& intersection, LocalPattern& localPattern)
208 requires (Impl::HasAssembleInteriorIntersectionMatrix<LocalAssemblers, Intersection> || ...)
209 {
210 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
211 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
212 if constexpr (Impl::HasAssembleInteriorIntersectionMatrix<LocalAssembler, Intersection>)
213 localAssembler.assembleInteriorIntersectionMatrixPattern(intersection, localPattern);
214 });
215 }
216
217 // Dune::Assembler vector-assembler interface
218
219 template<class TestRootLocalView>
220 void bindLocalView (const TestRootLocalView& testLocalView)
221 requires (Dune::Assembler::Concepts::BindableToLocalView<LocalAssemblers, TestRootLocalView> || ...)
222 {
223 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
224 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
225 if constexpr (Dune::Assembler::Concepts::BindableToLocalView<LocalAssembler, TestRootLocalView>)
226 localAssembler.bindLocalView(testLocalView);
227 });
228 }
229
230 template<class AnsatzRootLocalView>
231 void bindOutsideLocalView (const AnsatzRootLocalView& ansatzLocalView)
232 requires (Dune::Assembler::Concepts::BindableToOutsideLocalView<LocalAssemblers, AnsatzRootLocalView> || ...)
233 {
234 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
235 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
236 if constexpr (Dune::Assembler::Concepts::BindableToOutsideLocalView<LocalAssembler, AnsatzRootLocalView>)
237 localAssembler.bindOutsideLocalView(ansatzLocalView);
238 });
239 }
240
241 template<class Element, class LocalVector>
242 void assembleElementVector (const Element& element, LocalVector& localVector)
243 requires (Impl::HasAssembleElementVector<LocalAssemblers, Element> || ...)
244 {
245 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
246 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
247 if constexpr (Impl::HasAssembleElementVector<LocalAssembler, Element>)
248 localAssembler.assembleElementVector(element, localVector);
249 });
250 }
251
252 template<class Intersection, class LocalVector>
253 void assembleBoundaryIntersectionVector(const Intersection& intersection, LocalVector& localVector)
254 requires (Impl::HasAssembleBoundaryIntersectionVector<LocalAssemblers, Intersection> || ...)
255 {
256 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
257 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
258 if constexpr (Impl::HasAssembleBoundaryIntersectionVector<LocalAssembler, Intersection>)
259 localAssembler.assembleBoundaryIntersectionVector(intersection, localVector);
260 });
261 }
262
263 template <class Intersection, class LocalVector>
264 void assembleInteriorIntersectionVector(const Intersection &intersection, LocalVector &localVector)
265 requires(Impl::HasAssembleInteriorIntersectionVector<LocalAssemblers, Intersection> || ...)
266 {
267 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
268 using LocalAssembler = std::decay_t<decltype(localAssembler)>;
269 if constexpr (Impl::HasAssembleInteriorIntersectionVector<LocalAssembler, Intersection>)
270 localAssembler.assembleInteriorIntersectionVector(intersection, localVector);
271 });
272 }
273
274 // Old Dune::Fufem matrix-assember interface
275
276 template<class TestLocalView, class AnsatzLocalView>
277 void preprocess(const TestLocalView& testLocalView, const AnsatzLocalView& ansatzLocalView)
278 {
279 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
280 if constexpr(Dune::Std::is_detected_v<LocalAssemblerBinaryPreprocess, std::decay_t<decltype(localAssembler)>, TestLocalView, AnsatzLocalView>)
281 localAssembler.preprocess(testLocalView, ansatzLocalView);
282 });
283 }
284
285 template<class LocalContext, class LocalMatrix, class TestLocalView, class AnsatzLocalView>
286 void operator()(const LocalContext& localContext, LocalMatrix& localMatrix, const TestLocalView& testSubspaceLocalView, const AnsatzLocalView& ansatzSubspaceLocalView)
287 {
288 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
289 localAssembler(localContext, localMatrix, testSubspaceLocalView, ansatzSubspaceLocalView);
290 });
291 }
292
293 // Old Dune::Fufem vector-assember interface
294
295 template<class TestLocalView>
296 void preprocess(const TestLocalView& testLocalView)
297 {
298 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
299 if constexpr(Dune::Std::is_detected_v<LocalAssemblerUnaryPreprocess, std::decay_t<decltype(localAssembler)>, TestLocalView>)
300 localAssembler.preprocess(testLocalView);
301 });
302 }
303
304 template<class LocalContext, class LocalVector, class TestLocalView>
305 void operator()(const LocalContext& localContext, LocalVector& localVector, const TestLocalView& testSubspaceLocalView)
306 {
307 Impl::forEachTupleEntry(localAssemblers_, [&](auto& localAssembler) {
308 localAssembler(localContext, localVector, testSubspaceLocalView);
309 });
310 }
311
312 const auto& assemblers() const
313 {
314 return localAssemblers_;
315 }
316
317 private:
318 std::tuple<LocalAssemblers...> localAssemblers_;
319 };
320
321 template<class... LocalAssemblers>
322 struct IsLocalAssembler<LocalSumAssembler<LocalAssemblers...>> : public std::true_type {};
323
324
325
326} // namespace Dune::Fufem::Forms
327
328
329
330namespace Dune::Fufem::Forms::Impl {
331
332
333
334 // ************************************************************
335 // Implementation of sum(l,r).
336 // ************************************************************
337
338 template<class L, class R,
340 auto sum(const L& l, const R& r)
341 {
342 return LocalSumAssembler(l, r);
343 }
344
345 template<class... L, class R,
347 auto sum(const LocalSumAssembler<L...>& l, const R& r)
348 {
349 return std::apply([&](const auto&... li) {
350 return LocalSumAssembler(li..., r);
351 }, l.assemblers());
352 }
353
354 template<class L, class... R,
356 auto sum(const L& l, const LocalSumAssembler<R...>& r)
357 {
358 return std::apply([&](const auto&... ri) {
359 return LocalSumAssembler(l, ri...);
360 }, r.assemblers());
361 }
362
363 template<class... L, class... R>
364 auto sum(const LocalSumAssembler<L...>& l, const LocalSumAssembler<R...>& r)
365 {
366 return std::apply([&](const auto&... li) {
367 return std::apply([&](const auto&... ri) {
368 return LocalSumAssembler(li..., ri...);
369 }, r.assemblers());
370 }, l.assemblers());
371 }
372
373
374
375} // Dune::Fufem::Forms::Impl
376
377
378
379namespace Dune::Fufem::Forms {
380
381
382
383 // If we activate this doxygen documentation, we do not see the other operator+.
384
385 /*
386 * \brief Create the sum of two local assemblers
387 *
388 * \ingroup FormsUserInterfaceArithmetic
389 */
390 template<class L, class R,
392 auto operator+ (const L& l, const R& r)
393 {
394 return Impl::sum(l, r);
395 }
396
397
398
399} // namespace Dune::Fufem::Forms
400
401
402#endif // DUNE_FUFEM_FORMS_LOCALSUMASSEMBLER_HH
Definition baseclass.hh:22
ALBERTA EL Element
Definition localsumassembler.hh:80
Sum of local assemblers obtained using Dune::Fufem::Forms::integrate(...)
Definition localsumassembler.hh:101
void assembleInteriorIntersectionMatrix(const Intersection &intersection, LocalMatrix &localMatrix)
Definition localsumassembler.hh:196
void bindOutsideLocalView(const AnsatzRootLocalView &ansatzLocalView)
Definition localsumassembler.hh:231
void assembleInteriorIntersectionVector(const Intersection &intersection, LocalVector &localVector)
Definition localsumassembler.hh:264
void bindLocalViews(const TestRootLocalView &testLocalView, const AnsatzRootLocalView &ansatzLocalView)
Definition localsumassembler.hh:130
void bindLocalView(const TestRootLocalView &testLocalView)
Definition localsumassembler.hh:220
void bindElement(const Element &element)
Definition localsumassembler.hh:120
void assembleElementVector(const Element &element, LocalVector &localVector)
Definition localsumassembler.hh:242
void assembleBoundaryIntersectionVector(const Intersection &intersection, LocalVector &localVector)
Definition localsumassembler.hh:253
void assembleBoundaryIntersectionMatrix(const Intersection &intersection, LocalMatrix &localMatrix)
Definition localsumassembler.hh:174
LocalSumAssembler(const LocalAssemblers &... localAssemblers)
Definition localsumassembler.hh:113
void assembleBoundaryIntersectionMatrixPattern(const Intersection &intersection, LocalPattern &localPattern)
Definition localsumassembler.hh:185
void preprocess(const TestLocalView &testLocalView)
Definition localsumassembler.hh:296
void operator()(const LocalContext &localContext, LocalMatrix &localMatrix, const TestLocalView &testSubspaceLocalView, const AnsatzLocalView &ansatzSubspaceLocalView)
Definition localsumassembler.hh:286
void assembleElementMatrix(const Element &element, LocalMatrix &localMatrix)
Definition localsumassembler.hh:152
void preprocess(const TestLocalView &testLocalView, const AnsatzLocalView &ansatzLocalView)
Definition localsumassembler.hh:277
void operator()(const LocalContext &localContext, LocalVector &localVector, const TestLocalView &testSubspaceLocalView)
Definition localsumassembler.hh:305
void assembleInteriorIntersectionMatrixPattern(const Intersection &intersection, LocalPattern &localPattern)
Definition localsumassembler.hh:207
void bindOutsideLocalViews(const TestRootLocalView &testLocalView, const AnsatzRootLocalView &ansatzLocalView)
Definition localsumassembler.hh:141
void assembleElementMatrixPattern(const Element &element, LocalPattern &localPattern)
Definition localsumassembler.hh:163
const auto & assemblers() const
Definition localsumassembler.hh:312
T apply(T... args)
T forward(T... args)