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 }
141 "CCZ4ds": 1.0,
142 "CCZ4c": 1.0,
143 "CCZ4e": 1.0,
144 "CCZ4f": 0.75,
145 "CCZ4bs": 0.0,
146 "CCZ4sk": 0.0,
147 "CCZ4xi": 1.0,
148 "CCZ4itau": 1.0,
149 "CCZ4eta": 1.0,
150 "CCZ4k1": 0.1,
151 "CCZ4k2": 0.0,
152 "CCZ4k3": 0.5,
153 "CCZ4GLMc": 1.2,
154 "CCZ4GLMd": 2.0,
155 "CCZ4mu": 0.2,
156 }
157
165 """!
166
167 Add the headers for the compute kernels and initial condition implementations
168
169 Usually called by the subclass constructor.
170
171 """
172 self.add_user_action_set_includes(
173 """
174#include "CCZ4Kernels.h"
175#include "SecondOrderAuxiliaryVariablesReconstruction.h"
176"""
177 )
178 self.add_user_solver_includes(
179 """
180#include "CCZ4Kernels.h"
181#include "InitialValues.h"
182#include "SecondOrderAuxiliaryVariablesReconstruction.h"
183#include <cstring>
184"""
185 )
186
188 """!
189
190 Add domain-specific constants
191
192 I need a couple of constants. I could either replace them directly
193 within the Python snippets below, but I prefer here to go a different
194 way and to export them as proper C++ constants.
195
196 There are two ways to inject solver constants into Peano: We can either
197 add them to the Makefile as global const expressions, or we can add
198 them to the ExaHyPE2 solver. The latter is the route we go down here,
199 as these constants logically belong to the solver and not to the project.
200
201 This operation uses the parent class' add_solver_constants(). You still
202 can use this operation to add further parameters. Or you can, as a user,
203 always add new entries to integer_constants or double_constants and then
204 call this routine rather than adding individual constants one by one.
205
206 """
207 for key, value in self.integer_constants.items():
208 self.add_solver_constants(
209 "static constexpr int {} = {};".format(key, value)
210 )
211 for key, value in self.double_constants.items():
212 self.add_solver_constants(
213 "static constexpr double {} = {};".format(key, value)
214 )
215
216 def add_makefile_parameters(self, peano4_project, path_of_ccz4_application):
217 """!
218
219 Add include path and minimal required cpp files to makefile
220
221 If you have multiple CCZ4 solvers, i.e. different solvers of CCZ4 or multiple
222 instances of the CCZ4 type, please call this operation only once on one of
223 your solvers. At the moment, I add hte following cpp files to the setup:
224
225 - InitialValues.cpp
226 - CCZ4Kernels.cpp
227 - SecondOrderAuxiliaryVariablesReconstruction.cpp
228
229 You can always add further files via
230 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231 peano4_project.output.makefile.add_cpp_file( "mypath/myfile.cpp" )
232 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
233
234 """
235 if path_of_ccz4_application[-1] != "/":
236 path_of_ccz4_application += "/"
237
238 peano4_project.output.makefile.add_cpp_file(
239 path_of_ccz4_application + "InitialValues.cpp"
240 )
241 peano4_project.output.makefile.add_cpp_file(
242 path_of_ccz4_application + "CCZ4Kernels.cpp"
243 )
244 peano4_project.output.makefile.add_cpp_file(
245 path_of_ccz4_application + "SecondOrderAuxiliaryVariablesReconstruction.cpp"
246 )
247 peano4_project.output.makefile.add_header_search_path(path_of_ccz4_application)
248
249 @abstractmethod
251 self,
252 name,
253 coordinates,
254 project,
255 number_of_entries_between_two_db_flushes,
256 data_delta_between_two_snapsots,
257 time_delta_between_two_snapsots,
258 clear_database_after_flush,
259 tracer_unknowns=None,
260 ):
261 """!
262
263 Add tracer to project
264
265 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
266 some of the arguments. Most of them are simply piped through to this
267 class.
268
269 The tracer is given a name and initial coordinates (list of three-tuples).
270 We need to know the underlying project as well, as we have to add the
271 tracing to the time stepping and the database update to the plotting.
272 ~~~~~~~~~~~~~~~~~~~~~~~
273 project.add_action_set_to_timestepping(my_interpolation)
274 project.add_action_set_to_timestepping(exahype2.tracer.DumpTracerIntoDatabase(
275 particle_set=tracer_particles,
276 solver=self,
277 filename=name + "-" + self._name,
278 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
279 output_precision=10,
280 data_delta_between_two_snapsots = data_delta_between_two_snapsots,
281 time_delta_between_two_snapsots = time_delta_between_two_snapsots,
282 clear_database_after_flush = True,
283 ))
284 ~~~~~~~~~~~~~~~~~~~~~~~
285
286 """
287 assert "should not be called"
288 pass
289
290
293):
294 """!
295
296 CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking
297
298 Please consult CCZ4Solver_FV_GlobalAdaptiveTimeStepWithEnclaveTasking.
299
300 """
301
303 self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state
304 ):
305 AbstractCCZ4Solver.__init__(self)
306 exahype2.solvers.fv.rusanov.GlobalAdaptiveTimeStep.__init__(
307 self,
308 name=name,
309 patch_size=patch_size,
310 unknowns=sum(self._FO_formulation_unknowns.values()),
311 auxiliary_variables=0,
312 min_volume_h=min_volume_h,
313 max_volume_h=max_volume_h,
314 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
315 )
317
319 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
320 ncp=construct_FV_ncp(),
321 flux=exahype2.solvers.PDETerms.None_Implementation,
322 source_term=construct_FV_source_term(),
323 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
324 eigenvalues=construct_FV_eigenvalues(),
325 )
326
328
330 self,
331 name,
332 coordinates,
333 project,
334 number_of_entries_between_two_db_flushes,
335 data_delta_between_two_snapsots,
336 time_delta_between_two_snapsots,
337 clear_database_after_flush,
338 tracer_unknowns,
339 ):
340 """!
341
342 Add tracer to project
343
344 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
345 some of the arguments. Most of them are simply piped through to this
346 class.
347
348 project: exahype2.Project
349
350 """
352 name,
353 coordinates,
354 project,
355 self,
356 number_of_entries_between_two_db_flushes,
357 data_delta_between_two_snapsots,
358 time_delta_between_two_snapsots,
359 clear_database_after_flush,
360 tracer_unknowns,
361 )
362
363
365 AbstractCCZ4Solver,
367):
368 """!
369
370 CCZ4 solver using finite volumes and global adaptive time stepping incl enclave tasking
371
372 The constructor of this classs is straightforward and realises the standard
373 steps of any numerical implementation of the CCZ4 scheme:
374
375 1. Init the actual numerical scheme. This happens through the constructor
376 of the base class.
377
378 2. Add the header files that we need, i.e. those files which contain the
379 actual CCZ4 implementation.
380
381 3. Add some constants that any CCZ4 C++ code requires.
382
383 4. Set the actual implementation, i.e. link the generic PDE terms to the
384 CCZ4-specific function calls.
385
386 5. Add the CCZ4-specific postprocessing.
387
388 """
389
391 self,
392 name,
393 patch_size,
394 min_volume_h,
395 max_volume_h,
396 pde_terms_without_state,
397 ):
398 """!
399
400 Construct solver with enclave tasking and adaptive time stepping
401
402 """
403 AbstractCCZ4Solver.__init__(self)
404 exahype2.solvers.fv.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
405 self,
406 name=name,
407 patch_size=patch_size,
408 unknowns=sum(self._FO_formulation_unknowns.values()),
409 auxiliary_variables=0,
410 min_volume_h=min_volume_h,
411 max_volume_h=max_volume_h,
412 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
413 pde_terms_without_state=pde_terms_without_state,
414 )
416
418 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
419 ncp=construct_FV_ncp(),
420 flux=exahype2.solvers.PDETerms.None_Implementation,
421 source_term=construct_FV_source_term(),
422 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
423 eigenvalues=construct_FV_eigenvalues(),
424 )
425
427
429 self,
430 name,
431 coordinates,
432 project,
433 number_of_entries_between_two_db_flushes,
434 data_delta_between_two_snapsots,
435 time_delta_between_two_snapsots,
436 clear_database_after_flush,
437 tracer_unknowns,
438 ):
439 """!
440
441 Add tracer to project
442
443 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
444 some of the arguments. Most of them are simply piped through to this
445 class.
446
447
448 project: exahype2.Project
449
450 """
452 name,
453 coordinates,
454 project,
455 self,
456 number_of_entries_between_two_db_flushes,
457 data_delta_between_two_snapsots,
458 time_delta_between_two_snapsots,
459 clear_database_after_flush,
460 tracer_unknowns,
461 )
462
463
465 return """
466 double deltaQSerialised[NumberOfUnknowns*3];
467 for (int i=0; i<NumberOfUnknowns; i++) {
468 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
469 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
470 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
471
472 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
473 }
474 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, deltaQSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
475"""
476
477
479 return """
480 double deltaQSerialised[NumberOfUnknowns*3];
481 for (int i=0; i<NumberOfUnknowns; i++) {
482 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
483 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
484 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
485
486 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
487 }
488 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, deltaQSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
489"""
490
491
493 return """
494 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
495 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
496"""
497
498
500 return """
501 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
502 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
503"""
504
505
507 return """
508 return ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
509"""
510
511
513 return """
514 return ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
515"""
516
517
519 return """
520{
521 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}};
522 int index = 0;
523 for (int i=0;i<itmax;i++)
524 {
525 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
526 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
527 }
528 }
529"""
530
531
533 return """
534{
535 constexpr int itmax = {{NUMBER_OF_VOLUMES_PER_AXIS}} * {{NUMBER_OF_VOLUMES_PER_AXIS}} * {{NUMBER_OF_VOLUMES_PER_AXIS}};
536 int index = 0;
537 for (int i=0;i<itmax;i++)
538 {
539 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
540 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
541 }
542 }
543"""
544
545
547 name,
548 coordinates,
549 project,
550 solver,
551 number_of_entries_between_two_db_flushes,
552 data_delta_between_two_snapsots,
553 time_delta_between_two_snapsots,
554 clear_database_after_flush,
555 tracer_unknowns,
556):
557 """!
558
559 Add tracer to project
560
561 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
562 some of the arguments. Most of them are simply piped through to this
563 class.
564
565 I realise this as a separate routine, as we need it for all FV flavours
566
567 """
568 number_of_attributes = (
569 (solver.unknowns + solver.auxiliary_variables)
570 if tracer_unknowns == None
571 else len(tracer_unknowns)
572 )
573 tracer_particles = project.add_tracer(
574 name=name, attribute_count=number_of_attributes
575 )
577 particle_set=tracer_particles, coordinates=coordinates
578 )
579 init_action_set.descend_invocation_order = 0
580 project.add_action_set_to_initialisation(init_action_set)
581
582 project_on_tracer_properties_kernel = ""
583 if tracer_unknowns == None:
584 project_on_tracer_properties_kernel = (
585 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
586 )
587 # project_on_tracer_properties_kernel = "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear_explicit_Euler"
588 elif len(tracer_unknowns) == 1:
589 project_on_tracer_properties_kernel = (
590 "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
591 i, tracer_unknowns.index(i)
592 )
593 )
594 else:
595 project_on_tracer_properties_kernel = (
596 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
597 tracer_unknowns
598 )
599 .replace("[", "")
600 .replace("]", "")
601 )
602
603 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
604 tracer_particles,
605 solver,
606 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
607 )
608 tracing_action_set.descend_invocation_order = (
609 solver._action_set_update_cell.descend_invocation_order + 1
610 )
611 project.add_action_set_to_timestepping(tracing_action_set)
612 project.add_action_set_to_initialisation(tracing_action_set)
613
614 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
615 particle_set=tracer_particles,
616 solver=solver,
617 filename=name + "-" + solver._name,
618 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
619 output_precision=10,
620 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
621 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
622 clear_database_after_flush=clear_database_after_flush,
623 )
624 dump_into_database_action_set.descend_invocation_order = (
625 solver._action_set_update_cell.descend_invocation_order + 2
626 )
627 project.add_action_set_to_timestepping(dump_into_database_action_set)
628
629
631 name,
632 coordinates,
633 project,
634 solver,
635 number_of_entries_between_two_db_flushes,
636 data_delta_between_two_snapsots,
637 time_delta_between_two_snapsots,
638 clear_database_after_flush,
639 tracer_unknowns,
640):
641 """!
642
643 I realise this as a separate routine, as we need it for all FD4 flavours
644
645 This is a wrapper around all the tracer handling. It adds the tracer to the
646 exahype2.Project, but it also instantiates the solution to tracer mapping
647 as well as the database bookkeeping.
648
649 @param tracer_unknowns: Integer
650 You can set this variable to None. In this case, all variables are
651 dumped.
652
653 """
654 number_of_attributes = (
655 (solver.unknowns + solver.auxiliary_variables)
656 if tracer_unknowns == None
657 else len(tracer_unknowns)
658 )
659 tracer_particles = project.add_tracer(
660 name=name, attribute_count=number_of_attributes
661 )
662 project.add_action_set_to_initialisation(
664 particle_set=tracer_particles, coordinates=coordinates
665 )
666 )
667 project_on_tracer_properties_kernel = ""
668 if tracer_unknowns == None:
669 project_on_tracer_properties_kernel = (
670 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
671 )
672 elif len(tracer_unknowns) == 1:
673 project_on_tracer_properties_kernel = (
674 "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
675 i, tracer_unknowns.index(i)
676 )
677 )
678 else:
679 project_on_tracer_properties_kernel = (
680 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
681 tracer_unknowns
682 )
683 .replace("[", "")
684 .replace("]", "")
685 )
686
687 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
688 tracer_particles,
689 solver,
690 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
691 )
692 tracing_action_set.descend_invocation_order = (
693 solver._action_set_compute_final_linear_combination.descend_invocation_order + 1
694 )
695 project.add_action_set_to_timestepping(tracing_action_set)
696 project.add_action_set_to_initialisation(tracing_action_set)
697
698 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
699 particle_set=tracer_particles,
700 solver=solver,
701 filename=name + "-" + solver._name,
702 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
703 output_precision=10,
704 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
705 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
706 clear_database_after_flush=clear_database_after_flush,
707 )
708 dump_into_database_action_set.descend_invocation_order = (
709 solver._action_set_compute_final_linear_combination.descend_invocation_order + 2
710 )
711 project.add_action_set_to_timestepping(dump_into_database_action_set)
712
713
715 AbstractCCZ4Solver,
717):
718 """!
719
720 CCZ4 solver using fourth-order finite differences and global adaptive time stepping incl enclave tasking
721
722 The constructor of this classs is straightforward and realises the standard
723 steps of any numerical implementation of the CCZ4 scheme:
724
725 1. Init the actual numerical scheme. This happens through the constructor
726 of the base class.
727
728 2. Add the header files that we need, i.e. those files which contain the
729 actual CCZ4 implementation.
730
731 3. Add some constants that any CCZ4 C++ code requires.
732
733 4. Set the actual implementation, i.e. link the generic PDE terms to the
734 CCZ4-specific function calls.
735
736 5. Add the CCZ4-specific postprocessing.
737
738 6. Switch to higher-order interpolation and restriction.
739
740 """
741
743 self,
744 name,
745 patch_size,
746 rk_order,
747 min_meshcell_h,
748 max_meshcell_h,
749 pde_terms_without_state,
750 second_order=False,
751 ):
752 """!
753
754 Constructor
755
756 Calibrate the default time step size calibration with 1/16 to take into
757 account that we have a higher-order numerical scheme.
758
759 """
760 AbstractCCZ4Solver.__init__(self)
761 if second_order:
762 AbstractCCZ4Solver.enable_second_order(self)
763 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
764 self,
765 name=name,
766 patch_size=patch_size,
767 rk_order=rk_order,
768 unknowns=sum(self._FO_formulation_unknowns.values()),
769 auxiliary_variables=0,
770 min_meshcell_h=min_meshcell_h,
771 max_meshcell_h=max_meshcell_h,
773 pde_terms_without_state=pde_terms_without_state,
774 )
775
777
779 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
780 ncp=construct_FD4_ncp(),
781 flux=exahype2.solvers.PDETerms.None_Implementation,
782 source_term=construct_FD4_source_term(),
783 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
784 eigenvalues=construct_FD4_eigenvalues(),
785 )
786
788
789 """
790 # Use second order interpolation and restriction
791 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
792 self
793 )
794 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
795 self
796 )
797 """
798
799 # Use third order interpolation and restriction
800 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
801 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
802
803 """
804 # Use matrix interpolation and restriction
805 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
806 self
807 )
808 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
809 self
810 )
811 """
812
813 """
814 # Use tensor product interpolation and restriction
815 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
816 self,
817 "TP_linear_with_linear_extrap_normal_interp"
818 )
819 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
820 self,
821 "TP_average_normal_extrap"
822 )
823 """
824
826 self,
827 name,
828 coordinates,
829 project,
830 number_of_entries_between_two_db_flushes,
831 data_delta_between_two_snapsots,
832 time_delta_between_two_snapsots,
833 clear_database_after_flush,
834 tracer_unknowns,
835 ):
836 """!
837
838 Add tracer to project
839
840 This is a delegate to add_tracer_to_FD4_solver() which passes the
841 object in as first argument.
842
843 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
844 some of the arguments. Most of them are simply piped through to this
845 class.
846
847 @param project: exahype2.Project
848
849 @param tracer_unknowns: Integer
850 You can set this variable to None. In this case, all variables are
851 dumped.
852
853 """
855 name,
856 coordinates,
857 project,
858 self,
859 number_of_entries_between_two_db_flushes,
860 data_delta_between_two_snapsots,
861 time_delta_between_two_snapsots,
862 clear_database_after_flush,
863 tracer_unknowns,
864 )
865
866
869):
870 """!
871
872 CCZ4 solver using fourth-order finite differences and global adaptive time stepping without enclave tasking
873
874 Consult CCZ4Solver_FD4_GlobalAdaptiveTimeStepWithEnclaveTasking please.
875
876 """
877
879 self,
880 name,
881 patch_size,
882 rk_order,
883 min_meshcell_h,
884 max_meshcell_h,
885 second_order=False,
886 ):
887 """!
888
889 Constructor
890
891 Calibrate the default time step size calibration with 1/16 to take into
892 account that we have a higher-order numerical scheme.
893
894 """
895 AbstractCCZ4Solver.__init__(self)
896 if second_order:
897 AbstractCCZ4Solver.enable_second_order(self)
898 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStep.__init__(
899 self,
900 name=name,
901 patch_size=patch_size,
902 rk_order=rk_order,
903 unknowns=sum(self._FO_formulation_unknowns.values()),
904 auxiliary_variables=0,
905 min_meshcell_h=min_meshcell_h,
906 max_meshcell_h=max_meshcell_h,
908 )
909
911
913 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
914 ncp=construct_FD4_ncp(),
915 flux=exahype2.solvers.PDETerms.None_Implementation,
916 source_term=construct_FD4_source_term(),
917 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
918 eigenvalues=construct_FD4_eigenvalues(),
919 )
920
922
923 """
924 # Use second order interpolation and restriction
925 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
926 self
927 )
928 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
929 self
930 )
931 """
932
933 # Use third order interpolation and restriction
934 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
935 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
936
937 """
938 # Use matrix interpolation and restriction
939 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
940 self
941 )
942 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
943 self
944 )
945 """
946
947 """
948 # Use tensor product interpolation and restriction
949 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
950 self,
951 "TP_linear_with_linear_extrap_normal_interp"
952 )
953 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
954 self,
955 "TP_average_normal_extrap"
956 )
957 """
958
960 self,
961 name,
962 coordinates,
963 project,
964 number_of_entries_between_two_db_flushes,
965 data_delta_between_two_snapsots,
966 time_delta_between_two_snapsots,
967 clear_database_after_flush,
968 tracer_unknowns,
969 ):
970 """!
971
972 Add tracer to project
973
974 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
975 some of the arguments. Most of them are simply piped through to this
976 class.
977
978 project: exahype2.Project
979
980 """
982 name,
983 coordinates,
984 project,
985 self,
986 number_of_entries_between_two_db_flushes,
987 data_delta_between_two_snapsots,
988 time_delta_between_two_snapsots,
989 clear_database_after_flush=clear_database_after_flush,
990 tracer_unknowns=tracer_unknowns,
991 )
992
993
995 AbstractCCZ4Solver,
997):
998 """!
999
1000 Variation of classic FD4 which relies on second order PDE formulation
1001
1002 The traditional ExaHyPE CCZ4 formulation is the first order formulation
1003 introduced by Dumbser et al. In this formulation, the second order terms
1004 in CCZ4 are substituted with helper variables which represent first order
1005 derivatives. While formally straightforward, keeping the whole system
1006 consistent and stricly hyperbolic is a different challenge.
1007
1008 In this revised version, we have to evolve the primary quantities of CCZ4
1009 and also the helper variables, which blows the overall system up to 59
1010 equations in its simplest form. The work by Dumbser and others suggest that
1011 this is a consistent and stable approach, but limited work is actually
1012 published on proper physical simulations. We therefore also implemented a
1013 second order PDE version within ExaHyPE.
1014
1015 This second order variant is not really second order from the start.
1016 Instead, we use the first order formulation, and we reconstruct the helper
1017 term via finite differences prior to the compute kernel application. That is,
1018 the compute kernels see variables representing first order derivatives, and
1019 they also evolve these guys. Afterwards, we throw away the evolved quantities
1020 and reconstruct them from the primary unknowns prior to the next time step.
1021
1022 This might not be super efficient (it would be faster to stick to the
1023 second order formulation right from the start), but it allows us to reuse
1024 the compute kernels written for the first order PDE formulation.
1025
1026 ## Data layout
1027
1028 We have now a smaller number of real unknowns, i.e. only those guys who
1029 belong to the "original" second-order formulation. The remaining quantities
1030 compared to a first-order formulation are technically material or auxiliary
1031 quantities. We model them as such, which allows ExaHyPE`s data management
1032 to deal more efficiently with them.
1033
1034
1035 reconstruction_type: "4thOrder", "centralDifferences", "leftDifference", "rightDifference"
1036
1037 """
1038
1040 self,
1041 name,
1042 patch_size,
1043 rk_order,
1044 min_meshcell_h,
1045 max_meshcell_h,
1046 reconstruction_type,
1047 ):
1048 """!
1049
1050 Constructor
1051
1052 Calibrate the default time step size calibration with 1/16 to take into
1053 account that we have a higher-order numerical scheme.
1054
1055 """
1056 AbstractCCZ4Solver.__init__(self)
1057 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1058 self,
1059 name=name,
1060 patch_size=patch_size,
1061 rk_order=rk_order,
1063 auxiliary_variables=sum(self._FO_formulation_unknowns.values())
1065 min_meshcell_h=min_meshcell_h,
1066 max_meshcell_h=max_meshcell_h,
1067 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation
1068 / 16.0,
1069 )
1070
1072
1074 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1075 ncp="""
1076 double deltaQSerialised[NumberOfUnknowns*3];
1077 for (int i=0; i<NumberOfUnknowns; i++) {
1078 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
1079 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
1080 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
1081
1082 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1083 }
1084 ::applications::exahype2::ccz4::ncpSecondOrderFormulation(BTimesDeltaQ, Q, deltaQSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1085""",
1086 flux=exahype2.solvers.PDETerms.None_Implementation,
1087 source_term="""
1088 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1089 ::applications::exahype2::ccz4::sourceSecondOrderFormulation(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3);
1090""",
1091 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1092 eigenvalues="""
1093 // do we only set Q
1094 return ::applications::exahype2::ccz4::maxEigenvalueSecondOrderFormulation(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
1095""",
1096 )
1097
1099{
1100 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}};
1101 int index = 0;
1102 for (int i=0;i<itmax;i++)
1103 {
1104 applications::exahype2::ccz4::enforceCCZ4constraintsSecondOrderFormulation( newQ+index );
1105 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1106 }
1107 }
1108"""
1109
1110 """
1111 # Use second order interpolation and restriction
1112 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
1113 self
1114 )
1115 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
1116 self
1117 )
1118 """
1119
1120 # Use third order interpolation and restriction
1121 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
1122 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
1123
1124 """
1125 # Use matrix interpolation and restriction
1126 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
1127 self
1128 )
1129 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
1130 self
1131 )
1132 """
1133
1134 """
1135 # Use tensor product interpolation and restriction
1136 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
1137 self,
1138 "TP_linear_with_linear_extrap_normal_interp"
1139 )
1140 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
1141 self,
1142 "TP_average_normal_extrap"
1143 )
1144 """
1145
1147 """
1148::exahype2::CellData reconstructedPatchData(
1149 oldQWithHalo,
1150 marker.x(),
1151 marker.h(),
1152 timeStamp,
1153 timeStepSize,
1154 nullptr // targetPatch
1155);
1156::applications::exahype2::ccz4::recomputeAuxiliaryVariablesFD4_"""
1157 + reconstruction_type
1158 + """(
1159 reconstructedPatchData,
1160 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
1161 3, // haloSize,
1162 {{NUMBER_OF_UNKNOWNS}},
1163 {{NUMBER_OF_AUXILIARY_VARIABLES}}
1164);
1165"""
1166 )
1167
1169 self,
1170 name,
1171 coordinates,
1172 project,
1173 number_of_entries_between_two_db_flushes,
1174 data_delta_between_two_snapsots,
1175 time_delta_between_two_snapsots,
1176 clear_database_after_flush,
1177 tracer_unknowns,
1178 ):
1179 """!
1180
1181 Add tracer to project
1182
1183 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1184 some of the arguments. Most of them are simply piped through to this
1185 class.
1186
1187 project: exahype2.Project
1188
1189 """
1190 number_of_attributes = (
1192 if tracer_unknowns == None
1193 else len(tracer_unknowns)
1194 )
1195 tracer_particles = project.add_tracer(
1196 name=name, attribute_count=number_of_attributes
1197 )
1199 particle_set=tracer_particles, coordinates=coordinates
1200 )
1201 init_action_set.descend_invocation_order = 0
1202 project.add_action_set_to_initialisation(init_action_set)
1203
1204 project_on_tracer_properties_kernel = ""
1205 if tracer_unknowns == None:
1206 project_on_tracer_properties_kernel = (
1207 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
1208 )
1209 elif len(tracer_unknowns) == 1:
1210 project_on_tracer_properties_kernel = "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
1211 i, tracer_unknowns.index(i)
1212 )
1213 else:
1214 project_on_tracer_properties_kernel = (
1215 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
1216 tracer_unknowns
1217 )
1218 .replace("[", "")
1219 .replace("]", "")
1220 )
1221
1222 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
1223 tracer_particles,
1224 self,
1225 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
1226 )
1227 tracing_action_set.descend_invocation_order = (
1228 self._action_set_compute_final_linear_combination.descend_invocation_order
1229 + 1
1230 )
1231 project.add_action_set_to_timestepping(tracing_action_set)
1232 project.add_action_set_to_initialisation(tracing_action_set)
1233
1234 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1235 particle_set=tracer_particles,
1236 solver=self,
1237 filename=name + "-" + self._name_name_name,
1238 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1239 output_precision=10,
1240 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1241 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1242 clear_database_after_flush=True,
1243 )
1244 dump_into_database_action_set.descend_invocation_order = (
1245 self._action_set_compute_final_linear_combination.descend_invocation_order
1246 + 2
1247 )
1248 project.add_action_set_to_timestepping(dump_into_database_action_set)
1249
1250
1252 return """
1253 double dQdxSerialised[NumberOfUnknowns*3];
1254 for (int i=0; i<NumberOfUnknowns; i++) {
1255 dQdxSerialised[i+0*NumberOfUnknowns] = 0.0;
1256 dQdxSerialised[i+1*NumberOfUnknowns] = 0.0;
1257 dQdxSerialised[i+2*NumberOfUnknowns] = 0.0;
1258
1259 dQdxSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1260 }
1261 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, dQdxSerialised, normal%Dimensions, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1262"""
1263
1264
1266 return """
1267 tarch::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1268 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
1269"""
1270
1271
1273 return """
1274 return ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%Dimensions, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
1275"""
1276
1277
1279 return """
1280{
1281 constexpr int itmax = ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1);
1282 int index = 0;
1283 for (int i=0;i<itmax;i++)
1284 {
1285 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
1286 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1287 }
1288 }
1289"""
1290
1291
1293 name,
1294 coordinates,
1295 project,
1296 self,
1297 number_of_entries_between_two_db_flushes,
1298 data_delta_between_two_snapsots,
1299 time_delta_between_two_snapsots,
1300 clear_database_after_flush,
1301 tracer_unknowns,
1302):
1303 number_of_attributes = (
1304 (self.unknowns + self.auxiliary_variables)
1305 if tracer_unknowns == None
1306 else len(tracer_unknowns)
1307 )
1308 tracer_particles = project.add_tracer(
1309 name=name, attribute_count=number_of_attributes
1310 )
1312 particle_set=tracer_particles, coordinates=coordinates
1313 )
1314 init_action_set.descend_invocation_order = 0
1315 project.add_action_set_to_initialisation(init_action_set)
1316
1317 assert tracer_unknowns == None
1318
1320 tracer_particles,
1321 solver=self,
1322 project_on_tracer_properties_kernel="::exahype2::dg::projectAllValuesOntoParticle",
1323 )
1324 tracing_action_set.descend_invocation_order = (
1325 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1326 + 1
1327 )
1328 project.add_action_set_to_timestepping(tracing_action_set)
1329 project.add_action_set_to_initialisation(tracing_action_set)
1330
1331 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1332 particle_set=tracer_particles,
1333 solver=self,
1334 filename=name + "-" + self._name,
1335 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1336 output_precision=10,
1337 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1338 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1339 clear_database_after_flush=clear_database_after_flush,
1340 )
1341 dump_into_database_action_set.descend_invocation_order = (
1342 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1343 + 1
1344 )
1345 project.add_action_set_to_timestepping(dump_into_database_action_set)
1346
1347
1349 AbstractCCZ4Solver,
1351):
1352 """!
1353
1354 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1355
1356 The constructor of this classs is straightforward and realises the standard
1357 steps of any numerical implementation of the CCZ4 scheme:
1358
1359 1. Init the actual numerical scheme. This happens through the constructor
1360 of the base class.
1361
1362 2. Add the header files that we need, i.e. those files which contain the
1363 actual CCZ4 implementation.
1364
1365 3. Add some constants that any CCZ4 C++ code requires.
1366
1367 4. Set the actual implementation, i.e. link the generic PDE terms to the
1368 CCZ4-specific function calls.
1369
1370 5. Add the CCZ4-specific postprocessing.
1371
1372 6. Switch to higher-order interpolation and restriction.
1373
1374 """
1375
1377 self,
1378 name,
1379 rk_order,
1380 polynomials,
1381 min_cell_h,
1382 max_cell_h,
1383 pde_terms_without_state,
1384 ):
1385 """!
1386
1387 Construct solver with enclave tasking
1388
1389 """
1390 AbstractCCZ4Solver.__init__(self)
1391 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1392 self,
1393 name=name,
1394 rk_order=rk_order,
1395 polynomials=polynomials,
1396 unknowns=sum(self._FO_formulation_unknowns.values()),
1397 auxiliary_variables=0,
1398 min_cell_h=min_cell_h,
1399 max_cell_h=max_cell_h,
1400 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1401 pde_terms_without_state=pde_terms_without_state,
1402 )
1403
1405
1407 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1408 ncp=construct_DG_ncp(),
1409 flux=exahype2.solvers.PDETerms.None_Implementation,
1410 source_term=construct_DG_source_term(),
1411 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1412 eigenvalues=construct_DG_eigenvalues(),
1413 )
1414
1417 )
1418
1420 self,
1421 name,
1422 coordinates,
1423 project,
1424 number_of_entries_between_two_db_flushes,
1425 data_delta_between_two_snapsots,
1426 time_delta_between_two_snapsots,
1427 clear_database_after_flush,
1428 tracer_unknowns,
1429 ):
1430 """!
1431
1432 Add tracer to project
1433
1434 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1435 some of the arguments. Most of them are simply piped through to this
1436 class.
1437
1438 At this point, we have not yet created the Peano 4 project. Therefore, we
1439 have not yet befilled the time stepping action set.
1440
1441 project: exahype2.Project
1442
1443 """
1445 name,
1446 coordinates,
1447 project,
1448 self,
1449 number_of_entries_between_two_db_flushes,
1450 data_delta_between_two_snapsots,
1451 time_delta_between_two_snapsots,
1452 clear_database_after_flush,
1453 tracer_unknowns,
1454 )
1455
1456
1458 AbstractCCZ4Solver,
1460):
1461 """!
1462
1463 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1464
1465 The constructor of this classs is straightforward and realises the standard
1466 steps of any numerical implementation of the CCZ4 scheme:
1467
1468 1. Init the actual numerical scheme. This happens through the constructor
1469 of the base class.
1470
1471 2. Add the header files that we need, i.e. those files which contain the
1472 actual CCZ4 implementation.
1473
1474 3. Add some constants that any CCZ4 C++ code requires.
1475
1476 4. Set the actual implementation, i.e. link the generic PDE terms to the
1477 CCZ4-specific function calls.
1478
1479 5. Add the CCZ4-specific postprocessing.
1480
1481 6. Switch to higher-order interpolation and restriction.
1482
1483 """
1484
1486 self,
1487 name,
1488 rk_order,
1489 polynomials,
1490 min_cell_h,
1491 max_cell_h,
1492 pde_terms_without_state,
1493 ):
1494 """!
1495
1496 Construct solver with enclave tasking
1497
1498 """
1499 AbstractCCZ4Solver.__init__(self)
1500 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStep.__init__(
1501 self,
1502 name=name,
1503 rk_order=rk_order,
1504 polynomials=polynomials,
1505 unknowns=sum(self._FO_formulation_unknowns.values()),
1506 auxiliary_variables=0,
1507 min_cell_h=min_cell_h,
1508 max_cell_h=max_cell_h,
1509 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1510 pde_terms_without_state=pde_terms_without_state,
1511 )
1512
1514
1516 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1517 ncp=construct_DG_ncp(),
1518 flux=exahype2.solvers.PDETerms.None_Implementation,
1519 source_term=construct_DG_source_term(),
1520 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1521 eigenvalues=construct_DG_eigenvalues(),
1522 )
1523
1526 )
1527
1529 self,
1530 name,
1531 coordinates,
1532 project,
1533 number_of_entries_between_two_db_flushes,
1534 data_delta_between_two_snapsots,
1535 time_delta_between_two_snapsots,
1536 clear_database_after_flush,
1537 tracer_unknowns,
1538 ):
1539 """!
1540
1541 Add tracer to project
1542
1543 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1544 some of the arguments. Most of them are simply piped through to this
1545 class.
1546
1547 At this point, we have not yet created the Peano 4 project. Therefore, we
1548 have not yet befilled the time stepping action set.
1549
1550 project: exahype2.Project
1551
1552 """
1554 name,
1555 coordinates,
1556 project,
1557 self,
1558 number_of_entries_between_two_db_flushes,
1559 data_delta_between_two_snapsots,
1560 time_delta_between_two_snapsots,
1561 clear_database_after_flush,
1562 tracer_unknowns,
1563 )
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 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...
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)
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()