Peano
CCZ4Solver.py
Go to the documentation of this file.
1 import peano4
2 import exahype2
3 import dastgen2
4 
5 from abc import abstractmethod
6 
7 
8 class 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  """
136  self.integer_constantsinteger_constants = {
137  "CCZ4LapseType": 0,
138  "CCZ4SO": 0,
139  }
140  self.double_constantsdouble_constants = {
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 
159  self.integer_constantsinteger_constants.update({"CCZ4SO": 1})
161  self.Default_Time_Step_Size_RelaxationDefault_Time_Step_Size_RelaxationDefault_Time_Step_Size_Relaxation / 2
162  )
163 
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_constantsinteger_constants.items():
208  self.add_solver_constants(
209  "static constexpr int {} = {};".format(key, value)
210  )
211  for key, value in self.double_constantsdouble_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 
302  def __init__(
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_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  )
316  self._add_standard_includes_add_standard_includes()
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 
390  def __init__(
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_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  )
415  self._add_standard_includes_add_standard_includes()
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  std::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  std::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  )
576  init_action_set = exahype2.tracer.InsertParticlesByCoordinates(
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(
663  exahype2.tracer.InsertParticlesByCoordinates(
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,
716  exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking,
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 
742  def __init__(
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_FO_formulation_unknowns.values()),
769  auxiliary_variables=0,
770  min_meshcell_h=min_meshcell_h,
771  max_meshcell_h=max_meshcell_h,
772  time_step_relaxation=self.Default_Time_Step_Size_RelaxationDefault_Time_Step_Size_RelaxationDefault_Time_Step_Size_Relaxation,
773  pde_terms_without_state=pde_terms_without_state,
774  )
775 
776  self._add_standard_includes_add_standard_includes()
777 
778  self.set_implementation(
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 
787  self.postprocess_updated_patch += construct_FD4_postprocessing_kernel()
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 
868  AbstractCCZ4Solver, exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStep
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 
878  def __init__(
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_FO_formulation_unknowns.values()),
904  auxiliary_variables=0,
905  min_meshcell_h=min_meshcell_h,
906  max_meshcell_h=max_meshcell_h,
907  time_step_relaxation=self.Default_Time_Step_Size_RelaxationDefault_Time_Step_Size_RelaxationDefault_Time_Step_Size_Relaxation,
908  )
909 
910  self._add_standard_includes_add_standard_includes()
911 
912  self.set_implementation(
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 
921  self.postprocess_updated_patch += construct_FD4_postprocessing_kernel()
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,
996  exahype2.solvers.rkfd.fd4.GlobalAdaptiveTimeStepWithEnclaveTasking,
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,
1062  unknowns=len(self._SO_formulation_unknowns_SO_formulation_unknowns),
1063  auxiliary_variables=sum(self._FO_formulation_unknowns_FO_formulation_unknowns.values())
1064  - len(self._SO_formulation_unknowns_SO_formulation_unknowns),
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 
1071  self._add_standard_includes_add_standard_includes()
1072 
1073  self.set_implementation(
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  std::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 
1098  self.postprocess_updated_patch += """
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 
1146  self.preprocess_reconstructed_patch += (
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 = (
1191  (self.unknowns + self.auxiliary_variables)
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  )
1198  init_action_set = exahype2.tracer.InsertParticlesByCoordinates(
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,
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  std::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  )
1311  init_action_set = exahype2.tracer.InsertParticlesByCoordinates(
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 
1319  tracing_action_set = exahype2.tracer.DiscontinuousGalerkinTracing(
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,
1350  exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStepWithEnclaveTasking,
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_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 
1404  self._add_standard_includes_add_standard_includes()
1405 
1406  self.set_implementation(
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 
1415  self.postprocess_updated_cell_after_final_linear_combination += (
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,
1459  exahype2.solvers.rkdg.rusanov.GlobalAdaptiveTimeStep,
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_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 
1513  self._add_standard_includes_add_standard_includes()
1514 
1515  self.set_implementation(
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 
1524  self.postprocess_updated_cell_after_final_linear_combination += (
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  )
Dictionary which specifies the unknown names plus their cardinality.
Definition: CCZ4Solver.py:8
def 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)
Definition: CCZ4Solver.py:260
def add_makefile_parameters(self, peano4_project, path_of_ccz4_application)
Definition: CCZ4Solver.py:216
dictionary _FO_formulation_unknowns
Definition: CCZ4Solver.py:83
def __init__(self, name, patch_size, rk_order, min_meshcell_h, max_meshcell_h, pde_terms_without_state, second_order=False)
Definition: CCZ4Solver.py:751
def 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)
Definition: CCZ4Solver.py:835
def __init__(self, name, patch_size, rk_order, min_meshcell_h, max_meshcell_h, second_order=False)
Definition: CCZ4Solver.py:886
def 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)
Definition: CCZ4Solver.py:969
def __init__(self, name, patch_size, rk_order, min_meshcell_h, max_meshcell_h, reconstruction_type)
Definition: CCZ4Solver.py:1047
def 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)
Definition: CCZ4Solver.py:1178
def 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)
Definition: CCZ4Solver.py:438
def __init__(self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state)
Definition: CCZ4Solver.py:397
def 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)
Definition: CCZ4Solver.py:339
def __init__(self, name, patch_size, min_volume_h, max_volume_h, pde_terms_without_state)
Definition: CCZ4Solver.py:304
def 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)
Definition: CCZ4Solver.py:1429
def __init__(self, name, rk_order, polynomials, min_cell_h, max_cell_h, pde_terms_without_state)
Definition: CCZ4Solver.py:1384
def 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)
Definition: CCZ4Solver.py:1538
def __init__(self, name, rk_order, polynomials, min_cell_h, max_cell_h, pde_terms_without_state)
Definition: CCZ4Solver.py:1493
def construct_FV_source_term()
Definition: CCZ4Solver.py:499
def 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)
Definition: CCZ4Solver.py:640
def construct_DG_eigenvalues()
Definition: CCZ4Solver.py:1272
def construct_FD4_ncp()
Definition: CCZ4Solver.py:464
def construct_DG_source_term()
Definition: CCZ4Solver.py:1265
def construct_FV_postprocessing_kernel()
Definition: CCZ4Solver.py:532
def construct_FD4_postprocessing_kernel()
Definition: CCZ4Solver.py:518
def construct_FD4_source_term()
Definition: CCZ4Solver.py:492
def construct_FV_ncp()
Definition: CCZ4Solver.py:478
def construct_FV_eigenvalues()
Definition: CCZ4Solver.py:512
def 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)
Definition: CCZ4Solver.py:556
def construct_DG_postprocessing_kernel()
Definition: CCZ4Solver.py:1278
def construct_FD4_eigenvalues()
Definition: CCZ4Solver.py:506
def 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)
Definition: CCZ4Solver.py:1302
def construct_DG_ncp()
Definition: CCZ4Solver.py:1251