Peano
Loading...
Searching...
No Matches
CCZ4Solver.py
Go to the documentation of this file.
1import peano4
2import exahype2
3import dastgen2
4
5from abc import abstractmethod
6
7
8class AbstractCCZ4Solver(object):
9 """!
10
11 Abstract base class for any CCZ4 solver
12
13 Each CCZ4 solver inherits from this abstract base class which really only
14 defines some generic stuff such as the unknowns and includes that every
15 single solver will use.
16
17 The solver should, more or less, work out of the box, but you have to do
18 three things if you use a subclass:
19
20 1. If you use a CCZ4 solver, you will still have to add all the libraries to
21 your Peano project such that the Makefile picks them up. For this, the
22 solver offers an add_makefile_parameters().
23
24 2. You have to set the initial conditions via
25
26 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 my_solver.set_implementation(initial_conditions = " " "
28 for (int i=0; i<NumberOfUnknowns+NumberOfAuxiliaryVariables; i++) Q[i] = 0.0;
29 ::applications::exahype2::ccz4::gaugeWave(Q, volumeCentre, 0);
30 " " ")
31 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32
33 At this point, different CCZ4 solver variants might require different
34 syntax. The term volumeCentre for example above is only defined in a
35 finite volume ontext.
36
37 3. Finally, you have to add domain-specific constants to the project.
38 For this, call add_all_solver_constants(). See the comment below.
39
40 Further to that, you might want to have to set boundary conditions. By
41 default, we do not set any boundary conditions. This works fine if
42 periodic boundary conditions are used. But once you switch off periodic
43 boundary conditions, you have to tell the solver how to treat the boundary.
44 This is typically done via set_implementation(), too.
45
46 ## More complex scenarios
47
48 Setting particular implementations via set_implementation() is not always
49 convenient or possible. You might want to add new functions to your classes,
50 do something in the solver constructor, and so forth. If so, feel free to
51 modify the file MySolverName.cpp which the tool generates. In this context,
52 you might want to pass in
53
54 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 my_solver.set_implementation(initial_conditions = exahype2.solvers.PDETerms.User_Defined_Implementation,
56 refinement_criterion = exahype2.solvers.PDETerms.User_Defined_Implementation,
57 boundary_conditions=exahype2.solvers.PDETerms.User_Defined_Implementation
58 )
59
60 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61
62 which ensures that you get the right hook-in methods generated when you
63 invoke the Python script for the first time. These methods will contain
64 todo comments for you. Subsequent runs of the Python API should not
65 overwrite the solver implementation.
66
67 ## Constants
68
69 Each CCZ4 solver requires a minimal set of constants. These are represented
70 by integer_constants and double_constants. Please augment these dictionaries.
71 Eventually, you have to submit all the constants via add_all_solver_constants().
72
73 """
74
75 """!
76
77 Dictionary which specifies the unknown names plus their cardinality
78
79 Has to be class attribute, as we need it in the constructor, i.e. before the
80 abstract object is created.
81
82 """
83 _FO_formulation_unknowns = {
84 "G": 6,
85 "K": 6,
86 "theta": 1,
87 "Z": 3,
88 "lapse": 1,
89 "shift": 3,
90 "b": 3,
91 "dLapse": 3,
92 "dxShift": 3,
93 "dyShift": 3,
94 "dzShift": 3,
95 "dxG": 6,
96 "dyG": 6,
97 "dzG": 6,
98 "traceK": 1,
99 "phi": 1,
100 "P": 3,
101 "K0": 1,
102 }
103
104 """!
105
106 Primary unknowns of the CCZ4 formulation which are there in the initial
107 formulation. All the other variables are auxiliary variables, i.e. ones
108 introduced to return to a first-order formulation. Unfortunately, the
109 ordering in _FO_formulation_unknows is motivated by the original papers
110 and not by the fact which quantities are original ones and which one are
111 helper or auxiliary variables.
112
113 """
114 _SO_formulation_unknowns = {
115 "G",
116 "K",
117 "theta",
118 "Z",
119 "lapse",
120 "shift",
121 "b",
122 "traceK",
123 "phi",
124 }
125
126 Default_Time_Step_Size_Relaxation = 0.1
127
128 def __init__(self):
129 """!
130
131 Constructor
132
133 Initialise the two dictionaries with default values (which work).
134
135 """
137 "CCZ4LapseType": 0,
138 "CCZ4SO": 0,
139 "ProductionRun":0
140 }
142 "CCZ4ds": 1.0,
143 "CCZ4c": 1.0,
144 "CCZ4e": 1.0,
145 "CCZ4f": 0.75,
146 "CCZ4bs": 0.0,
147 "CCZ4sk": 0.0,
148 "CCZ4xi": 1.0,
149 "CCZ4itau": 1.0,
150 "CCZ4eta": 1.0,
151 "CCZ4k1": 0.1,
152 "CCZ4k2": 0.0,
153 "CCZ4k3": 0.5,
154 "CCZ4GLMc": 1.2,
155 "CCZ4GLMd": 2.0,
156 "CCZ4mu": 0.2,
157 }
158
166 """!
167
168 Add the headers for the compute kernels and initial condition implementations
169
170 Usually called by the subclass constructor.
171
172 """
173 self.add_user_action_set_includes(
174 """
175#include "CCZ4Kernels.h"
176#include "SecondOrderAuxiliaryVariablesReconstruction.h"
177"""
178 )
179 self.add_user_solver_includes(
180 """
181#include "CCZ4Kernels.h"
182#include "InitialValues.h"
183#include "SecondOrderAuxiliaryVariablesReconstruction.h"
184#include <cstring>
185"""
186 )
187
189 """!
190
191 Add domain-specific constants
192
193 I need a couple of constants. I could either replace them directly
194 within the Python snippets below, but I prefer here to go a different
195 way and to export them as proper C++ constants.
196
197 There are two ways to inject solver constants into Peano: We can either
198 add them to the Makefile as global const expressions, or we can add
199 them to the ExaHyPE2 solver. The latter is the route we go down here,
200 as these constants logically belong to the solver and not to the project.
201
202 This operation uses the parent class' add_solver_constants(). You still
203 can use this operation to add further parameters. Or you can, as a user,
204 always add new entries to integer_constants or double_constants and then
205 call this routine rather than adding individual constants one by one.
206
207 """
208 for key, value in self.integer_constants.items():
209 self.add_solver_constants(
210 "static constexpr int {} = {};".format(key, value)
211 )
212 for key, value in self.double_constants.items():
213 self.add_solver_constants(
214 "static constexpr double {} = {};".format(key, value)
215 )
216
217 def add_makefile_parameters(self, peano4_project, path_of_ccz4_application):
218 """!
219
220 Add include path and minimal required cpp files to makefile
221
222 If you have multiple CCZ4 solvers, i.e. different solvers of CCZ4 or multiple
223 instances of the CCZ4 type, please call this operation only once on one of
224 your solvers. At the moment, I add hte following cpp files to the setup:
225
226 - InitialValues.cpp
227 - CCZ4Kernels.cpp
228 - SecondOrderAuxiliaryVariablesReconstruction.cpp
229
230 You can always add further files via
231 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232 peano4_project.output.makefile.add_cpp_file( "mypath/myfile.cpp" )
233 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
234
235 """
236 if path_of_ccz4_application[-1] != "/":
237 path_of_ccz4_application += "/"
238
239 peano4_project.output.makefile.add_cpp_file(
240 path_of_ccz4_application + "InitialValues.cpp"
241 )
242 peano4_project.output.makefile.add_cpp_file(
243 path_of_ccz4_application + "CCZ4Kernels.cpp"
244 )
245 peano4_project.output.makefile.add_cpp_file(
246 path_of_ccz4_application + "SecondOrderAuxiliaryVariablesReconstruction.cpp"
247 )
248 peano4_project.output.makefile.add_header_search_path(path_of_ccz4_application)
249
250 @abstractmethod
252 self,
253 name,
254 coordinates,
255 project,
256 number_of_entries_between_two_db_flushes,
257 data_delta_between_two_snapsots,
258 time_delta_between_two_snapsots,
259 clear_database_after_flush,
260 tracer_unknowns=None,
261 ):
262 """!
263
264 Add tracer to project
265
266 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
267 some of the arguments. Most of them are simply piped through to this
268 class.
269
270 The tracer is given a name and initial coordinates (list of three-tuples).
271 We need to know the underlying project as well, as we have to add the
272 tracing to the time stepping and the database update to the plotting.
273 ~~~~~~~~~~~~~~~~~~~~~~~
274 project.add_action_set_to_timestepping(my_interpolation)
275 project.add_action_set_to_timestepping(exahype2.tracer.DumpTracerIntoDatabase(
276 particle_set=tracer_particles,
277 solver=self,
278 filename=name + "-" + self._name,
279 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
280 output_precision=10,
281 data_delta_between_two_snapsots = data_delta_between_two_snapsots,
282 time_delta_between_two_snapsots = time_delta_between_two_snapsots,
283 clear_database_after_flush = True,
284 ))
285 ~~~~~~~~~~~~~~~~~~~~~~~
286
287 """
288 assert "should not be called"
289 pass
290
291
294):
295 """!
296
297 CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking
298
299 Please consult CCZ4Solver_FV_GlobalAdaptiveTimeStepWithEnclaveTasking.
300
301 """
302
304 self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state
305 ):
306 AbstractCCZ4Solver.__init__(self)
307 exahype2.solvers.fv.rusanov.GlobalAdaptiveTimeStep.__init__(
308 self,
309 name=name,
310 patch_size=patch_size,
311 unknowns=sum(self._FO_formulation_unknowns.values()),
312 auxiliary_variables=0,
313 min_volume_h=min_volume_h,
314 max_volume_h=max_volume_h,
315 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
316 )
318
320 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
321 ncp=construct_FV_ncp(),
322 flux=exahype2.solvers.PDETerms.None_Implementation,
323 source_term=construct_FV_source_term(),
324 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
325 eigenvalues=construct_FV_eigenvalues(),
326 )
327
329
331 self,
332 name,
333 coordinates,
334 project,
335 number_of_entries_between_two_db_flushes,
336 data_delta_between_two_snapsots,
337 time_delta_between_two_snapsots,
338 clear_database_after_flush,
339 tracer_unknowns,
340 ):
341 """!
342
343 Add tracer to project
344
345 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
346 some of the arguments. Most of them are simply piped through to this
347 class.
348
349 project: exahype2.Project
350
351 """
353 name,
354 coordinates,
355 project,
356 self,
357 number_of_entries_between_two_db_flushes,
358 data_delta_between_two_snapsots,
359 time_delta_between_two_snapsots,
360 clear_database_after_flush,
361 tracer_unknowns,
362 )
363
364
367):
368 """!
369
370 CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking
371
372 Please consult CCZ4Solver_FV_GlobalAdaptiveTimeStepWithEnclaveTasking.
373
374 """
375
377 self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state
378 ):
379 AbstractCCZ4Solver.__init__(self)
380 exahype2.solvers.fv.musclhancock.GlobalAdaptiveTimeStep.__init__(
381 self,
382 name=name,
383 patch_size=patch_size,
384 unknowns=sum(self._FO_formulation_unknowns.values()),
385 auxiliary_variables=0,
386 min_volume_h=min_volume_h,
387 max_volume_h=max_volume_h,
388 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
389 )
391
393 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
394 ncp=construct_FV_ncp(),
395 flux=exahype2.solvers.PDETerms.None_Implementation,
396 source_term=construct_FV_source_term(),
397 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
398 eigenvalues=construct_FV_eigenvalues(),
399 )
400
402
404 self,
405 name,
406 coordinates,
407 project,
408 number_of_entries_between_two_db_flushes,
409 data_delta_between_two_snapsots,
410 time_delta_between_two_snapsots,
411 clear_database_after_flush,
412 tracer_unknowns,
413 ):
414 """!
415
416 Add tracer to project
417
418 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
419 some of the arguments. Most of them are simply piped through to this
420 class.
421
422 project: exahype2.Project
423
424 """
426 name,
427 coordinates,
428 project,
429 self,
430 number_of_entries_between_two_db_flushes,
431 data_delta_between_two_snapsots,
432 time_delta_between_two_snapsots,
433 clear_database_after_flush,
434 tracer_unknowns,
435 )
436
437
439 AbstractCCZ4Solver,
441):
442 """!
443
444 CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking
445
446 The constructor of this classs is straightforward and realises the standard
447 steps of any numerical implementation of the CCZ4 scheme:
448
449 1. Init the actual numerical scheme. This happens through the constructor
450 of the base class.
451
452 2. Add the header files that we need, i.e. those files which contain the
453 actual CCZ4 implementation.
454
455 3. Add some constants that any CCZ4 C++ code requires.
456
457 4. Set the actual implementation, i.e. link the generic PDE terms to the
458 CCZ4-specific function calls.
459
460 5. Add the CCZ4-specific postprocessing.
461
462 """
463
465 self,
466 name,
467 patch_size,
468 min_volume_h,
469 max_volume_h,
470 pde_terms_without_state,
471 ):
472 """!
473
474 Construct solver with enclave tasking and adaptive time stepping
475
476 """
477 AbstractCCZ4Solver.__init__(self)
478 exahype2.solvers.fv.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
479 self,
480 name=name,
481 patch_size=patch_size,
482 unknowns=sum(self._FO_formulation_unknowns.values()),
483 auxiliary_variables=0,
484 min_volume_h=min_volume_h,
485 max_volume_h=max_volume_h,
486 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
487 pde_terms_without_state=pde_terms_without_state,
488 )
490
492 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
493 ncp=construct_FV_ncp(),
494 flux=exahype2.solvers.PDETerms.None_Implementation,
495 source_term=construct_FV_source_term(),
496 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
497 eigenvalues=construct_FV_eigenvalues(),
498 )
499
501
503 self,
504 name,
505 coordinates,
506 project,
507 number_of_entries_between_two_db_flushes,
508 data_delta_between_two_snapsots,
509 time_delta_between_two_snapsots,
510 clear_database_after_flush,
511 tracer_unknowns,
512 ):
513 """!
514
515 Add tracer to project
516
517 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
518 some of the arguments. Most of them are simply piped through to this
519 class.
520
521
522 project: exahype2.Project
523
524 """
526 name,
527 coordinates,
528 project,
529 self,
530 number_of_entries_between_two_db_flushes,
531 data_delta_between_two_snapsots,
532 time_delta_between_two_snapsots,
533 clear_database_after_flush,
534 tracer_unknowns,
535 )
536
537
540):
541 """!
542
543 CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking
544
545 Please consult CCZ4Solver_FV_GlobalAdaptiveTimeStepWithEnclaveTasking.
546
547 """
548
550 self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state
551 ):
552 AbstractCCZ4Solver.__init__(self)
553 exahype2.solvers.fv.musclhancock.GlobalAdaptiveTimeStep.__init__(
554 self,
555 name=name,
556 patch_size=patch_size,
557 unknowns=sum(self._FO_formulation_unknowns.values()),
558 auxiliary_variables=0,
559 min_volume_h=min_volume_h,
560 max_volume_h=max_volume_h,
561 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
562 pde_terms_without_state=pde_terms_without_state,
563 )
565
567 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
568 ncp=construct_FV_ncp(),
569 flux=exahype2.solvers.PDETerms.None_Implementation,
570 source_term=construct_FV_source_term(),
571 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
572 eigenvalues=construct_FV_eigenvalues(),
573 )
574
576
578 self,
579 name,
580 coordinates,
581 project,
582 number_of_entries_between_two_db_flushes,
583 data_delta_between_two_snapsots,
584 time_delta_between_two_snapsots,
585 clear_database_after_flush,
586 tracer_unknowns,
587 ):
588 """!
589
590 Add tracer to project
591
592 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
593 some of the arguments. Most of them are simply piped through to this
594 class.
595
596 project: exahype2.Project
597
598 """
600 name,
601 coordinates,
602 project,
603 self,
604 number_of_entries_between_two_db_flushes,
605 data_delta_between_two_snapsots,
606 time_delta_between_two_snapsots,
607 clear_database_after_flush,
608 tracer_unknowns,
609 )
610
611
613 return """
614#if defined(GPUOffloadingOMP)
615 double* deltaQSerialised = new double[NumberOfUnknowns*3];
616#else
617 double deltaQSerialised[NumberOfUnknowns*3];
618#endif
619 for (int i=0; i<NumberOfUnknowns; i++) {
620 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
621 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
622 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
623
624 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
625 }
626 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, deltaQSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
627#if defined(GPUOffloadingOMP)
628 delete[] deltaQSerialised;
629#endif
630"""
631
632
634 return """
635#if defined(GPUOffloadingOMP)
636 double* deltaQSerialised = new double[NumberOfUnknowns*3];
637#else
638 double deltaQSerialised[NumberOfUnknowns*3];
639#endif
640 for (int i=0; i<NumberOfUnknowns; i++) {
641 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
642 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
643 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
644
645 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
646 }
647 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, deltaQSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
648#if defined(GPUOffloadingOMP)
649 delete[] deltaQSerialised;
650#endif
651"""
652
653
655 return """
656 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
657"""
658
659
661 return """
662 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
663"""
664
665
667 return """
668 ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd, maxEigenvalue );
669"""
670
671
673 return """
674 ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd, maxEigenvalue );
675"""
676
677
679 return """
680{
681 constexpr int itmax = {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}};
682 int index = 0;
683 for (int i=0;i<itmax;i++)
684 {
685 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
686 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
687 }
688 }
689"""
690
691
693 return """
694{
695 constexpr int itmax = {{NUMBER_OF_VOLUMES_PER_AXIS}} * {{NUMBER_OF_VOLUMES_PER_AXIS}} * {{NUMBER_OF_VOLUMES_PER_AXIS}};
696 int index = 0;
697 for (int i=0;i<itmax;i++)
698 {
699 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
700 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
701 }
702 }
703"""
704
705
707 name,
708 coordinates,
709 project,
710 solver,
711 number_of_entries_between_two_db_flushes,
712 data_delta_between_two_snapsots,
713 time_delta_between_two_snapsots,
714 clear_database_after_flush,
715 tracer_unknowns,
716):
717 """!
718
719 Add tracer to project
720
721 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
722 some of the arguments. Most of them are simply piped through to this
723 class.
724
725 I realise this as a separate routine, as we need it for all FV flavours
726
727 """
728 number_of_attributes = (
729 (solver.unknowns + solver.auxiliary_variables)
730 if tracer_unknowns == None
731 else len(tracer_unknowns)
732 )
733 tracer_particles = project.add_tracer(
734 name=name, attribute_count=number_of_attributes
735 )
737 particle_set=tracer_particles, coordinates=coordinates
738 )
739 init_action_set.descend_invocation_order = 0
740 project.add_action_set_to_initialisation(init_action_set)
741
742 project_on_tracer_properties_kernel = ""
743 if tracer_unknowns == None:
744 project_on_tracer_properties_kernel = (
745 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
746 )
747 # project_on_tracer_properties_kernel = "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear_explicit_Euler"
748 elif len(tracer_unknowns) == 1:
749 project_on_tracer_properties_kernel = (
750 "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
751 i, tracer_unknowns.index(i)
752 )
753 )
754 else:
755 project_on_tracer_properties_kernel = (
756 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
757 tracer_unknowns
758 )
759 .replace("[", "")
760 .replace("]", "")
761 )
762
763 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
764 tracer_particles,
765 solver,
766 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
767 )
768 tracing_action_set.descend_invocation_order = (
769 solver._action_set_update_cell.descend_invocation_order + 1
770 )
771 project.add_action_set_to_timestepping(tracing_action_set)
772 project.add_action_set_to_initialisation(tracing_action_set)
773
774 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
775 particle_set=tracer_particles,
776 solver=solver,
777 filename=name + "-" + solver._name,
778 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
779 output_precision=10,
780 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
781 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
782 clear_database_after_flush=clear_database_after_flush,
783 )
784 dump_into_database_action_set.descend_invocation_order = (
785 solver._action_set_update_cell.descend_invocation_order + 2
786 )
787 project.add_action_set_to_timestepping(dump_into_database_action_set)
788
789
791 name,
792 coordinates,
793 project,
794 solver,
795 number_of_entries_between_two_db_flushes,
796 data_delta_between_two_snapsots,
797 time_delta_between_two_snapsots,
798 clear_database_after_flush,
799 tracer_unknowns,
800):
801 """!
802
803 I realise this as a separate routine, as we need it for all FD4 flavours
804
805 This is a wrapper around all the tracer handling. It adds the tracer to the
806 exahype2.Project, but it also instantiates the solution to tracer mapping
807 as well as the database bookkeeping.
808
809 @param tracer_unknowns: Integer
810 You can set this variable to None. In this case, all variables are
811 dumped.
812
813 """
814 number_of_attributes = (
815 (solver.unknowns + solver.auxiliary_variables)
816 if tracer_unknowns == None
817 else len(tracer_unknowns)
818 )
819 tracer_particles = project.add_tracer(
820 name=name, attribute_count=number_of_attributes
821 )
822 project.add_action_set_to_initialisation(
824 particle_set=tracer_particles, coordinates=coordinates
825 )
826 )
827 project_on_tracer_properties_kernel = ""
828 if tracer_unknowns == None:
829 project_on_tracer_properties_kernel = (
830 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
831 )
832 elif len(tracer_unknowns) == 1:
833 project_on_tracer_properties_kernel = (
834 "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
835 i, tracer_unknowns.index(i)
836 )
837 )
838 else:
839 project_on_tracer_properties_kernel = (
840 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
841 tracer_unknowns
842 )
843 .replace("[", "")
844 .replace("]", "")
845 )
846
847 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
848 tracer_particles,
849 solver,
850 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
851 )
852 tracing_action_set.descend_invocation_order = (
853 solver._action_set_compute_final_linear_combination.descend_invocation_order + 1
854 )
855 project.add_action_set_to_timestepping(tracing_action_set)
856 project.add_action_set_to_initialisation(tracing_action_set)
857
858 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
859 particle_set=tracer_particles,
860 solver=solver,
861 filename=name + "-" + solver._name,
862 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
863 output_precision=10,
864 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
865 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
866 clear_database_after_flush=clear_database_after_flush,
867 )
868 dump_into_database_action_set.descend_invocation_order = (
869 solver._action_set_compute_final_linear_combination.descend_invocation_order + 2
870 )
871 project.add_action_set_to_timestepping(dump_into_database_action_set)
872
873
875 AbstractCCZ4Solver,
877):
878 """!
879
880 CCZ4 solver using fourth-order finite differences and global adaptive time stepping incl enclave tasking
881
882 The constructor of this classs is straightforward and realises the standard
883 steps of any numerical implementation of the CCZ4 scheme:
884
885 1. Init the actual numerical scheme. This happens through the constructor
886 of the base class.
887
888 2. Add the header files that we need, i.e. those files which contain the
889 actual CCZ4 implementation.
890
891 3. Add some constants that any CCZ4 C++ code requires.
892
893 4. Set the actual implementation, i.e. link the generic PDE terms to the
894 CCZ4-specific function calls.
895
896 5. Add the CCZ4-specific postprocessing.
897
898 6. Switch to higher-order interpolation and restriction.
899
900 """
901
903 self,
904 name,
905 patch_size,
906 rk_order,
907 min_meshcell_h,
908 max_meshcell_h,
909 pde_terms_without_state,
910 second_order=False,
911 device_resident_rk=False,
912 ):
913 """!
914
915 Constructor
916
917 Calibrate the default time step size calibration with 1/16 to take into
918 account that we have a higher-order numerical scheme.
919
920 """
921 AbstractCCZ4Solver.__init__(self)
922 if second_order:
923 AbstractCCZ4Solver.enable_second_order(self)
924 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
925 self,
926 name=name,
927 patch_size=patch_size,
928 rk_order=rk_order,
929 unknowns=sum(self._FO_formulation_unknowns.values()),
930 auxiliary_variables=0,
931 min_meshcell_h=min_meshcell_h,
932 max_meshcell_h=max_meshcell_h,
934 pde_terms_without_state=pde_terms_without_state,
935 device_resident_rk=device_resident_rk,
936 plot_grid_properties=True
937 )
938
940
942 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
943 ncp=construct_FD4_ncp(),
944 flux=exahype2.solvers.PDETerms.None_Implementation,
945 source_term=construct_FD4_source_term(),
946 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
947 eigenvalues=construct_FD4_eigenvalues(),
948 )
949
951
952 """
953 # Use second order interpolation and restriction
954 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
955 self
956 )
957 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
958 self
959 )
960 """
961
962 # Use third order interpolation and restriction
963 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
964 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
965
966 """
967 # Use matrix interpolation and restriction
968 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
969 self
970 )
971 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
972 self
973 )
974 """
975
976 """
977 # Use tensor product interpolation and restriction
978 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
979 self,
980 "TP_linear_with_linear_extrap_normal_interp"
981 )
982 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
983 self,
984 "TP_average_normal_extrap"
985 )
986 """
987
989 self,
990 name,
991 coordinates,
992 project,
993 number_of_entries_between_two_db_flushes,
994 data_delta_between_two_snapsots,
995 time_delta_between_two_snapsots,
996 clear_database_after_flush,
997 tracer_unknowns,
998 ):
999 """!
1000
1001 Add tracer to project
1002
1003 This is a delegate to add_tracer_to_FD4_solver() which passes the
1004 object in as first argument.
1005
1006 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1007 some of the arguments. Most of them are simply piped through to this
1008 class.
1009
1010 @param project: exahype2.Project
1011
1012 @param tracer_unknowns: Integer
1013 You can set this variable to None. In this case, all variables are
1014 dumped.
1015
1016 """
1018 name,
1019 coordinates,
1020 project,
1021 self,
1022 number_of_entries_between_two_db_flushes,
1023 data_delta_between_two_snapsots,
1024 time_delta_between_two_snapsots,
1025 clear_database_after_flush,
1026 tracer_unknowns,
1027 )
1028
1029
1032):
1033 """!
1034
1035 CCZ4 solver using fourth-order finite differences and global adaptive time stepping without enclave tasking
1036
1037 Consult CCZ4Solver_FD4_GlobalAdaptiveTimeStepWithEnclaveTasking please.
1038
1039 """
1040
1042 self,
1043 name,
1044 patch_size,
1045 rk_order,
1046 min_meshcell_h,
1047 max_meshcell_h,
1048 second_order=False,
1049 ):
1050 """!
1051
1052 Constructor
1053
1054 Calibrate the default time step size calibration with 1/16 to take into
1055 account that we have a higher-order numerical scheme.
1056
1057 """
1058 AbstractCCZ4Solver.__init__(self)
1059 if second_order:
1060 AbstractCCZ4Solver.enable_second_order(self)
1061 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStep.__init__(
1062 self,
1063 name=name,
1064 patch_size=patch_size,
1065 rk_order=rk_order,
1066 unknowns=sum(self._FO_formulation_unknowns.values()),
1067 auxiliary_variables=0,
1068 min_meshcell_h=min_meshcell_h,
1069 max_meshcell_h=max_meshcell_h,
1071 )
1072
1074
1076 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1077 ncp=construct_FD4_ncp(),
1078 flux=exahype2.solvers.PDETerms.None_Implementation,
1079 source_term=construct_FD4_source_term(),
1080 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1081 eigenvalues=construct_FD4_eigenvalues(),
1082 )
1083
1085
1086 """
1087 # Use second order interpolation and restriction
1088 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
1089 self
1090 )
1091 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
1092 self
1093 )
1094 """
1095
1096 # Use third order interpolation and restriction
1097 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
1098 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
1099
1100 """
1101 # Use matrix interpolation and restriction
1102 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
1103 self
1104 )
1105 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
1106 self
1107 )
1108 """
1109
1110 """
1111 # Use tensor product interpolation and restriction
1112 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
1113 self,
1114 "TP_linear_with_linear_extrap_normal_interp"
1115 )
1116 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
1117 self,
1118 "TP_average_normal_extrap"
1119 )
1120 """
1121
1123 self,
1124 name,
1125 coordinates,
1126 project,
1127 number_of_entries_between_two_db_flushes,
1128 data_delta_between_two_snapsots,
1129 time_delta_between_two_snapsots,
1130 clear_database_after_flush,
1131 tracer_unknowns,
1132 ):
1133 """!
1134
1135 Add tracer to project
1136
1137 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1138 some of the arguments. Most of them are simply piped through to this
1139 class.
1140
1141 project: exahype2.Project
1142
1143 """
1145 name,
1146 coordinates,
1147 project,
1148 self,
1149 number_of_entries_between_two_db_flushes,
1150 data_delta_between_two_snapsots,
1151 time_delta_between_two_snapsots,
1152 clear_database_after_flush=clear_database_after_flush,
1153 tracer_unknowns=tracer_unknowns,
1154 )
1155
1156
1158 AbstractCCZ4Solver,
1160):
1161 """!
1162
1163 Variation of classic FD4 which relies on second order PDE formulation
1164
1165 The traditional ExaHyPE CCZ4 formulation is the first order formulation
1166 introduced by Dumbser et al. In this formulation, the second order terms
1167 in CCZ4 are substituted with helper variables which represent first order
1168 derivatives. While formally straightforward, keeping the whole system
1169 consistent and stricly hyperbolic is a different challenge.
1170
1171 In this revised version, we have to evolve the primary quantities of CCZ4
1172 and also the helper variables, which blows the overall system up to 59
1173 equations in its simplest form. The work by Dumbser and others suggest that
1174 this is a consistent and stable approach, but limited work is actually
1175 published on proper physical simulations. We therefore also implemented a
1176 second order PDE version within ExaHyPE.
1177
1178 This second order variant is not really second order from the start.
1179 Instead, we use the first order formulation, and we reconstruct the helper
1180 term via finite differences prior to the compute kernel application. That is,
1181 the compute kernels see variables representing first order derivatives, and
1182 they also evolve these guys. Afterwards, we throw away the evolved quantities
1183 and reconstruct them from the primary unknowns prior to the next time step.
1184
1185 This might not be super efficient (it would be faster to stick to the
1186 second order formulation right from the start), but it allows us to reuse
1187 the compute kernels written for the first order PDE formulation.
1188
1189 ## Data layout
1190
1191 We have now a smaller number of real unknowns, i.e. only those guys who
1192 belong to the "original" second-order formulation. The remaining quantities
1193 compared to a first-order formulation are technically material or auxiliary
1194 quantities. We model them as such, which allows ExaHyPE's data management
1195 to deal more efficiently with them.
1196
1197
1198 reconstruction_type: "4thOrder", "centralDifferences", "leftDifference", "rightDifference"
1199
1200 """
1201
1203 self,
1204 name,
1205 patch_size,
1206 rk_order,
1207 min_meshcell_h,
1208 max_meshcell_h,
1209 reconstruction_type,
1210 ):
1211 """!
1212
1213 Constructor
1214
1215 Calibrate the default time step size calibration with 1/16 to take into
1216 account that we have a higher-order numerical scheme.
1217
1218 """
1219 AbstractCCZ4Solver.__init__(self)
1220 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1221 self,
1222 name=name,
1223 patch_size=patch_size,
1224 rk_order=rk_order,
1226 auxiliary_variables=sum(self._FO_formulation_unknowns.values())
1228 min_meshcell_h=min_meshcell_h,
1229 max_meshcell_h=max_meshcell_h,
1230 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation
1231 / 16.0,
1232 )
1233
1235
1237 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1238 ncp="""
1239 double deltaQSerialised[NumberOfUnknowns*3];
1240 for (int i=0; i<NumberOfUnknowns; i++) {
1241 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
1242 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
1243 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
1244
1245 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1246 }
1247 ::applications::exahype2::ccz4::ncpSecondOrderFormulation(BTimesDeltaQ, Q, deltaQSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1248""",
1249 flux=exahype2.solvers.PDETerms.None_Implementation,
1250 source_term="""
1251 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1252 ::applications::exahype2::ccz4::sourceSecondOrderFormulation(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3);
1253""",
1254 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1255 eigenvalues="""
1256 // do we only set Q
1257 return ::applications::exahype2::ccz4::maxEigenvalueSecondOrderFormulation(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
1258""",
1259 )
1260
1262{
1263 constexpr int itmax = {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}} * {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}};
1264 int index = 0;
1265 for (int i=0;i<itmax;i++)
1266 {
1267 applications::exahype2::ccz4::enforceCCZ4constraintsSecondOrderFormulation( newQ+index );
1268 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1269 }
1270 }
1271"""
1272
1273 """
1274 # Use second order interpolation and restriction
1275 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
1276 self
1277 )
1278 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
1279 self
1280 )
1281 """
1282
1283 # Use third order interpolation and restriction
1284 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
1285 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
1286
1287 """
1288 # Use matrix interpolation and restriction
1289 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
1290 self
1291 )
1292 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
1293 self
1294 )
1295 """
1296
1297 """
1298 # Use tensor product interpolation and restriction
1299 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
1300 self,
1301 "TP_linear_with_linear_extrap_normal_interp"
1302 )
1303 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
1304 self,
1305 "TP_average_normal_extrap"
1306 )
1307 """
1308
1310 """
1311::exahype2::CellData reconstructedPatchData(
1312 oldQWithHalo,
1313 marker.x(),
1314 marker.h(),
1315 timeStamp,
1316 timeStepSize,
1317 nullptr // targetPatch
1318);
1319::applications::exahype2::ccz4::recomputeAuxiliaryVariablesFD4_"""
1320 + reconstruction_type
1321 + """(
1322 reconstructedPatchData,
1323 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
1324 3, // haloSize,
1325 {{NUMBER_OF_UNKNOWNS}},
1326 {{NUMBER_OF_AUXILIARY_VARIABLES}}
1327);
1328"""
1329 )
1330
1332 self,
1333 name,
1334 coordinates,
1335 project,
1336 number_of_entries_between_two_db_flushes,
1337 data_delta_between_two_snapsots,
1338 time_delta_between_two_snapsots,
1339 clear_database_after_flush,
1340 tracer_unknowns,
1341 ):
1342 """!
1343
1344 Add tracer to project
1345
1346 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1347 some of the arguments. Most of them are simply piped through to this
1348 class.
1349
1350 project: exahype2.Project
1351
1352 """
1353 number_of_attributes = (
1355 if tracer_unknowns == None
1356 else len(tracer_unknowns)
1357 )
1358 tracer_particles = project.add_tracer(
1359 name=name, attribute_count=number_of_attributes
1360 )
1362 particle_set=tracer_particles, coordinates=coordinates
1363 )
1364 init_action_set.descend_invocation_order = 0
1365 project.add_action_set_to_initialisation(init_action_set)
1366
1367 project_on_tracer_properties_kernel = ""
1368 if tracer_unknowns == None:
1369 project_on_tracer_properties_kernel = (
1370 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
1371 )
1372 elif len(tracer_unknowns) == 1:
1373 project_on_tracer_properties_kernel = "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
1374 i, tracer_unknowns.index(i)
1375 )
1376 else:
1377 project_on_tracer_properties_kernel = (
1378 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
1379 tracer_unknowns
1380 )
1381 .replace("[", "")
1382 .replace("]", "")
1383 )
1384
1385 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
1386 tracer_particles,
1387 self,
1388 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
1389 )
1390 tracing_action_set.descend_invocation_order = (
1391 self._action_set_compute_final_linear_combination.descend_invocation_order
1392 + 1
1393 )
1394 project.add_action_set_to_timestepping(tracing_action_set)
1395 project.add_action_set_to_initialisation(tracing_action_set)
1396
1397 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1398 particle_set=tracer_particles,
1399 solver=self,
1400 filename=name + "-" + self._name_name_name,
1401 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1402 output_precision=10,
1403 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1404 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1405 clear_database_after_flush=True,
1406 )
1407 dump_into_database_action_set.descend_invocation_order = (
1408 self._action_set_compute_final_linear_combination.descend_invocation_order
1409 + 2
1410 )
1411 project.add_action_set_to_timestepping(dump_into_database_action_set)
1412
1413
1415 return """
1416#if defined(GPUOffloadingOMP)
1417 double* dQdxSerialised = new double[NumberOfUnknowns*3];
1418#else
1419 double dQdxSerialised[NumberOfUnknowns*3];
1420#endif
1421 for (int i=0; i<NumberOfUnknowns; i++) {
1422 dQdxSerialised[i+0*NumberOfUnknowns] = 0.0;
1423 dQdxSerialised[i+1*NumberOfUnknowns] = 0.0;
1424 dQdxSerialised[i+2*NumberOfUnknowns] = 0.0;
1425
1426 dQdxSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1427 }
1428 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, dQdxSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1429#if defined(GPUOffloadingOMP)
1430 delete[] dQdxSerialised;
1431#endif
1432"""
1433
1434
1436 return """
1437 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1438 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
1439"""
1440
1441
1443 return """
1444 ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd, maxEigenvalue );
1445"""
1446
1447
1449 return """
1450{
1451 constexpr int itmax = ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1);
1452 int index = 0;
1453 for (int i=0;i<itmax;i++)
1454 {
1455 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
1456 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1457 }
1458 }
1459"""
1460
1461
1463 name,
1464 coordinates,
1465 project,
1466 self,
1467 number_of_entries_between_two_db_flushes,
1468 data_delta_between_two_snapsots,
1469 time_delta_between_two_snapsots,
1470 clear_database_after_flush,
1471 tracer_unknowns,
1472):
1473 number_of_attributes = (
1474 (self.unknowns + self.auxiliary_variables)
1475 if tracer_unknowns == None
1476 else len(tracer_unknowns)
1477 )
1478 tracer_particles = project.add_tracer(
1479 name=name, attribute_count=number_of_attributes
1480 )
1482 particle_set=tracer_particles, coordinates=coordinates
1483 )
1484 init_action_set.descend_invocation_order = 0
1485 project.add_action_set_to_initialisation(init_action_set)
1486
1487 assert tracer_unknowns == None
1488
1490 tracer_particles,
1491 solver=self,
1492 project_on_tracer_properties_kernel="::exahype2::dg::projectAllValuesOntoParticle",
1493 )
1494 tracing_action_set.descend_invocation_order = (
1495 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1496 + 1
1497 )
1498 project.add_action_set_to_timestepping(tracing_action_set)
1499 project.add_action_set_to_initialisation(tracing_action_set)
1500
1501 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1502 particle_set=tracer_particles,
1503 solver=self,
1504 filename=name + "-" + self._name,
1505 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1506 output_precision=10,
1507 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1508 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1509 clear_database_after_flush=clear_database_after_flush,
1510 )
1511 dump_into_database_action_set.descend_invocation_order = (
1512 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1513 + 1
1514 )
1515 project.add_action_set_to_timestepping(dump_into_database_action_set)
1516
1517
1519 AbstractCCZ4Solver,
1521):
1522 """!
1523
1524 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1525
1526 The constructor of this classs is straightforward and realises the standard
1527 steps of any numerical implementation of the CCZ4 scheme:
1528
1529 1. Init the actual numerical scheme. This happens through the constructor
1530 of the base class.
1531
1532 2. Add the header files that we need, i.e. those files which contain the
1533 actual CCZ4 implementation.
1534
1535 3. Add some constants that any CCZ4 C++ code requires.
1536
1537 4. Set the actual implementation, i.e. link the generic PDE terms to the
1538 CCZ4-specific function calls.
1539
1540 5. Add the CCZ4-specific postprocessing.
1541
1542 6. Switch to higher-order interpolation and restriction.
1543
1544 """
1545
1547 self,
1548 name,
1549 rk_order,
1550 polynomials,
1551 min_cell_h,
1552 max_cell_h,
1553 pde_terms_without_state,
1554 ):
1555 """!
1556
1557 Construct solver with enclave tasking
1558
1559 """
1560 AbstractCCZ4Solver.__init__(self)
1561 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1562 self,
1563 name=name,
1564 rk_order=rk_order,
1565 polynomials=polynomials,
1566 unknowns=sum(self._FO_formulation_unknowns.values()),
1567 auxiliary_variables=0,
1568 min_cell_h=min_cell_h,
1569 max_cell_h=max_cell_h,
1570 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1571 pde_terms_without_state=pde_terms_without_state,
1572 )
1573
1575
1577 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1578 ncp=construct_DG_ncp(),
1579 flux=exahype2.solvers.PDETerms.None_Implementation,
1580 source_term=construct_DG_source_term(),
1581 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1582 eigenvalues=construct_DG_eigenvalues(),
1583 )
1584
1587 )
1588
1590 self,
1591 name,
1592 coordinates,
1593 project,
1594 number_of_entries_between_two_db_flushes,
1595 data_delta_between_two_snapsots,
1596 time_delta_between_two_snapsots,
1597 clear_database_after_flush,
1598 tracer_unknowns,
1599 ):
1600 """!
1601
1602 Add tracer to project
1603
1604 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1605 some of the arguments. Most of them are simply piped through to this
1606 class.
1607
1608 At this point, we have not yet created the Peano 4 project. Therefore, we
1609 have not yet befilled the time stepping action set.
1610
1611 project: exahype2.Project
1612
1613 """
1615 name,
1616 coordinates,
1617 project,
1618 self,
1619 number_of_entries_between_two_db_flushes,
1620 data_delta_between_two_snapsots,
1621 time_delta_between_two_snapsots,
1622 clear_database_after_flush,
1623 tracer_unknowns,
1624 )
1625
1626
1628 AbstractCCZ4Solver,
1630):
1631 """!
1632
1633 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1634
1635 The constructor of this classs is straightforward and realises the standard
1636 steps of any numerical implementation of the CCZ4 scheme:
1637
1638 1. Init the actual numerical scheme. This happens through the constructor
1639 of the base class.
1640
1641 2. Add the header files that we need, i.e. those files which contain the
1642 actual CCZ4 implementation.
1643
1644 3. Add some constants that any CCZ4 C++ code requires.
1645
1646 4. Set the actual implementation, i.e. link the generic PDE terms to the
1647 CCZ4-specific function calls.
1648
1649 5. Add the CCZ4-specific postprocessing.
1650
1651 6. Switch to higher-order interpolation and restriction.
1652
1653 """
1654
1656 self,
1657 name,
1658 rk_order,
1659 polynomials,
1660 min_cell_h,
1661 max_cell_h,
1662 pde_terms_without_state,
1663 ):
1664 """!
1665
1666 Construct solver with enclave tasking
1667
1668 """
1669 AbstractCCZ4Solver.__init__(self)
1670 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStep.__init__(
1671 self,
1672 name=name,
1673 rk_order=rk_order,
1674 polynomials=polynomials,
1675 unknowns=sum(self._FO_formulation_unknowns.values()),
1676 auxiliary_variables=0,
1677 min_cell_h=min_cell_h,
1678 max_cell_h=max_cell_h,
1679 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1680 pde_terms_without_state=pde_terms_without_state,
1681 )
1682
1684
1686 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1687 ncp=construct_DG_ncp(),
1688 flux=exahype2.solvers.PDETerms.None_Implementation,
1689 source_term=construct_DG_source_term(),
1690 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1691 eigenvalues=construct_DG_eigenvalues(),
1692 )
1693
1696 )
1697
1699 self,
1700 name,
1701 coordinates,
1702 project,
1703 number_of_entries_between_two_db_flushes,
1704 data_delta_between_two_snapsots,
1705 time_delta_between_two_snapsots,
1706 clear_database_after_flush,
1707 tracer_unknowns,
1708 ):
1709 """!
1710
1711 Add tracer to project
1712
1713 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1714 some of the arguments. Most of them are simply piped through to this
1715 class.
1716
1717 At this point, we have not yet created the Peano 4 project. Therefore, we
1718 have not yet befilled the time stepping action set.
1719
1720 project: exahype2.Project
1721
1722 """
1724 name,
1725 coordinates,
1726 project,
1727 self,
1728 number_of_entries_between_two_db_flushes,
1729 data_delta_between_two_snapsots,
1730 time_delta_between_two_snapsots,
1731 clear_database_after_flush,
1732 tracer_unknowns,
1733 )
Abstract base class for any CCZ4 solver.
Definition CCZ4Solver.py:8
__init__(self)
Constructor.
_add_standard_includes(self)
Add the headers for the compute kernels and initial condition implementations.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns=None)
Add tracer to project.
add_all_solver_constants(self)
Add domain-specific constants.
add_makefile_parameters(self, peano4_project, path_of_ccz4_application)
Add include path and minimal required cpp files to makefile.
CCZ4 solver using fourth-order finite differences and global adaptive time stepping incl enclave task...
__init__(self, name, patch_size, rk_order, min_meshcell_h, max_meshcell_h, pde_terms_without_state, second_order=False, device_resident_rk=False)
Constructor.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
CCZ4 solver using fourth-order finite differences and global adaptive time stepping without enclave t...
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
__init__(self, name, patch_size, rk_order, min_meshcell_h, max_meshcell_h, second_order=False)
Constructor.
Variation of classic FD4 which relies on second order PDE formulation.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
__init__(self, name, patch_size, rk_order, min_meshcell_h, max_meshcell_h, reconstruction_type)
Constructor.
CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
__init__(self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state)
Construct solver with enclave tasking and adaptive time stepping.
CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
__init__(self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state)
Constructor.
CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking.
__init__(self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state)
Constructor.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
__init__(self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state)
Constructor.
CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave t...
__init__(self, name, rk_order, polynomials, min_cell_h, max_cell_h, pde_terms_without_state)
Construct solver with enclave tasking.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave t...
__init__(self, name, rk_order, polynomials, min_cell_h, max_cell_h, pde_terms_without_state)
Construct solver with enclave tasking.
add_tracer(self, name, coordinates, project, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
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...
postprocess_updated_patch(self)
Definition FV.py:1587
postprocess_updated_patch(self, kernel)
Define a postprocessing routine over the data.
Definition FV.py:1592
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=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=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...
postprocess_updated_cell_after_final_linear_combination(self, kernel)
Define a postprocessing routine over the data.
set_implementation(self, flux=None, ncp=None, eigenvalues=None, boundary_conditions=None, refinement_criterion=None, initial_conditions=None, source_term=None, point_source=None, 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, point_source=None, 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...
RKDG solver with Rusanov Riemann solver employing global adaptive time stepping.
set_implementation(self, flux=None, ncp=None, eigenvalues=None, boundary_conditions=None, refinement_criterion=None, initial_conditions=None, source_term=None, point_source=None, 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...
postprocess_updated_patch(self, kernel)
Define a postprocessing routine over the data.
preprocess_reconstructed_patch(self, kernel)
Please consult exahype2.solvers.fv.FV.preprocess_reconstructed_patch() for a documentation on this ro...
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...
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, reconstruction_with_rk=False)
If you pass in User_Defined, then the generator will create C++ stubs that you have to befill manuall...
Particle tracing over the Finite Volumes solver.
construct_FD4_ncp()
add_tracer_to_FV_solver(name, coordinates, project, solver, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
Add tracer to project.
construct_FV_source_term()
add_tracer_to_DG_solver(name, coordinates, project, self, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
construct_FV_eigenvalues()
add_tracer_to_FD4_solver(name, coordinates, project, solver, number_of_entries_between_two_db_flushes, data_delta_between_two_snapsots, time_delta_between_two_snapsots, clear_database_after_flush, tracer_unknowns)
I realise this as a separate routine, as we need it for all FD4 flavours.
construct_FD4_postprocessing_kernel()
construct_FD4_source_term()
construct_DG_eigenvalues()
construct_FV_postprocessing_kernel()
construct_FD4_eigenvalues()
construct_DG_postprocessing_kernel()
construct_DG_source_term()