Peano
Loading...
Searching...
No Matches
Project.py
Go to the documentation of this file.
1# This file is part of the ExaHyPE2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import peano4
5
6import dastgen2
7
8import os
9import sys
10
11import exahype2.grid
13
14class Project(object):
15 """!
16
17 ExaHyPE 2 project
18
19 Represents an ExaHyPE 2 project. An ExaHyPE2 project is a Peano 4
20 project with a particular set of actions (algorithmic phases)
21 that you can choose from and with particular solver types. It
22 realises a builder mechanism, i.e. you build up your ExaHyPE 2
23 project and then you finally tell the project "give me the Peano 4
24 project". From hereon, you can use this Peano 4 project to actually
25 set up the Peano 4 application.
26
27 The project will have a marker per cell that encodes stuff alike
28 a boundary marker. But it is also used to coordinate different
29 solver types.
30
31 @see generate_Peano4_project()
32 """
33
34 def __init__(self, namespace, project_name, executable, directory=".", subdirectory="", abstract_overwrite=True):
35 self._project = peano4.Project(namespace, project_name, directory, subdirectory)
36 self._subdirectory = subdirectory
37 self._abstract_overwrite = abstract_overwrite
38
39 self._solvers = []
40 self._domain_offset = [0.0, 0.0, 0.0]
41 self._domain_size = [1.0, 1.0, 1.0]
42 self._dimensions = 3
51 self._log_filter_file = "exahype.log-filter"
52 self._number_of_threads = "tarch::multicore::Core::UseDefaultNumberOfThreads"
53 self._multicore_orchestration = "tarch::multicore::orchestration::createDefaultStrategy()"
54 self._timeout = 3600
55 self._gpus = []
56 self._additional_includes = [ "tarch/logging/LogFilterFileReader.h",
57 "tarch/accelerator/Device.h"
58 ]
60 self._build_mode = peano4.output.CompileMode.Asserts
61 self._executable_name = executable
62 self._periodic_BC = [False, False, False]
63 self._plot_filters = []
64 self._output_path = "./"
68
73
74
75 self.create_grid = peano4.solversteps.Step("CreateGrid", False)
76 self.init_grid = peano4.solversteps.Step("InitGrid", False)
77 self.create_grid_but_postpone_refinement = peano4.solversteps.Step("CreateGridButPostponeRefinement", False)
78 self.create_grid_and_converge_lb = peano4.solversteps.Step("CreateGridAndConvergeLoadBalancing", False)
79 self.plot_solution = peano4.solversteps.Step("PlotSolution", False)
80 self.checkpoint_solution = peano4.solversteps.Step("CheckpointSolution", False)
82
83
84 def set_load_balancing(self, load_balancer_name, load_balancer_arguments=""):
85 """
86 load_balancer_name: string
87 Should be full-qualified name of the load balancer.
88 By default, I recommend to pass "toolbox::loadbalancing::strategies::RecursiveSubdivision".
89
90 load_balancer_arguments: string
91 If your load balancing requires parameters, add them
92 here. It is a string that will be copied into the C++ class instantiation.
93 Please add the brackets yourself, i.e. "(3,4,5)" is fine, but "3,4,5" is not.
94 The only exception is the empty parameter list. Here, you can/should simply
95 add the empty string.
96 """
97 self._load_balancer_name = load_balancer_name
98 self._load_balancer_arguments = load_balancer_arguments
99
100
101 def set_log_filter_file(self, file_name):
102 """! Set a log filter file name
103 Pass in the empty string, if you want the code to use the hard-coded
104 defaults.
105 """
106 self._log_filter_file = file_name
107
108
109 def set_number_of_threads(self, value):
110 """! Set number of threads to use
111 Pass in number of threads (positive integer) or a string such as
112 "tarch::multicore::Core::UseDefaultNumberOfThreads".
113 """
114 self._number_of_threads = value
115
116
118 """! Set orchestration
119 value has to be a string which creates an orchestration object,
120 i.e., an object of the type tarch::multicore::orchestration::Orchestration.
121 You can either create it directly (in this case you need to add a new),
122 or you can use a factory method such as
123 "tarch::multicore::orchestration::StrategyFactory::createDefaultStrategy()".
124 """
125 self._multicore_orchestration = value
126
127
128 def set_timeout(self, value):
129 """! Set timeout
130 value has to be a number greater or equal to zero, this then sets the
131 timeout in seconds after which a node waiting for an MPI message shall
132 quit an shutdown the whole application with an error report.
133 If zero is passed, this feature is switched off and nodes will wait
134 indefinitely.
135 """
136 if value < 0:
137 raise Exception("Timeout has to be greater or equal to 0")
138 self._timeout = value
139
140
141 def set_gpus(self, value):
142 """! Set GPUs to be used
143 value is a list of integers or the empty list if you want the code to
144 use all GPUs that are visible to a rank.
145 """
146 self._gpus = value
147
148
149 """
150 The standard extensions that I use for both Peano and ExaHyPE.
151 """
152 LibraryDebug = "_debug"
153 LibraryRelease = ""
154 LibraryTrace = "_trace"
155 LibraryAsserts = "_asserts"
156 LibraryStats = "_stats"
157
158 def set_Peano4_installation(self, src_path, mode=peano4.output.CompileMode.Release):
159 """
160 src_path: string
161 Path (relative or absolute) to the src directory of Peano. This path
162 should hold both the headers (in subdirectories) and all the static
163 libraries.
164
165 mode: peano4.output.CompileMode
166 """
167 self._Peano_src_directory = src_path
168 self._build_mode = mode
169
170 def add_solver(self, solver):
171 self._solvers.append(solver)
172
173 def add_plot_filter(self, offset, size, frequency=1):
174 """
175 Add a new filter to Peano/ExaHyPE
176
177 offset: (float,float,float)
178
179 size: (float,float,float)
180
181 frequency: int
182 A positive value. Peano makes snapshots every dt simulation
183 units. This is something you specify once per simulation. But
184 you might decide only to splot every k of these snapshots.
185 """
186 new_entry = "{{"
187 new_entry += str(offset[0])
188 for i in offset[1:]:
189 new_entry += ","
190 new_entry += str(i)
191 new_entry += "},{"
192 new_entry += str(size[0])
193 for i in size[1:]:
194 new_entry += ","
195 new_entry += str(i)
196 new_entry += "},"
197 new_entry += str(frequency)
198 new_entry += "}"
199
200 self._plot_filters.append(new_entry)
201
203 self._solvers = []
204 self._project.cleanup()
205
207 """
208 We export ExaHyPE's constants. Besides the constants from ExaHyPE,
209 we also export some parameters from Peano onto the ExaHyPE constants
210 file. Therefore, it is important that you parse the configure output
211 before we export the constants.
212 """
213 self._project.constants.clear()
214 offset_string = "{" + str(self._domain_offset[0])
215 size_string = "{" + str(self._domain_size[0])
216 for i in range(1, self._dimensions):
217 offset_string += ","
218 size_string += ","
219 offset_string += str(self._domain_offset[i])
220 size_string += str(self._domain_size[i])
221 offset_string += "}"
222 size_string += "}"
223 self._project.constants.add_include("""#include <bitset>""")
224 self._project.constants.add_include("""#include "tarch/la/Vector.h" """)
225 self._project.constants.add_include("""#include "peano4/utils/Globals.h" """)
226 self._project.constants.export_const_with_type(
227 "DomainOffset", offset_string, "tarch::la::Vector<Dimensions,double>"
228 )
229 self._project.constants.export_const_with_type(
230 "DomainSize", size_string, "tarch::la::Vector<Dimensions,double>"
231 )
232 self._project.constants.export("MinTerminalTime", str(self._min_terminal_time))
234 self._project.constants.export(
235 "MaxTerminalTime", str(self._max_terminal_time)
236 )
237 else:
238 self._project.constants.export(
239 "MaxTerminalTime", "std::numeric_limits<double>::max()"
240 )
241
243 self._project.constants.export(
244 "FirstPlotTimeStamp", f"{self._restart_timestamp:.{5}g}"
245 )
246 self._project.constants.export(
247 "FirstCheckpointTimeStamp", f"{self._restart_timestamp:.{5}g}"
248 )
249 else:
250 self._project.constants.export(
251 "FirstPlotTimeStamp", str(self._first_plot_time_stamp)
252 )
253 self._project.constants.export(
254 "FirstCheckpointTimeStamp", str(self._first_checkpoint_time_stamp)
255 )
256
257 self._project.constants.export(
258 "TimeInBetweenPlots", str(self._time_in_between_plots)
259 )
260
261 self._project.constants.export(
262 "TimeInBetweenCheckpoints", str(self._time_in_between_checkpoints)
263 )
264
266 if self._solvers_file_collection==[] or len(self._solvers_file_collection)<len(self._solvers):
267 error_message = "No checkpoint found for all/part of solvers, please check your path and checkpoint files."
268 sys.stderr.write(error_message + "\n")
269 sys.exit(1)
270 else:
271 for i in range(len(self._solvers)):
272 file_string = "{" + self._solvers_file_collection[i][0]
273 for j in range(1, len(self._solvers_file_collection[i])):
274 file_string += ","
275 file_string += self._solvers_file_collection[i][j]
276 file_string += "}"
277 self._project.constants.export_const_with_type(
278 "CheckpointFilesOf"+self._solvers[i]._name, file_string, "std::vector<std::string>"
279 )
280 self._project.constants.export(
281 "CheckpointTimeStamp", str(self._restart_timestamp)
282 )
283
284 self._project.constants.export("PlotterPrecision", str(self._plotter_precision))
285 self._project.constants.export_boolean_sequence("PeriodicBC", self._periodic_BC)
286
287 build_string = "python3 "
288 for i in sys.argv:
289 build_string += " "
290 build_string += i
291 self._project.constants.export_string("BuildInformation", build_string)
292 self._project.constants.export_string(
293 "ConfigureInformation", self._project.output.makefile.configure_call
294 )
295
296 self._project.output.readme.add_package_description(
297 """
298
299### ExaHyPE 2
300
301This code uses ExaHyPE in its second generation. The first generation of the
302code was developed through an EU FET HPC project called ExaHyPE. This first
303generation was built on top of Peano in its third generation. The present
304code uses ExaHyPE 2 which is a complete rewrite built on top of Peano 4. We
305do not yet have a release paper for this second generation of ExaHyPE, and
306thus appreciate any citation of the original release paper
307
308 @article{Reinarz:2020:ExaHyPE,
309 title = {ExaHyPE: An engine for parallel dynamically adaptive simulations of wave problems},
310 journal = {Computer Physics Communications},
311 volume = {254},
312 pages = {107251},
313 year = {2020},
314 issn = {0010-4655},
315 doi = {https://doi.org/10.1016/j.cpc.2020.107251},
316 url = {https://www.sciencedirect.com/science/article/pii/S001046552030076X},
317 author = {Anne Reinarz and Dominic E. Charrier and Michael Bader and Luke Bovard and Michael Dumbser and Kenneth Duru and Francesco Fambri and Alice-Agnes Gabriel and Jean-Matthieu Gallard and Sven K\"oppel and Lukas Krenz and Leonhard Rannabauer and Luciano Rezzolla and Philipp Samfass and Maurizio Tavelli and Tobias Weinzierl},
318 keywords = {Hyperbolic, PDE, ADER-DG, Finite volumes, AMR, MPI, TBB, MPI+X},
319 abstract = {ExaHyPE (An Exascale Hyperbolic PDE Engine) is a software engine for solving systems of first-order hyperbolic partial differential equations (PDEs). Hyperbolic PDEs are typically derived from the conservation laws of physics and are useful in a wide range of application areas. Applications powered by ExaHyPE can be run on a student's laptop, but are also able to exploit thousands of processor cores on state-of-the-art supercomputers. The engine is able to dynamically increase the accuracy of the simulation using adaptive mesh refinement where required. Due to the robustness and shock capturing abilities of ExaHyPE's numerical methods, users of the engine can simulate linear and non-linear hyperbolic PDEs with very high accuracy. Users can tailor the engine to their particular PDE by specifying evolved quantities, fluxes, and source terms. A complete simulation code for a new hyperbolic PDE can often be realised within a few hours - a task that, traditionally, can take weeks, months, often years for researchers starting from scratch. In this paper, we showcase ExaHyPE's workflow and capabilities through real-world scenarios from our two main application areas: seismology and astrophysics.
320 Program summary
321 Program title: ExaHyPE-Engine Program Files doi: http://dx.doi.org/10.17632/6sz8h6hnpz.1 Licensing provisions: BSD 3-clause Programming languages: C++, Python, Fortran Nature of Problem: The ExaHyPE PDE engine offers robust algorithms to solve linear and non-linear hyperbolic systems of PDEs written in first order form. The systems may contain both conservative and non-conservative terms. Solution method: ExaHyPE employs the discontinuous Galerkin (DG) method combined with explicit one-step ADER (arbitrary high-order derivative) time-stepping. An a-posteriori limiting approach is applied to the ADER-DG solution, whereby spurious solutions are discarded and recomputed with a robust, patch-based finite volume scheme. ExaHyPE uses dynamical adaptive mesh refinement to enhance the accuracy of the solution around shock waves, complex geometries, and interesting features.
322 }
323 }
324"""
325 )
326
327 for i in self._solvers:
328 self._project.output.readme.add_entry(
329 i.create_readme_descriptor(self._domain_offset[0], self._domain_size[0])
330 )
331 # self._min_volume_h = min_volume_h
332 # self._max_volume_h = max_volume_h
333
335 self._project.output.makefile.set_dimension(self._dimensions)
336 self._project.output.makefile.set_executable_name(self._executable_name)
337
339 self,
340 dimensions,
341 offset,
342 size,
343 min_end_time,
344 first_plot_time_stamp,
345 time_in_between_plots,
346 periodic_BC=[False, False, False],
347 plotter_precision=5,
348 max_end_time=0.0,
349 first_checkpoint_time_stamp=0.0,
350 time_in_between_checkpoints=0.0
351 ):
352 """
353 ! Set the global simulation parameters
354
355 @param dimensions: 2 or 3
356
357 @param offset: [Float]
358 Has to have dimension number of entries.
359
360 @param size: [Float}
361 Has to have dimension number of entries and all of them have to be
362 positive. At this point, we strongly suggest that all size entries
363 are exactly the same. While Peano and ExaHyPE do support anisotropic
364 meshes, most compute kernels do not, so working with something else
365 than a square or cube will likely break all numerics.
366
367 @param first_plot_time_stamp: Float
368 Is irrelevant if time_in_between_plots equals zero
369
370 @param time_in_between_plots: Float
371 Set to zero if you don't want to have any plots
372
373 @param max_end_time: Float
374 If you set it zero (or actually any value smaller than min_end_time), then
375 the code will run until the cell that lags behind the most hits the min time.
376 If you specify a valid max time however, you can stop the sim as soon as the
377 most advanced cell exceeds this threshold.
378 """
379 self._domain_offset = offset
380 self._domain_size = size
381 self._dimensions = dimensions
382
383 assert (
384 len(self._domain_offset) == dimensions
385 ), "domain offset vector and dimensions don't match"
386 assert (
387 len(self._domain_size) == dimensions
388 ), "domain offset vector and dimensions don't match"
389
390 self._max_terminal_time = max_end_time
391 self._min_terminal_time = min_end_time
392 self._first_plot_time_stamp = first_plot_time_stamp
393 self._time_in_between_plots = time_in_between_plots
394 self._first_checkpoint_time_stamp = first_checkpoint_time_stamp
395 self._time_in_between_checkpoints = time_in_between_checkpoints
396 self._project.constants.export(
397 "TimeInBetweenPlots", str(self._time_in_between_plots)
398 )
399 self._project.constants.export(
400 "TimeInBetweenCheckpoints", str(self._time_in_between_checkpoints)
401 )
402
403 self._periodic_BC = []
404 self._plotter_precision = plotter_precision
405 for d in range(0, dimensions):
406 self._periodic_BC.append(periodic_BC[d])
407 if plotter_precision <= 0:
408 raise Exception("Plotter precision has to be bigger than 0")
409
410 def set_restart_from_checkpoint(self, expected_restart_timestamp=0, checkpoint_path="./"):
411 '''
412 set checkpointing. The function accept the corresponding peano
413 patch file and create corresponding arrays recording the checkpoint
414 file names.
415
416 @param restart_timestamp float
417 targeting restart timestamp, the function will find the first
418 checkpointed timestamp right after this input time. Thus the final
419 restarting timestamp may not be equal to this specified time.
420
421 @param checkpoint_file string
422 the location of the checkpoint meta-file
423 '''
424
425 self._restart_from_checkpoint = True
426 self._restart_timestamp = expected_restart_timestamp
427 self._checkpoint_path = checkpoint_path
428
429 for solver in self._solvers:
430 checkpoint_meta_file=checkpoint_path+"checkpoint-"+solver._name+".peano-patch-file"
431 recording_current_snapshot=False
432 solver_file_collection=[]
433 with open(checkpoint_meta_file,'r') as file:
434 for line in file:
435 if line.strip().split()==[]: continue
436 if line.strip().split()[0] == "timestamp" and float(line.strip().split()[1])>=self._restart_timestamp:
437 self._restart_timestamp = float(line.strip().split()[1])
438 recording_current_snapshot=True
439 if line.strip().split()[0] == "include" and recording_current_snapshot==True:
440 solver_file_collection.append( line.strip().split()[1] )
441 if line.strip().split()[0] == "end" and recording_current_snapshot==True:
442 break
443 if recording_current_snapshot:
444 self._solvers_file_collection.append(solver_file_collection)
445
446
447 def set_output_path(self, path):
448 self._output_path = path
449 if not os.path.exists(self._output_path):
450 try:
451 os.makedirs(self._output_path)
452 except:
453 print("Couldn't create the defined output path, please ensure that this path exists")
454 if not self._output_path.endswith("/"):
455 self._output_path += "/"
456
457 def add_mainfile_include(self,value):
458 self._additional_includes.append( value )
459
462 "SOLVERS": [],
463 "LOAD_BALANCER": self._load_balancer_name,
464 "LOAD_BALANCER_ARGUMENTS": self._load_balancer_arguments,
465 "PLOT_FILTER": self._plot_filters,
466 "TRACERS": [x.name for x in self._tracer_particles],
467 "LOG_FILTER_FILE": self._log_filter_file,
468 "NUMBER_OF_THREADS": self._number_of_threads,
469 "MULTICORE_ORCHESTRATION": self._multicore_orchestration,
470 "TIMEOUT": self._timeout,
471 "GPUS": self._gpus,
472 "ADDITIONAL_INCLUDES": self._additional_includes,
473 }
474
476 """
477 I have to call finishedTraversal() for each tracer set. As tracers
478 are a subclass of DoF, they have a name property.
479 """
480
482
483 for solver in self._solvers:
484 self.solverRepositoryDictionary["SOLVERS"].append(
485 (solver._name, solver.get_name_of_global_instance())
486 )
487
488 templatefile_prefix = (
489 os.path.realpath(__file__).replace(".pyc", "").replace(".py", "")
490 )
491 generated_solver_files = (
493 templatefile_prefix + "SolverRepository.template.h",
494 templatefile_prefix + "SolverRepository.template.cpp",
495 "SolverRepository",
496 self._project.namespace + ["repositories"],
497 self._project.subdirectory + "repositories",
499 True,
500 )
501 )
502
503 self._project.output.add(generated_solver_files)
504 self._project.output.makefile.add_cpp_file(
505 self._project.subdirectory + "repositories/SolverRepository.cpp", generated=True
506 )
507
509 self,
510 name,
511 attribute_count=0,
512 plot=True,
513 sort_descend_invocation_order_within_action_sets=-1,
514 plot_descend_invocation_order_within_action_sets=65536,
515 ):
516 """!
517
518 Add a tracer to the project
519
520 Tracers have to be the very last thing you add to your project.
521 At this point, all solvers have to be added to the project.
522 However, you have to add the tracers prior to any user-defined
523 routines. See docu of init_new_user_defined_algorithmic_step().
524
525 We rely on the particle toolbox. Therefore, our particles have
526 already a position x, a search radius (which we don't usually
527 use here), and a (parallel) state. The search radius determines
528 how Peano sorts particles within the tree, and we can set it to
529 zero here. This ensures that the particle has no real volume and
530 thus is always sieved through to the finest grid level.
531
532 @see peano4.toolbox.particles.Particle
533
534
535 ## Projection of data onto particles and database dumping
536
537 The projection onto the particle has to be realised separately, as
538 it depends on the solver variant chosen. The same holds for the
539 dump of particle data into a database if this shall happen
540 on-the-fly.
541
542 Most bigger applications add their solvers an add_tracer() operation,
543 which takes all of this domain knowledge into account. This
544 add_tracer() then forwards to this routine, adding further
545 behaviour.
546
547 See the class application.exahype2.ccz.CCZ4Solver and its derived
548 variants for examples.
549
550
551 ## Moving particles
552
553 Tracers in ExaHyPE can move, though they do not have to move. Even if
554 they move, they never have a native velocity, i.e. their velocity will
555 always be a projection of an ExaHyPE solution. We are talking about
556 tracers after all and not about a proper PIC approach. Due to this
557 constraint, we do not need a velocity vector. However, we need an
558 additional enumeration which clarifies if a
559 particle has moved already or not. This enumeration is needed by the
560 particle update routines. Obviously, nothing stops you from adding
561 a separate velocity field to the tracer object and thus to redefine
562 this behaviour.
563
564
565 ## ExaHyPE-specific particle attributes
566
567 We add each
568 particle a number which is a tuple consisting of the tree number
569 (on which tree has a particle been generated plus what was the
570 tree-local number of this particle at the time). Through this
571 tuple, we can track tracers later on even if they move across
572 domains.
573
574 We can plot the data - if there is data to be tracked - directly,
575 as it is a large double array. For the index, we have to type cast
576 the data, as this is a tuple of integers, and Peano's VTK plotter
577 supports only double vectors.
578
579 @see peano4.toolbox.particles.PlotParticlesInVTKFormat.add_attribute_to_plot()
580
581
582 ## Action set order
583
584 We add the particle ordering with descend order -1. This should do the job
585 for most setups, but we might be wrong. The following action sets are
586 automatically added:
587
588 - UpdateParallelState is added to each and every time step and plotting
589 sweep. As we also add
590 - peano4.toolbox.particles.api.UpdateParticleGridAssociation_LiftDrop to each and every time step,
591 particles can move at any point. We always resort them immediately.
592
593 Both action sets are assigned the standard priority of sort_descend_invocation_order_within_action_sets.
594
595
596 ## Arguments
597
598 name: String
599 Has to be a unique name for this tracer
600
601 attribute_count: integer
602 Number of attributes that we track per particle (scalar values added
603 pre particle). Can be 0 if you don't want any attributes.
604
605 h and noise:
606 See tracer.InsertParticles
607
608 plot: Boolean
609 If this flag is set, ExaHyPE dumps the particles as vtu files whenever
610 it writes patch files. You can switch this behaviour off. A lot of codes
611 do so if they dump the tracer data independently into another database
612 anyway.
613
614 sort_descend_invocation_order_within_action_sets: Integer
615 You have to clarify what the priority of the tracer is within the
616 action sets. By default, all ExaHyPE solvers start with priority
617 0 and then up to n. So you are fine with using the default of -1
618 which means that the tracer precedes any solver. However, there
619 might be cases where you wanna move the priorities manually.
620
621 Returns the particle set that you can use to modify further
622 """
623 particle = peano4.toolbox.particles.Particle(name)
624
625 if attribute_count > 0:
626 particle_attr = peano4.dastgen2.Peano4DoubleArray(
627 "data", str(attribute_count)
628 )
629 particle.data.add_attribute(particle_attr)
630
631 particle.data.add_attribute(
632 dastgen2.attributes.Enumeration("MoveState", ["NotMovedYet", "Moved"])
633 )
634
635 particle_number = peano4.dastgen2.Peano4IntegerArray("number", "2")
636 particle.data.add_attribute(particle_number)
637
638 particles = peano4.toolbox.particles.ParticleSet(particle)
639
640 self._project.datamodel.add_global_object(particle)
641 self._project.datamodel.add_vertex(particles)
642
643 self.plot_solution.use_vertex(particles)
644 self.checkpoint_solution.use_vertex(particles)
645 self.init_grid.use_vertex(particles)
646 self.perform_time_step.use_vertex(particles)
647 self.create_grid.use_vertex(particles)
648 self.create_grid_but_postpone_refinement.use_vertex(particles)
649 self.create_grid_and_converge_lb.use_vertex(particles)
650
651 #
652 # Initialisation
653 #
654 self.init_grid.add_action_set(
656 )
657
658 update_particle_association_action_set = (
660 )
661 update_particle_association_action_set.descend_invocation_order = sort_descend_invocation_order_within_action_sets
662 update_particle_association_action_set.parallel = True
663
664 update_particle_parallel_state_action_set = (
666 )
667 update_particle_parallel_state_action_set.descend_invocation_order = (
668 sort_descend_invocation_order_within_action_sets
669 )
670 update_particle_parallel_state_action_set.parallel = True
671
672 #
673 # Move particles
674 #
675 self.perform_time_step.add_action_set(update_particle_association_action_set)
676 self.perform_time_step.add_action_set(update_particle_parallel_state_action_set)
677
678 #
679 # Plotter: The timestamp here is slightly wrong, as I use the min time stamp. It
680 # really should be the time stamp of the underlying solver. However, tracers are
681 # not tied to one solver, so I have to find a quantity that makes sense. If the
682 # user requires the time stamp, they have to add this one as data field to the
683 # particle
684 #
685 if plot:
687 filename=name,
688 particle_set=particles,
689 time_stamp_evaluation="repositories::getMinTimeStamp()",
690 additional_includes="""
691#include "repositories/SolverRepository.h"
692""",
693 )
694 if attribute_count > 0:
695 particle_plotter.add_attribute_to_plot(particle_attr, attribute_count)
696 particle_plotter.add_attribute_to_plot(
697 particle_number, 2, "tarch::la::convertScalar<double>(p->getNumber())"
698 )
699 particle_plotter.descend_invocation_order = plot_descend_invocation_order_within_action_sets
700 self.plot_solution.add_action_set(particle_plotter)
701 self.checkpoint_solution.add_action_set(particle_plotter)
702
703 self.plot_solution.add_action_set(update_particle_association_action_set)
704 self.plot_solution.add_action_set(update_particle_parallel_state_action_set)
705
706 self.checkpoint_solution.add_action_set(update_particle_association_action_set)
707 self.checkpoint_solution.add_action_set(update_particle_parallel_state_action_set)
708
709 self._tracer_particles.append(particle)
710 self._tracer_particle_sets.append(particles)
711
712 return particles
713
714 def add_action_set_to_timestepping(self, action_set):
715 """!
716
717 Add a new action set to the time stepping
718
719 You have to be careful with the priorities, i.e. you might want to
720 use myproject.perform_time_step.max_priority() or myproject.perform_time_step.min_priority()
721 to find out which
722 priority you should assign to action_set.
723
724 """
725 self.perform_time_step.add_action_set(action_set)
726
727 def add_action_set_to_plot_solution(self, action_set):
728 """!
729
730 Add a new action set to the plotting
731
732 """
733 self.plot_solution.add_action_set(action_set)
734
736 """!
737
738 Add a new action set to the checkpointing
739
740 """
741 self.checkpoint_solution.add_action_set(action_set)
742
743 def add_action_set_to_initialisation(self, action_set):
744 self.init_grid.add_action_set(action_set)
745
746 def add_action_set_to_create_grid(self, action_set):
747 """!
748
749 Add an action set to create grid
750
751 This routine actually adds an action set to each and every grid
752 creation routine. After all, we distinguish three flavours of it
753
754 - with refinement;
755 - without refinement as we've just refined or split up domain;
756 - without refinement to let load balancing converge.
757
758 """
759 self.create_grid.add_action_set(action_set)
760 self.create_grid_but_postpone_refinement.add_action_set(action_set)
761 self.create_grid_and_converge_lb.add_action_set(action_set)
762
763 def generate_Peano4_project(self, verbose=False):
764 """!
765
766 Construct a Peano 4 project and return it
767
768 Build the Peano 4 project, i.e., all the action sets et al that you require
769 to run this ExaHyPE 2 application. The project is built within self._project
770 and eventually returned.
771
772 This routine generates a Peano project, i.e. the domain-specific ExaHyPE
773 view is translated into a Peano model. Once you have called this routine,
774 any changes to the ExaHyPE 2 configuration do not propagate into the Peano
775 setup anymore. If you alter the ExaHyPE setup, you have to call
776 generate_Peano4_project() again to get a new snapshot/version of the
777 Peano setup.
778 """
779 # self._project.cleanup()
780
781 self._project.solversteps.add_step(self.create_grid)
782 self._project.solversteps.add_step(self.init_grid)
783 self._project.solversteps.add_step(self.create_grid_but_postpone_refinement)
784 self._project.solversteps.add_step(self.create_grid_and_converge_lb)
785 self._project.solversteps.add_step(self.plot_solution)
786 self._project.solversteps.add_step(self.checkpoint_solution)
787 self._project.solversteps.add_step(self.perform_time_step)
788
789 for solver in self._solvers:
790 print("---------------------------------------")
791 print("Create data for solver " + solver._name)
792 print("---------------------------------------")
793 print(str(solver))
794
795 solver.add_to_Peano4_datamodel(self._project.datamodel, verbose)
796
797 solver.add_use_data_statements_to_Peano4_solver_step(self.create_grid)
798 solver.add_use_data_statements_to_Peano4_solver_step(self.plot_solution)
799 solver.add_use_data_statements_to_Peano4_solver_step(self.checkpoint_solution)
800 solver.add_use_data_statements_to_Peano4_solver_step(self.perform_time_step)
801 solver.add_use_data_statements_to_Peano4_solver_step(self.init_grid)
802 solver.add_use_data_statements_to_Peano4_solver_step(
804 )
805 solver.add_use_data_statements_to_Peano4_solver_step(
807 )
808
809 solver.add_actions_to_create_grid(
810 self.create_grid, evaluate_refinement_criterion=True
811 )
812
813 if self._restart_from_checkpoint: #avoid error when use solver without checkpoint feature
814 solver.add_actions_to_init_grid(self.init_grid, self._restart_from_checkpoint)
815 solver.add_actions_to_plot_solution(self.plot_solution, self._output_path, self._restart_from_checkpoint)
816 solver.add_actions_to_checkpoint_solution(self.checkpoint_solution, self._output_path, self._restart_from_checkpoint)
817 else:
818 solver.add_actions_to_init_grid(self.init_grid)
819 solver.add_actions_to_plot_solution(self.plot_solution, self._output_path)
820 if ( (self._time_in_between_checkpoints != 0) or (self._first_checkpoint_time_stamp != 0) ):
821 solver.add_actions_to_checkpoint_solution(self.checkpoint_solution, self._output_path)
822
823 solver.add_actions_to_create_grid(
825 evaluate_refinement_criterion=False,
826 )
827 solver.add_actions_to_create_grid(
828 self.create_grid_and_converge_lb, evaluate_refinement_criterion=False
829 )
830
831 solver.add_actions_to_perform_time_step(self.perform_time_step)
832
833 if self._abstract_overwrite==False:
834 solver.add_implementation_files_to_project(
835 self._project.namespace, self._project.output, self._dimensions, self._subdirectory, self._abstract_overwrite
836 )
837 else:
838 solver.add_implementation_files_to_project( self._project.namespace, self._project.output, self._dimensions, self._subdirectory )
839
841
842 self._project.main = exahype2.ExaHyPEMain(self._project)
843
845 self._project.output.makefile.parse_configure_script_outcome(
847 )
848 self.__export_constants()
849
850 self._project.output.makefile.set_mode(self._build_mode)
851
852 return self._project
853
854
856 step,
857 ):
858 """! Inform ExaHyPE 2 that there is an additional solver step not resulting from vanilla solver versions
859
860 Use this routine whenever you have created your own
861 @ref page_architecture "algorithmic step". Please note that the routine
862 should be called after you have created all of your solvers. Otherwise,
863 we'll miss out a few of your solvers and the data access patterns
864 will/might be corrupted. Also all tracers have to be added at this
865 point already.
866
867 The routine has no side-effects, i.e. does not alter the underlying
868 project. It only manipulates the step. Therefore, you can even call it
869 after you have distilled the Peano project from the ExaHyPE project,
870 i.e. after you have called exahype2.Project.generate_Peano4_project().
871 In return, you however still have to add the new step manually to the
872 Peano project. That is, this routine merely initialises the new step,
873 but it does not yet add it to the sweeps known by Peano.
874
875 @param step: peano4.solversteps.Step
876
877 """
878 for solver in self._solvers:
879 solver.add_use_data_statements_to_Peano4_solver_step(step)
880
881 for tracer_set in self._tracer_particle_sets:
882 step.use_vertex(tracer_set)
883
884 @property
885 def subdirectory(self):
886 return self._subdirectory
887
888 @property
890 return self._additional_includes
Wrapper around C++ enumerations which is not a datatype supported natively by MPI.
Definition Enumeration.py:6
ExaHyPE 2 project.
Definition Project.py:14
set_restart_from_checkpoint(self, expected_restart_timestamp=0, checkpoint_path="./")
set checkpointing.
Definition Project.py:410
__generate_solver_repository(self)
I have to call finishedTraversal() for each tracer set.
Definition Project.py:475
init_new_user_defined_algorithmic_step(self, step)
Inform ExaHyPE 2 that there is an additional solver step not resulting from vanilla solver versions.
Definition Project.py:857
add_action_set_to_timestepping(self, action_set)
Add a new action set to the time stepping.
Definition Project.py:714
set_load_balancing(self, load_balancer_name, load_balancer_arguments="")
load_balancer_name: string Should be full-qualified name of the load balancer.
Definition Project.py:84
set_number_of_threads(self, value)
Set number of threads to use Pass in number of threads (positive integer) or a string such as "tarch:...
Definition Project.py:109
set_Peano4_installation(self, src_path, mode=peano4.output.CompileMode.Release)
src_path: string Path (relative or absolute) to the src directory of Peano.
Definition Project.py:158
add_solver(self, solver)
Definition Project.py:170
set_output_path(self, path)
Definition Project.py:447
add_plot_filter(self, offset, size, frequency=1)
Add a new filter to Peano/ExaHyPE.
Definition Project.py:173
generate_Peano4_project(self, verbose=False)
Construct a Peano 4 project and return it.
Definition Project.py:763
add_tracer(self, name, attribute_count=0, plot=True, sort_descend_invocation_order_within_action_sets=-1, plot_descend_invocation_order_within_action_sets=65536)
Add a tracer to the project.
Definition Project.py:515
__init__(self, namespace, project_name, executable, directory=".", subdirectory="", abstract_overwrite=True)
Definition Project.py:34
set_timeout(self, value)
Set timeout value has to be a number greater or equal to zero, this then sets the timeout in seconds ...
Definition Project.py:128
add_action_set_to_plot_solution(self, action_set)
Add a new action set to the plotting.
Definition Project.py:727
__set_solver_repository_dict(self)
Definition Project.py:460
set_multicore_orchestration(self, value)
Set orchestration value has to be a string which creates an orchestration object, i....
Definition Project.py:117
add_action_set_to_create_grid(self, action_set)
Add an action set to create grid.
Definition Project.py:746
add_mainfile_include(self, value)
Definition Project.py:457
set_global_simulation_parameters(self, dimensions, offset, size, min_end_time, first_plot_time_stamp, time_in_between_plots, periodic_BC=[False, False, False], plotter_precision=5, max_end_time=0.0, first_checkpoint_time_stamp=0.0, time_in_between_checkpoints=0.0)
! Set the global simulation parameters
Definition Project.py:351
set_log_filter_file(self, file_name)
Set a log filter file name Pass in the empty string, if you want the code to use the hard-coded defau...
Definition Project.py:101
__export_constants(self)
We export ExaHyPE's constants.
Definition Project.py:206
set_gpus(self, value)
Set GPUs to be used value is a list of integers or the empty list if you want the code to use all GPU...
Definition Project.py:141
add_action_set_to_checkpoint_solution(self, action_set)
Add a new action set to the checkpointing.
Definition Project.py:735
add_action_set_to_initialisation(self, action_set)
Definition Project.py:743
Represents a Peano 4 project.
Definition Project.py:16
Specialisation of dastgen2.attributes.DoubleArray which relies on Peano's tarch.
Update the parallel state of particles and keep stats of them.