109 Path (relative or absolute) to the src directory of Peano. This path
110 should hold both the headers (in subdirectories) and all the static
113 mode: peano4.output.CompileMode
116 swift2dir = os.path.join(src_path,
"src",
"swift2")
117 peano4dir = os.path.join(src_path,
"src",
"peano4")
118 tarchdir = os.path.join(src_path,
"src",
"tarch")
120 for d
in (swift2dir, peano4dir, tarchdir):
121 if not os.path.exists(d):
122 dir_stripped = d[len(src_path) :]
123 raise FileNotFoundError(
124 f
"Didn't find directory {dir_stripped} in passed peano root dir={src_path}"
140 We export SWIFT's constants. Besides the constants from SWIFT,
141 I also export some parameters from Peano onto the SWIFT constants
142 file. Therefore, it is important that you parse the configure output
143 before we export the constants.
156 self.
_project.constants.add_include(
"""#include <bitset>""")
157 self.
_project.constants.add_include(
"""#include "tarch/la/Vector.h" """)
158 self.
_project.constants.add_include(
"""#include "peano4/utils/Globals.h" """)
159 self.
_project.constants.export_const_with_type(
160 "DomainOffset", offset_string,
"tarch::la::Vector<Dimensions,double>"
162 self.
_project.constants.export_const_with_type(
163 "DomainSize", size_string,
"tarch::la::Vector<Dimensions,double>"
172 "MaxTerminalTime",
"std::numeric_limits<double>::max()"
184 build_string =
"python3 "
188 self.
_project.constants.export_string(
"BuildInformation", build_string)
189 self.
_project.constants.export_string(
190 "ConfigureInformation", self.
_project.output.makefile.configure_call
197This code uses the second generation of the SWIFT code controlled through
198its Python API. Under the hood it uses Peano 4. We do not yet have a release
199paper for this second generation of SWIFT yet, and thus appreciate any
200citation of the original SWIFT paper
202 @article{Schaller:2020:SWIFT,
212We assume that you use a domain of ("""
227We assume that you use a domain of ("""
246Peano 4 will cut this domain equidistantly and recursively into three parts along each coordinate axis. This yields a spacetree.
248The coarsest mesh chosen has a mesh width of h_max="""
251As Peano realises three-partitioning, the actual maximum mesh size will be h_max="""
254This corresponds to at least """
256 +
""" spacetree levels.
257The coarsest regular mesh hence will host """
261Once this resultion is reached, the mesh will stop the initial load balancing, insert the
262particles and then kick off the simulation. The mesh might be refined and erased subsequently,
263but it will never become coarser than these constraints.
265Each particle provides its own additional meshing constraints:
267Species | max_h | coarsest level | min_h | finest level
268--------|-------|----------------|-------|-------------"""
273{} | {} | {} | {} | {}
284The meshing quantities abive are species-specific. Once you have multiple
285particle species, the actual grid results from a combination of their
286properties, and some species particles might reside on different resolution
290 self.
_project.output.readme.add_package_description(readme_text)
408 Build the Peano4 project
410 The main job of this routine is to add all the action sets et al that you
411 require to run this ExaHyPE2 application.
413 This routine generates a Peano project, i.e. the domain-specific ExaHyPE
414 view is translated into a Peano model. Once you have called this routine,
415 any changes to the ExaHyPE 2 configuration do not propagate into the Peano
416 setup anymore. If you alter the ExaHyPE setup, you have to call
417 generate_Peano4_project() again to get a new snapshot/version of the
423 The initial grid will be a regular one, spanned through
425 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
426 action_set_create_regular_grid = peano4.toolbox.CreateRegularGrid(...)
427 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
429 According to the documentation of peano4.toolbox.CreateRegularGrid,
430 the action set will produce a mesh that is just finer than the mesh
431 width passed, so we meet the max mesh width, but do not create a
432 mesh that is significantly finer.
434 As we insert particles in SPH, we have therefore to make this initial
435 resolution three times coarser than what we allow, as we only insert
436 particles into the finest mesh.
440 ## Task graph compiler
442 The core contribution of the generation is the task graph compiler which
443 really is a mapping of algorithm steps per particle species onto grid
444 sweeps. The actual mapping is outsourced into the function represented
445 by self.task_graph_compiler. This way, users can switch the translator's
446 behaviour. This function returns a sequence of mesh traversals. On top
447 of that, we have the default traversals to create a grid, to plot it,
448 to initialise the setup, and to clean up after we're done.
450 Once we have our three default steps plus a sequence of algorithmic steps
451 per time step, we run through the following steps:
453 - Create a particle set around each species and add it to the project as
454 global variable. This is the global container administering these guys.
455 - Tell each algorithmic step to use this particle set. An exception could be
456 the grid creation. At this point, we don't have particles yet. We add
457 the data structure nevertheless. It ensures that we have all the data
458 in place, and it we also then can be sure that everything is properly
459 initialised. The actual particle set will be empty at this point of the
461 - Ensure that plotting and initialisation use the update particle-grid
462 association properly. The plot has to update it, as previous steps
463 might have started a resort yet might not have finished it.
464 - Add all the algorithmic steps, including the default ones, to
468 ## Particle initialisation and proper sorting
470 The particle initialisation might end up with an invalid association of
471 particles to vertices. The graph compiler might make the first step of a
472 time step sequence sort if and only if the last one has altered the
473 particles' position. Consequently, we might end up with an initialisation
474 which yields an inconsistent data association. We therefore make it sort
475 the particles, but we need another grid sweep to finalise this sort in
476 case we have to do some global rearrangements. This is our rationale why
477 we realise the initialisation in two steps.
524 self.
_project.datamodel.add_global_object(
525 current_species_set.particle_model
527 self.
_project.datamodel.add_vertex(current_species_set)
538 cell_marker_for_statistics = (
539 DynamicMeshRefinementAnalysis.create_cell_marker(
540 current_species_set.name
544 current_species_set.name
547 task_name=current_species_set.name,
548 full_qualified_enumerator_type=
"::swift2::TaskEnumerator",
549 enumerator_include=
""" #include "swift2/TaskEnumerator.h" """,
553 self.
_project.datamodel.add_cell(cell_marker_for_statistics)
554 self.
_project.datamodel.add_cell(cell_marker_for_tasks)
555 self.
_project.datamodel.add_vertex(vertex_marker_for_tasks)
573 for solverstep
in solver_steps:
574 solverstep.use_vertex(current_species_set)
575 solverstep.use_vertex(vertex_marker_for_tasks)
576 solverstep.use_cell(cell_marker_for_statistics)
577 solverstep.use_cell(cell_marker_for_tasks)
579 for solverstep
in initialisation_steps:
580 solverstep.use_vertex(current_species_set)
581 solverstep.use_vertex(vertex_marker_for_tasks)
582 solverstep.use_cell(cell_marker_for_statistics)
583 solverstep.use_cell(cell_marker_for_tasks)
587 time_stamp_evaluation=
"repositories::getMinTimeStamp()",
588 additional_includes=
"""
589#include "repositories/GlobalState.h"
592 action_set_plot_grid.descend_invocation_order = (
595 action_set_plot_grid.parallel =
True
601 action_set_create_regular_grid.descend_invocation_order = (
604 action_set_create_regular_grid.parallel =
True
612 for solverstep
in solver_steps:
614 solverstep.add_action_set(action_set)
615 self.
_project.solversteps.add_step(solverstep)
617 for initialisation_step
in initialisation_steps:
618 self.
_project.solversteps.add_step(initialisation_step)
621 self.
_project, initialisation_steps, solver_steps
625 self.
_project.output.makefile.parse_configure_script_outcome(