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 ):
912 """!
913
914 Constructor
915
916 Calibrate the default time step size calibration with 1/16 to take into
917 account that we have a higher-order numerical scheme.
918
919 """
920 AbstractCCZ4Solver.__init__(self)
921 if second_order:
922 AbstractCCZ4Solver.enable_second_order(self)
923 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
924 self,
925 name=name,
926 patch_size=patch_size,
927 rk_order=rk_order,
928 unknowns=sum(self._FO_formulation_unknowns.values()),
929 auxiliary_variables=0,
930 min_meshcell_h=min_meshcell_h,
931 max_meshcell_h=max_meshcell_h,
933 pde_terms_without_state=pde_terms_without_state,
934 )
935
937
939 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
940 ncp=construct_FD4_ncp(),
941 flux=exahype2.solvers.PDETerms.None_Implementation,
942 source_term=construct_FD4_source_term(),
943 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
944 eigenvalues=construct_FD4_eigenvalues(),
945 )
946
948
949 """
950 # Use second order interpolation and restriction
951 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
952 self
953 )
954 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
955 self
956 )
957 """
958
959 # Use third order interpolation and restriction
960 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
961 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
962
963 """
964 # Use matrix interpolation and restriction
965 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
966 self
967 )
968 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
969 self
970 )
971 """
972
973 """
974 # Use tensor product interpolation and restriction
975 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
976 self,
977 "TP_linear_with_linear_extrap_normal_interp"
978 )
979 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
980 self,
981 "TP_average_normal_extrap"
982 )
983 """
984
986 self,
987 name,
988 coordinates,
989 project,
990 number_of_entries_between_two_db_flushes,
991 data_delta_between_two_snapsots,
992 time_delta_between_two_snapsots,
993 clear_database_after_flush,
994 tracer_unknowns,
995 ):
996 """!
997
998 Add tracer to project
999
1000 This is a delegate to add_tracer_to_FD4_solver() which passes the
1001 object in as first argument.
1002
1003 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1004 some of the arguments. Most of them are simply piped through to this
1005 class.
1006
1007 @param project: exahype2.Project
1008
1009 @param tracer_unknowns: Integer
1010 You can set this variable to None. In this case, all variables are
1011 dumped.
1012
1013 """
1015 name,
1016 coordinates,
1017 project,
1018 self,
1019 number_of_entries_between_two_db_flushes,
1020 data_delta_between_two_snapsots,
1021 time_delta_between_two_snapsots,
1022 clear_database_after_flush,
1023 tracer_unknowns,
1024 )
1025
1026
1029):
1030 """!
1031
1032 CCZ4 solver using fourth-order finite differences and global adaptive time stepping without enclave tasking
1033
1034 Consult CCZ4Solver_FD4_GlobalAdaptiveTimeStepWithEnclaveTasking please.
1035
1036 """
1037
1039 self,
1040 name,
1041 patch_size,
1042 rk_order,
1043 min_meshcell_h,
1044 max_meshcell_h,
1045 second_order=False,
1046 ):
1047 """!
1048
1049 Constructor
1050
1051 Calibrate the default time step size calibration with 1/16 to take into
1052 account that we have a higher-order numerical scheme.
1053
1054 """
1055 AbstractCCZ4Solver.__init__(self)
1056 if second_order:
1057 AbstractCCZ4Solver.enable_second_order(self)
1058 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStep.__init__(
1059 self,
1060 name=name,
1061 patch_size=patch_size,
1062 rk_order=rk_order,
1063 unknowns=sum(self._FO_formulation_unknowns.values()),
1064 auxiliary_variables=0,
1065 min_meshcell_h=min_meshcell_h,
1066 max_meshcell_h=max_meshcell_h,
1068 )
1069
1071
1073 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1074 ncp=construct_FD4_ncp(),
1075 flux=exahype2.solvers.PDETerms.None_Implementation,
1076 source_term=construct_FD4_source_term(),
1077 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1078 eigenvalues=construct_FD4_eigenvalues(),
1079 )
1080
1082
1083 """
1084 # Use second order interpolation and restriction
1085 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
1086 self
1087 )
1088 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
1089 self
1090 )
1091 """
1092
1093 # Use third order interpolation and restriction
1094 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
1095 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
1096
1097 """
1098 # Use matrix interpolation and restriction
1099 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
1100 self
1101 )
1102 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
1103 self
1104 )
1105 """
1106
1107 """
1108 # Use tensor product interpolation and restriction
1109 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
1110 self,
1111 "TP_linear_with_linear_extrap_normal_interp"
1112 )
1113 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
1114 self,
1115 "TP_average_normal_extrap"
1116 )
1117 """
1118
1120 self,
1121 name,
1122 coordinates,
1123 project,
1124 number_of_entries_between_two_db_flushes,
1125 data_delta_between_two_snapsots,
1126 time_delta_between_two_snapsots,
1127 clear_database_after_flush,
1128 tracer_unknowns,
1129 ):
1130 """!
1131
1132 Add tracer to project
1133
1134 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1135 some of the arguments. Most of them are simply piped through to this
1136 class.
1137
1138 project: exahype2.Project
1139
1140 """
1142 name,
1143 coordinates,
1144 project,
1145 self,
1146 number_of_entries_between_two_db_flushes,
1147 data_delta_between_two_snapsots,
1148 time_delta_between_two_snapsots,
1149 clear_database_after_flush=clear_database_after_flush,
1150 tracer_unknowns=tracer_unknowns,
1151 )
1152
1153
1155 AbstractCCZ4Solver,
1157):
1158 """!
1159
1160 Variation of classic FD4 which relies on second order PDE formulation
1161
1162 The traditional ExaHyPE CCZ4 formulation is the first order formulation
1163 introduced by Dumbser et al. In this formulation, the second order terms
1164 in CCZ4 are substituted with helper variables which represent first order
1165 derivatives. While formally straightforward, keeping the whole system
1166 consistent and stricly hyperbolic is a different challenge.
1167
1168 In this revised version, we have to evolve the primary quantities of CCZ4
1169 and also the helper variables, which blows the overall system up to 59
1170 equations in its simplest form. The work by Dumbser and others suggest that
1171 this is a consistent and stable approach, but limited work is actually
1172 published on proper physical simulations. We therefore also implemented a
1173 second order PDE version within ExaHyPE.
1174
1175 This second order variant is not really second order from the start.
1176 Instead, we use the first order formulation, and we reconstruct the helper
1177 term via finite differences prior to the compute kernel application. That is,
1178 the compute kernels see variables representing first order derivatives, and
1179 they also evolve these guys. Afterwards, we throw away the evolved quantities
1180 and reconstruct them from the primary unknowns prior to the next time step.
1181
1182 This might not be super efficient (it would be faster to stick to the
1183 second order formulation right from the start), but it allows us to reuse
1184 the compute kernels written for the first order PDE formulation.
1185
1186 ## Data layout
1187
1188 We have now a smaller number of real unknowns, i.e. only those guys who
1189 belong to the "original" second-order formulation. The remaining quantities
1190 compared to a first-order formulation are technically material or auxiliary
1191 quantities. We model them as such, which allows ExaHyPE's data management
1192 to deal more efficiently with them.
1193
1194
1195 reconstruction_type: "4thOrder", "centralDifferences", "leftDifference", "rightDifference"
1196
1197 """
1198
1200 self,
1201 name,
1202 patch_size,
1203 rk_order,
1204 min_meshcell_h,
1205 max_meshcell_h,
1206 reconstruction_type,
1207 ):
1208 """!
1209
1210 Constructor
1211
1212 Calibrate the default time step size calibration with 1/16 to take into
1213 account that we have a higher-order numerical scheme.
1214
1215 """
1216 AbstractCCZ4Solver.__init__(self)
1217 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1218 self,
1219 name=name,
1220 patch_size=patch_size,
1221 rk_order=rk_order,
1223 auxiliary_variables=sum(self._FO_formulation_unknowns.values())
1225 min_meshcell_h=min_meshcell_h,
1226 max_meshcell_h=max_meshcell_h,
1227 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation
1228 / 16.0,
1229 )
1230
1232
1234 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1235 ncp="""
1236 double deltaQSerialised[NumberOfUnknowns*3];
1237 for (int i=0; i<NumberOfUnknowns; i++) {
1238 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
1239 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
1240 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
1241
1242 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1243 }
1244 ::applications::exahype2::ccz4::ncpSecondOrderFormulation(BTimesDeltaQ, Q, deltaQSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1245""",
1246 flux=exahype2.solvers.PDETerms.None_Implementation,
1247 source_term="""
1248 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1249 ::applications::exahype2::ccz4::sourceSecondOrderFormulation(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3);
1250""",
1251 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1252 eigenvalues="""
1253 // do we only set Q
1254 return ::applications::exahype2::ccz4::maxEigenvalueSecondOrderFormulation(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
1255""",
1256 )
1257
1259{
1260 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}};
1261 int index = 0;
1262 for (int i=0;i<itmax;i++)
1263 {
1264 applications::exahype2::ccz4::enforceCCZ4constraintsSecondOrderFormulation( newQ+index );
1265 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1266 }
1267 }
1268"""
1269
1270 """
1271 # Use second order interpolation and restriction
1272 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
1273 self
1274 )
1275 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
1276 self
1277 )
1278 """
1279
1280 # Use third order interpolation and restriction
1281 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
1282 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
1283
1284 """
1285 # Use matrix interpolation and restriction
1286 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
1287 self
1288 )
1289 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
1290 self
1291 )
1292 """
1293
1294 """
1295 # Use tensor product interpolation and restriction
1296 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
1297 self,
1298 "TP_linear_with_linear_extrap_normal_interp"
1299 )
1300 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
1301 self,
1302 "TP_average_normal_extrap"
1303 )
1304 """
1305
1307 """
1308::exahype2::CellData reconstructedPatchData(
1309 oldQWithHalo,
1310 marker.x(),
1311 marker.h(),
1312 timeStamp,
1313 timeStepSize,
1314 nullptr // targetPatch
1315);
1316::applications::exahype2::ccz4::recomputeAuxiliaryVariablesFD4_"""
1317 + reconstruction_type
1318 + """(
1319 reconstructedPatchData,
1320 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
1321 3, // haloSize,
1322 {{NUMBER_OF_UNKNOWNS}},
1323 {{NUMBER_OF_AUXILIARY_VARIABLES}}
1324);
1325"""
1326 )
1327
1329 self,
1330 name,
1331 coordinates,
1332 project,
1333 number_of_entries_between_two_db_flushes,
1334 data_delta_between_two_snapsots,
1335 time_delta_between_two_snapsots,
1336 clear_database_after_flush,
1337 tracer_unknowns,
1338 ):
1339 """!
1340
1341 Add tracer to project
1342
1343 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1344 some of the arguments. Most of them are simply piped through to this
1345 class.
1346
1347 project: exahype2.Project
1348
1349 """
1350 number_of_attributes = (
1352 if tracer_unknowns == None
1353 else len(tracer_unknowns)
1354 )
1355 tracer_particles = project.add_tracer(
1356 name=name, attribute_count=number_of_attributes
1357 )
1359 particle_set=tracer_particles, coordinates=coordinates
1360 )
1361 init_action_set.descend_invocation_order = 0
1362 project.add_action_set_to_initialisation(init_action_set)
1363
1364 project_on_tracer_properties_kernel = ""
1365 if tracer_unknowns == None:
1366 project_on_tracer_properties_kernel = (
1367 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
1368 )
1369 elif len(tracer_unknowns) == 1:
1370 project_on_tracer_properties_kernel = "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
1371 i, tracer_unknowns.index(i)
1372 )
1373 else:
1374 project_on_tracer_properties_kernel = (
1375 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
1376 tracer_unknowns
1377 )
1378 .replace("[", "")
1379 .replace("]", "")
1380 )
1381
1382 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
1383 tracer_particles,
1384 self,
1385 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
1386 )
1387 tracing_action_set.descend_invocation_order = (
1388 self._action_set_compute_final_linear_combination.descend_invocation_order
1389 + 1
1390 )
1391 project.add_action_set_to_timestepping(tracing_action_set)
1392 project.add_action_set_to_initialisation(tracing_action_set)
1393
1394 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1395 particle_set=tracer_particles,
1396 solver=self,
1397 filename=name + "-" + self._name_name_name,
1398 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1399 output_precision=10,
1400 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1401 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1402 clear_database_after_flush=True,
1403 )
1404 dump_into_database_action_set.descend_invocation_order = (
1405 self._action_set_compute_final_linear_combination.descend_invocation_order
1406 + 2
1407 )
1408 project.add_action_set_to_timestepping(dump_into_database_action_set)
1409
1410
1412 return """
1413#if defined(GPUOffloadingOMP)
1414 double* dQdxSerialised = new double[NumberOfUnknowns*3];
1415#else
1416 double dQdxSerialised[NumberOfUnknowns*3];
1417#endif
1418 for (int i=0; i<NumberOfUnknowns; i++) {
1419 dQdxSerialised[i+0*NumberOfUnknowns] = 0.0;
1420 dQdxSerialised[i+1*NumberOfUnknowns] = 0.0;
1421 dQdxSerialised[i+2*NumberOfUnknowns] = 0.0;
1422
1423 dQdxSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1424 }
1425 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, dQdxSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1426#if defined(GPUOffloadingOMP)
1427 delete[] dQdxSerialised;
1428#endif
1429"""
1430
1431
1433 return """
1434 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1435 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
1436"""
1437
1438
1440 return """
1441 ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd, maxEigenvalue );
1442"""
1443
1444
1446 return """
1447{
1448 constexpr int itmax = ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1);
1449 int index = 0;
1450 for (int i=0;i<itmax;i++)
1451 {
1452 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
1453 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1454 }
1455 }
1456"""
1457
1458
1460 name,
1461 coordinates,
1462 project,
1463 self,
1464 number_of_entries_between_two_db_flushes,
1465 data_delta_between_two_snapsots,
1466 time_delta_between_two_snapsots,
1467 clear_database_after_flush,
1468 tracer_unknowns,
1469):
1470 number_of_attributes = (
1471 (self.unknowns + self.auxiliary_variables)
1472 if tracer_unknowns == None
1473 else len(tracer_unknowns)
1474 )
1475 tracer_particles = project.add_tracer(
1476 name=name, attribute_count=number_of_attributes
1477 )
1479 particle_set=tracer_particles, coordinates=coordinates
1480 )
1481 init_action_set.descend_invocation_order = 0
1482 project.add_action_set_to_initialisation(init_action_set)
1483
1484 assert tracer_unknowns == None
1485
1487 tracer_particles,
1488 solver=self,
1489 project_on_tracer_properties_kernel="::exahype2::dg::projectAllValuesOntoParticle",
1490 )
1491 tracing_action_set.descend_invocation_order = (
1492 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1493 + 1
1494 )
1495 project.add_action_set_to_timestepping(tracing_action_set)
1496 project.add_action_set_to_initialisation(tracing_action_set)
1497
1498 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1499 particle_set=tracer_particles,
1500 solver=self,
1501 filename=name + "-" + self._name,
1502 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1503 output_precision=10,
1504 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1505 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1506 clear_database_after_flush=clear_database_after_flush,
1507 )
1508 dump_into_database_action_set.descend_invocation_order = (
1509 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1510 + 1
1511 )
1512 project.add_action_set_to_timestepping(dump_into_database_action_set)
1513
1514
1516 AbstractCCZ4Solver,
1518):
1519 """!
1520
1521 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1522
1523 The constructor of this classs is straightforward and realises the standard
1524 steps of any numerical implementation of the CCZ4 scheme:
1525
1526 1. Init the actual numerical scheme. This happens through the constructor
1527 of the base class.
1528
1529 2. Add the header files that we need, i.e. those files which contain the
1530 actual CCZ4 implementation.
1531
1532 3. Add some constants that any CCZ4 C++ code requires.
1533
1534 4. Set the actual implementation, i.e. link the generic PDE terms to the
1535 CCZ4-specific function calls.
1536
1537 5. Add the CCZ4-specific postprocessing.
1538
1539 6. Switch to higher-order interpolation and restriction.
1540
1541 """
1542
1544 self,
1545 name,
1546 rk_order,
1547 polynomials,
1548 min_cell_h,
1549 max_cell_h,
1550 pde_terms_without_state,
1551 ):
1552 """!
1553
1554 Construct solver with enclave tasking
1555
1556 """
1557 AbstractCCZ4Solver.__init__(self)
1558 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1559 self,
1560 name=name,
1561 rk_order=rk_order,
1562 polynomials=polynomials,
1563 unknowns=sum(self._FO_formulation_unknowns.values()),
1564 auxiliary_variables=0,
1565 min_cell_h=min_cell_h,
1566 max_cell_h=max_cell_h,
1567 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1568 pde_terms_without_state=pde_terms_without_state,
1569 )
1570
1572
1574 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1575 ncp=construct_DG_ncp(),
1576 flux=exahype2.solvers.PDETerms.None_Implementation,
1577 source_term=construct_DG_source_term(),
1578 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1579 eigenvalues=construct_DG_eigenvalues(),
1580 )
1581
1584 )
1585
1587 self,
1588 name,
1589 coordinates,
1590 project,
1591 number_of_entries_between_two_db_flushes,
1592 data_delta_between_two_snapsots,
1593 time_delta_between_two_snapsots,
1594 clear_database_after_flush,
1595 tracer_unknowns,
1596 ):
1597 """!
1598
1599 Add tracer to project
1600
1601 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1602 some of the arguments. Most of them are simply piped through to this
1603 class.
1604
1605 At this point, we have not yet created the Peano 4 project. Therefore, we
1606 have not yet befilled the time stepping action set.
1607
1608 project: exahype2.Project
1609
1610 """
1612 name,
1613 coordinates,
1614 project,
1615 self,
1616 number_of_entries_between_two_db_flushes,
1617 data_delta_between_two_snapsots,
1618 time_delta_between_two_snapsots,
1619 clear_database_after_flush,
1620 tracer_unknowns,
1621 )
1622
1623
1625 AbstractCCZ4Solver,
1627):
1628 """!
1629
1630 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1631
1632 The constructor of this classs is straightforward and realises the standard
1633 steps of any numerical implementation of the CCZ4 scheme:
1634
1635 1. Init the actual numerical scheme. This happens through the constructor
1636 of the base class.
1637
1638 2. Add the header files that we need, i.e. those files which contain the
1639 actual CCZ4 implementation.
1640
1641 3. Add some constants that any CCZ4 C++ code requires.
1642
1643 4. Set the actual implementation, i.e. link the generic PDE terms to the
1644 CCZ4-specific function calls.
1645
1646 5. Add the CCZ4-specific postprocessing.
1647
1648 6. Switch to higher-order interpolation and restriction.
1649
1650 """
1651
1653 self,
1654 name,
1655 rk_order,
1656 polynomials,
1657 min_cell_h,
1658 max_cell_h,
1659 pde_terms_without_state,
1660 ):
1661 """!
1662
1663 Construct solver with enclave tasking
1664
1665 """
1666 AbstractCCZ4Solver.__init__(self)
1667 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStep.__init__(
1668 self,
1669 name=name,
1670 rk_order=rk_order,
1671 polynomials=polynomials,
1672 unknowns=sum(self._FO_formulation_unknowns.values()),
1673 auxiliary_variables=0,
1674 min_cell_h=min_cell_h,
1675 max_cell_h=max_cell_h,
1676 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1677 pde_terms_without_state=pde_terms_without_state,
1678 )
1679
1681
1683 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1684 ncp=construct_DG_ncp(),
1685 flux=exahype2.solvers.PDETerms.None_Implementation,
1686 source_term=construct_DG_source_term(),
1687 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1688 eigenvalues=construct_DG_eigenvalues(),
1689 )
1690
1693 )
1694
1696 self,
1697 name,
1698 coordinates,
1699 project,
1700 number_of_entries_between_two_db_flushes,
1701 data_delta_between_two_snapsots,
1702 time_delta_between_two_snapsots,
1703 clear_database_after_flush,
1704 tracer_unknowns,
1705 ):
1706 """!
1707
1708 Add tracer to project
1709
1710 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1711 some of the arguments. Most of them are simply piped through to this
1712 class.
1713
1714 At this point, we have not yet created the Peano 4 project. Therefore, we
1715 have not yet befilled the time stepping action set.
1716
1717 project: exahype2.Project
1718
1719 """
1721 name,
1722 coordinates,
1723 project,
1724 self,
1725 number_of_entries_between_two_db_flushes,
1726 data_delta_between_two_snapsots,
1727 time_delta_between_two_snapsots,
1728 clear_database_after_flush,
1729 tracer_unknowns,
1730 )
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...
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, pde_terms_without_state, second_order=False)
Constructor.
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()