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
292 AbstractCCZ4Solver, exahype2.solvers.fv.rusanov.GlobalAdaptiveTimeStep
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
318 self.set_implementation(
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
327 self.postprocess_updated_patch += construct_FV_postprocessing_kernel()
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,
366 exahype2.solvers.fv.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking,
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
417 self.set_implementation(
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
426 self.postprocess_updated_patch += construct_FV_postprocessing_kernel()
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 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
495"""
496
497
499 return """
500 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
501"""
502
503
505 return """
506 return ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%DIMENSIONS, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
507"""
508
509
511 return """
512 return ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%DIMENSIONS, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
513"""
514
515
517 return """
518{
519 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}};
520 int index = 0;
521 for (int i=0;i<itmax;i++)
522 {
523 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
524 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
525 }
526 }
527"""
528
529
531 return """
532{
533 constexpr int itmax = {{NUMBER_OF_VOLUMES_PER_AXIS}} * {{NUMBER_OF_VOLUMES_PER_AXIS}} * {{NUMBER_OF_VOLUMES_PER_AXIS}};
534 int index = 0;
535 for (int i=0;i<itmax;i++)
536 {
537 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
538 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
539 }
540 }
541"""
542
543
545 name,
546 coordinates,
547 project,
548 solver,
549 number_of_entries_between_two_db_flushes,
550 data_delta_between_two_snapsots,
551 time_delta_between_two_snapsots,
552 clear_database_after_flush,
553 tracer_unknowns,
554):
555 """!
556
557 Add tracer to project
558
559 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
560 some of the arguments. Most of them are simply piped through to this
561 class.
562
563 I realise this as a separate routine, as we need it for all FV flavours
564
565 """
566 number_of_attributes = (
567 (solver.unknowns + solver.auxiliary_variables)
568 if tracer_unknowns == None
569 else len(tracer_unknowns)
570 )
571 tracer_particles = project.add_tracer(
572 name=name, attribute_count=number_of_attributes
573 )
574 init_action_set = exahype2.tracer.InsertParticlesByCoordinates(
575 particle_set=tracer_particles, coordinates=coordinates
576 )
577 init_action_set.descend_invocation_order = 0
578 project.add_action_set_to_initialisation(init_action_set)
579
580 project_on_tracer_properties_kernel = ""
581 if tracer_unknowns == None:
582 project_on_tracer_properties_kernel = (
583 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
584 )
585 # project_on_tracer_properties_kernel = "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear_explicit_Euler"
586 elif len(tracer_unknowns) == 1:
587 project_on_tracer_properties_kernel = (
588 "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
589 i, tracer_unknowns.index(i)
590 )
591 )
592 else:
593 project_on_tracer_properties_kernel = (
594 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
595 tracer_unknowns
596 )
597 .replace("[", "")
598 .replace("]", "")
599 )
600
601 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
602 tracer_particles,
603 solver,
604 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
605 )
606 tracing_action_set.descend_invocation_order = (
607 solver._action_set_update_cell.descend_invocation_order + 1
608 )
609 project.add_action_set_to_timestepping(tracing_action_set)
610 project.add_action_set_to_initialisation(tracing_action_set)
611
612 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
613 particle_set=tracer_particles,
614 solver=solver,
615 filename=name + "-" + solver._name,
616 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
617 output_precision=10,
618 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
619 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
620 clear_database_after_flush=clear_database_after_flush,
621 )
622 dump_into_database_action_set.descend_invocation_order = (
623 solver._action_set_update_cell.descend_invocation_order + 2
624 )
625 project.add_action_set_to_timestepping(dump_into_database_action_set)
626
627
629 name,
630 coordinates,
631 project,
632 solver,
633 number_of_entries_between_two_db_flushes,
634 data_delta_between_two_snapsots,
635 time_delta_between_two_snapsots,
636 clear_database_after_flush,
637 tracer_unknowns,
638):
639 """!
640
641 I realise this as a separate routine, as we need it for all FD4 flavours
642
643 This is a wrapper around all the tracer handling. It adds the tracer to the
644 exahype2.Project, but it also instantiates the solution to tracer mapping
645 as well as the database bookkeeping.
646
647 @param tracer_unknowns: Integer
648 You can set this variable to None. In this case, all variables are
649 dumped.
650
651 """
652 number_of_attributes = (
653 (solver.unknowns + solver.auxiliary_variables)
654 if tracer_unknowns == None
655 else len(tracer_unknowns)
656 )
657 tracer_particles = project.add_tracer(
658 name=name, attribute_count=number_of_attributes
659 )
660 project.add_action_set_to_initialisation(
661 exahype2.tracer.InsertParticlesByCoordinates(
662 particle_set=tracer_particles, coordinates=coordinates
663 )
664 )
665 project_on_tracer_properties_kernel = ""
666 if tracer_unknowns == None:
667 project_on_tracer_properties_kernel = (
668 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
669 )
670 elif len(tracer_unknowns) == 1:
671 project_on_tracer_properties_kernel = (
672 "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
673 i, tracer_unknowns.index(i)
674 )
675 )
676 else:
677 project_on_tracer_properties_kernel = (
678 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
679 tracer_unknowns
680 )
681 .replace("[", "")
682 .replace("]", "")
683 )
684
685 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
686 tracer_particles,
687 solver,
688 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
689 )
690 tracing_action_set.descend_invocation_order = (
691 solver._action_set_compute_final_linear_combination.descend_invocation_order + 1
692 )
693 project.add_action_set_to_timestepping(tracing_action_set)
694 project.add_action_set_to_initialisation(tracing_action_set)
695
696 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
697 particle_set=tracer_particles,
698 solver=solver,
699 filename=name + "-" + solver._name,
700 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
701 output_precision=10,
702 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
703 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
704 clear_database_after_flush=clear_database_after_flush,
705 )
706 dump_into_database_action_set.descend_invocation_order = (
707 solver._action_set_compute_final_linear_combination.descend_invocation_order + 2
708 )
709 project.add_action_set_to_timestepping(dump_into_database_action_set)
710
711
713 AbstractCCZ4Solver,
714 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking,
715):
716 """!
717
718 CCZ4 solver using fourth-order finite differences and global adaptive time stepping incl enclave tasking
719
720 The constructor of this classs is straightforward and realises the standard
721 steps of any numerical implementation of the CCZ4 scheme:
722
723 1. Init the actual numerical scheme. This happens through the constructor
724 of the base class.
725
726 2. Add the header files that we need, i.e. those files which contain the
727 actual CCZ4 implementation.
728
729 3. Add some constants that any CCZ4 C++ code requires.
730
731 4. Set the actual implementation, i.e. link the generic PDE terms to the
732 CCZ4-specific function calls.
733
734 5. Add the CCZ4-specific postprocessing.
735
736 6. Switch to higher-order interpolation and restriction.
737
738 """
739
741 self,
742 name,
743 patch_size,
744 rk_order,
745 min_meshcell_h,
746 max_meshcell_h,
747 pde_terms_without_state,
748 second_order=False,
749 ):
750 """!
751
752 Constructor
753
754 Calibrate the default time step size calibration with 1/16 to take into
755 account that we have a higher-order numerical scheme.
756
757 """
758 AbstractCCZ4Solver.__init__(self)
759 if second_order:
760 AbstractCCZ4Solver.enable_second_order(self)
761 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
762 self,
763 name=name,
764 patch_size=patch_size,
765 rk_order=rk_order,
766 unknowns=sum(self._FO_formulation_unknowns.values()),
767 auxiliary_variables=0,
768 min_meshcell_h=min_meshcell_h,
769 max_meshcell_h=max_meshcell_h,
771 pde_terms_without_state=pde_terms_without_state,
772 )
773
775
776 self.set_implementation(
777 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
778 ncp=construct_FD4_ncp(),
779 flux=exahype2.solvers.PDETerms.None_Implementation,
780 source_term=construct_FD4_source_term(),
781 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
782 eigenvalues=construct_FD4_eigenvalues(),
783 )
784
785 self.postprocess_updated_patch += construct_FD4_postprocessing_kernel()
786
787 """
788 # Use second order interpolation and restriction
789 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
790 self
791 )
792 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
793 self
794 )
795 """
796
797 # Use third order interpolation and restriction
798 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
799 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
800
801 """
802 # Use matrix interpolation and restriction
803 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
804 self
805 )
806 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
807 self
808 )
809 """
810
811 """
812 # Use tensor product interpolation and restriction
813 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
814 self,
815 "TP_linear_with_linear_extrap_normal_interp"
816 )
817 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
818 self,
819 "TP_average_normal_extrap"
820 )
821 """
822
824 self,
825 name,
826 coordinates,
827 project,
828 number_of_entries_between_two_db_flushes,
829 data_delta_between_two_snapsots,
830 time_delta_between_two_snapsots,
831 clear_database_after_flush,
832 tracer_unknowns,
833 ):
834 """!
835
836 Add tracer to project
837
838 This is a delegate to add_tracer_to_FD4_solver() which passes the
839 object in as first argument.
840
841 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
842 some of the arguments. Most of them are simply piped through to this
843 class.
844
845 @param project: exahype2.Project
846
847 @param tracer_unknowns: Integer
848 You can set this variable to None. In this case, all variables are
849 dumped.
850
851 """
853 name,
854 coordinates,
855 project,
856 self,
857 number_of_entries_between_two_db_flushes,
858 data_delta_between_two_snapsots,
859 time_delta_between_two_snapsots,
860 clear_database_after_flush,
861 tracer_unknowns,
862 )
863
864
866 AbstractCCZ4Solver, exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStep
867):
868 """!
869
870 CCZ4 solver using fourth-order finite differences and global adaptive time stepping without enclave tasking
871
872 Consult CCZ4Solver_FD4_GlobalAdaptiveTimeStepWithEnclaveTasking please.
873
874 """
875
877 self,
878 name,
879 patch_size,
880 rk_order,
881 min_meshcell_h,
882 max_meshcell_h,
883 second_order=False,
884 ):
885 """!
886
887 Constructor
888
889 Calibrate the default time step size calibration with 1/16 to take into
890 account that we have a higher-order numerical scheme.
891
892 """
893 AbstractCCZ4Solver.__init__(self)
894 if second_order:
895 AbstractCCZ4Solver.enable_second_order(self)
896 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStep.__init__(
897 self,
898 name=name,
899 patch_size=patch_size,
900 rk_order=rk_order,
901 unknowns=sum(self._FO_formulation_unknowns.values()),
902 auxiliary_variables=0,
903 min_meshcell_h=min_meshcell_h,
904 max_meshcell_h=max_meshcell_h,
906 )
907
909
910 self.set_implementation(
911 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
912 ncp=construct_FD4_ncp(),
913 flux=exahype2.solvers.PDETerms.None_Implementation,
914 source_term=construct_FD4_source_term(),
915 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
916 eigenvalues=construct_FD4_eigenvalues(),
917 )
918
919 self.postprocess_updated_patch += construct_FD4_postprocessing_kernel()
920
921 """
922 # Use second order interpolation and restriction
923 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
924 self
925 )
926 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
927 self
928 )
929 """
930
931 # Use third order interpolation and restriction
932 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
933 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
934
935 """
936 # Use matrix interpolation and restriction
937 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
938 self
939 )
940 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
941 self
942 )
943 """
944
945 """
946 # Use tensor product interpolation and restriction
947 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
948 self,
949 "TP_linear_with_linear_extrap_normal_interp"
950 )
951 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
952 self,
953 "TP_average_normal_extrap"
954 )
955 """
956
958 self,
959 name,
960 coordinates,
961 project,
962 number_of_entries_between_two_db_flushes,
963 data_delta_between_two_snapsots,
964 time_delta_between_two_snapsots,
965 clear_database_after_flush,
966 tracer_unknowns,
967 ):
968 """!
969
970 Add tracer to project
971
972 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
973 some of the arguments. Most of them are simply piped through to this
974 class.
975
976 project: exahype2.Project
977
978 """
980 name,
981 coordinates,
982 project,
983 self,
984 number_of_entries_between_two_db_flushes,
985 data_delta_between_two_snapsots,
986 time_delta_between_two_snapsots,
987 clear_database_after_flush=clear_database_after_flush,
988 tracer_unknowns=tracer_unknowns,
989 )
990
991
993 AbstractCCZ4Solver,
994 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking,
995):
996 """!
997
998 Variation of classic FD4 which relies on second order PDE formulation
999
1000 The traditional ExaHyPE CCZ4 formulation is the first order formulation
1001 introduced by Dumbser et al. In this formulation, the second order terms
1002 in CCZ4 are substituted with helper variables which represent first order
1003 derivatives. While formally straightforward, keeping the whole system
1004 consistent and stricly hyperbolic is a different challenge.
1005
1006 In this revised version, we have to evolve the primary quantities of CCZ4
1007 and also the helper variables, which blows the overall system up to 59
1008 equations in its simplest form. The work by Dumbser and others suggest that
1009 this is a consistent and stable approach, but limited work is actually
1010 published on proper physical simulations. We therefore also implemented a
1011 second order PDE version within ExaHyPE.
1012
1013 This second order variant is not really second order from the start.
1014 Instead, we use the first order formulation, and we reconstruct the helper
1015 term via finite differences prior to the compute kernel application. That is,
1016 the compute kernels see variables representing first order derivatives, and
1017 they also evolve these guys. Afterwards, we throw away the evolved quantities
1018 and reconstruct them from the primary unknowns prior to the next time step.
1019
1020 This might not be super efficient (it would be faster to stick to the
1021 second order formulation right from the start), but it allows us to reuse
1022 the compute kernels written for the first order PDE formulation.
1023
1024 ## Data layout
1025
1026 We have now a smaller number of real unknowns, i.e. only those guys who
1027 belong to the "original" second-order formulation. The remaining quantities
1028 compared to a first-order formulation are technically material or auxiliary
1029 quantities. We model them as such, which allows ExaHyPE`s data management
1030 to deal more efficiently with them.
1031
1032
1033 reconstruction_type: "4thOrder", "centralDifferences", "leftDifference", "rightDifference"
1034
1035 """
1036
1038 self,
1039 name,
1040 patch_size,
1041 rk_order,
1042 min_meshcell_h,
1043 max_meshcell_h,
1044 reconstruction_type,
1045 ):
1046 """!
1047
1048 Constructor
1049
1050 Calibrate the default time step size calibration with 1/16 to take into
1051 account that we have a higher-order numerical scheme.
1052
1053 """
1054 AbstractCCZ4Solver.__init__(self)
1055 exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1056 self,
1057 name=name,
1058 patch_size=patch_size,
1059 rk_order=rk_order,
1061 auxiliary_variables=sum(self._FO_formulation_unknowns.values())
1063 min_meshcell_h=min_meshcell_h,
1064 max_meshcell_h=max_meshcell_h,
1065 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation
1066 / 16.0,
1067 )
1068
1070
1071 self.set_implementation(
1072 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1073 ncp="""
1074 double deltaQSerialised[NumberOfUnknowns*3];
1075 for (int i=0; i<NumberOfUnknowns; i++) {
1076 deltaQSerialised[i+0*NumberOfUnknowns] = 0.0;
1077 deltaQSerialised[i+1*NumberOfUnknowns] = 0.0;
1078 deltaQSerialised[i+2*NumberOfUnknowns] = 0.0;
1079
1080 deltaQSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1081 }
1082 ::applications::exahype2::ccz4::ncpSecondOrderFormulation(BTimesDeltaQ, Q, deltaQSerialised, normal%DIMENSIONS, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1083""",
1084 flux=exahype2.solvers.PDETerms.None_Implementation,
1085 source_term="""
1086 std::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1087 ::applications::exahype2::ccz4::sourceSecondOrderFormulation(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3);
1088""",
1089 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1090 eigenvalues="""
1091 // do we only set Q
1092 return ::applications::exahype2::ccz4::maxEigenvalueSecondOrderFormulation(Q, normal%DIMENSIONS, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
1093""",
1094 )
1095
1096 self.postprocess_updated_patch += """
1097{
1098 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}};
1099 int index = 0;
1100 for (int i=0;i<itmax;i++)
1101 {
1102 applications::exahype2::ccz4::enforceCCZ4constraintsSecondOrderFormulation( newQ+index );
1103 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1104 }
1105 }
1106"""
1107
1108 """
1109 # Use second order interpolation and restriction
1110 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_interpolation(
1111 self
1112 )
1113 exahype2.solvers.rkfd.fd4.switch_to_FD4_second_order_restriction(
1114 self
1115 )
1116 """
1117
1118 # Use third order interpolation and restriction
1119 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_interpolation(self)
1120 exahype2.solvers.rkfd.fd4.switch_to_FD4_third_order_restriction(self)
1121
1122 """
1123 # Use matrix interpolation and restriction
1124 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_interpolation(
1125 self
1126 )
1127 exahype2.solvers.rkfd.fd4.switch_to_FD4_matrix_restriction(
1128 self
1129 )
1130 """
1131
1132 """
1133 # Use tensor product interpolation and restriction
1134 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_interpolation(
1135 self,
1136 "TP_linear_with_linear_extrap_normal_interp"
1137 )
1138 exahype2.solvers.rkfd.fd4.switch_to_FD4_tensor_product_restriction(
1139 self,
1140 "TP_average_normal_extrap"
1141 )
1142 """
1143
1144 self.preprocess_reconstructed_patch += (
1145 """
1146::exahype2::CellData reconstructedPatchData(
1147 oldQWithHalo,
1148 marker.getX(),
1149 marker.getH(),
1150 timeStamp,
1151 timeStepSize,
1152 nullptr // targetPatch
1153);
1154::applications::exahype2::ccz4::recomputeAuxiliaryVariablesFD4_"""
1155 + reconstruction_type
1156 + """(
1157 reconstructedPatchData,
1158 {{NUMBER_OF_GRID_CELLS_PER_PATCH_PER_AXIS}},
1159 3, // haloSize,
1160 {{NUMBER_OF_UNKNOWNS}},
1161 {{NUMBER_OF_AUXILIARY_VARIABLES}}
1162);
1163"""
1164 )
1165
1167 self,
1168 name,
1169 coordinates,
1170 project,
1171 number_of_entries_between_two_db_flushes,
1172 data_delta_between_two_snapsots,
1173 time_delta_between_two_snapsots,
1174 clear_database_after_flush,
1175 tracer_unknowns,
1176 ):
1177 """!
1178
1179 Add tracer to project
1180
1181 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1182 some of the arguments. Most of them are simply piped through to this
1183 class.
1184
1185 project: exahype2.Project
1186
1187 """
1188 number_of_attributes = (
1189 (self.unknowns + self.auxiliary_variables)
1190 if tracer_unknowns == None
1191 else len(tracer_unknowns)
1192 )
1193 tracer_particles = project.add_tracer(
1194 name=name, attribute_count=number_of_attributes
1195 )
1196 init_action_set = exahype2.tracer.InsertParticlesByCoordinates(
1197 particle_set=tracer_particles, coordinates=coordinates
1198 )
1199 init_action_set.descend_invocation_order = 0
1200 project.add_action_set_to_initialisation(init_action_set)
1201
1202 project_on_tracer_properties_kernel = ""
1203 if tracer_unknowns == None:
1204 project_on_tracer_properties_kernel = (
1205 "::exahype2::fv::projectAllValuesOntoParticle_piecewiseLinear"
1206 )
1207 elif len(tracer_unknowns) == 1:
1208 project_on_tracer_properties_kernel = "::exahype2::fv::projectValueOntoParticle_piecewiseLinear<{},{}>".format(
1209 i, tracer_unknowns.index(i)
1210 )
1211 else:
1212 project_on_tracer_properties_kernel = (
1213 "::exahype2::fv::projectValuesOntoParticle_piecewiseLinear<{}>".format(
1214 tracer_unknowns
1215 )
1216 .replace("[", "")
1217 .replace("]", "")
1218 )
1219
1220 tracing_action_set = exahype2.tracer.FiniteVolumesTracing(
1221 tracer_particles,
1222 self,
1223 project_on_tracer_properties_kernel=project_on_tracer_properties_kernel,
1224 )
1225 tracing_action_set.descend_invocation_order = (
1226 self._action_set_compute_final_linear_combination.descend_invocation_order
1227 + 1
1228 )
1229 project.add_action_set_to_timestepping(tracing_action_set)
1230 project.add_action_set_to_initialisation(tracing_action_set)
1231
1232 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1233 particle_set=tracer_particles,
1234 solver=self,
1235 filename=name + "-" + self._name,
1236 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1237 output_precision=10,
1238 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1239 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1240 clear_database_after_flush=True,
1241 )
1242 dump_into_database_action_set.descend_invocation_order = (
1243 self._action_set_compute_final_linear_combination.descend_invocation_order
1244 + 2
1245 )
1246 project.add_action_set_to_timestepping(dump_into_database_action_set)
1247
1248
1250 return """
1251 double dQdxSerialised[NumberOfUnknowns*3];
1252 for (int i=0; i<NumberOfUnknowns; i++) {
1253 dQdxSerialised[i+0*NumberOfUnknowns] = 0.0;
1254 dQdxSerialised[i+1*NumberOfUnknowns] = 0.0;
1255 dQdxSerialised[i+2*NumberOfUnknowns] = 0.0;
1256
1257 dQdxSerialised[i+normal*NumberOfUnknowns] = deltaQ[i];
1258 }
1259 ::applications::exahype2::ccz4::ncp(BTimesDeltaQ, Q, dQdxSerialised, normal%DIMENSIONS, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4mu, CCZ4SO);
1260"""
1261
1262
1264 return """
1265 std::memset(S, 0.0, NumberOfUnknowns*sizeof(double));
1266 ::applications::exahype2::ccz4::source(S,Q, CCZ4LapseType, CCZ4ds, CCZ4c, CCZ4e, CCZ4f, CCZ4bs, CCZ4sk, CCZ4xi, CCZ4itau, CCZ4eta, CCZ4k1, CCZ4k2, CCZ4k3, CCZ4SO);
1267"""
1268
1269
1271 return """
1272 return ::applications::exahype2::ccz4::maxEigenvalue(Q, normal%DIMENSIONS, CCZ4e, CCZ4ds, CCZ4GLMc, CCZ4GLMd );
1273"""
1274
1275
1277 return """
1278{
1279 constexpr int itmax = ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1) * ({{DG_ORDER}}+1);
1280 int index = 0;
1281 for (int i=0;i<itmax;i++)
1282 {
1283 applications::exahype2::ccz4::enforceCCZ4constraints( newQ+index );
1284 index += {{NUMBER_OF_UNKNOWNS}} + {{NUMBER_OF_AUXILIARY_VARIABLES}};
1285 }
1286 }
1287"""
1288
1289
1291 name,
1292 coordinates,
1293 project,
1294 self,
1295 number_of_entries_between_two_db_flushes,
1296 data_delta_between_two_snapsots,
1297 time_delta_between_two_snapsots,
1298 clear_database_after_flush,
1299 tracer_unknowns,
1300):
1301 number_of_attributes = (
1302 (self.unknowns + self.auxiliary_variables)
1303 if tracer_unknowns == None
1304 else len(tracer_unknowns)
1305 )
1306 tracer_particles = project.add_tracer(
1307 name=name, attribute_count=number_of_attributes
1308 )
1309 init_action_set = exahype2.tracer.InsertParticlesByCoordinates(
1310 particle_set=tracer_particles, coordinates=coordinates
1311 )
1312 init_action_set.descend_invocation_order = 0
1313 project.add_action_set_to_initialisation(init_action_set)
1314
1315 assert tracer_unknowns == None
1316
1317 tracing_action_set = exahype2.tracer.DiscontinuousGalerkinTracing(
1318 tracer_particles,
1319 solver=self,
1320 project_on_tracer_properties_kernel="::exahype2::dg::projectAllValuesOntoParticle",
1321 )
1322 tracing_action_set.descend_invocation_order = (
1323 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1324 + 1
1325 )
1326 project.add_action_set_to_timestepping(tracing_action_set)
1327 project.add_action_set_to_initialisation(tracing_action_set)
1328
1329 dump_into_database_action_set = exahype2.tracer.DumpTracerIntoDatabase(
1330 particle_set=tracer_particles,
1331 solver=self,
1332 filename=name + "-" + self._name,
1333 number_of_entries_between_two_db_flushes=number_of_entries_between_two_db_flushes,
1334 output_precision=10,
1335 data_delta_between_two_snapsots=data_delta_between_two_snapsots,
1336 time_delta_between_two_snapsots=time_delta_between_two_snapsots,
1337 clear_database_after_flush=clear_database_after_flush,
1338 )
1339 dump_into_database_action_set.descend_invocation_order = (
1340 self._action_set_compute_final_linear_combination_and_project_solution_onto_faces.descend_invocation_order
1341 + 1
1342 )
1343 project.add_action_set_to_timestepping(dump_into_database_action_set)
1344
1345
1347 AbstractCCZ4Solver,
1348 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking,
1349):
1350 """!
1351
1352 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1353
1354 The constructor of this classs is straightforward and realises the standard
1355 steps of any numerical implementation of the CCZ4 scheme:
1356
1357 1. Init the actual numerical scheme. This happens through the constructor
1358 of the base class.
1359
1360 2. Add the header files that we need, i.e. those files which contain the
1361 actual CCZ4 implementation.
1362
1363 3. Add some constants that any CCZ4 C++ code requires.
1364
1365 4. Set the actual implementation, i.e. link the generic PDE terms to the
1366 CCZ4-specific function calls.
1367
1368 5. Add the CCZ4-specific postprocessing.
1369
1370 6. Switch to higher-order interpolation and restriction.
1371
1372 """
1373
1375 self,
1376 name,
1377 rk_order,
1378 polynomials,
1379 min_cell_h,
1380 max_cell_h,
1381 pde_terms_without_state,
1382 ):
1383 """!
1384
1385 Construct solver with enclave tasking
1386
1387 """
1388 AbstractCCZ4Solver.__init__(self)
1389 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking.__init__(
1390 self,
1391 name=name,
1392 rk_order=rk_order,
1393 polynomials=polynomials,
1394 unknowns=sum(self._FO_formulation_unknowns.values()),
1395 auxiliary_variables=0,
1396 min_cell_h=min_cell_h,
1397 max_cell_h=max_cell_h,
1398 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1399 pde_terms_without_state=pde_terms_without_state,
1400 )
1401
1403
1404 self.set_implementation(
1405 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1406 ncp=construct_DG_ncp(),
1407 flux=exahype2.solvers.PDETerms.None_Implementation,
1408 source_term=construct_DG_source_term(),
1409 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1410 eigenvalues=construct_DG_eigenvalues(),
1411 )
1412
1413 self.postprocess_updated_cell_after_final_linear_combination += (
1415 )
1416
1418 self,
1419 name,
1420 coordinates,
1421 project,
1422 number_of_entries_between_two_db_flushes,
1423 data_delta_between_two_snapsots,
1424 time_delta_between_two_snapsots,
1425 clear_database_after_flush,
1426 tracer_unknowns,
1427 ):
1428 """!
1429
1430 Add tracer to project
1431
1432 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1433 some of the arguments. Most of them are simply piped through to this
1434 class.
1435
1436 At this point, we have not yet created the Peano 4 project. Therefore, we
1437 have not yet befilled the time stepping action set.
1438
1439 project: exahype2.Project
1440
1441 """
1443 name,
1444 coordinates,
1445 project,
1446 self,
1447 number_of_entries_between_two_db_flushes,
1448 data_delta_between_two_snapsots,
1449 time_delta_between_two_snapsots,
1450 clear_database_after_flush,
1451 tracer_unknowns,
1452 )
1453
1454
1456 AbstractCCZ4Solver,
1457 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStep,
1458):
1459 """!
1460
1461 CCZ4 solver using Runge-Kutta Discontinuous Galerkin and global adaptive time stepping incl enclave tasking
1462
1463 The constructor of this classs is straightforward and realises the standard
1464 steps of any numerical implementation of the CCZ4 scheme:
1465
1466 1. Init the actual numerical scheme. This happens through the constructor
1467 of the base class.
1468
1469 2. Add the header files that we need, i.e. those files which contain the
1470 actual CCZ4 implementation.
1471
1472 3. Add some constants that any CCZ4 C++ code requires.
1473
1474 4. Set the actual implementation, i.e. link the generic PDE terms to the
1475 CCZ4-specific function calls.
1476
1477 5. Add the CCZ4-specific postprocessing.
1478
1479 6. Switch to higher-order interpolation and restriction.
1480
1481 """
1482
1484 self,
1485 name,
1486 rk_order,
1487 polynomials,
1488 min_cell_h,
1489 max_cell_h,
1490 pde_terms_without_state,
1491 ):
1492 """!
1493
1494 Construct solver with enclave tasking
1495
1496 """
1497 AbstractCCZ4Solver.__init__(self)
1498 exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStep.__init__(
1499 self,
1500 name=name,
1501 rk_order=rk_order,
1502 polynomials=polynomials,
1503 unknowns=sum(self._FO_formulation_unknowns.values()),
1504 auxiliary_variables=0,
1505 min_cell_h=min_cell_h,
1506 max_cell_h=max_cell_h,
1507 time_step_relaxation=AbstractCCZ4Solver.Default_Time_Step_Size_Relaxation,
1508 pde_terms_without_state=pde_terms_without_state,
1509 )
1510
1512
1513 self.set_implementation(
1514 boundary_conditions=exahype2.solvers.PDETerms.Empty_Implementation,
1515 ncp=construct_DG_ncp(),
1516 flux=exahype2.solvers.PDETerms.None_Implementation,
1517 source_term=construct_DG_source_term(),
1518 refinement_criterion=exahype2.solvers.PDETerms.Empty_Implementation,
1519 eigenvalues=construct_DG_eigenvalues(),
1520 )
1521
1522 self.postprocess_updated_cell_after_final_linear_combination += (
1524 )
1525
1527 self,
1528 name,
1529 coordinates,
1530 project,
1531 number_of_entries_between_two_db_flushes,
1532 data_delta_between_two_snapsots,
1533 time_delta_between_two_snapsots,
1534 clear_database_after_flush,
1535 tracer_unknowns,
1536 ):
1537 """!
1538
1539 Add tracer to project
1540
1541 Consult exahype2.tracer.DumpTracerIntoDatabase for an explanation of
1542 some of the arguments. Most of them are simply piped through to this
1543 class.
1544
1545 At this point, we have not yet created the Peano 4 project. Therefore, we
1546 have not yet befilled the time stepping action set.
1547
1548 project: exahype2.Project
1549
1550 """
1552 name,
1553 coordinates,
1554 project,
1555 self,
1556 number_of_entries_between_two_db_flushes,
1557 data_delta_between_two_snapsots,
1558 time_delta_between_two_snapsots,
1559 clear_database_after_flush,
1560 tracer_unknowns,
1561 )
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.
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()