Peano
Loading...
Searching...
No Matches
Interpolation.cpp
Go to the documentation of this file.
1#include "Interpolation.h"
2
3#include <vector>
4
5#include "Enumeration.h"
6#include "peano4/utils/Loop.h"
13
14namespace {
15 [[maybe_unused]] tarch::logging::Log _log("toolbox::blockstructured");
16
17 tarch::multicore::BooleanSemaphore interpolationMapSemaphore;
18} // namespace
19
21 createPiecewiseConstantInterpolationMatrix(int numberOfDoFsPerAxisInPatch) {
22#if Dimensions == 2
23 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch;
24 const int numberOfPatches = 3 * 3;
25#else
26 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
27 * numberOfDoFsPerAxisInPatch;
28 const int numberOfPatches = 3 * 3 * 3;
29#endif
30
32 patchSize * numberOfPatches,
33 patchSize
34 );
35
36 int currentRow = 0;
37 dfor3(patchIndex) dfor(volumeIndex, numberOfDoFsPerAxisInPatch) {
39 sourceCell = (volumeIndex + patchIndex * numberOfDoFsPerAxisInPatch) / 3;
40 int sourceCellLinearised = peano4::utils::dLinearised(
41 sourceCell,
42 numberOfDoFsPerAxisInPatch
43 );
44 (*result)(currentRow, sourceCellLinearised) = 1.0;
45 currentRow++;
46 }
48
50 "createPiecewiseConstantInterpolationMatrix(int)",
51 "created new volumetric matrix for "
52 << numberOfDoFsPerAxisInPatch << ": " << result->toString()
53 );
54 return result;
55}
56
59 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
60 [[maybe_unused]] int normal,
61 [[maybe_unused]] int overlap
62 ) {
63 tarch::la::DynamicMatrix P1d(3, 1, {{1.0}, {1.0}, {1.0}});
64 P1d.replicateRows(3, numberOfDoFsPerAxisInPatch, 1, true);
65
67 P1d,
68 numberOfDoFsPerAxisInPatch,
69 normal
70 );
71}
72
75 const tarch::la::DynamicMatrix& P1d,
76 int numberOfDoFsPerAxisInPatch,
77 int normal
78 ) {
79 assertionEquals1(P1d.cols(), numberOfDoFsPerAxisInPatch, P1d.toString());
80 assertionEquals1(P1d.rows(), 3 * numberOfDoFsPerAxisInPatch, P1d.toString());
81
82#if Dimensions == 3
84#else
86#endif
87
88 int pattern = 0;
89 switch (normal) {
90 case 0:
91 pattern = 1;
92 break;
93 case 1:
94 pattern = numberOfDoFsPerAxisInPatch;
95 break;
96 case 2:
97 pattern = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch;
98 break;
99 }
100
101 P->insertEmptyColumns(pattern, pattern, pattern);
102 P->replicateRows(pattern, 2, pattern, false);
103 logDebug(
104 "createInterpolationMatrixFrom1dTemplateByInsertingZeroColsAndRows(...)",
105 "matrix for normal=" << normal << ": " << P->toString()
106 );
107 return P;
108}
109
112 const tarch::la::DynamicMatrix& P1d,
113 int numberOfDoFsPerAxisInPatch,
114 int normal
115 ) {
116 assertionEquals1(P1d.cols(), numberOfDoFsPerAxisInPatch, P1d.toString());
117 assertionEquals1(P1d.rows(), 3 * numberOfDoFsPerAxisInPatch, P1d.toString());
118
119#if Dimensions == 3
121#else
123#endif
124
125 int pattern = 0;
126 switch (normal) {
127 case 0:
128 pattern = 1;
129 break;
130 case 1:
131 pattern = numberOfDoFsPerAxisInPatch;
132 break;
133 case 2:
134 pattern = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch;
135 break;
136 }
137
138 P->scale(0.5);
139
140 // Split matrix into blocks of pattern columns and copy each block once.
141 // Matrix grows by factor of two which reflects the fact that the overlap
142 // is of size 1.
143 P->replicateCols(pattern, 2, 0, false);
144 P->replicateRows(pattern, 2, 0, false);
145 logDebug(
146 "createInterpolationMatrixFrom1dTemplateByLinearInterpolationAlongNormal(...)",
147 "matrix for normal=" << normal << ": " << P->toString()
148 );
149 return P;
150}
151
154 int numberOfDoFsPerAxisInPatch,
155 int normal,
156 bool extrapolateLinearly,
157 bool interpolateLinearlyBetweenRealAndRestrictedVolumes
158 ) {
160 3,
161 3,
162 {{1.0 / 3.0, 2.0 / 3.0, 0.0},
163 {0.0, 3.0 / 3.0, 0.0},
164 {0.0, 2.0 / 3.0, 1.0 / 3.0}}
165 );
166 P1d.replicateRows(3, numberOfDoFsPerAxisInPatch, 1, true);
167 P1d.removeColumn(0);
168 P1d.removeColumn(numberOfDoFsPerAxisInPatch);
169
170 if (extrapolateLinearly) {
171 P1d(0, 0) = 2.0 / 3.0 + 1.0 / 3.0 * 2.0;
172 P1d(0, 1) = -1.0 / 3.0;
173 P1d(
174 numberOfDoFsPerAxisInPatch * 3 - 1,
175 numberOfDoFsPerAxisInPatch - 1
176 ) = 2.0 / 3.0 + 1.0 / 3.0 * 2.0;
177 P1d(
178 numberOfDoFsPerAxisInPatch * 3 - 1,
179 numberOfDoFsPerAxisInPatch - 2
180 ) = -1.0 / 3.0;
181 } else {
182 P1d(0, 0) = 1.0;
183 P1d(0, 1) = 0.0;
184 P1d(
185 numberOfDoFsPerAxisInPatch * 3 - 1,
186 numberOfDoFsPerAxisInPatch - 1
187 ) = 1.0;
188 P1d(
189 numberOfDoFsPerAxisInPatch * 3 - 1,
190 numberOfDoFsPerAxisInPatch - 2
191 ) = 0.0;
192 }
193
194 logDebug(
195 "createLinearInterpolationMatrix(...)",
196 "1d matrix: " << P1d.toString()
197 );
198
199 if (interpolateLinearlyBetweenRealAndRestrictedVolumes) {
201 P1d,
202 numberOfDoFsPerAxisInPatch,
203 normal
204 );
205 } else {
207 P1d,
208 numberOfDoFsPerAxisInPatch,
209 normal
210 );
211 }
212}
213
216 int numberOfDoFsPerAxisInPatch,
217 bool extrapolateLinearly
218 ) {
220 "createLinearInterpolationMatrix(...)",
221 numberOfDoFsPerAxisInPatch
222 );
224 3,
225 3,
226 {{1.0 / 3.0, 2.0 / 3.0, 0.0},
227 {0.0, 3.0 / 3.0, 0.0},
228 {0.0, 2.0 / 3.0, 1.0 / 3.0}}
229 );
230 P1d.replicateRows(3, numberOfDoFsPerAxisInPatch, 1, true);
231 P1d.removeColumn(0);
232 P1d.removeColumn(numberOfDoFsPerAxisInPatch);
233
234 if (extrapolateLinearly) {
235 P1d(0, 0) = 2.0 / 3.0 + 1.0 / 3.0 * 2.0;
236 P1d(0, 1) = -1.0 / 3.0;
237 P1d(
238 numberOfDoFsPerAxisInPatch * 3 - 1,
239 numberOfDoFsPerAxisInPatch - 1
240 ) = 2.0 / 3.0 + 1.0 / 3.0 * 2.0;
241 P1d(
242 numberOfDoFsPerAxisInPatch * 3 - 1,
243 numberOfDoFsPerAxisInPatch - 2
244 ) = -1.0 / 3.0;
245 } else {
246 P1d(0, 0) = 1.0;
247 P1d(0, 1) = 0.0;
248 P1d(
249 numberOfDoFsPerAxisInPatch * 3 - 1,
250 numberOfDoFsPerAxisInPatch - 1
251 ) = 1.0;
252 P1d(
253 numberOfDoFsPerAxisInPatch * 3 - 1,
254 numberOfDoFsPerAxisInPatch - 2
255 ) = 0.0;
256 }
257
258 logDebug(
259 "createLinearInterpolationMatrix(...)",
260 "1d interpolation matrix: " << P1d.toString(true)
261 );
262
263 tarch::la::DynamicMatrix P2d(P1d, P1d, false);
264 logDebug(
265 "createLinearInterpolationMatrix(...)",
266 "2d interpolation matrix: " << P2d.toString(true)
267 );
268
269 logTraceOut("createLinearInterpolationMatrix(...)");
270#if Dimensions == 3
271 return new tarch::la::DynamicMatrix(P2d, P1d, false);
272#else
273 return new tarch::la::DynamicMatrix(P2d);
274#endif
275}
276
280 int numberOfDoFsPerAxisInPatch,
281 int overlap,
282 int unknowns,
283 const double* __restrict__ fineGridCellValuesLeft,
284 const double* __restrict__ fineGridCellValuesRight,
285 double* fineGridFaceValues
286 ) {
288 "projectInterpolatedFineCellsOnHaloLayer_AoS(...)",
289 marker.toString(),
290 numberOfDoFsPerAxisInPatch,
291 overlap
292 );
293
294 const int normal = marker.getSelectedFaceNumber() % Dimensions;
295
296 dfore(kFine, numberOfDoFsPerAxisInPatch, normal, 0) {
297 for (int iFine = 0; iFine < overlap; iFine++) {
298 tarch::la::Vector<Dimensions, int> fineVolumeLeftDest = kFine;
299 tarch::la::Vector<Dimensions, int> fineVolumeLeftSrc = kFine;
300
301 fineVolumeLeftDest(normal) = iFine;
302 fineVolumeLeftSrc(normal) = numberOfDoFsPerAxisInPatch - overlap + iFine;
303
304 tarch::la::Vector<Dimensions, int> fineVolumeRightDest = kFine;
305 tarch::la::Vector<Dimensions, int> fineVolumeRightSrc = kFine;
306
307 fineVolumeRightDest(normal) = iFine + overlap;
308 fineVolumeRightSrc(normal) = iFine;
309
310 int fineVolumeLeftDestLinearised = serialiseVoxelIndexInOverlap(
311 fineVolumeLeftDest,
312 numberOfDoFsPerAxisInPatch,
313 overlap,
314 normal
315 );
316 int fineVolumeRightDestLinearised = serialiseVoxelIndexInOverlap(
317 fineVolumeRightDest,
318 numberOfDoFsPerAxisInPatch,
319 overlap,
320 normal
321 );
322 int fineVolumeLeftSrcLinearised = peano4::utils::dLinearised(
323 fineVolumeLeftSrc,
324 numberOfDoFsPerAxisInPatch
325 );
326 int fineVolumeRightSrcLinearised = peano4::utils::dLinearised(
327 fineVolumeRightSrc,
328 numberOfDoFsPerAxisInPatch
329 );
330
331 for (int j = 0; j < unknowns; j++) {
332 fineGridFaceValues[fineVolumeLeftDestLinearised * unknowns + j]
333 = fineGridCellValuesLeft[fineVolumeLeftSrcLinearised * unknowns + j];
334 fineGridFaceValues[fineVolumeRightDestLinearised * unknowns + j]
335 = fineGridCellValuesRight
336 [fineVolumeRightSrcLinearised * unknowns + j];
337 }
338 }
339 }
340
341 logTraceOut("projectInterpolatedFineCellsOnHaloLayer_AoS(...)");
342}
343
344//
345// ==========================================
346// Piece-wise constant interpolation routines
347// ==========================================
348//
351 int numberOfDoFsPerAxisInPatch,
352 int overlap,
353 int unknowns,
354 const double* __restrict__ coarseGridFaceValues,
355 double* __restrict__ fineGridFaceValues
356) {
358 "interpolateHaloLayer_AoS_piecewise_constant(...)",
359 marker.toString(),
360 numberOfDoFsPerAxisInPatch,
361 overlap,
362 unknowns
363 );
364
365 const int normal = marker.getSelectedFaceNumber() % Dimensions;
366
367 static internal::FaceInterpolationMap faceInterpolationMap;
369 key(numberOfDoFsPerAxisInPatch, overlap, normal);
370
371 tarch::multicore::Lock lock(interpolationMapSemaphore);
372 if (faceInterpolationMap.count(key) == 0) {
373 faceInterpolationMap[key] = internal::
374 createPiecewiseConstantInterpolationMatrix(
375 numberOfDoFsPerAxisInPatch,
376 normal,
377 overlap
378 );
379 }
380 tarch::la::DynamicMatrix* P = faceInterpolationMap[key];
381 lock.free();
382
383#if Dimensions == 2
384 const int patchSize = numberOfDoFsPerAxisInPatch * 2 * overlap;
385#else
386 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
387 * 2 * overlap;
388#endif
389
390 logDebug(
391 "interpolateHaloLayer_AoS_piecewise_constant(...)",
392 marker.toString() << ": " << P->toString()
393 );
394
395 P->batchedMultiplyAoS(
396 fineGridFaceValues, // image
397 coarseGridFaceValues, // preimage
398 unknowns, // batch size, i.e. how often to apply it in one AoS rush
399 patchSize, // result size, i.e. size of image
401 marker.getRelativePositionWithinFatherCell(),
402 normal
403 ) * patchSize
404 );
405
406 logTraceOut("interpolateHaloLayer_AoS_piecewise_constant(...)");
407}
408
411 int numberOfDoFsPerAxisInPatch,
412 int overlap,
413 int unknowns,
414 const double* __restrict__ coarseGridCellValues,
415 const double* __restrict__ coarseGridFaceValues,
416 double* __restrict__ fineGridFaceValues
417) {
419 "interpolateHaloLayer_AoS_piecewise_constant(...)",
420 marker.toString(),
421 numberOfDoFsPerAxisInPatch,
422 overlap,
423 unknowns
424 );
425
426 if (marker.isInteriorFaceWithinPatch()) {
427#if Dimensions == 2
428 const int patchSize = numberOfDoFsPerAxisInPatch
429 * numberOfDoFsPerAxisInPatch;
430#else
431 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
432 * numberOfDoFsPerAxisInPatch;
433#endif
434
435 double* leftAdjacentPatchData = tarch::allocateMemory<double>(
436 patchSize * unknowns,
438 );
439 double* rightAdjacentPatchData = tarch::allocateMemory<double>(
440 patchSize * unknowns,
442 );
443
445 leftAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
447 rightAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
448 leftAdjacentPatchIndex(marker.getSelectedFaceNumber() % Dimensions)--;
449
450 internal::interpolateCell_AoS_piecewise_constant(
451 leftAdjacentPatchIndex,
452 numberOfDoFsPerAxisInPatch,
453 unknowns,
454 coarseGridCellValues,
455 leftAdjacentPatchData
456 );
457 internal::interpolateCell_AoS_piecewise_constant(
458 rightAdjacentPatchIndex,
459 numberOfDoFsPerAxisInPatch,
460 unknowns,
461 coarseGridCellValues,
462 rightAdjacentPatchData
463 );
464
465 internal::projectInterpolatedFineCellsOnHaloLayer_AoS(
466 marker,
467 numberOfDoFsPerAxisInPatch,
468 overlap,
469 unknowns,
470 leftAdjacentPatchData,
471 rightAdjacentPatchData,
472 fineGridFaceValues
473 );
474
475 tarch::freeMemory(leftAdjacentPatchData, tarch::MemoryLocation::Heap);
476 tarch::freeMemory(rightAdjacentPatchData, tarch::MemoryLocation::Heap);
477 } else {
479 marker,
480 numberOfDoFsPerAxisInPatch,
481 overlap,
482 unknowns,
483 coarseGridFaceValues,
484 fineGridFaceValues
485 );
486 }
487
488 logTraceOut("interpolateHaloLayer_AoS_piecewise_constant(...)");
489}
490
493 int numberOfDoFsPerAxisInPatch,
494 int unknowns,
495 const double* __restrict__ coarseGridCellValues,
496 double* __restrict__ fineGridCellValues
497) {
499 "interpolateCell_AoS_piecewise_constant(...)",
500 marker.toString(),
501 numberOfDoFsPerAxisInPatch,
502 unknowns
503 );
504
505 internal::interpolateCell_AoS_piecewise_constant(
506 marker.getRelativePositionWithinFatherCell(),
507 numberOfDoFsPerAxisInPatch,
508 unknowns,
509 coarseGridCellValues,
510 fineGridCellValues
511 );
512
513 logTraceOut("interpolateCell_AoS_piecewise_constant(...)");
514}
515
517 const tarch::la::Vector<Dimensions, int>& relativePositionWithinFatherCell,
518 int numberOfDoFsPerAxisInPatch,
519 int unknowns,
520 const double* __restrict__ coarseGridCellValues,
521 double* __restrict__ fineGridCellValues
522) {
523 static internal::CellInterpolationMap cellInterpolationMap;
524 internal::CellInterpolationOperatorKey key(numberOfDoFsPerAxisInPatch);
525
526 tarch::multicore::Lock lock(interpolationMapSemaphore);
527 if (cellInterpolationMap.count(key) == 0) {
528 cellInterpolationMap[key] = internal::
529 createPiecewiseConstantInterpolationMatrix(numberOfDoFsPerAxisInPatch);
530 }
531 tarch::la::DynamicMatrix* P = cellInterpolationMap[key];
532 lock.free();
533
534#if Dimensions == 2
535 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch;
536#else
537 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
538 * numberOfDoFsPerAxisInPatch;
539#endif
540
542 fineGridCellValues, // image
543 coarseGridCellValues, // preimage
544 unknowns, // batch size, i.e. how often to apply it in one AoS rush
545 patchSize, // result size, i.e. size of image
546 serialiseMarkerIn3x3PatchAssembly(
547 relativePositionWithinFatherCell,
548 numberOfDoFsPerAxisInPatch
549 )
550 );
551}
552
553//
554// =============================
555// Linear interpolation routines
556// =============================
557//
561 int numberOfDoFsPerAxisInPatch,
562 int overlap,
563 int unknowns,
564 const double* __restrict__ coarseGridFaceValues,
565 double* __restrict__ fineGridFaceValues
566 ) {
568 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation(...)",
569 marker.toString(),
570 numberOfDoFsPerAxisInPatch,
571 overlap,
572 unknowns
573 );
574
575 const int normal = marker.getSelectedFaceNumber() % Dimensions;
576
577 static internal::FaceInterpolationMap faceInterpolationMap;
579 key(numberOfDoFsPerAxisInPatch, overlap, normal);
580
581 assertionEquals(overlap, 1);
582
583 tarch::multicore::Lock lock(interpolationMapSemaphore);
584 if (faceInterpolationMap.count(key) == 0) {
585 faceInterpolationMap[key] = internal::createLinearInterpolationMatrix(
586 numberOfDoFsPerAxisInPatch,
587 normal,
588 false,
589 false
590 );
591 }
592 tarch::la::DynamicMatrix* P = faceInterpolationMap[key];
593 lock.free();
594
595#if Dimensions == 2
596 const int patchSize = numberOfDoFsPerAxisInPatch * 2 * overlap;
597#else
598 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
599 * 2 * overlap;
600#endif
601
602 logDebug(
603 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation(...)",
604 marker.toString() << ": " << P->toString()
605 );
606
607 P->batchedMultiplyAoS(
608 fineGridFaceValues, // image
609 coarseGridFaceValues, // preimage
610 unknowns, // batch size, i.e. how often to apply it in one AoS rush
611 patchSize, // result size, i.e. size of image
613 marker.getRelativePositionWithinFatherCell(),
614 normal
615 ) * patchSize
616 );
617
618 logTraceOut("interpolateHaloLayer_AoS_linear_with_constant_extrapolation(...)"
619 );
620}
621
625 int numberOfDoFsPerAxisInPatch,
626 int overlap,
627 int unknowns,
628 const double* __restrict__ coarseGridCellValues,
629 const double* __restrict__ coarseGridFaceValues,
630 double* __restrict__ fineGridFaceValues
631 ) {
633 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation(...)",
634 marker.toString(),
635 numberOfDoFsPerAxisInPatch,
636 overlap,
637 unknowns
638 );
639
640 if (marker.isInteriorFaceWithinPatch()) {
641#if Dimensions == 2
642 const int patchSize = numberOfDoFsPerAxisInPatch
643 * numberOfDoFsPerAxisInPatch;
644#else
645 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
646 * numberOfDoFsPerAxisInPatch;
647#endif
648
649 double* leftAdjacentPatchData = tarch::allocateMemory<double>(
650 patchSize * unknowns,
652 );
653 double* rightAdjacentPatchData = tarch::allocateMemory<double>(
654 patchSize * unknowns,
656 );
657
659 leftAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
661 rightAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
662 leftAdjacentPatchIndex(marker.getSelectedFaceNumber() % Dimensions)--;
663
664 internal::interpolateCell_AoS_linear(
665 leftAdjacentPatchIndex,
666 numberOfDoFsPerAxisInPatch,
667 unknowns,
668 coarseGridCellValues,
669 leftAdjacentPatchData,
670 false
671 );
672 internal::interpolateCell_AoS_linear(
673 rightAdjacentPatchIndex,
674 numberOfDoFsPerAxisInPatch,
675 unknowns,
676 coarseGridCellValues,
677 rightAdjacentPatchData,
678 false
679 );
680
681 internal::projectInterpolatedFineCellsOnHaloLayer_AoS(
682 marker,
683 numberOfDoFsPerAxisInPatch,
684 overlap,
685 unknowns,
686 leftAdjacentPatchData,
687 rightAdjacentPatchData,
688 fineGridFaceValues
689 );
690
691 tarch::freeMemory(leftAdjacentPatchData, tarch::MemoryLocation::Heap);
692 tarch::freeMemory(rightAdjacentPatchData, tarch::MemoryLocation::Heap);
693 } else {
695 marker,
696 numberOfDoFsPerAxisInPatch,
697 overlap,
698 unknowns,
699 coarseGridFaceValues,
700 fineGridFaceValues
701 );
702 }
703
704 logTraceOut("interpolateHaloLayer_AoS_linear_with_constant_extrapolation(...)"
705 );
706}
707
711 int numberOfDoFsPerAxisInPatch,
712 int unknowns,
713 const double* __restrict__ coarseGridCellValues,
714 double* __restrict__ fineGridCellValues
715 ) {
717 "interpolateCell_AoS_linear_with_constant_extrapolation(...)",
718 marker.toString(),
719 numberOfDoFsPerAxisInPatch,
720 unknowns
721 );
722
723 internal::interpolateCell_AoS_linear(
724 marker.getRelativePositionWithinFatherCell(),
725 numberOfDoFsPerAxisInPatch,
726 unknowns,
727 coarseGridCellValues,
728 fineGridCellValues,
729 false
730 );
731
732 logTraceOut("interpolateCell_AoS_linear_with_constant_extrapolation(...)");
733}
734
738 int numberOfDoFsPerAxisInPatch,
739 int overlap,
740 int unknowns,
741 const double* __restrict__ coarseGridFaceValues,
742 double* __restrict__ fineGridFaceValues
743 ) {
745 "interpolateHaloLayer_AoS_linear_with_linear_extrapolation(...)",
746 marker.toString(),
747 numberOfDoFsPerAxisInPatch,
748 overlap,
749 unknowns
750 );
751
752 const int normal = marker.getSelectedFaceNumber() % Dimensions;
753
754 static internal::FaceInterpolationMap faceInterpolationMap;
756 key(numberOfDoFsPerAxisInPatch, overlap, normal);
757
758 assertionEquals(overlap, 1);
759
760 tarch::multicore::Lock lock(interpolationMapSemaphore);
761 if (faceInterpolationMap.count(key) == 0) {
762 faceInterpolationMap[key] = internal::createLinearInterpolationMatrix(
763 numberOfDoFsPerAxisInPatch,
764 normal,
765 true,
766 false
767 );
768 }
769 tarch::la::DynamicMatrix* P = faceInterpolationMap[key];
770 lock.free();
771
772#if Dimensions == 2
773 const int patchSize = numberOfDoFsPerAxisInPatch * 2 * overlap;
774#else
775 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
776 * 2 * overlap;
777#endif
778
779 logDebug(
780 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation(...)",
781 marker.toString() << ": " << P->toString()
782 );
783
784 P->batchedMultiplyAoS(
785 fineGridFaceValues, // image
786 coarseGridFaceValues, // preimage
787 unknowns, // batch size, i.e. how often to apply it in one AoS rush
788 patchSize, // result size, i.e. size of image
790 marker.getRelativePositionWithinFatherCell(),
791 normal
792 ) * patchSize
793 );
794
795 logTraceOut("interpolateHaloLayer_AoS_linear_with_linear_extrapolation(...)");
796}
797
801 int numberOfDoFsPerAxisInPatch,
802 int overlap,
803 int unknowns,
804 const double* __restrict__ coarseGridCellValues,
805 const double* __restrict__ coarseGridFaceValues,
806 double* __restrict__ fineGridFaceValues
807 ) {
809 "interpolateHaloLayer_AoS_linear_with_linear_extrapolation(...)",
810 marker.toString(),
811 numberOfDoFsPerAxisInPatch,
812 overlap,
813 unknowns
814 );
815
816 if (marker.isInteriorFaceWithinPatch()) {
817#if Dimensions == 2
818 const int patchSize = numberOfDoFsPerAxisInPatch
819 * numberOfDoFsPerAxisInPatch;
820#else
821 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
822 * numberOfDoFsPerAxisInPatch;
823#endif
824
825 double* leftAdjacentPatchData = tarch::allocateMemory<double>(
826 patchSize * unknowns,
828 );
829 double* rightAdjacentPatchData = tarch::allocateMemory<double>(
830 patchSize * unknowns,
832 );
833
835 leftAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
837 rightAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
838 leftAdjacentPatchIndex(marker.getSelectedFaceNumber() % Dimensions)--;
839
840 internal::interpolateCell_AoS_linear(
841 leftAdjacentPatchIndex,
842 numberOfDoFsPerAxisInPatch,
843 unknowns,
844 coarseGridCellValues,
845 leftAdjacentPatchData,
846 true
847 );
848 internal::interpolateCell_AoS_linear(
849 rightAdjacentPatchIndex,
850 numberOfDoFsPerAxisInPatch,
851 unknowns,
852 coarseGridCellValues,
853 rightAdjacentPatchData,
854 true
855 );
856
857 internal::projectInterpolatedFineCellsOnHaloLayer_AoS(
858 marker,
859 numberOfDoFsPerAxisInPatch,
860 overlap,
861 unknowns,
862 leftAdjacentPatchData,
863 rightAdjacentPatchData,
864 fineGridFaceValues
865 );
866
867 tarch::freeMemory(leftAdjacentPatchData, tarch::MemoryLocation::Heap);
868 tarch::freeMemory(rightAdjacentPatchData, tarch::MemoryLocation::Heap);
869 } else {
871 marker,
872 numberOfDoFsPerAxisInPatch,
873 overlap,
874 unknowns,
875 coarseGridFaceValues,
876 fineGridFaceValues
877 );
878 }
879
880 logTraceOut("interpolateHaloLayer_AoS_linear_with_linear_extrapolation(...)");
881}
882
886 int numberOfDoFsPerAxisInPatch,
887 int unknowns,
888 const double* __restrict__ coarseGridCellValues,
889 double* __restrict__ fineGridCellValues
890 ) {
892 "interpolateCell_AoS_linear_with_linear_extrapolation(...)",
893 marker.toString(),
894 numberOfDoFsPerAxisInPatch,
895 unknowns
896 );
897
898 internal::interpolateCell_AoS_linear(
899 marker.getRelativePositionWithinFatherCell(),
900 numberOfDoFsPerAxisInPatch,
901 unknowns,
902 coarseGridCellValues,
903 fineGridCellValues,
904 true
905 );
906
907 logTraceOut("interpolateCell_AoS_linear_with_linear_extrapolation(...)");
908}
909
913 int numberOfDoFsPerAxisInPatch,
914 int overlap,
915 int unknowns,
916 const double* __restrict__ coarseGridFaceValues,
917 double* __restrict__ fineGridFaceValues
918 ) {
920 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)",
921 marker.toString(),
922 numberOfDoFsPerAxisInPatch,
923 overlap,
924 unknowns
925 );
926
927 const int normal = marker.getSelectedFaceNumber() % Dimensions;
928
929 static internal::FaceInterpolationMap faceInterpolationMap;
931 key(numberOfDoFsPerAxisInPatch, overlap, normal);
932
933 assertionEquals(overlap, 1);
934
935 tarch::multicore::Lock lock(interpolationMapSemaphore);
936 if (faceInterpolationMap.count(key) == 0) {
937 faceInterpolationMap[key] = internal::createLinearInterpolationMatrix(
938 numberOfDoFsPerAxisInPatch,
939 normal,
940 false,
941 true
942 );
943 }
944 tarch::la::DynamicMatrix* P = faceInterpolationMap[key];
945 lock.free();
946
947#if Dimensions == 2
948 const int patchSize = numberOfDoFsPerAxisInPatch * 2 * overlap;
949#else
950 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
951 * 2 * overlap;
952#endif
953
954 logDebug(
955 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)",
956 marker.toString() << ": " << P->toString()
957 );
958
959 P->batchedMultiplyAoS(
960 fineGridFaceValues, // image
961 coarseGridFaceValues, // preimage
962 unknowns, // batch size, i.e. how often to apply it in one AoS rush
963 patchSize, // result size, i.e. size of image
965 marker.getRelativePositionWithinFatherCell(),
966 normal
967 ) * patchSize
968 );
969
971 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)"
972 );
973}
974
978 int numberOfDoFsPerAxisInPatch,
979 int overlap,
980 int unknowns,
981 const double* __restrict__ coarseGridCellValues,
982 const double* __restrict__ coarseGridFaceValues,
983 double* __restrict__ fineGridFaceValues
984 ) {
986 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)",
987 marker.toString(),
988 numberOfDoFsPerAxisInPatch,
989 overlap,
990 unknowns
991 );
992
993 if (marker.isInteriorFaceWithinPatch()) {
994#if Dimensions == 2
995 const int patchSize = numberOfDoFsPerAxisInPatch
996 * numberOfDoFsPerAxisInPatch;
997#else
998 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
999 * numberOfDoFsPerAxisInPatch;
1000#endif
1001
1002 double* leftAdjacentPatchData = tarch::allocateMemory<double>(
1003 patchSize * unknowns,
1005 );
1006 double* rightAdjacentPatchData = tarch::allocateMemory<double>(
1007 patchSize * unknowns,
1009 );
1010
1012 leftAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
1014 rightAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
1015 leftAdjacentPatchIndex(marker.getSelectedFaceNumber() % Dimensions)--;
1016
1017 internal::interpolateCell_AoS_linear(
1018 leftAdjacentPatchIndex,
1019 numberOfDoFsPerAxisInPatch,
1020 unknowns,
1021 coarseGridCellValues,
1022 leftAdjacentPatchData,
1023 false
1024 );
1025 internal::interpolateCell_AoS_linear(
1026 rightAdjacentPatchIndex,
1027 numberOfDoFsPerAxisInPatch,
1028 unknowns,
1029 coarseGridCellValues,
1030 rightAdjacentPatchData,
1031 false
1032 );
1033
1034 internal::projectInterpolatedFineCellsOnHaloLayer_AoS(
1035 marker,
1036 numberOfDoFsPerAxisInPatch,
1037 overlap,
1038 unknowns,
1039 leftAdjacentPatchData,
1040 rightAdjacentPatchData,
1041 fineGridFaceValues
1042 );
1043
1044 tarch::freeMemory(leftAdjacentPatchData, tarch::MemoryLocation::Heap);
1045 tarch::freeMemory(rightAdjacentPatchData, tarch::MemoryLocation::Heap);
1046 } else {
1048 marker,
1049 numberOfDoFsPerAxisInPatch,
1050 overlap,
1051 unknowns,
1052 coarseGridFaceValues,
1053 fineGridFaceValues
1054 );
1055 }
1056
1058 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)"
1059 );
1060}
1061
1065 int numberOfDoFsPerAxisInPatch,
1066 int unknowns,
1067 const double* __restrict__ coarseGridCellValues,
1068 double* __restrict__ fineGridCellValues
1069 ) {
1071 "interpolateCell_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)",
1072 marker.toString(),
1073 numberOfDoFsPerAxisInPatch,
1074 unknowns
1075 );
1076
1077 internal::interpolateCell_AoS_linear(
1078 marker.getRelativePositionWithinFatherCell(),
1079 numberOfDoFsPerAxisInPatch,
1080 unknowns,
1081 coarseGridCellValues,
1082 fineGridCellValues,
1083 false
1084 );
1085
1087 "interpolateCell_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)"
1088 );
1089}
1090
1094 int numberOfDoFsPerAxisInPatch,
1095 int overlap,
1096 int unknowns,
1097 const double* __restrict__ coarseGridFaceValues,
1098 double* __restrict__ fineGridFaceValues
1099 ) {
1101 "interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(...)",
1102 marker.toString(),
1103 numberOfDoFsPerAxisInPatch,
1104 overlap,
1105 unknowns
1106 );
1107
1108 const int normal = marker.getSelectedFaceNumber() % Dimensions;
1109
1110 static internal::FaceInterpolationMap faceInterpolationMap;
1112 key(numberOfDoFsPerAxisInPatch, overlap, normal);
1113
1114 assertionEquals(overlap, 1);
1115
1116 tarch::multicore::Lock lock(interpolationMapSemaphore);
1117 if (faceInterpolationMap.count(key) == 0) {
1118 faceInterpolationMap[key] = internal::createLinearInterpolationMatrix(
1119 numberOfDoFsPerAxisInPatch,
1120 normal,
1121 true,
1122 true
1123 );
1124 }
1125 tarch::la::DynamicMatrix* P = faceInterpolationMap[key];
1126 lock.free();
1127
1128#if Dimensions == 2
1129 const int patchSize = numberOfDoFsPerAxisInPatch * 2 * overlap;
1130#else
1131 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
1132 * 2 * overlap;
1133#endif
1134
1135 logDebug(
1136 "interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(...)",
1137 marker.toString() << ": " << P->toString()
1138 );
1139
1140 P->batchedMultiplyAoS(
1141 fineGridFaceValues, // image
1142 coarseGridFaceValues, // preimage
1143 unknowns, // batch size, i.e. how often to apply it in one AoS rush
1144 patchSize, // result size, i.e. size of image
1146 marker.getRelativePositionWithinFatherCell(),
1147 normal
1148 ) * patchSize
1149 );
1150
1152 "interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(...)"
1153 );
1154}
1155
1159 int numberOfDoFsPerAxisInPatch,
1160 int overlap,
1161 int unknowns,
1162 const double* __restrict__ coarseGridCellValues,
1163 const double* __restrict__ coarseGridFaceValues,
1164 double* __restrict__ fineGridFaceValues
1165 ) {
1167 "interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(...)",
1168 marker.toString(),
1169 numberOfDoFsPerAxisInPatch,
1170 overlap,
1171 unknowns
1172 );
1173
1174 if (marker.isInteriorFaceWithinPatch()) {
1175#if Dimensions == 2
1176 const int patchSize = numberOfDoFsPerAxisInPatch
1177 * numberOfDoFsPerAxisInPatch;
1178#else
1179 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
1180 * numberOfDoFsPerAxisInPatch;
1181#endif
1182
1183 double* leftAdjacentPatchData = tarch::allocateMemory<double>(
1184 patchSize * unknowns,
1186 );
1187 double* rightAdjacentPatchData = tarch::allocateMemory<double>(
1188 patchSize * unknowns,
1190 );
1191
1193 leftAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
1195 rightAdjacentPatchIndex = marker.getRelativePositionWithinFatherCell();
1196 leftAdjacentPatchIndex(marker.getSelectedFaceNumber() % Dimensions)--;
1197
1198 internal::interpolateCell_AoS_linear(
1199 leftAdjacentPatchIndex,
1200 numberOfDoFsPerAxisInPatch,
1201 unknowns,
1202 coarseGridCellValues,
1203 leftAdjacentPatchData,
1204 true
1205 );
1206 internal::interpolateCell_AoS_linear(
1207 rightAdjacentPatchIndex,
1208 numberOfDoFsPerAxisInPatch,
1209 unknowns,
1210 coarseGridCellValues,
1211 rightAdjacentPatchData,
1212 true
1213 );
1214
1215 internal::projectInterpolatedFineCellsOnHaloLayer_AoS(
1216 marker,
1217 numberOfDoFsPerAxisInPatch,
1218 overlap,
1219 unknowns,
1220 leftAdjacentPatchData,
1221 rightAdjacentPatchData,
1222 fineGridFaceValues
1223 );
1224
1225 tarch::freeMemory(leftAdjacentPatchData, tarch::MemoryLocation::Heap);
1226 tarch::freeMemory(rightAdjacentPatchData, tarch::MemoryLocation::Heap);
1227 } else {
1229 marker,
1230 numberOfDoFsPerAxisInPatch,
1231 overlap,
1232 unknowns,
1233 coarseGridFaceValues,
1234 fineGridFaceValues
1235 );
1236 }
1237
1239 "interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(...)"
1240 );
1241}
1242
1243
1246 int numberOfDoFsPerAxisInSourcePatch,
1247 int numberOfDoFsPerAxisInDestinationPatch,
1248 int haloSourcePatch,
1249 int haloDestinationPatch,
1250 int unknowns,
1251 const double* __restrict__ sourceValues,
1252 double* __restrict__ destinationValues,
1253 ::peano4::utils::LoopPlacement parallelisation
1254 ) {
1255 assertion(
1256 numberOfDoFsPerAxisInDestinationPatch > numberOfDoFsPerAxisInSourcePatch
1257 );
1258
1259 simtDforWithSchedulerInstructions(
1260 destinationVolume,
1261 numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch,
1262 parallelisation
1263 ) const int baseIndexDestination
1265 destinationVolume,
1266 numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch
1267 )
1268 * unknowns;
1269 for (int unknown = 0; unknown < unknowns; unknown++) {
1270 destinationValues[baseIndexDestination + unknown] = 0.0;
1271 }
1272
1273 dfor(sourceVolume, numberOfDoFsPerAxisInSourcePatch + 2 * haloSourcePatch) {
1275 normalisedSourcePosition = tarch::la::multiplyComponents(
1276 tarch::la::
1277 Vector<Dimensions, double>(1.0 / numberOfDoFsPerAxisInSourcePatch),
1278 tarch::la::convertScalar<double>(sourceVolume
1279 ) + tarch::la::Vector<Dimensions, double>(0.5 - haloSourcePatch)
1280 );
1282 normalisedDestinationPosition = tarch::la::multiplyComponents(
1284 1.0 / numberOfDoFsPerAxisInDestinationPatch
1285 ),
1286 tarch::la::convertScalar<double>(destinationVolume
1287 ) + tarch::la::Vector<Dimensions, double>(0.5 - haloDestinationPatch)
1288 );
1289
1290 int outsidePatchAlongCoordinateAxis = 0;
1291 for (int d = 0; d < Dimensions; d++) {
1292 // outsidePatchAlongCoordinateAxis += ( sourceVolume(d) <
1293 // haloSourcePatch ) ? 1 : 0; outsidePatchAlongCoordinateAxis += (
1294 // sourceVolume(d) >=
1295 // haloSourcePatch+numberOfDoFsPerAxisInSourcePatch ) ? 1 : 0;
1296 if (sourceVolume(d) < haloSourcePatch)
1297 outsidePatchAlongCoordinateAxis++;
1298 if (sourceVolume(d) >= haloSourcePatch + numberOfDoFsPerAxisInSourcePatch)
1299 outsidePatchAlongCoordinateAxis++;
1300 }
1301 const bool isFromUnitialisedDiagonal = outsidePatchAlongCoordinateAxis > 1;
1302
1303 double weight = 1.0;
1304 for (int d = 0; d < Dimensions; d++) {
1305 double distanceAlongCoordinateAxis = std::abs(
1306 normalisedDestinationPosition(d) - normalisedSourcePosition(d)
1307 );
1308 double h = 1.0 / static_cast<double>(numberOfDoFsPerAxisInSourcePatch);
1309 distanceAlongCoordinateAxis = 1.0 - distanceAlongCoordinateAxis / h;
1310 weight *= std::max(0.0, distanceAlongCoordinateAxis);
1311 }
1312#if !defined(SharedSYCL)
1313 assertion(tarch::la::greaterEquals(weight, 0.0));
1314 assertion(tarch::la::smallerEquals(weight, 1.0));
1315#endif
1316
1317 tarch::la::Vector<Dimensions, int> amendedSourceVolume = sourceVolume;
1318 if (isFromUnitialisedDiagonal) {
1319#pragma unroll
1320 for (int d = 0; d < Dimensions; d++) {
1321 amendedSourceVolume(d
1322 ) = std::max(amendedSourceVolume(d), haloSourcePatch);
1323 amendedSourceVolume(d) = std::min(
1324 amendedSourceVolume(d),
1325 haloSourcePatch + numberOfDoFsPerAxisInSourcePatch - 1
1326 );
1327 }
1328 }
1329
1330 int baseIndexSource = peano4::utils::dLinearised(
1331 amendedSourceVolume,
1332 numberOfDoFsPerAxisInSourcePatch + 2 * haloSourcePatch
1333 )
1334 * unknowns;
1335 for (int unknown = 0; unknown < unknowns; unknown++) {
1336 destinationValues[baseIndexDestination + unknown]
1337 += weight * sourceValues[baseIndexSource + unknown];
1338 }
1339 }
1341}
1342
1343
1346 int numberOfDoFsPerAxisInSourcePatch,
1347 int numberOfDoFsPerAxisInDestinationPatch,
1348 int haloSourcePatch,
1349 int haloDestinationPatch,
1350 int unknowns,
1351 const double* __restrict__ interpolationData,
1352 const int* __restrict__ columnIndices,
1353 const int* __restrict__ rowIndices,
1354 const double* __restrict__ sourceValues,
1355 double* __restrict__ destinationValues,
1356 ::peano4::utils::LoopPlacement parallelisation
1357 ) {
1358 int destinationSize
1359 = (numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch)
1360 * (numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch)
1361 * (numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch);
1362
1363 for (int row = 0; row < destinationSize; row++) {
1364 for (int unknown = 0; unknown < unknowns; unknown++) {
1365 destinationValues[row * unknowns + unknown] = 0.0;
1366 }
1367 for (int column = rowIndices[row]; column < rowIndices[row + 1]; column++) {
1368 for (int unknown = 0; unknown < unknowns; unknown++) {
1369 destinationValues[row * unknowns + unknown]
1370 += interpolationData[column]
1371 * sourceValues[columnIndices[column] * unknowns + unknown];
1372 }
1373 }
1374 }
1375}
1376
1379 int numberOfDoFsPerAxisInSourcePatch,
1380 int numberOfDoFsPerAxisInDestinationPatch,
1381 int haloSourcePatch,
1382 int haloDestinationPatch,
1383 int unknowns,
1384 const double* __restrict__ sourceValues,
1385 double* __restrict__ destinationValues,
1386 ::peano4::utils::LoopPlacement parallelisation
1387 ) {
1388
1389 int indices[18];
1391 double* centerValues = new double[unknowns];
1392 int numberOfDerivatives = (Dimensions == 2) ? 5 : 9;
1393
1394 dfor(volume, numberOfDoFsPerAxisInSourcePatch + 2) {
1396 sourceVolume = volume
1397 + tarch::la::Vector<Dimensions, int>(haloSourcePatch - 1);
1398 int outsidePatchAlongCoordinateAxis = 0;
1399 for (int d = 0; d < Dimensions; d++) {
1400 if (sourceVolume(d) < haloSourcePatch || sourceVolume(d) >= numberOfDoFsPerAxisInSourcePatch + haloSourcePatch) {
1401 outsidePatchAlongCoordinateAxis++;
1402 }
1403 }
1404
1405 tarch::la::Vector<Dimensions, int> stencilOffset(0);
1406 for (int d = 0; d < Dimensions; d++) {
1407 if (sourceVolume(d) == 0)
1408 stencilOffset(d) = 1;
1409 if (sourceVolume(d) == numberOfDoFsPerAxisInSourcePatch + 2 * haloSourcePatch - 1)
1410 stencilOffset = -1;
1411 }
1412 for (int d1 = 0; d1 < Dimensions; d1++) {
1413 for (int d2 = d1 + 1; d2 < Dimensions; d2++) {
1414 if (sourceVolume(d1) == haloSourcePatch and sourceVolume(d2) == haloSourcePatch) {
1415 stencilOffset(d1) = 1;
1416 stencilOffset(d2) = 1;
1417 }
1418 if (sourceVolume(d1) == haloSourcePatch and sourceVolume(d2) == haloSourcePatch + numberOfDoFsPerAxisInSourcePatch - 1) {
1419 stencilOffset(d1) = 1;
1420 stencilOffset(d2) = -1;
1421 }
1422 if (sourceVolume(d1) == haloSourcePatch + numberOfDoFsPerAxisInSourcePatch - 1 and sourceVolume(d2) == haloSourcePatch) {
1423 stencilOffset(d1) = -1;
1424 stencilOffset(d2) = 1;
1425 }
1426 if (sourceVolume(d1) == haloSourcePatch + numberOfDoFsPerAxisInSourcePatch - 1 and sourceVolume(d2) == haloSourcePatch + numberOfDoFsPerAxisInSourcePatch - 1) {
1427 stencilOffset(d1) = -1;
1428 stencilOffset(d2) = -1;
1429 }
1430 }
1431 }
1432
1433 if (outsidePatchAlongCoordinateAxis <= 1) {
1434 int stencilSize = 0;
1435 dfor(offset, 3) {
1436 if (
1437 offset != tarch::la::Vector<Dimensions, int>(1) - stencilOffset and
1438#if Dimensions == 3
1439 !(offset(0) + stencilOffset(0) != 1
1440 and offset(1) + stencilOffset(1) != 1
1441 and offset(2) + stencilOffset(2) != 1)
1442#elif Dimensions == 2
1443 !(offset(0) + stencilOffset(0) != 1
1444 and offset(1) + stencilOffset(1) != 1)
1445#endif
1446 ) {
1447 stencil[stencilSize] = stencilOffset + offset
1449 indices[stencilSize] = peano4::utils::dLinearised(
1450 sourceVolume + offset + stencilOffset
1452 numberOfDoFsPerAxisInSourcePatch + 2 * haloSourcePatch
1453 );
1454 stencilSize++;
1455 }
1456 }
1457
1458 int centerIndex = peano4::utils::dLinearised(
1459 sourceVolume,
1460 numberOfDoFsPerAxisInSourcePatch + 2 * haloSourcePatch
1461 );
1462 for (int unknown = 0; unknown < unknowns; unknown++) {
1463 centerValues[unknown] = sourceValues[centerIndex * unknowns + unknown];
1464 }
1465
1466 tarch::la::DynamicMatrix deltas(stencilSize, unknowns);
1467 for (int k = 0; k < stencilSize; k++) {
1468 for (int unknown = 0; unknown < unknowns; unknown++) {
1469 deltas(
1470 k,
1471 unknown
1472 ) = sourceValues[indices[k] * unknowns + unknown]
1473 - centerValues[unknown];
1474 }
1475 }
1476 tarch::la::DynamicMatrix A(stencilSize, numberOfDerivatives);
1477 for (int row = 0; row < stencilSize; row++) {
1478 int column = 0;
1479 tarch::la::Vector<Dimensions, int>& cell = stencil[row];
1480 for (int a = 0; a < Dimensions; a++) {
1481 A(row, column) = cell(a);
1482 column++;
1483 }
1484 for (int a = 0; a < Dimensions; a++) {
1485 for (int b = a; b < Dimensions; b++) {
1486 A(row, column) = 0.5 * cell(a) * cell(b);
1487 column++;
1488 }
1489 }
1490 }
1491
1492 tarch::la::DynamicMatrix x(numberOfDerivatives, unknowns);
1493 if (A.rows() >= A.cols()){
1496
1498
1499 auto Q_T = tarch::la::transpose(Q);
1500 tarch::la::DynamicMatrix c = Q_T * deltas;
1501
1503 inverseR.multiplyBySmallMatrix(x.data(), c);
1504 } else{
1507
1509 tarch::la::modifiedGramSchmidt(ATranspose, Q, R);
1510
1512 tarch::la::DynamicMatrix c = inverseTransposeR * deltas;
1513
1514 Q.multiplyBySmallMatrix(x.data(), c);
1515 }
1516
1517 tarch::la::Vector<Dimensions, int> destinationCorner1
1518 = (sourceVolume - tarch::la::Vector<Dimensions, int>(haloSourcePatch)
1519 ) * numberOfDoFsPerAxisInDestinationPatch
1520 / numberOfDoFsPerAxisInSourcePatch
1521 + tarch::la::Vector<Dimensions, int>(haloDestinationPatch);
1522 tarch::la::Vector<Dimensions, int> destinationCorner2
1523 = (sourceVolume
1524 - tarch::la::Vector<Dimensions, int>(haloSourcePatch - 1)
1525 ) * numberOfDoFsPerAxisInDestinationPatch
1526 / numberOfDoFsPerAxisInSourcePatch
1527 + tarch::la::Vector<Dimensions, int>(haloDestinationPatch);
1528 for (int d = 0; d < Dimensions; d++) {
1529 destinationCorner1(d) = std::max(0, destinationCorner1(d));
1530 destinationCorner2(d) = std::min(
1531 numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch,
1532 destinationCorner2(d)
1533 );
1534 }
1535
1537 destinationSpan = destinationCorner2 - destinationCorner1;
1538 int destinationDimensionsProduct = 1;
1539 for (int d = 0; d < Dimensions; d++)
1540 destinationDimensionsProduct *= destinationSpan(d);
1541
1542 int row = 0;
1543 tarch::la::Vector<Dimensions, double> normalisedCornerPosition
1544 = (1.0 / numberOfDoFsPerAxisInDestinationPatch)
1545 * (tarch::la::convertScalar<double>(destinationCorner1) + tarch::la::Vector<Dimensions, double>(0.5 - haloDestinationPatch));
1546 tarch::la::Vector<Dimensions, double> normalisedSourcePosition
1547 = (1.0 / numberOfDoFsPerAxisInSourcePatch)
1548 * (tarch::la::convertScalar<double>(sourceVolume) + tarch::la::Vector<Dimensions, double>(0.5 - haloSourcePatch));
1550 cornerDisplacement = (normalisedCornerPosition
1551 - normalisedSourcePosition)
1552 * (double)numberOfDoFsPerAxisInSourcePatch;
1553
1554 double* matrixData = new double
1555 [destinationDimensionsProduct * numberOfDerivatives];
1556 int writeIndex = 0;
1557
1558 dfor(localDestinationVolume, destinationSpan) {
1560 displacement = cornerDisplacement
1561 + ((double)numberOfDoFsPerAxisInSourcePatch
1562 / numberOfDoFsPerAxisInDestinationPatch)
1564 double>(localDestinationVolume);
1565
1566 for (int a = 0; a < Dimensions; a++) {
1567 matrixData[writeIndex] = displacement(a);
1568 writeIndex++;
1569 }
1570 for (int a = 0; a < Dimensions; a++) {
1571 for (int b = a; b < Dimensions; b++) {
1572 matrixData[writeIndex] = 0.5 * displacement(a) * displacement(b);
1573 writeIndex++;
1574 }
1575 }
1576 }
1577
1578 tarch::la::DynamicMatrix destinationMatrix(
1579 destinationDimensionsProduct,
1580 numberOfDerivatives,
1581 matrixData
1582 );
1583 tarch::la::DynamicMatrix destinationValuesDelta = destinationMatrix * x;
1584
1585 int destinationVolumeNumber = 0;
1586 dfor(localDestinationVolume, destinationSpan) {
1588 destinationVolume = destinationCorner1 + localDestinationVolume;
1589 int destinationIndex = peano4::utils::dLinearised(
1590 destinationVolume,
1591 numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch
1592 );
1593 for (int unknown = 0; unknown < unknowns; unknown++) {
1594 destinationValues[destinationIndex * unknowns + unknown]
1595 = centerValues[unknown]
1596 + destinationValuesDelta(destinationVolumeNumber, unknown);
1597 }
1598 destinationVolumeNumber++;
1599 }
1600 }
1601 }
1602 delete[] centerValues;
1603}
1604
1607 int numberOfDoFsPerAxisInSourcePatch,
1608 int numberOfDoFsPerAxisInDestinationPatch,
1609 int haloSourcePatch,
1610 int haloDestinationPatch,
1611 int unknowns,
1612 const double* __restrict__ sourceValues,
1613 double* __restrict__ destinationValues,
1614 ::peano4::utils::LoopPlacement parallelisation
1615 ) {
1616 assertion(
1617 numberOfDoFsPerAxisInDestinationPatch > numberOfDoFsPerAxisInSourcePatch
1618 );
1619
1620 simtDforWithSchedulerInstructions(
1621 destinationVolume,
1622 numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch,
1623 parallelisation
1624 ) const int baseIndexDestination
1626 destinationVolume,
1627 numberOfDoFsPerAxisInDestinationPatch + 2 * haloDestinationPatch
1628 )
1629 * unknowns;
1630 for (int unknown = 0; unknown < unknowns; unknown++) {
1631 destinationValues[baseIndexDestination + unknown] = 0.0;
1632 }
1634}
1635
1636
1640 int numberOfDoFsPerAxisInPatch,
1641 int unknowns,
1642 const double* __restrict__ coarseGridCellValues,
1643 double* __restrict__ fineGridCellValues
1644 ) {
1646 "interpolateCell_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(...)",
1647 marker.toString(),
1648 numberOfDoFsPerAxisInPatch,
1649 unknowns
1650 );
1651
1652 internal::interpolateCell_AoS_linear(
1653 marker.getRelativePositionWithinFatherCell(),
1654 numberOfDoFsPerAxisInPatch,
1655 unknowns,
1656 coarseGridCellValues,
1657 fineGridCellValues,
1658 true
1659 );
1660
1662 "interpolateCell_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(...)"
1663 );
1664}
1665
1667 const tarch::la::Vector<Dimensions, int>& relativePositionWithinFatherCell,
1668 int numberOfDoFsPerAxisInPatch,
1669 int unknowns,
1670 const double* __restrict__ coarseGridCellValues,
1671 double* __restrict__ fineGridCellValues,
1672 bool extrapolateLinearly
1673) {
1674 static internal::CellInterpolationMap cellInterpolationMap;
1675 internal::CellInterpolationOperatorKey key(numberOfDoFsPerAxisInPatch);
1676
1677 tarch::multicore::Lock lock(interpolationMapSemaphore);
1678 if (cellInterpolationMap.count(key) == 0) {
1679 cellInterpolationMap[key] = internal::createLinearInterpolationMatrix(
1680 numberOfDoFsPerAxisInPatch,
1681 extrapolateLinearly
1682 );
1683 }
1684 tarch::la::DynamicMatrix* P = cellInterpolationMap[key];
1685 lock.free();
1686
1687#if Dimensions == 2
1688 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch;
1689#else
1690 const int patchSize = numberOfDoFsPerAxisInPatch * numberOfDoFsPerAxisInPatch
1691 * numberOfDoFsPerAxisInPatch;
1692#endif
1693
1695 fineGridCellValues, // image
1696 coarseGridCellValues, // preimage
1697 unknowns, // batch size, i.e. how often to apply it in one AoS rush
1698 patchSize, // result size, i.e. size of image
1699 serialiseMarkerIn3x3PatchAssembly(
1700 relativePositionWithinFatherCell,
1701 numberOfDoFsPerAxisInPatch
1702 )
1703 );
1704}
1705
1708 int numberOfDoFsPerAxisInPatch,
1709 int overlap,
1710 int unknowns,
1711 const double* __restrict__ coarseGridFaceValues,
1712 double* __restrict__ fineGridFaceValues
1713) {
1714 const int normal = marker.getSelectedFaceNumber() % Dimensions;
1715 const int i = (normal + 1) % Dimensions;
1716#if Dimensions == 3
1717 const int j = (normal + 2) % Dimensions;
1718#endif
1719
1721 coarseStart(i
1722 ) = marker.getRelativePositionWithinFatherCell()(i)
1723 * numberOfDoFsPerAxisInPatch / 3;
1724#if Dimensions == 3
1725 coarseStart(j
1726 ) = marker.getRelativePositionWithinFatherCell()(j)
1727 * numberOfDoFsPerAxisInPatch / 3;
1728#endif
1729
1731 coarseEnd(i
1732 ) = ((marker.getRelativePositionWithinFatherCell()(i) + 1
1733 ) * numberOfDoFsPerAxisInPatch
1734 + 2)
1735 / 3;
1736#if Dimensions == 3
1737 coarseEnd(j
1738 ) = ((marker.getRelativePositionWithinFatherCell()(j) + 1
1739 ) * numberOfDoFsPerAxisInPatch
1740 + 2)
1741 / 3;
1742#endif
1743
1744 tarch::la::Vector<Dimensions, int> fineDataStart(0);
1745 fineDataStart(i
1746 ) = (marker.getRelativePositionWithinFatherCell()(i)
1747 * numberOfDoFsPerAxisInPatch)
1748 % 3;
1749#if Dimensions == 3
1750 fineDataStart(j
1751 ) = (marker.getRelativePositionWithinFatherCell()(j)
1752 * numberOfDoFsPerAxisInPatch)
1753 % 3;
1754#endif
1755
1756 tarch::la::Vector<Dimensions, int> faceDimensions = coarseEnd - coarseStart;
1757 faceDimensions(normal) = (overlap - 1) / 3 + 1;
1758
1759 int indices[18];
1761 double* centerValues = new double[unknowns];
1762
1763 dfor(kCoarse, faceDimensions) {
1764 tarch::la::Vector<Dimensions, int> center = kCoarse + coarseStart;
1765 center(normal
1766 ) = (marker.getSelectedFaceNumber() < Dimensions)
1767 ? overlap - kCoarse(normal) - 1
1768 : overlap + kCoarse(normal);
1769 tarch::la::Vector<Dimensions, int> stencilOffset(0);
1770
1771 if (center(i) == 0)
1772 stencilOffset(i) = 1;
1773 if (center(i) == numberOfDoFsPerAxisInPatch - 1)
1774 stencilOffset(i) = -1;
1775#if Dimensions == 3
1776 if (center(j) == 0)
1777 stencilOffset(j) = 1;
1778 if (center(j) == numberOfDoFsPerAxisInPatch - 1)
1779 stencilOffset(j) = -1;
1780#endif
1781
1782 int stencilSize = 0;
1783 dfor(offset, 3) {
1784 if (
1785 offset != tarch::la::Vector<Dimensions, int>(1) - stencilOffset and
1786#if Dimensions == 3
1787 !(offset(0) + stencilOffset(0) != 1
1788 and offset(1) + stencilOffset(1) != 1
1789 and offset(2) + stencilOffset(2) != 1)
1790#elif Dimensions == 2
1791 !(offset(0) + stencilOffset(0) != 1
1792 and offset(1) + stencilOffset(1) != 1)
1793#endif
1794 ) {
1795 stencil[stencilSize] = stencilOffset + offset
1797 indices[stencilSize] = serialiseVoxelIndexInOverlap(
1798 center + offset + stencilOffset
1800 numberOfDoFsPerAxisInPatch,
1801 overlap,
1802 normal
1803 );
1804 stencilSize++;
1805 }
1806 }
1807
1809 center,
1810 numberOfDoFsPerAxisInPatch,
1811 overlap,
1812 normal
1813 );
1814 for (int unknown = 0; unknown < unknowns; unknown++) {
1815 centerValues[unknown] = coarseGridFaceValues[index * unknowns + unknown];
1816 }
1817
1818 tarch::la::DynamicMatrix deltas(stencilSize, unknowns);
1819 for (int k = 0; k < stencilSize; k++) {
1820 for (int unknown = 0; unknown < unknowns; unknown++) {
1821 deltas(
1822 k,
1823 unknown
1824 ) = coarseGridFaceValues[indices[k] * unknowns + unknown]
1825 - centerValues[unknown];
1826 }
1827 }
1828
1829 int numberOfDerivatives = (Dimensions == 2) ? 5 : 9;
1830 tarch::la::DynamicMatrix A(stencilSize, numberOfDerivatives);
1831 for (int row = 0; row < stencilSize; row++) {
1832 int column = 0;
1834 for (int a = 0; a < Dimensions; a++) {
1835 A(row, column) = cell(a);
1836 column++;
1837 }
1838 for (int a = 0; a < Dimensions; a++) {
1839 for (int b = a; b < Dimensions; b++) {
1840 A(row, column) = 0.5 * cell(a) * cell(b);
1841 column++;
1842 }
1843 }
1844 }
1845
1846 tarch::la::DynamicMatrix x(numberOfDerivatives, unknowns);
1847 if (A.rows() >= A.cols()){
1848 tarch::la::DynamicMatrix Q(A.rows(), A.cols());
1849 tarch::la::DynamicMatrix R(A.cols(), A.cols());
1850
1852
1853 auto Q_T = tarch::la::transpose(Q);
1854 tarch::la::DynamicMatrix c = Q_T * deltas;
1855
1857 inverseR.multiplyBySmallMatrix(x.data(), c);
1858 } else{
1859 tarch::la::DynamicMatrix Q(A.cols(), A.rows());
1860 tarch::la::DynamicMatrix R(A.rows(), A.rows());
1861
1863 tarch::la::modifiedGramSchmidt(ATranspose, Q, R);
1864
1866 tarch::la::DynamicMatrix c = inverseTransposeR * deltas;
1867
1868 Q.multiplyBySmallMatrix(x.data(), c);
1869 }
1870
1873
1874 if (kCoarse(i) == 0)
1875 fineStart(i
1876 ) = (marker.getRelativePositionWithinFatherCell()(i)
1877 * numberOfDoFsPerAxisInPatch)
1878 % 3;
1879#if Dimensions == 3
1880 if (kCoarse(j) == 0)
1881 fineStart(j
1882 ) = (marker.getRelativePositionWithinFatherCell()(j)
1883 * numberOfDoFsPerAxisInPatch)
1884 % 3;
1885#endif
1886
1887 int modulus = (marker.getRelativePositionWithinFatherCell()(i) + 1)
1888 * numberOfDoFsPerAxisInPatch;
1889 if (modulus % 3 != 0)
1890 modulus = modulus % 3;
1891 else
1892 modulus = 3;
1893 if (kCoarse(i) == faceDimensions(i) - 1)
1894 fineEnd(i) = modulus;
1895
1896#if Dimensions == 3
1897 modulus = (marker.getRelativePositionWithinFatherCell()(j) + 1)
1898 * numberOfDoFsPerAxisInPatch;
1899 if (modulus % 3 != 0)
1900 modulus = modulus % 3;
1901 else
1902 modulus = 3;
1903 if (kCoarse(j) == faceDimensions(j) - 1)
1904 fineEnd(j) = modulus;
1905#endif
1906
1907 tarch::la::Vector<Dimensions, int> fineDimensions = fineEnd - fineStart;
1908 fineDimensions(normal) = std::min(overlap - kCoarse(normal) * 3, 3);
1909 if (fineDimensions(normal) % 3 != 0)
1910 fineDimensions(normal) = fineDimensions(normal) % 3;
1911 else
1912 fineDimensions(normal) = 3;
1913#if Dimensions == 3
1914 int fineDimensionsProduct = fineDimensions(normal) * fineDimensions(i)
1915 * fineDimensions(j);
1916#elif Dimensions == 2
1917 int fineDimensionsProduct = fineDimensions(normal) * fineDimensions(i);
1918#endif
1920 fineMatrix(fineDimensionsProduct, numberOfDerivatives);
1921 int row = 0;
1922
1923 dfor(kFine, fineDimensions) {
1925 cell = fineStart + kFine - tarch::la::Vector<Dimensions, int>(1);
1926 int column = 0;
1927 for (int a = 0; a < Dimensions; a++) {
1928 fineMatrix(row, column) = (1.0 / 3.0) * cell(a);
1929 column++;
1930 }
1931 for (int a = 0; a < Dimensions; a++) {
1932 for (int b = a; b < Dimensions; b++) {
1933 fineMatrix(row, column) = (1.0 / 18.0) * cell(a) * cell(b);
1934 column++;
1935 }
1936 }
1937 row++;
1938 }
1939 tarch::la::DynamicMatrix fineValues = fineMatrix * x;
1940
1941 int fineCellNumber = 0;
1943 fineCorner = kCoarse * 3 + fineStart - fineDataStart;
1944 fineCorner(normal
1945 ) = (marker.getSelectedFaceNumber() < Dimensions)
1946 ? (kCoarse(normal) * 3)
1947 : overlap + (kCoarse(normal) * 3);
1948
1949 dfor(kFine, fineDimensions) {
1950 tarch::la::Vector<Dimensions, int> fineCell = kFine + fineCorner;
1952 fineCell,
1953 numberOfDoFsPerAxisInPatch,
1954 overlap,
1955 normal
1956 );
1957
1958 for (int unknown = 0; unknown < unknowns; unknown++) {
1959 fineGridFaceValues[index * unknowns + unknown]
1960 = centerValues[unknown] + fineValues(fineCellNumber, unknown);
1961 }
1962 fineCellNumber++;
1963 }
1964 }
1965
1966 delete[] centerValues;
1967
1968}
1969
1972 int numberOfDoFsPerAxisInPatch,
1973 int overlap,
1974 int unknowns,
1975 const double* __restrict__ coarseGridFaceValues,
1976 double* __restrict__ fineGridFaceValues
1977) {
1978 const int normal = marker.getSelectedFaceNumber() % Dimensions;
1979 const int i = (normal + 1) % Dimensions;
1980#if Dimensions == 3
1981 const int j = (normal + 2) % Dimensions;
1982#endif
1983
1985 coarseStart(i
1986 ) = marker.getRelativePositionWithinFatherCell()(i)
1987 * numberOfDoFsPerAxisInPatch / 3;
1988#if Dimensions == 3
1989 coarseStart(j
1990 ) = marker.getRelativePositionWithinFatherCell()(j)
1991 * numberOfDoFsPerAxisInPatch / 3;
1992#endif
1993
1995 coarseEnd(i
1996 ) = ((marker.getRelativePositionWithinFatherCell()(i) + 1
1997 ) * numberOfDoFsPerAxisInPatch
1998 + 2)
1999 / 3;
2000#if Dimensions == 3
2001 coarseEnd(j
2002 ) = ((marker.getRelativePositionWithinFatherCell()(j) + 1
2003 ) * numberOfDoFsPerAxisInPatch
2004 + 2)
2005 / 3;
2006#endif
2007
2008 tarch::la::Vector<Dimensions, int> fineDataStart(0);
2009 fineDataStart(i
2010 ) = (marker.getRelativePositionWithinFatherCell()(i)
2011 * numberOfDoFsPerAxisInPatch)
2012 % 3;
2013#if Dimensions == 3
2014 fineDataStart(j
2015 ) = (marker.getRelativePositionWithinFatherCell()(j)
2016 * numberOfDoFsPerAxisInPatch)
2017 % 3;
2018#endif
2019
2020 tarch::la::Vector<Dimensions, int> faceDimensions = coarseEnd - coarseStart;
2021 faceDimensions(normal) = (overlap - 1) / 3 + 1;
2022
2023 double* centerValues = new double[unknowns];
2024 int indices[32];
2026
2027
2028 dfor(kCoarse, faceDimensions) {
2029 tarch::la::Vector<Dimensions, int> center = kCoarse + coarseStart;
2030 center(normal
2031 ) = (marker.getSelectedFaceNumber() < Dimensions)
2032 ? overlap - kCoarse(normal) - 1
2033 : overlap + kCoarse(normal);
2034 tarch::la::Vector<Dimensions, int> stencilOffset(0);
2035
2036 if (center(i) == 0)
2037 stencilOffset(i) = 1;
2038 if (center(i) == numberOfDoFsPerAxisInPatch - 1)
2039 stencilOffset(i) = -1;
2040#if Dimensions == 3
2041 if (center(j) == 0)
2042 stencilOffset(j) = 1;
2043 if (center(j) == numberOfDoFsPerAxisInPatch - 1)
2044 stencilOffset(j) = -1;
2045#endif
2046
2047 int stencilSize = 0;
2048 dfor(offset, 3) {
2049 if (offset != tarch::la::Vector<Dimensions, int>(1) - stencilOffset) {
2050 stencil[stencilSize] = stencilOffset + offset
2052 indices[stencilSize] = serialiseVoxelIndexInOverlap(
2053 center + offset + stencilOffset
2055 numberOfDoFsPerAxisInPatch,
2056 overlap,
2057 normal
2058 );
2059 stencilSize++;
2060 }
2061 }
2062
2063 for (int axis = 0; axis < Dimensions; axis++) {
2064 if (center(axis) > 1) {
2066 offset(axis) = -2;
2067 stencil[stencilSize] = stencilOffset + offset;
2068 indices[stencilSize] = serialiseVoxelIndexInOverlap(
2069 center + stencilOffset + offset,
2070 numberOfDoFsPerAxisInPatch,
2071 overlap,
2072 normal
2073 );
2074 stencilSize++;
2075 }
2076 if (center(axis) < numberOfDoFsPerAxisInPatch - 2) {
2078 offset(axis) = 2;
2079 stencil[stencilSize] = stencilOffset + offset;
2080 indices[stencilSize] = serialiseVoxelIndexInOverlap(
2081 center + stencilOffset + offset,
2082 numberOfDoFsPerAxisInPatch,
2083 overlap,
2084 normal
2085 );
2086 stencilSize++;
2087 }
2088 }
2089
2091 center,
2092 numberOfDoFsPerAxisInPatch,
2093 overlap,
2094 normal
2095 );
2096 for (int unknown = 0; unknown < unknowns; unknown++) {
2097 centerValues[unknown] = coarseGridFaceValues[index * unknowns + unknown];
2098 }
2099 tarch::la::DynamicMatrix deltas(stencilSize, unknowns);
2100 for (int k = 0; k < stencilSize; k++) {
2101 for (int unknown = 0; unknown < unknowns; unknown++) {
2102 deltas(
2103 k,
2104 unknown
2105 ) = coarseGridFaceValues[indices[k] * unknowns + unknown]
2106 - centerValues[unknown];
2107 }
2108 }
2109
2110 int numberOfDerivatives = (Dimensions == 2) ? 9 : 19;
2111 tarch::la::DynamicMatrix A(stencilSize, numberOfDerivatives);
2112
2113 for (int row = 0; row < stencilSize; row++) {
2114 int column = 0;
2116 for (int a = 0; a < Dimensions; a++) {
2117 A(row, column) = cell(a);
2118 column++;
2119 }
2120 for (int a = 0; a < Dimensions; a++) {
2121 for (int b = a; b < Dimensions; b++) {
2122 A(row, column) = 0.5 * cell(a) * cell(b);
2123 column++;
2124 }
2125 }
2126 for (int a = 0; a < Dimensions; a++) {
2127 for (int b = a; b < Dimensions; b++) {
2128 for (int c = b; c < Dimensions; c++) {
2129 A(row, column) = (1.0 / 6.0) * cell(a) * cell(b) * cell(c);
2130 column++;
2131 }
2132 }
2133 }
2134 }
2135
2136 tarch::la::DynamicMatrix x(numberOfDerivatives, unknowns);
2137 if (A.rows() >= A.cols()){
2138 tarch::la::DynamicMatrix Q(A.rows(), A.cols());
2139 tarch::la::DynamicMatrix R(A.cols(), A.cols());
2140
2142
2143 auto Q_T = tarch::la::transpose(Q);
2144 tarch::la::DynamicMatrix c = Q_T * deltas;
2145
2147 inverseR.multiplyBySmallMatrix(x.data(), c);
2148 } else{
2149 tarch::la::DynamicMatrix Q(A.cols(), A.rows());
2150 tarch::la::DynamicMatrix R(A.rows(), A.rows());
2151
2153 tarch::la::modifiedGramSchmidt(ATranspose, Q, R);
2154
2156 tarch::la::DynamicMatrix c = inverseTransposeR * deltas;
2157 Q.multiplyBySmallMatrix(x.data(), c);
2158 }
2159
2162
2163 if (kCoarse(i) == 0)
2164 fineStart(i
2165 ) = (marker.getRelativePositionWithinFatherCell()(i)
2166 * numberOfDoFsPerAxisInPatch)
2167 % 3;
2168#if Dimensions == 3
2169 if (kCoarse(j) == 0)
2170 fineStart(j
2171 ) = (marker.getRelativePositionWithinFatherCell()(j)
2172 * numberOfDoFsPerAxisInPatch)
2173 % 3;
2174#endif
2175
2176 int modulus = (marker.getRelativePositionWithinFatherCell()(i) + 1)
2177 * numberOfDoFsPerAxisInPatch;
2178 if (modulus % 3 != 0)
2179 modulus = modulus % 3;
2180 else
2181 modulus = 3;
2182 if (kCoarse(i) == faceDimensions(i) - 1)
2183 fineEnd(i) = modulus;
2184
2185#if Dimensions == 3
2186 modulus = (marker.getRelativePositionWithinFatherCell()(j) + 1)
2187 * numberOfDoFsPerAxisInPatch;
2188 if (modulus % 3 != 0)
2189 modulus = modulus % 3;
2190 else
2191 modulus = 3;
2192 if (kCoarse(j) == faceDimensions(j) - 1)
2193 fineEnd(j) = modulus;
2194#endif
2195
2196 tarch::la::Vector<Dimensions, int> fineDimensions = fineEnd - fineStart;
2197 fineDimensions(normal) = std::min(overlap - kCoarse(normal) * 3, 3);
2198 if (fineDimensions(normal) % 3 != 0)
2199 fineDimensions(normal) = fineDimensions(normal) % 3;
2200 else
2201 fineDimensions(normal) = 3;
2202
2203#if Dimensions == 3
2204 int fineDimensionsProduct = fineDimensions(normal) * fineDimensions(i)
2205 * fineDimensions(j);
2206#elif Dimensions == 2
2207 int fineDimensionsProduct = fineDimensions(normal) * fineDimensions(i);
2208#endif
2209
2211 fineMatrix(fineDimensionsProduct, numberOfDerivatives);
2212 int row = 0;
2213
2214 dfor(kFine, fineDimensions) {
2216 cell = fineStart + kFine - tarch::la::Vector<Dimensions, int>(1);
2217 int column = 0;
2218 for (int a = 0; a < Dimensions; a++) {
2219 fineMatrix(row, column) = (1.0 / 3.0) * cell(a);
2220 column++;
2221 }
2222 for (int a = 0; a < Dimensions; a++) {
2223 for (int b = a; b < Dimensions; b++) {
2224 fineMatrix(row, column) = (1.0 / 18.0) * cell(a) * cell(b);
2225 column++;
2226 }
2227 }
2228 for (int a = 0; a < Dimensions; a++) {
2229 for (int b = a; b < Dimensions; b++) {
2230 for (int c = b; c < Dimensions; c++) {
2231 fineMatrix(
2232 row,
2233 column
2234 ) = (1.0 / 162.0) * cell(a) * cell(b) * cell(c);
2235 column++;
2236 }
2237 }
2238 }
2239 row++;
2240 }
2241 tarch::la::DynamicMatrix fineValues = fineMatrix * x;
2242
2243 int fineCellNumber = 0;
2245 fineCorner = kCoarse * 3 + fineStart - fineDataStart;
2246 fineCorner(normal
2247 ) = (marker.getSelectedFaceNumber() < Dimensions)
2248 ? (kCoarse(normal) * 3)
2249 : overlap + (kCoarse(normal) * 3);
2250
2251 dfor(kFine, fineDimensions) {
2252 tarch::la::Vector<Dimensions, int> fineCell = kFine + fineCorner;
2254 fineCell,
2255 numberOfDoFsPerAxisInPatch,
2256 overlap,
2257 normal
2258 );
2259
2260 for (int unknown = 0; unknown < unknowns; unknown++) {
2261 fineGridFaceValues[index * unknowns + unknown]
2262 = centerValues[unknown] + fineValues(fineCellNumber, unknown);
2263 }
2264 fineCellNumber++;
2265 }
2266 }
2267
2268 delete[] centerValues;
2269}
2270
2271
2274 int numberOfDoFsPerAxisInPatch,
2275 int overlap,
2276 int unknowns,
2277 const double* __restrict__ interpolationData,
2278 const int* __restrict__ columnIndices,
2279 const int* __restrict__ rowIndices,
2280 int dataStart,
2281 int rowIndicesStart,
2282 const double* __restrict__ coarseGridFaceValues,
2283 double* __restrict__ fineGridFaceValues
2284) {
2285 tarch::la::Vector<Dimensions, int> fineFaceDimensions(
2286 numberOfDoFsPerAxisInPatch
2287 );
2288 tarch::la::Vector<Dimensions, int> coarseFaceDimensions(
2289 numberOfDoFsPerAxisInPatch
2290 );
2291
2292 const int normal = marker.getSelectedFaceNumber() % Dimensions;
2293 const int matrixColumns = 2 * overlap
2294 * std::
2295 pow(numberOfDoFsPerAxisInPatch, Dimensions - 1);
2296 const int matrixRows = overlap
2297 * std::pow(numberOfDoFsPerAxisInPatch, Dimensions - 1);
2298
2299 fineFaceDimensions(normal) = overlap;
2300 coarseFaceDimensions(normal) = 2 * overlap;
2301
2302 double* rearrangedCoarseData = new double[matrixColumns * unknowns];
2303
2304 dfor(kCoarse, coarseFaceDimensions) {
2305 int currentIndex = serialiseVoxelIndexInOverlap(
2306 kCoarse,
2307 numberOfDoFsPerAxisInPatch,
2308 overlap,
2309 normal
2310 );
2311 int newIndex = (marker.getSelectedFaceNumber() >= Dimensions)
2312 ? kCoarse(normal)
2313 : 2 * overlap - kCoarse(normal) - 1;
2314 int base = overlap * 2;
2315 for (int d = 1; d < Dimensions; d++) {
2316 newIndex += kCoarse((normal + d) % Dimensions) * base;
2317 base *= numberOfDoFsPerAxisInPatch;
2318 }
2319 for (int unknown = 0; unknown < unknowns; unknown++) {
2320 rearrangedCoarseData[newIndex * unknowns + unknown] = coarseGridFaceValues
2321 [currentIndex * unknowns + unknown];
2322 }
2323 }
2324
2325 dfor(kFine, fineFaceDimensions) {
2326 auto fineCoords = kFine;
2327 fineCoords(normal) = (marker.getSelectedFaceNumber() < Dimensions)
2328 ? overlap - kFine(normal) - 1
2329 : overlap + kFine(normal);
2330
2331 int fineIndex = serialiseVoxelIndexInOverlap(
2332 fineCoords,
2333 numberOfDoFsPerAxisInPatch,
2334 overlap,
2335 normal
2336 );
2337
2338 int row = kFine(normal);
2339 int base = overlap;
2340 for (int d = 1; d < Dimensions; d++) {
2341 row += kFine((normal + d) % Dimensions) * base;
2342 base *= numberOfDoFsPerAxisInPatch;
2343 }
2344
2345 for (int unknown = 0; unknown < unknowns; unknown++) {
2346 fineGridFaceValues[fineIndex * unknowns + unknown] = 0.0;
2347 }
2348
2349 int columnStart = rowIndices[rowIndicesStart + row];
2350 int columnEnd = rowIndices[rowIndicesStart + row + 1];
2351
2352 for (int column = columnStart; column < columnEnd; column++) {
2353 for (int unknown = 0; unknown < unknowns; unknown++) {
2354 fineGridFaceValues[fineIndex * unknowns + unknown]
2355 += interpolationData[dataStart + column]
2356 * rearrangedCoarseData
2357 [(columnIndices[dataStart + column]) * unknowns + unknown];
2358 }
2359 }
2360 }
2361
2362 delete[] rearrangedCoarseData;
2363}
2364
2367 int numberOfDoFsPerAxisInPatch,
2368 int overlap,
2369 int unknowns,
2370 const double* __restrict__ normalInterpolationMatrix1d,
2371 const double* __restrict__ tangentialInterpolationMatrix1d,
2372 const double* __restrict__ coarseGridFaceValues,
2373 double* __restrict__ fineGridFaceValues
2374) {
2376 "interpolateHaloLayer_AoS_tensor_product(...)",
2377 marker.toString(),
2378 numberOfDoFsPerAxisInPatch,
2379 overlap
2380 );
2381
2382 const int normal = marker.getSelectedFaceNumber() % Dimensions;
2383
2384 dfore(kFine, numberOfDoFsPerAxisInPatch, normal, 0) {
2385 for (int iFine = 0; iFine < overlap; iFine++) {
2387 dest(normal
2388 ) = (marker.getSelectedFaceNumber() < Dimensions)
2389 ? iFine
2390 : 2 * overlap - iFine - 1;
2391
2392 int destLinearised = serialiseVoxelIndexInOverlap(
2393 dest,
2394 numberOfDoFsPerAxisInPatch,
2395 overlap,
2396 normal
2397 );
2398
2399 logDebug(
2400 "interpolateHaloLayer_AoS_tensor_product(...)",
2401 "clear dof " << dest
2402 );
2403 for (int unknown = 0; unknown < unknowns; unknown++) {
2404 fineGridFaceValues[destLinearised * unknowns + unknown] = 0.0;
2405 }
2406
2407 dfore(kCoarse, numberOfDoFsPerAxisInPatch, normal, 0) {
2408 for (int iCoarse = 0; iCoarse < 2 * overlap; iCoarse++) {
2410 src(normal
2411 ) = (marker.getSelectedFaceNumber() < Dimensions)
2412 ? iCoarse
2413 : 2 * overlap - iCoarse - 1;
2414 int srcLinearised = serialiseVoxelIndexInOverlap(
2415 src,
2416 numberOfDoFsPerAxisInPatch,
2417 overlap,
2418 normal
2419 );
2420
2421 double weight = 1.0;
2422 for (int d = 0; d < Dimensions; d++) {
2423 if (d == normal) {
2424 int col = iCoarse;
2425 int row = iFine;
2426
2427 assertion4(col >= 0, row, col, src, dest);
2428 assertion4(row >= 0, row, col, src, dest);
2429 int index = col + row * 2 * overlap;
2430 logDebug(
2431 "interpolateHaloLayer_AoS_tensor_product(...)",
2432 "(" << row << "," << col << ")=" << index
2433 << " (normal contribution)"
2434 );
2435 weight *= normalInterpolationMatrix1d[index];
2436 assertion(weight == weight);
2437 } else {
2438 int col = src(d);
2439 int row = dest(d)
2440 + marker.getRelativePositionWithinFatherCell()(d
2441 ) * numberOfDoFsPerAxisInPatch;
2442 assertion4(col >= 0, row, col, src, dest);
2443 assertion4(row >= 0, row, col, src, dest);
2444 int index = col + row * numberOfDoFsPerAxisInPatch;
2445 logDebug(
2446 "interpolateHaloLayer_AoS_tensor_product(...)",
2447 "(" << row << "," << col << ")=" << index
2448 << " (tangential contribution)"
2449 );
2450 weight *= tangentialInterpolationMatrix1d[index];
2451 assertion(weight == weight);
2452 }
2453 }
2454
2455 logDebug(
2456 "interpolateHaloLayer_AoS_tensor_product(...)",
2457 "add dof " << src << " to " << dest << " with weight " << weight
2458 );
2459
2460 for (int unknown = 0; unknown < unknowns; unknown++) {
2461 fineGridFaceValues[destLinearised * unknowns + unknown]
2462 += weight
2463 * coarseGridFaceValues[srcLinearised * unknowns + unknown];
2464 }
2465 }
2466 }
2467 }
2468 }
2469
2470 logTraceOut("interpolateHaloLayer_AoS_tensor_product(...)");
2471}
2472
2474 [[maybe_unused]] const peano4::datamanagement::FaceMarker& marker,
2475 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2476 [[maybe_unused]] int overlap,
2477 [[maybe_unused]] int unknowns,
2478 [[maybe_unused]] const double* __restrict__ normalInterpolationMatrix1d,
2479 [[maybe_unused]] const double* __restrict__ tangentialInterpolationMatrix1d,
2480 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2481 [[maybe_unused]] const double* __restrict__ coarseGridFaceValues,
2482 [[maybe_unused]] double* __restrict__ fineGridFaceValues
2483) {
2484 assertion(false);
2485}
2486
2488 [[maybe_unused]] const peano4::datamanagement::FaceMarker& marker,
2489 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2490 [[maybe_unused]] int overlap,
2491 [[maybe_unused]] int unknowns,
2492 [[maybe_unused]] const double* __restrict__ interpolationData,
2493 [[maybe_unused]] const int* __restrict__ columnIndices,
2494 [[maybe_unused]] const int* __restrict__ rowIndices,
2495 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2496 [[maybe_unused]] const double* __restrict__ coarseGridFaceValues,
2497 [[maybe_unused]] double* __restrict__ fineGridFaceValues
2498) {
2499 assertion(false);
2500}
2501
2503 [[maybe_unused]] const peano4::datamanagement::FaceMarker& marker,
2504 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2505 [[maybe_unused]] int overlap,
2506 [[maybe_unused]] int unknowns,
2507 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2508 [[maybe_unused]] const double* __restrict__ coarseGridFaceValues,
2509 [[maybe_unused]] double* __restrict__ fineGridFaceValues
2510) {
2511 assertion(false);
2512}
2513
2515 [[maybe_unused]] const peano4::datamanagement::FaceMarker& marker,
2516 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2517 [[maybe_unused]] int overlap,
2518 [[maybe_unused]] int unknowns,
2519 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2520 [[maybe_unused]] const double* __restrict__ coarseGridFaceValues,
2521 [[maybe_unused]] double* __restrict__ fineGridFaceValues
2522) {
2523 assertion(false);
2524}
2525
2527 [[maybe_unused]] const peano4::datamanagement::CellMarker& marker,
2528 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2529 [[maybe_unused]] int unknowns,
2530 [[maybe_unused]] const double* __restrict__ interpolationMatrix1d,
2531 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2532 [[maybe_unused]] double* __restrict__ fineGridCellValues
2533) {
2534 assertion(false);
2535}
2536
2538 [[maybe_unused]] const peano4::datamanagement::CellMarker& marker,
2539 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2540 [[maybe_unused]] int unknowns,
2541 [[maybe_unused]] const double* __restrict__ interpolationData,
2542 [[maybe_unused]] const int* __restrict__ columnIndices,
2543 [[maybe_unused]] const int* __restrict__ rowIndices,
2544 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2545 [[maybe_unused]] double* __restrict__ fineGridCellValues
2546) {
2547 assertion(false);
2548}
2549
2551 [[maybe_unused]] const peano4::datamanagement::CellMarker& marker,
2552 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2553 [[maybe_unused]] int unknowns,
2554 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2555 [[maybe_unused]] double* __restrict__ fineGridCellValues
2556) {
2557 assertion(false);
2558}
2559
2561 [[maybe_unused]] const peano4::datamanagement::CellMarker& marker,
2562 [[maybe_unused]] int numberOfDoFsPerAxisInPatch,
2563 [[maybe_unused]] int unknowns,
2564 [[maybe_unused]] const double* __restrict__ coarseGridCellValues,
2565 [[maybe_unused]] double* __restrict__ fineGridCellValues
2566) {
2567 assertion(false);
2568}
#define assertion4(expr, param0, param1, param2, param3)
#define assertionEquals1(lhs, rhs, a)
#define assertionEquals(lhs, rhs)
#define assertion(expr)
#define logDebug(methodName, logMacroMessageStream)
Definition Log.h:50
#define logTraceOut(methodName)
Definition Log.h:379
#define logTraceInWith4Arguments(methodName, argument0, argument1, argument2, argument3)
Definition Log.h:373
#define logTraceInWith3Arguments(methodName, argument0, argument1, argument2)
Definition Log.h:372
#define logTraceInWith1Argument(methodName, argument0)
Definition Log.h:370
#define dfor3(counter)
Shortcut For dfor(counter,3)
Definition Loop.h:647
#define dfore(counter, max, dim, value)
This is an exclusive d-dimensional for loop.
Definition Loop.h:942
#define dfor(counter, max)
d-dimensional Loop
Definition Loop.h:313
#define enddforx
I prefer to use this macro for dforx instead of a closing bracket as many syntax parser fail otherwis...
Definition Loop.h:933
tarch::logging::Log _log("::")
float P
Definition vec.h:7
My standard matrix is a matrix where the size is fixed at compile time.
void batchedMultiplyAoS(double *__restrict__ result, const double *__restrict__ x, int batchCount, int resultSize, int firstRow)
This operation assumes that x holds a whole batch of vectors in AoS format.
void multiplyBySmallMatrix(double *result, const DynamicMatrix &matrix) const
void replicateRows(int blockSize, int numberOfReplications, int shiftAfterEveryReplication, bool extendColumnsToAccommodateShifts)
Split the matrix into blocks of rows of size blockSize.
std::string toString(bool addLineBreaks=false) const
Log Device.
Definition Log.h:516
Create a lock around a boolean semaphore region.
Definition Lock.h:19
void free()
Free the lock.
Definition Lock.cpp:37
#define endSimtDfor
Definition Loop.h:181
const float const float const float struct part *restrict struct part *restrict const float a
Definition hydro_iact.h:55
list offset
Definition acoustic.py:42
j
Definition euler.py:99
index
Definition makeIC.py:38
LoopPlacement
Guide loop-level parallelism.
Definition Loop.h:65
CPUGPUMethod int dLinearised(const tarch::la::Vector< Dimensions, int > &counter, int max)
Map d-dimensional vector onto integer index.
Definition Loop.cpp:106
list stencil
Definition poisson.py:32
CF abs(const CF &cf)
b
Definition swe.py:86
My collection of tiny vector operations.
DynamicMatrix transpose(const DynamicMatrix &matrix)
bool greaterEquals(double lhs, double rhs, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
tarch::la::SmartPointerVector< Size, NewScalarType > convertScalar(const tarch::la::SmartPointerVector< Size, Scalar > &SmartPointerVector)
DynamicMatrix invertUpperTriangular(const DynamicMatrix &R)
void modifiedGramSchmidt(Matrix< Rows, Cols, Scalar > A, Matrix< Rows, Cols, Scalar > &Q, Matrix< Cols, Cols, Scalar > &R)
Produces an economy-size QR decomposition of a matrix A, A is changed.
bool smallerEquals(double lhs, double rhs, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
Matrix< Rows, Cols, Scalar > multiplyComponents(const Matrix< Rows, X, Scalar > &lhs, const Matrix< X, Cols, Scalar > &rhs)
Vector< Cols, Scalar > row(const Matrix< Rows, Cols, Scalar > &matrix, int whichRow)
Extract row from matrix.
void freeMemory(void *data, MemoryLocation location, int device=accelerator::Device::HostDevice)
Free memory.
@ Heap
Create data on the heap of the local device.
tarch::la::DynamicMatrix * createInterpolationMatrixFrom1dTemplateByInsertingZeroColsAndRows(const tarch::la::DynamicMatrix &P1d, int numberOfDoFsPerAxisInPatch, int normal)
This routine accepts a matrix as input.
void interpolateCell_AoS_linear(const tarch::la::Vector< Dimensions, int > &relativePositionWithinFatherCell, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ fineGridValues, double *coarseGridValues, bool extrapolateLinearly)
std::map< FaceInterpolationOperatorKey, tarch::la::DynamicMatrix * > FaceInterpolationMap
tarch::la::DynamicMatrix * createInterpolationMatrixFrom1dTemplateByLinearInterpolationAlongNormal(const tarch::la::DynamicMatrix &P1d, int numberOfDoFsPerAxisInPatch, int normal)
This is an extension of createInterpolationMatrixFrom1dTemplateByInsertingZeroColsAndRows().
void interpolateCell_AoS_piecewise_constant(const tarch::la::Vector< Dimensions, int > &relativePositionWithinFatherCell, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ fineGridValues, double *coarseGridValues)
void projectInterpolatedFineCellsOnHaloLayer_AoS(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ fineGridCellValuesLeft, const double *__restrict__ fineGridCellValuesRight, double *fineGridFaceValues)
This routine assumes that you have the whole patch data of hte left and right adjacent patch at hands...
tarch::la::DynamicMatrix * createPiecewiseConstantInterpolationMatrix(int numberOfDoFsPerAxisInPatch, int normal, int overlap)
Create piecewise constant interpolation matrix.
tarch::la::DynamicMatrix * createLinearInterpolationMatrix(int numberOfDoFsPerAxisInPatch, int normal, bool extrapolateLinearly, bool interpolateLinearlyAlongNormal)
The realisation relies on the following observations/follows these steps:
void interpolateHaloLayer_AoS_tensor_product(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
This is a wrapper around the toolbox routines.
void interpolateCell_AoS_matrix(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
int serialisePatchIndexInOverlap(const tarch::la::Vector< Dimensions, int > &patchIndex, int normal)
Patches along a face are basically organised as arrays, i.e.
void interpolateCellDataAssociatedToVolumesIntoOverlappingCell_linear(int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int haloSourcePatch, int haloDestinationPatch, int unknowns, const double *__restrict__ sourceValues, double *__restrict__ destinationValues, ::peano4::utils::LoopPlacement parallelisation)
void interpolateHaloLayer_AoS_matrix(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
void interpolateCell_AoS_linear_with_constant_extrapolation(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
void interpolateCell_AoS_piecewise_constant(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
This routine is called if we create a new cell (dynamic AMR)
void interpolateCell_AoS_linear_with_linear_extrapolation(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
void interpolateCellDataAssociatedToVolumesIntoOverlappingCell_secondOrder(int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int haloSourcePatch, int haloDestinationPatch, int unknowns, const double *__restrict__ sourceValues, double *__restrict__ destinationValues, ::peano4::utils::LoopPlacement parallelisation)
void interpolateCell_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
void interpolateHaloLayer_AoS_linear_with_constant_extrapolation(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
int serialiseVoxelIndexInOverlap(const tarch::la::Vector< Dimensions, int > &overlapCell, int numberOfDoFsPerAxisInPatch, int overlap, int normal)
The volumes or elements within an overlap are always enumerated lexicographically.
void interpolateHaloLayer_AoS_piecewise_constant(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
Take the coarse grid values and interpolate them onto the fine grid.
void interpolateCell_AoS_tensor_product(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
void interpolateHaloLayer_AoS_linear_with_linear_extrapolation_and_linear_normal_interpolation(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
void interpolateHaloLayer_AoS_third_order(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
void interpolateHaloLayer_AoS_linear_with_linear_extrapolation(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
void interpolateCellDataAssociatedToVolumesIntoOverlappingCell_fourthOrder(int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int haloSourcePatch, int haloDestinationPatch, int unknowns, const double *__restrict__ sourceValues, double *__restrict__ destinationValues, ::peano4::utils::LoopPlacement parallelisation)
void interpolateHaloLayer_AoS_second_order(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridCellValues, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
void interpolateHaloLayer_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(const peano4::datamanagement::FaceMarker &marker, int numberOfDoFsPerAxisInPatch, int overlap, int unknowns, const double *__restrict__ coarseGridFaceValues, double *__restrict__ fineGridFaceValues)
void interpolateCell_AoS_third_order(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
void interpolateCell_AoS_linear_with_constant_extrapolation_and_linear_normal_interpolation(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
void interpolateCellDataAssociatedToVolumesIntoOverlappingCell_matrix(int numberOfDoFsPerAxisInSourcePatch, int numberOfDoFsPerAxisInDestinationPatch, int haloSourcePatch, int haloDestinationPatch, int unknowns, const double *__restrict__ interpolationData, const int *__restrict__ columnIndices, const int *__restrict__ rowIndices, const double *__restrict__ sourceValues, double *__restrict__ destinationValues, ::peano4::utils::LoopPlacement parallelisation)
This interpolation should be used if a cell hosts two sets of unknowns.
void interpolateCell_AoS_second_order(const peano4::datamanagement::CellMarker &marker, int numberOfDoFsPerAxisInPatch, int unknowns, const double *__restrict__ coarseGridCellValues, double *__restrict__ fineGridCellValues)
Provide information about selected face.
Definition FaceMarker.h:35
Simple vector class.
Definition Vector.h:150