Peano
Loading...
Searching...
No Matches
SBH.py
Go to the documentation of this file.
1# This file is part of the Peano project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import os
4import argparse
5
6import peano4
7import exahype2
8import dastgen2
9
11import numpy as np
12
13import jinja2
14
15
17
18from enum import Enum
19
20# See comments in README.dox
21# export PYTHONPATH=../../../../python
22# export PYTHONPATH=$PYTHONPATH:../../../../applications/exahype2/ccz4
23from CCZ4Solver import CCZ4Solver_FV_GlobalAdaptiveTimeStepWithEnclaveTasking
24from CCZ4Solver import CCZ4Solver_FD4_GlobalAdaptiveTimeStepWithEnclaveTasking
25from CCZ4Solver import (
26 CCZ4Solver_FD4_SecondOrderFormulation_GlobalAdaptiveTimeStepWithEnclaveTasking,
27)
28
29from CCZ4Solver import CCZ4Solver_FV_GlobalAdaptiveTimeStep
30from CCZ4Solver import CCZ4Solver_FD4_GlobalAdaptiveTimeStep
31
32
33# for the coupling
34from exahype2.solvers.fv.actionsets.AbstractFVActionSet import AbstractFVActionSet
35
36BlackHoleRegion = 0.1
37
38
40 NONE = "::peano4::utils::LoopPlacement::Serial"
41 PARALLEL_FOR = "::peano4::utils::LoopPlacement::Nested"
42 SUBTASKS = "::peano4::utils::LoopPlacement::SpreadOut"
43
44
46 """!
47
48 Construct the Finite Volume (limiter) scheme
49
50 We assume that the underlying Finite Differences scheme has a patch
51 size of 6x6x6. To make the Finite Volume scheme's time stepping (and
52 accuracy) match this patch size, we have to employ a 16 times finer
53 mesh.
54
55 It is interesting to see that the limiter does not really have a min
56 and max mesh size. The point is that the higher order solver dictates
57 the mesh structure, and we then follow this structure with the
58 Finite Volume scheme.
59
60 """
61
63 self,
64 name,
65 patch_size,
66 amend_priorities: bool,
67 parallelisation_of_kernels: KernelParallelisation,
68 ):
69 """!
70
71 Construct the limiter
72
73 patch_size: Integer
74 Pass in the patch size of the FD4 scheme or, if you are using RKDG,
75 hand in the number 1. The Finite Volume patch then will be 16 times
76 finer.
77
78 """
79 SubPatchSize = int(patch_size * 4 * 4)
80
81 super(Limiter, self).__init__(
82 name=name + "_FV",
83 patch_size=SubPatchSize,
84 min_volume_h=1.0 / 65536, # @so refine to the minimum
85 max_volume_h=1.0 / 65536, # @not really a regular grid, as we work localised
86 pde_terms_without_state=True,
87 )
88 self.double_constants["BlackHoleFVRegion"] = BlackHoleRegion
89
91#include "toolbox/blockstructured/Restriction.h"
92#include "toolbox/blockstructured/Interpolation.h"
93"""
94
95 if amend_priorities:
96 self.enclave_task_priorityenclave_task_priority = "tarch::multicore::Task::DefaultPriority+1"
97
98 # self._fused_compute_kernel_call_gpu = exahype2.solvers.fv.rusanov.kernels.create_compute_Riemann_kernel_for_Rusanov(
99 # self._flux_implementation, self._ncp_implementation, self._source_term_implementation,
100 # compute_max_eigenvalue_of_next_time_step=True,
101 # solver_variant = exahype2.solvers.fv.rusanov.kernels.SolverVariant.Accelerator,
102 # kernel_variant = exahype2.solvers.fv.rusanov.kernels.KernelVariant.GenericAoS
103 # )
104
106 initial_conditions=exahype2.solvers.PDETerms.User_Defined_Implementation,
107 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
108 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
109 )
110
111 if parallelisation_of_kernels == KernelParallelisation.SUBTASKS:
112 # self._compute_kernel_call = exahype2.solvers.fv.rusanov.kernels.create_compute_Riemann_kernel_for_Rusanov(
113 # self._flux_implementation, self._ncp_implementation, self._source_term_implementation,
114 # compute_max_eigenvalue_of_next_time_step=True,
115 # solver_variant = exahype2.solvers.fv.rusanov.kernels.SolverVariant.WithVirtualFunctions,
116 # kernel_variant = exahype2.solvers.fv.rusanov.kernels.KernelVariant.PatchWiseAoSHeap
117 # )
118
119 self._fused_compute_kernel_call_cpu = exahype2.solvers.fv.rusanov.kernels.create_compute_Riemann_kernel_for_Rusanov(
123 compute_max_eigenvalue_of_next_time_step=True,
124 solver_variant=exahype2.solvers.fv.rusanov.kernels.SolverVariant.Multicore,
125 kernel_variant=exahype2.solvers.fv.rusanov.kernels.KernelVariant.PatchWiseAoSHeap,
126 )
127
130
132 """!
133
134 Mask out exterior cells
135
136 """
137 return (
138 """("""
139 + super(Limiter, self)._store_cell_data_default_guard()
140 + " and repositories::instanceOf"
141 + self._name_name_name
142 + ".isCellOverlappingWithBHImpactArea(marker) )"
143 )
144
146 return (
147 """("""
148 + super(Limiter, self)._load_cell_data_default_guard()
149 + " and repositories::instanceOf"
150 + self._name_name_name
151 + ".isCellOverlappingWithBHImpactArea(marker) )"
152 )
153
155 return (
156 """("""
158 + " and repositories::instanceOf"
159 + self._name_name_name
160 + ".isCellOverlappingWithBHImpactArea(marker) )"
161 )
162
164 return "{} and repositories::instanceOf{}.isOneAdjacentCellOverlappingWithBHImpactArea(marker)".format(
167 )
168
170 return "({} and repositories::instanceOf{}.areBothAdjacentCellsOverlappingWithBHImpactArea(marker))".format(
171 super(Limiter, self)._store_face_data_default_guard(), self._name_name_name
172 )
173
175 return "({} and repositories::instanceOf{}.areBothAdjacentCellsOverlappingWithBHImpactArea(marker))".format(
176 super(Limiter, self)._load_face_data_default_guard(), self._name_name_name
177 )
178
180 """!
181
182 Not really a lot of things to do here. The only exception that is
183 really important is that we have to ensure that we only solve stuff
184 inside the local domain of the FV. By default, ExaHyPE 2 solves the
185 PDE everywhere. If data is not stored persistently or loaded from
186 the persistent stacks, it still solves, as it then would assume that
187 such data arises from dynamic AMR. In this particular case, we have
188 to really mask out certain subdomains.
189
190 It is not just a nice optimisation to do so. It is absolutely key,
191 as the application of the compute kernel on garbage would mean that
192 we end up with invalid eigenvalues.
193
194 """
195 super(Limiter, self).create_action_sets()
196
197 self._action_set_update_cell_action_set_update_cell.guard = "({} and repositories::instanceOf{}.isCellOverlappingWithBHImpactArea(marker))".format(
199 )
200 self._action_set_merge_enclave_task_outcome.guard = "({} and repositories::instanceOf{}.isCellOverlappingWithBHImpactArea(marker))".format(
202 )
203
204
206 """!
207
208 4th order Finite Differences solver with a limiter
209
210 The FD scheme is our primary solver, i.e. the one we wanna use (almost)
211 everywhere. Hence, we have to be sure that we use the right boundary
212 conditions. In our case, that should be Sommerfeld ones. As we work
213 with a limited FD4 solver, we have to ensure that we get the
214 @ref benchmarks_exahype2_ccz4_single_black_hole "solver coupling" right.
215
216 The primary solver is a plain CCZ4 FD4 solver with enclave tasking. There
217 are some modification though:
218
219 1. We ensure that we use Sommerfeld boundary conditions. This means that
220 we have to replace the whole generic boundary treatment with a bespoke
221 action set.
222 2. The coupling has to be injected. We model the coupling as separate
223 (enclave) tasks to avoid that we totally serialise the solver steps
224 whenever we encounter a coupling.
225
226 """
227
229 self,
230 name,
231 patch_size,
232 min_cell_size,
233 max_cell_size,
234 parallelisation_of_interpolation: KernelParallelisation,
235 parallelisation_of_kernels: KernelParallelisation,
236 interpolation_method,
237 ):
239 self._parallelisation_of_interpolation = parallelisation_of_interpolation
240 self.interpolation_method = interpolation_method
241
242 CCZ4Solver_FD4_GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
243 self,
244 name=name + "_FD4",
245 patch_size=patch_size,
246 rk_order=1,
247 min_meshcell_h=min_cell_size / patch_size,
248 max_meshcell_h=max_cell_size / patch_size,
249 pde_terms_without_state=False,
250 )
251
252 self._user_action_set_includes += """
253#include "toolbox/blockstructured/Projection.h"
254#include "toolbox/blockstructured/Restriction.h"
255#include "toolbox/blockstructured/Interpolation.h"
256#include "toolbox/blockstructured/Copy.h"
257"""
258 if self.interpolation_method == "matrix":
260 """
261#include "matrixdata/Interpolator_"""
262 + str(patch_size)
263 + """_"""
264 + str(patch_size * 16)
265 + """.h"
266"""
267 )
268 self.double_constants["BlackHoleFVRegion"] = BlackHoleRegion
269
271 initial_conditions=exahype2.solvers.PDETerms.User_Defined_Implementation,
272 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
273 boundary_conditions=exahype2.solvers.PDETerms.None_Implementation,
274 )
275
278
279 if parallelisation_of_kernels == KernelParallelisation.SUBTASKS:
280 print(
281 "WARNING: Unfortunately, we have not yet written parallelised kernels for FD4"
282 )
283 pass
284
285
286 if self.interpolation_method == "matrix":
287 solver_matrix_interpolator = exahype2.solvers.SolverMatrixInterpolator(
288 patch_size, patch_size * 16, 3, 1
289 )
290 solver_matrix_interpolator.generateData()
291
293 """!
294
295 Tailor action set behaviour
296
297 We first make a few additional cells skeleton cells. The rationale
298 behind additional skeletons is given in the @ref benchmarks_exahype2_ccz4_single_black_hole "generic overview".
299 Given the first remark there on FD4-FV coupling, one would be tempted
300 to use the predicate
301
302 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
303 self._action_set_update_cell.additional_skeleton_guard = " " "(
304 repositories::instanceOf" " " + self._name_without_FD4_extension + " " "_FV.isCellOverlappingWithBHImpactArea(marker)
305 and
306 not repositories::instanceOf" " " + self._name_without_FD4_extension + " " "_FV.areAllFaceConnectedCellsOverlappingWithBHImpactArea(marker)
307 )
308 " " "
309 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310
311 Once we study the other items (notably the fourth), we see that it is
312 reasonable to make all the overlap region a skeleton within the FD4
313 solver.
314
315 """
316 super(FD4SolverWithLimiter, self).create_action_sets()
317
318 self._action_set_handle_boundary.TemplateHandleBoundary_KernelCalls = (
319 """
320 double Qinf[59]={1.0, 0.0, 0.0, 1.0, 0.0, 1.0, //q0-5
321 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q6-11
322 0.0, 0.0, 0.0, 0.0, //q12-15
323 1.0, 0.0, 0.0, 0.0, //q16-19
324 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q20-25
325 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q26-34
326 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
327 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q35-52
328 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 //q53-58
329 }; //approximate background solution at infinity
330 ::exahype2::fd::applySommerfeldConditions(
331 [&](
332 const double * __restrict__ Q,
333 const tarch::la::Vector<Dimensions,double>& faceCentre,
334 const tarch::la::Vector<Dimensions,double>& gridCellH,
335 double t,
336 double dt,
337 int normal
338 ) -> double {
339 double temp;
340 repositories::{{SOLVER_INSTANCE}}.maxEigenvalue( Q, faceCentre, gridCellH, t, dt, normal, &temp );
341 return temp;
342 },
343 [&](
344 double * __restrict__ Q,
345 const tarch::la::Vector<Dimensions,double>& faceCentre,
346 const tarch::la::Vector<Dimensions,double>& gridCellH
347 ) -> void {
348 for (int i=0; i<"""
350 + """; i++) {
351 Q[i] = 0.0;
352 }
353 Q[0] = 1.0; Q[3] = 1.0; Q[5] = 1.0;
354 Q[16] = 0.95; Q[54] = 0.95;
355 },
356 marker.x(),
357 marker.h(),
358 {{FACE_METADATA_ACCESSOR}}.getOldTimeStamp(marker.getSelectedFaceNumber()<Dimensions ? 1 : 0),
359 repositories::{{SOLVER_INSTANCE}}.getMinTimeStepSize(),
360 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
361 {{OVERLAP}},
362 {{NUMBER_OF_UNKNOWNS}},
363 {{NUMBER_OF_AUXILIARY_VARIABLES}},
364 marker.getSelectedFaceNumber(),
365 {0.0, 0.0, 0.0},
366 fineGridFace{{UNKNOWN_IDENTIFIER}}Old.value,
367 fineGridFace{{UNKNOWN_IDENTIFIER}}New.value,
368 -1 //not use checkpoint yet
369 );
370 """
371 )
372
374 solver=self,
375 enclave_task_cell_label="fineGridCell"
377 + "_FVCellLabel",
378 compute_kernel_implementation="""
379const int sizeOfPatch = (repositories::instanceOf"""
381 + """_FV.NumberOfFiniteVolumesPerAxisPerPatch+2)
382 * (repositories::instanceOf"""
384 + """_FV.NumberOfFiniteVolumesPerAxisPerPatch+2)
385 * (repositories::instanceOf"""
387 + """_FV.NumberOfFiniteVolumesPerAxisPerPatch+2)
388 * (repositories::instanceOf"""
390 + """_FV.NumberOfUnknowns + repositories::instanceOf"""
392 + """_FV.NumberOfAuxiliaryVariables);
393const int sizeOfFace = 2
394 * (repositories::instanceOf"""
396 + """_FV.NumberOfFiniteVolumesPerAxisPerPatch+2)
397 * (repositories::instanceOf"""
399 + """_FV.NumberOfFiniteVolumesPerAxisPerPatch+2)
400 * (repositories::instanceOf"""
402 + """_FV.NumberOfUnknowns + repositories::instanceOf"""
404 + """_FV.NumberOfAuxiliaryVariables);
405
406double* interpolatedFVDataWithHalo = ::tarch::allocateMemory<double>(sizeOfPatch, ::tarch::MemoryLocation::Heap);
407
408bool faceIsReal0 = repositories::instanceOf"""
410 + """_FV.areBothAdjacentCellsOverlappingWithBHImpactArea(marker,0);
411bool faceIsReal1 = repositories::instanceOf"""
413 + """_FV.areBothAdjacentCellsOverlappingWithBHImpactArea(marker,1);
414bool faceIsReal2 = repositories::instanceOf"""
416 + """_FV.areBothAdjacentCellsOverlappingWithBHImpactArea(marker,2);
417bool faceIsReal3 = repositories::instanceOf"""
419 + """_FV.areBothAdjacentCellsOverlappingWithBHImpactArea(marker,3);
420bool faceIsReal4 = repositories::instanceOf"""
422 + """_FV.areBothAdjacentCellsOverlappingWithBHImpactArea(marker,4);
423bool faceIsReal5 = repositories::instanceOf"""
425 + """_FV.areBothAdjacentCellsOverlappingWithBHImpactArea(marker,5);
426
427double* realFace0 = faceIsReal0 ? fineGridFaces"""
429 + """_FVQNew(0).value : nullptr;
430double* realFace1 = faceIsReal1 ? fineGridFaces"""
432 + """_FVQNew(1).value : nullptr;
433double* realFace2 = faceIsReal2 ? fineGridFaces"""
435 + """_FVQNew(2).value : nullptr;
436double* realFace3 = faceIsReal3 ? fineGridFaces"""
438 + """_FVQNew(3).value : nullptr;
439double* realFace4 = faceIsReal4 ? fineGridFaces"""
441 + """_FVQNew(4).value : nullptr;
442double* realFace5 = faceIsReal5 ? fineGridFaces"""
444 + """_FVQNew(5).value : nullptr;
445
446double* dummyFace0 = faceIsReal0 ? nullptr : ::tarch::allocateMemory<double>(sizeOfFace, ::tarch::MemoryLocation::Heap);
447double* dummyFace1 = faceIsReal1 ? nullptr : ::tarch::allocateMemory<double>(sizeOfFace, ::tarch::MemoryLocation::Heap);
448double* dummyFace2 = faceIsReal2 ? nullptr : ::tarch::allocateMemory<double>(sizeOfFace, ::tarch::MemoryLocation::Heap);
449double* dummyFace3 = faceIsReal3 ? nullptr : ::tarch::allocateMemory<double>(sizeOfFace, ::tarch::MemoryLocation::Heap);
450double* dummyFace4 = faceIsReal4 ? nullptr : ::tarch::allocateMemory<double>(sizeOfFace, ::tarch::MemoryLocation::Heap);
451double* dummyFace5 = faceIsReal5 ? nullptr : ::tarch::allocateMemory<double>(sizeOfFace, ::tarch::MemoryLocation::Heap);
452
453::toolbox::blockstructured::interpolateCellDataAssociatedToVolumesIntoOverlappingCell_"""
455 + """(
456 repositories::instanceOf"""
458 + """_FD4.NumberOfGridCellsPerPatchPerAxis,
459 repositories::instanceOf"""
461 + """_FV.NumberOfFiniteVolumesPerAxisPerPatch,
462 3, // halo in FD4
463 1, // halo in FV
464 repositories::instanceOf"""
466 + """_FV.NumberOfUnknowns + repositories::instanceOf"""
468 + """_FV.NumberOfAuxiliaryVariables,
469 """
470 + (
471 """InterpolationMatrixData::Data,
472 InterpolationMatrixData::Indices,
473 InterpolationMatrixData::Indptr,"""
474 if self.interpolation_method == "matrix"
475 else """"""
476 )
477 + """
478 oldQWithHalo,
479 interpolatedFVDataWithHalo,
480 """
481 + str(self._parallelisation_of_interpolation.value)
482 + """
483);
484
485::toolbox::blockstructured::projectPatchHaloOntoFaces(
486 repositories::instanceOf"""
488 + """_FV.NumberOfFiniteVolumesPerAxisPerPatch,
489 1, // int haloSize,
490 repositories::instanceOf"""
492 + """_FV.NumberOfUnknowns,
493 repositories::instanceOf"""
495 + """_FV.NumberOfAuxiliaryVariables,
496 interpolatedFVDataWithHalo,
497 faceIsReal0 ? realFace0 : dummyFace0,
498 faceIsReal1 ? realFace1 : dummyFace1,
499 faceIsReal2 ? realFace2 : dummyFace2,
500 faceIsReal3 ? realFace3 : dummyFace3,
501 faceIsReal4 ? realFace4 : dummyFace4,
502 faceIsReal5 ? realFace5 : dummyFace5
503);
504
505::tarch::freeMemory(interpolatedFVDataWithHalo, tarch::MemoryLocation::Heap );
506if (dummyFace0!=nullptr) ::tarch::freeMemory(dummyFace0, tarch::MemoryLocation::Heap );
507if (dummyFace1!=nullptr) ::tarch::freeMemory(dummyFace1, tarch::MemoryLocation::Heap );
508if (dummyFace2!=nullptr) ::tarch::freeMemory(dummyFace2, tarch::MemoryLocation::Heap );
509if (dummyFace3!=nullptr) ::tarch::freeMemory(dummyFace3, tarch::MemoryLocation::Heap );
510if (dummyFace4!=nullptr) ::tarch::freeMemory(dummyFace4, tarch::MemoryLocation::Heap );
511if (dummyFace5!=nullptr) ::tarch::freeMemory(dummyFace5, tarch::MemoryLocation::Heap );
512""",
513 )
514
516 "("
518 + """
519 and
520 repositories::instanceOf"""
522 + """_FV.isCellOverlappingWithBHImpactArea(marker)
523 and
524 not repositories::instanceOf"""
526 + """_FV.areAllFaceConnectedCellsOverlappingWithBHImpactArea(marker)
527 and
528 not marker.willBeRefined()
529 )"""
530 )
531
533 self,
534 """
535if (
536 repositories::instanceOf{0}_FV.isCellOverlappingWithBHImpactArea(marker)
537 and
538 not marker.willBeRefined()
539) {{
540 logTraceIn( "touchCellFirstTime(...)-inject" );
541
542 repositories::instanceOf{0}_FV.incNumberOfPatches();
543
544 //if ( repositories::instanceOf{0}_FV.areAllFaceConnectedCellsOverlappingWithBHImpactArea(marker) ) {{
545 ::toolbox::blockstructured::restrictCellIntoOverlappingCell_inject(
546 repositories::instanceOf{0}_FV.NumberOfFiniteVolumesPerAxisPerPatch,
547 repositories::instanceOf{0}_FD4.NumberOfGridCellsPerPatchPerAxis,
548 repositories::instanceOf{0}_FV.NumberOfUnknowns + repositories::instanceOf{0}_FV.NumberOfAuxiliaryVariables,
549 fineGridCell{0}_FVQ.value,
550 fineGridCell{0}_FD4Q.value
551 );
552 /*}}
553 else {{
554 ::toolbox::blockstructured::restrictCellIntoOverlappingCell_inject_and_average(
555 repositories::instanceOf{0}_FV.NumberOfFiniteVolumesPerAxisPerPatch,
556 repositories::instanceOf{0}_FD4.NumberOfGridCellsPerPatchPerAxis,
557 repositories::instanceOf{0}_FV.NumberOfUnknowns + repositories::instanceOf{0}_FV.NumberOfAuxiliaryVariables,
558 fineGridCell{0}_FVQ.value,
559 fineGridCell{0}_FD4Q.value
560 );
561 }}*/
562
563 logTraceOut( "touchCellFirstTime(...)-inject" );
564}}
565""".format(
567 ),
568 )
569
570
572 """!
573
574 Construct 4th order Finite Differences solver without a limiter
575
576 """
577
579 self,
580 name,
581 patch_size,
582 min_cell_size,
583 max_cell_size,
584 production_run = 0
585 ):
587
588 CCZ4Solver_FD4_GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
589 self,
590 name=name + "_FD4",
591 patch_size=patch_size,
592 rk_order=1,
593 min_meshcell_h=min_cell_size / patch_size,
594 max_meshcell_h=max_cell_size / patch_size,
595 pde_terms_without_state=False,
596 )
597
598 self._user_action_set_includes += """
599#include "toolbox/blockstructured/Projection.h"
600#include "toolbox/blockstructured/Restriction.h"
601#include "toolbox/blockstructured/Interpolation.h"
602#include "toolbox/blockstructured/Copy.h"
603"""
604
606 self.double_constants["BlackHoleFVRegion"] = BlackHoleRegion
607
609 initial_conditions=exahype2.solvers.PDETerms.User_Defined_Implementation,
610 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
611 boundary_conditions=exahype2.solvers.PDETerms.None_Implementation,
612 )
613
614 self.integer_constants["ProductionRun"] = production_run
617
619 """!
620
621 Tailor action set behaviour
622
623 We first make a few additional cells skeleton cells. The rationale
624 behind additional skeletons is given in the @ref benchmarks_exahype2_ccz4_single_black_hole "generic overview".
625 Given the first remark there on FD4-FV coupling, one would be tempted
626 to use the predicate
627
628 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
629 self._action_set_update_cell.additional_skeleton_guard = " " "(
630 repositories::instanceOf" " " + self._name_without_FD4_extension + " " "_FV.isCellOverlappingWithBHImpactArea(marker)
631 and
632 not repositories::instanceOf" " " + self._name_without_FD4_extension + " " "_FV.areAllFaceConnectedCellsOverlappingWithBHImpactArea(marker)
633 )
634 " " "
635 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
636
637 Once we study the other items (notably the fourth), we see that it is
638 reasonable to make all the overlap region a skeleton within the FD4
639 solver.
640
641 """
642 super(FD4SolverWithoutLimiter, self).create_action_sets()
643
644 self._action_set_handle_boundary.TemplateHandleBoundary_KernelCalls = (
645 """
646 double Qinf[59]={1.0, 0.0, 0.0, 1.0, 0.0, 1.0, //q0-5
647 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q6-11
648 0.0, 0.0, 0.0, 0.0, //q12-15
649 1.0, 0.0, 0.0, 0.0, //q16-19
650 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q20-25
651 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q26-34
652 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
653 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q35-52
654 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 //q53-58
655 }; //approximate background solution at infinity
656 ::exahype2::fd::applySommerfeldConditions(
657 [&](
658 const double * __restrict__ Q,
659 const tarch::la::Vector<Dimensions,double>& faceCentre,
660 const tarch::la::Vector<Dimensions,double>& gridCellH,
661 double t,
662 double dt,
663 int normal
664 ) -> double {
665 double temp;
666 repositories::{{SOLVER_INSTANCE}}.maxEigenvalue( Q, faceCentre, gridCellH, t, dt, normal, &temp );
667 return temp;
668 },
669 [&](
670 double * __restrict__ Q,
671 const tarch::la::Vector<Dimensions,double>& faceCentre,
672 const tarch::la::Vector<Dimensions,double>& gridCellH
673 ) -> void {
674 for (int i=0; i<"""
676 + """; i++) {
677 Q[i] = 0.0;
678 }
679 Q[0] = 1.0; Q[3] = 1.0; Q[5] = 1.0;
680 Q[16] = 0.95; Q[54] = 0.95;
681 },
682 marker.x(),
683 marker.h(),
684 {{FACE_METADATA_ACCESSOR}}.getOldTimeStamp(marker.getSelectedFaceNumber()<Dimensions ? 1 : 0),
685 repositories::{{SOLVER_INSTANCE}}.getMinTimeStepSize(),
686 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
687 {{OVERLAP}},
688 {{NUMBER_OF_UNKNOWNS}},
689 {{NUMBER_OF_AUXILIARY_VARIABLES}},
690 marker.getSelectedFaceNumber(),
691 {0.0, 0.0, 0.0},
692 fineGridFace{{UNKNOWN_IDENTIFIER}}Old.value,
693 fineGridFace{{UNKNOWN_IDENTIFIER}}New.value,
694 -1 // @todo Han, can you add a comment here please why we do -1?
695 );
696 """
697 )
698
699
701 """!
702
703 A finite volume solver
704
705 This solver is not appropriate to simulate black holes as a stand-alone
706 solver, as it is way too diffusive. If you use it without another scheme,
707 you typically see the black hole disappear after a brief period. So we
708 have it in here merely for performance tests.
709
710 """
711
713 self,
714 name,
715 patch_size,
716 min_cell_size,
717 max_cell_size,
718 ):
719 """!
720
721 Construct the Finite Volume solver
722
723 @param patch_size: Integer
724 Defines how big the individual patches are. If you pass in 10, each
725 Finite Volume patch will have the dimensions 10x10x10.
726 @param min_cell_size: Float
727 This parameter refers to the cell size, i.e. the size of a whole
728 patch. We use this one here, to make the signature the same as for
729 the FD and DG solver variants. The superclass constructor argues
730 over finite volume sizes, and we hence have to recalibrate this
731 parameter with patch_size.
732
733 """
734
735 super(FVSolver, self).__init__(
736 name=name + "_FV",
737 patch_size=patch_size,
738 min_volume_h=min_cell_size / patch_size,
739 max_volume_h=max_cell_size / patch_size,
740 pde_terms_without_state=True,
741 )
742
743 self._user_action_set_includes += """
744#include "toolbox/blockstructured/Projection.h"
745#include "toolbox/blockstructured/Restriction.h"
746#include "toolbox/blockstructured/Interpolation.h"
747#include "toolbox/blockstructured/Copy.h"
748#include "exahype2/fd/BoundaryConditions.h"
749"""
750
752 self.double_constants["BlackHoleFVRegion"] = BlackHoleRegion
753
755 initial_conditions=exahype2.solvers.PDETerms.User_Defined_Implementation,
756 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
757 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
758 )
759
762
764 """!
765
766 Tailor action set behaviour
767
768 We first make a few additional cells skeleton cells. The rationale
769 behind additional skeletons is given in the @ref benchmarks_exahype2_ccz4_single_black_hole "generic overview".
770 Given the first remark there on FD4-FV coupling, one would be tempted
771 to use the predicate
772
773 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
774 self._action_set_update_cell.additional_skeleton_guard = " " "(
775 repositories::instanceOf" " " + self._name_without_FD4_extension + " " "_FV.isCellOverlappingWithBHImpactArea(marker)
776 and
777 not repositories::instanceOf" " " + self._name_without_FD4_extension + " " "_FV.areAllFaceConnectedCellsOverlappingWithBHImpactArea(marker)
778 )
779 " " "
780 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
781
782 Once we study the other items (notably the fourth), we see that it is
783 reasonable to make all the overlap region a skeleton within the FD4
784 solver.
785
786 """
787 super(FVSolver, self).create_action_sets()
788
789 self._action_set_handle_boundary.TemplateHandleBoundary_KernelCalls = (
790 """
791 double Qinf[59]={1.0, 0.0, 0.0, 1.0, 0.0, 1.0, //q0-5
792 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q6-11
793 0.0, 0.0, 0.0, 0.0, //q12-15
794 1.0, 0.0, 0.0, 0.0, //q16-19
795 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q20-25
796 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q26-34
797 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
798 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, //q35-52
799 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 //q53-58
800 }; //approximate background solution at infinity
801 ::exahype2::fd::applySommerfeldConditions(
802 [&](
803 const double * __restrict__ Q,
804 const tarch::la::Vector<Dimensions,double>& faceCentre,
805 const tarch::la::Vector<Dimensions,double>& gridCellH,
806 double t,
807 double dt,
808 int normal
809 ) -> double {
810 double temp;
811 repositories::{{SOLVER_INSTANCE}}.maxEigenvalue( Q, faceCentre, gridCellH, t, dt, normal, &temp );
812 return temp;
813 },
814 [&](
815 double * __restrict__ Q,
816 const tarch::la::Vector<Dimensions,double>& faceCentre,
817 const tarch::la::Vector<Dimensions,double>& gridCellH
818 ) -> void {
819 for (int i=0; i<"""
821 + """; i++) {
822 Q[i] = 0.0;
823 }
824 Q[0] = 1.0; Q[3] = 1.0; Q[5] = 1.0;
825 Q[16] = 0.95; Q[54] = 0.95;
826 },
827 marker.x(),
828 marker.h(),
829 {{FACE_METADATA_ACCESSOR}}.getOldTimeStamp(marker.getSelectedFaceNumber()<Dimensions ? 1 : 0),
830 repositories::{{SOLVER_INSTANCE}}.getMinTimeStepSize(),
831 {{NUMBER_OF_VOLUMES_PER_AXIS}},
832 {{OVERLAP}},
833 {{NUMBER_OF_UNKNOWNS}},
834 {{NUMBER_OF_AUXILIARY_VARIABLES}},
835 marker.getSelectedFaceNumber(),
836 {0.0, 0.0, 0.0},
837 fineGridFace{{UNKNOWN_IDENTIFIER}}Old.value,
838 fineGridFace{{UNKNOWN_IDENTIFIER}}New.value,
839 -1 // @todo Han, can you add a comment here please why we do -1?
840 );
841 """
842 )
843
844
846 """!
847
848 Update preconfigured solver parameters
849
850 The default parameters of CCZ4 are tailored towards gauge waves or similar.
851 For the single black hole, two parameters have to be changed. That's bs and
852 sk which both have to be 1.0.
853
854 """
855 solver.double_constants["CCZ4bs"] = 1.0
856 solver.double_constants["CCZ4sk"] = 1.0
add_all_solver_constants(self)
Add domain-specific constants.
CCZ4 solver using fourth-order finite differences and global adaptive time stepping incl enclave task...
CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking.
4th order Finite Differences solver with a limiter
Definition SBH.py:205
__init__(self, name, patch_size, min_cell_size, max_cell_size, KernelParallelisation parallelisation_of_interpolation, KernelParallelisation parallelisation_of_kernels, interpolation_method)
Constructor.
Definition SBH.py:237
create_action_sets(self)
Tailor action set behaviour.
Definition SBH.py:292
Construct 4th order Finite Differences solver without a limiter.
Definition SBH.py:571
create_action_sets(self)
Tailor action set behaviour.
Definition SBH.py:618
__init__(self, name, patch_size, min_cell_size, max_cell_size, production_run=0)
Constructor.
Definition SBH.py:585
A finite volume solver.
Definition SBH.py:700
__init__(self, name, patch_size, min_cell_size, max_cell_size)
Construct the Finite Volume solver.
Definition SBH.py:718
create_action_sets(self)
Tailor action set behaviour.
Definition SBH.py:763
_auxiliary_variables
Definition SBH.py:820
Construct the Finite Volume (limiter) scheme.
Definition SBH.py:45
_flux_implementation
Definition SBH.py:120
create_action_sets(self)
Not really a lot of things to do here.
Definition SBH.py:179
_source_term_implementation
Definition SBH.py:122
_fused_compute_kernel_call_cpu
Definition SBH.py:119
_provide_face_data_to_compute_kernels_default_guard(self)
Definition SBH.py:163
_store_cell_data_default_guard(self)
Mask out exterior cells.
Definition SBH.py:131
_ncp_implementation
Definition SBH.py:121
_provide_cell_data_to_compute_kernels_default_guard(self)
Default logic when to create cell data or not.
Definition SBH.py:154
_store_face_data_default_guard(self)
Extend the guard via ands only.
Definition SBH.py:169
_load_cell_data_default_guard(self)
Extend the guard via ands only.
Definition SBH.py:145
__init__(self, name, patch_size, bool amend_priorities, KernelParallelisation parallelisation_of_kernels)
Construct the limiter.
Definition SBH.py:68
enclave_task_priority
Definition SBH.py:96
_load_face_data_default_guard(self)
Extend the guard via ands only.
Definition SBH.py:174
set_implementation(self, boundary_conditions, refinement_criterion, initial_conditions, memory_location, use_split_loop, additional_action_set_includes, additional_user_includes)
If you pass in User_Defined, then the generator will create C++ stubs that you have to befill manuall...
set_implementation(self, flux=None, ncp=None, eigenvalues=None, boundary_conditions=None, refinement_criterion=None, initial_conditions=None, source_term=None, memory_location=None, use_split_loop=False, additional_action_set_includes="", additional_user_includes="")
If you pass in User_Defined, then the generator will create C++ stubs that you have to befill manuall...
set_implementation(self, flux, ncp, source_term, eigenvalues, boundary_conditions, refinement_criterion, initial_conditions, memory_location, additional_action_set_includes, additional_user_includes)
If you pass in User_Defined, then the generator will create C++ stubs that you have to befill manuall...
set_implementation(self, flux=None, ncp=None, source_term=None, eigenvalues=None, boundary_conditions=None, refinement_criterion=None, initial_conditions=None, memory_location=None, additional_action_set_includes="", additional_user_includes="", KOSigma=None)
If you pass in User_Defined, then the generator will create C++ stubs that you have to befill manuall...
update_solver_parameters_for_single_black_hole(solver)
Update preconfigured solver parameters.
Definition SBH.py:845