dune-assembler 2.12
Loading...
Searching...
No Matches
defaultglobalassembler.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
3
4#ifndef DUNE_ASSEMBLER_GLOBALASSEMBLER_HH
5#define DUNE_ASSEMBLER_GLOBALASSEMBLER_HH
6
11
15
17#include <dune/functions/functionspacebases/concepts.hh>
18
19#include <dune/grid/common/capabilities.hh>
21
23
24namespace Dune::Assembler {
25
26
41template <Concepts::GlobalBasis RowBasis, Concepts::GlobalBasis ColBasis = RowBasis, class Executor = SequentialExecutor>
43{
44 using RowLocalView = typename RowBasis::LocalView;
45 using ColLocalView = typename ColBasis::LocalView;
46
47 template <class LA>
48 static constexpr bool isLocalElementMatrixAssembler =
50
51 template <class LA>
52 static constexpr bool isLocalElementVectorAssembler =
54
55 template <class LA>
58
59 template <class LA>
62
63 template <class LA>
66
67 template <class LA>
70
71private:
72 const RowBasis& rowBasis_;
73 const ColBasis& colBasis_;
74 Executor executor_;
75
76public:
77
92 Assembler (const RowBasis& rowBasis, const ColBasis& colBasis, Executor executor)
93 : rowBasis_(rowBasis)
94 , colBasis_(colBasis)
95 , executor_(executor)
96 {
98 {
99 constexpr bool threadSafeViews =
102 static_assert(threadSafeViews, "Trying to use Assembler with parallel Executor, but grid view is not viewThreadSafe.");
103 }
104 }
105
116 Assembler (const RowBasis& rowBasis, const ColBasis& colBasis)
117 requires std::is_default_constructible_v<Executor>
119 {}
120
130 Assembler (const RowBasis& rowBasis)
131 requires std::same_as<RowBasis, ColBasis> && std::is_default_constructible_v<Executor>
133 {}
134
135 // ....
136 template <Concepts::LocalMatrixAssembler<RowLocalView,ColLocalView> LocalAssembler,
137 class Matrix>
139 {
140 executor_([&, la](auto context) mutable
141 {
142 auto localViews = LocalViewPair{rowBasis_, colBasis_};
143 la.bindLocalViews(get<0>(localViews), get<1>(localViews));
144
145 auto outsideLocalViews = LocalViewPair{rowBasis_, colBasis_};
147 la.bindOutsideLocalViews(get<0>(outsideLocalViews), get<1>(outsideLocalViews));
148
149 // local matrices for local assembling
150 using LocalMatrix = typename Matrix::LocalMatrix;
151 FlatArray<LocalMatrix,2,2> localMatrices{LocalMatrix(get<0>(localViews).maxSize(), get<1>(localViews).maxSize())};
152
153 using LocalPattern = typename Matrix::LocalPattern;
154 FlatArray<LocalPattern,2,2> localPattern{LocalPattern(get<0>(localViews).maxSize(), get<1>(localViews).maxSize())};
155
157 context.forEach(elements(rowBasis_.gridView()), [&](const auto& e)
158 {
159 const auto insideIndex = mapper.index(e);
160 localViews.bind(e);
161
162 // initialize the matrix to zero
163 localMatrices[0][0].resize(get<0>(localViews).size(), get<1>(localViews).size());
164 localPattern[0][0].resize(get<0>(localViews).size(), get<1>(localViews).size());
165 localMatrices[0][0] = 0;
166 localPattern[0][0].clear();
167
168 // Whenever any contribution was computed on this
169 // element, we need to scatter the local element data.
170 bool elementContributionsComputed = false;
171
172 const bool hasBoundaryIntersections = e.hasBoundaryIntersections();
173
174 // only bind to an element if necessary
175 if (isLocalElementMatrixAssembler<LocalAssembler> ||
176 isLocalInteriorIntersectionMatrixAssembler<LocalAssembler> || (isLocalBoundaryIntersectionMatrixAssembler<LocalAssembler> && hasBoundaryIntersections))
177 la.bindElement(e);
178
179 if constexpr (isLocalElementMatrixAssembler<LocalAssembler>)
180 {
181 la.assembleElementMatrix(e, localMatrices[0][0]);
182 la.assembleElementMatrixPattern(e, localPattern[0][0]);
183 elementContributionsComputed = true;
184 }
185
186 // Only assemble on inner or boundary intersections if the assembler
187 // supports this.
190 {
191 // We only need to traverse the intersections if the assembler
192 // supports interior intersections or if there are boundary intersections.
194 hasBoundaryIntersections)
195 {
196 for (auto const& is : intersections(rowBasis_.gridView(), e))
197 {
198 // the intersection is on a domain boundary
199 if (is.boundary() && !is.neighbor())
200 {
202 {
203 la.assembleBoundaryIntersectionMatrix(is, localMatrices[0][0]);
204 la.assembleBoundaryIntersectionMatrixPattern(is, localPattern[0][0]);
206 }
207 }
208
209 // the intersection is a regular inner boundary
210 if (!is.boundary() && is.neighbor())
211 {
213 {
214 const auto outsideIndex = mapper.index(is.outside());
215 // visit each intersection only once
217 {
218 outsideLocalViews.bind(is.outside());
219
220 // update the sizes of the local matrices and patterns
221 localMatrices[0][1].resize(get<0>(localViews).size(), get<1>(outsideLocalViews).size());
222 localMatrices[1][0].resize(get<0>(outsideLocalViews).size(), get<1>(localViews).size());
223 localMatrices[1][1].resize(get<0>(outsideLocalViews).size(), get<1>(outsideLocalViews).size());
224 localPattern[0][1].resize(get<0>(localViews).size(), get<1>(outsideLocalViews).size());
225 localPattern[1][0].resize(get<0>(outsideLocalViews).size(), get<1>(localViews).size());
226 localPattern[1][1].resize(get<0>(outsideLocalViews).size(), get<1>(outsideLocalViews).size());
227
228 // initialize the coupling matrices to zero
229 localMatrices[0][1] = 0;
230 localMatrices[1][0] = 0;
231 localMatrices[1][1] = 0;
232 localPattern[0][1].clear();
233 localPattern[1][0].clear();
234 localPattern[1][1].clear();
235
236 la.assembleInteriorIntersectionMatrix(is, localMatrices);
237 la.assembleInteriorIntersectionMatrixPattern(is, localPattern);
239
240 matrix.scatter(get<0>(localViews),get<1>(outsideLocalViews), localMatrices[0][1], localPattern[0][1]);
241 matrix.scatter(get<0>(outsideLocalViews),get<1>(localViews), localMatrices[1][0], localPattern[1][0]);
243 }
244 }
245 }
246 }
247 }
248 }
250 matrix.scatter(get<0>(localViews),get<1>(localViews), localMatrices[0][0], localPattern[0][0]);
251 });
252 });
253 }
254
255 template <Concepts::LocalMatrixAssembler<RowLocalView,ColLocalView> LocalAssembler,
256 class MatrixPattern>
258 {
259 executor_([&, la](auto context) mutable
260 {
261 auto localViews = LocalViewPair{rowBasis_, colBasis_};
262 la.bindLocalViews(get<0>(localViews), get<1>(localViews));
263
264 auto outsideLocalViews = LocalViewPair{rowBasis_, colBasis_};
266 la.bindOutsideLocalViews(get<0>(outsideLocalViews), get<1>(outsideLocalViews));
267
268 using LocalPattern = typename MatrixPattern::LocalPattern;
269 FlatArray<LocalPattern,2,2> localPattern{LocalPattern(get<0>(localViews).maxSize(), get<1>(localViews).maxSize())};
270
272 context.forEach(elements(rowBasis_.gridView()), [&](const auto& e)
273 {
274 const auto insideIndex = mapper.index(e);
275 localViews.bind(e);
276
277 localPattern[0][0].resize(get<0>(localViews).size(), get<1>(localViews).size());
278 localPattern[0][0].clear();
279
280 // Whenever any contribution was computed on this
281 // element, we need to scatter the local element data.
282 bool elementContributionsComputed = false;
283
284 const bool hasBoundaryIntersections = e.hasBoundaryIntersections();
285
286 // only bind to an element if necessary
287 if (isLocalElementMatrixAssembler<LocalAssembler> ||
288 isLocalInteriorIntersectionMatrixAssembler<LocalAssembler> || (isLocalBoundaryIntersectionMatrixAssembler<LocalAssembler> && hasBoundaryIntersections))
289 la.bindElement(e);
290
291 if constexpr (isLocalElementMatrixAssembler<LocalAssembler>)
292 {
293 la.assembleElementMatrixPattern(e, localPattern[0][0]);
294 elementContributionsComputed = true;
295 }
296
297 // Only assemble on inner or boundary intersections if the assembler
298 // supports this.
301 {
302 // We only need to traverse the intersections if the assembler
303 // supports interior intersections or if there are boundary intersections.
305 hasBoundaryIntersections)
306 {
307 for (auto const& is : intersections(rowBasis_.gridView(), e))
308 {
309 // the intersection is on a domain boundary
310 if (is.boundary() && !is.neighbor())
311 {
313 {
314 la.assembleBoundaryIntersectionMatrixPattern(is, localPattern[0][0]);
316 }
317 }
318
319 // the intersection is a regular inner boundary
320 if (!is.boundary() && is.neighbor())
321 {
323 {
324 const auto outsideIndex = mapper.index(is.outside());
325 // visit each intersection only once
327 {
328 outsideLocalViews.bind(is.outside());
329
330 localPattern[0][1].resize(get<0>(localViews).size(), get<1>(outsideLocalViews).size());
331 localPattern[1][0].resize(get<0>(outsideLocalViews).size(), get<1>(localViews).size());
332 localPattern[1][1].resize(get<0>(outsideLocalViews).size(), get<1>(outsideLocalViews).size());
333
334 localPattern[0][1].clear();
335 localPattern[1][0].clear();
336 localPattern[1][1].clear();
337
338 la.assembleInteriorIntersectionMatrixPattern(is, localPattern);
340
344 }
345 }
346 }
347 }
348 }
349 }
352 });
353 });
354 }
355
356 template <Concepts::LocalVectorAssembler<typename RowBasis::LocalView> LocalAssembler, class Vector>
358 {
359 executor_([&, la](auto context) mutable
360 {
361 auto localView = rowBasis_.localView();
362 la.bindLocalView(localView);
363
364 auto outsideLocalView = rowBasis_.localView();
366 la.bindOutsideLocalView(outsideLocalView);
367
368 // local vectors for local assembling
369 using LocalVector = typename Vector::LocalVector;
370 std::array<LocalVector,2> localVectors{LocalVector(localView.maxSize())};
371
373 context.forEach(elements(rowBasis_.gridView()), [&](const auto& e)
374 {
375 const auto insideIndex = mapper.index(e);
376 localView.bind(e);
377
378 // initialize the matrix to zero
379 localVectors[0].resize(localView.size());
380 localVectors[0] = 0;
381
382 // Whenever any contribution was computed on this
383 // element, we need to scatter the local element data.
384 bool elementContributionsComputed = false;
385
386 const bool hasBoundaryIntersections = e.hasBoundaryIntersections();
387
388 // only bind to an element if necessary
389 if (isLocalElementVectorAssembler<LocalAssembler> ||
390 isLocalInteriorIntersectionVectorAssembler<LocalAssembler> || (isLocalBoundaryIntersectionVectorAssembler<LocalAssembler> && hasBoundaryIntersections))
391 la.bindElement(e);
392
393 if constexpr (isLocalElementVectorAssembler<LocalAssembler>)
394 {
395 la.assembleElementVector(e, localVectors[0]);
396 elementContributionsComputed = true;
397 }
398
399 // Only assemble on inner or boundary intersections if the assembler
400 // supports this.
403 {
404 // We only need to traverse the intersections if the assembler
405 // supports interior intersections or if there are boundary intersections.
407 hasBoundaryIntersections)
408 {
409 for (auto const& is : intersections(rowBasis_.gridView(), e))
410 {
411 // the intersection is on a domain boundary
412 if (is.boundary() && !is.neighbor())
413 {
415 {
416 la.assembleBoundaryIntersectionVector(is, localVectors[0]);
418 }
419 }
420
421 // the intersection is a regular inner boundary
422 if (!is.boundary() && is.neighbor())
423 {
425 {
426 const auto outsideIndex = mapper.index(is.outside());
427 // visit each intersection only once
429 {
430 outsideLocalView.bind(is.outside());
431
432 // initialize the coupling matrices to zero
433 localVectors[1].resize(outsideLocalView.size());
434 localVectors[1] = 0;
435
436 la.assembleInteriorIntersectionVector(is, localVectors);
438
439 vector.scatter(outsideLocalView, localVectors[1]);
440 }
441 }
442 }
443 }
444 }
445 }
447 vector.scatter(localView, localVectors[0]);
448 });
449 });
450 }
451
452};
453
454
455
456} // end namespace Dune::Assembler
457
458#endif // DUNE_ASSEMBLER_GLOBALASSEMBLER_HH
Definition localboundaryintersectionmatrixassembler.hh:9
MCMGLayout mcmgElementLayout()
A global assembler for assembling matrices and vectors.
Definition defaultglobalassembler.hh:43
Assembler(const RowBasis &rowBasis, const ColBasis &colBasis)
Construct global assembler.
Definition defaultglobalassembler.hh:116
static constexpr bool isLocalInteriorIntersectionVectorAssembler
Definition defaultglobalassembler.hh:60
void assembleVectorEntries(LocalAssembler &la, Vector &vector)
Definition defaultglobalassembler.hh:357
Assembler(const RowBasis &rowBasis)
Construct global assembler.
Definition defaultglobalassembler.hh:130
typename ColBasis::LocalView ColLocalView
Definition defaultglobalassembler.hh:45
typename RowBasis::LocalView RowLocalView
Definition defaultglobalassembler.hh:44
static constexpr bool isLocalInteriorIntersectionMatrixAssembler
Definition defaultglobalassembler.hh:56
static constexpr bool isLocalBoundaryIntersectionVectorAssembler
Definition defaultglobalassembler.hh:68
Assembler(const RowBasis &rowBasis, const ColBasis &colBasis, Executor executor)
Construct global assembler.
Definition defaultglobalassembler.hh:92
static constexpr bool isLocalElementMatrixAssembler
Definition defaultglobalassembler.hh:48
void assembleMatrixPattern(LocalAssembler &la, MatrixPattern &matrixPattern)
Definition defaultglobalassembler.hh:257
static constexpr bool isLocalElementVectorAssembler
Definition defaultglobalassembler.hh:52
void assembleMatrixEntries(LocalAssembler &la, Matrix &matrix)
Definition defaultglobalassembler.hh:138
static constexpr bool isLocalBoundaryIntersectionMatrixAssembler
Definition defaultglobalassembler.hh:64
A pair of local views constructed from a pair of global bases.
Definition localviewpair.hh:24