Peano
Loading...
Searching...
No Matches
noh.py
Go to the documentation of this file.
1import os
2import argparse
3import numpy as np
4
5import peano4.api
6import exaparty
7import exaparty.api.sphtools as sphtools
8import dastgen2
9
10import shutil
11
12
13
16
17
19 parser = argparse.ArgumentParser(description="SPH benchmarking script")
20 parser.add_argument(
21 "-j",
22 "--parallel-builds",
23 dest="j",
24 type=int,
25 default=-1,
26 help="Parallel builds",
27 )
28 parser.add_argument(
29 "-v",
30 "--verbose",
31 dest="verbose",
32 action="store_true",
33 default=False,
34 help="Verbose",
35 )
36 parser.add_argument(
37 "-c",
38 "--clean",
39 dest="clean_temporary_files",
40 action="store_true",
41 help="Remove temporary directories and output files before script starts",
42 )
43 parser.add_argument(
44 "-np",
45 "--particle-number",
46 dest="particle_number",
47 required=True,
48 type=int,
49 help="Particle number (1D)",
50 )
51 parser.add_argument(
52 "-t",
53 "--trees",
54 dest="trees",
55 default=0,
56 type=int,
57 help="Number of trees (subdomains) rank rank (0 uses all threads)",
58 )
59 parser.add_argument(
60 "-et",
61 "--end-time",
62 dest="end_time",
63 type=float,
64 default=0.2,
65 help="End of simulation",
66 )
67 parser.add_argument(
68 "-o",
69 "--output",
70 dest="output_file",
71 default="noh2D",
72 help="Executable file name",
73 )
74 parser.add_argument(
75 "-plot",
76 "--plot-delta",
77 dest="plot_delta",
78 type=float,
79 default=0.01,
80 help="Plot delta (0 switches off)",
81 )
82 parser.add_argument(
83 "-dt",
84 "--timestep-size",
85 dest="timestep_size",
86 type=float,
87 default=1e-4,
88 help="Global timestep size (initial value)",
89 )
90 parser.add_argument(
91 "-cfl",
92 "--cfl-factor",
93 dest="cfl_factor",
94 type=float,
95 default=0.1,
96 help="Value of the CFL constant",
97 )
98 parser.add_argument(
99 "-ppc",
100 "--particles-per-cell",
101 dest="particles_per_cell",
102 type=int,
103 default=100,
104 help="Particles per cell. If we have x particles, we will have 2^d*x particle comparisons on average per cell, as we compare to neighbouring half cells as well",
105 )
106 parser.add_argument(
107 "-pd",
108 "--peano-dir",
109 dest="peanodir",
110 default="../../../..",
111 help="Peano4 directory",
112 )
113 parser.add_argument(
114 "-m",
115 "--mode",
116 dest="mode",
117 choices=["release", "stats", "trace", "asserts", "debug"],
118 default="release",
119 help="Pick build type",
120 )
121 parser.add_argument(
122 "-rea",
123 "--realisation",
124 dest="realisation",
125 default="domain-decomposition.scattered.multiscale-sorting.no-optimisation",
126 help="Realisation to use. See Peano/src/exaparty/api/ProjectRealisation.py for options",
127 )
128 parser.add_argument(
129 "-ms",
130 "--mantissa-size",
131 dest="mantissa_size",
132 type=int,
133 default=0,
134 help="Mantissa size for clang truncation (if supported by compiler). Default of 0 disables any compression",
135 )
136 parser.add_argument(
137 "-k",
138 "--kernel",
139 dest="kernel",
140 type=str,
141 default="quartic_spline",
142 choices=sphtools.sph_kernel_list,
143 help="SPH kernel function to use.",
144 )
145
146 return parser.parse_args()
147
148
149if __name__ == "__main__":
150 args = parse_args()
151
152
155
156project_namespace = ["benchmarks", "exaparty", "noh2D"]
157
159 namespace=project_namespace, project_name="Noh2D", executable=args.output_file
160)
161
162# Initialise the SPH particle --------------------------------------------------
163# If multiple particle species are present, we can specify the parameters
164# independently for each case.
165
166name = "HydroPart"
167
168dimensions = 2
169hydro_dimensions = 2 # dimensions for the hydro
170
171particles_per_cell = args.particles_per_cell
172total_number_of_particles = args.particle_number**hydro_dimensions
173total_number_of_cells = total_number_of_particles / particles_per_cell
174cells_per_dimension = total_number_of_cells ** (1.0 / hydro_dimensions)
175max_cell_size = 2.0 / cells_per_dimension * 3.0
176
177print(
178 "{} particles in total fit into {} cells, i.e. {} cells per dimension. This gives h={}".format(
179 total_number_of_particles,
180 total_number_of_cells,
181 cells_per_dimension,
182 max_cell_size,
183 )
184)
185
187 name=name,
188 dimensions_hydro=hydro_dimensions,
189 cfl_factor=args.cfl_factor,
190 initial_time_step_size=args.timestep_size,
191 constant_time_step_size=True,
192 exaparty_project_namespace=project_namespace,
193 particles_per_cell=particles_per_cell,
194 min_h=max_cell_size,
195 max_h=max_cell_size,
196)
197
198
204
205offset = [0, 0, 0]
206domain_size = [2, 2, 2]
207periodic_boundary_conditions = [False, False, False]
208
209# HYDRO_DIMENSION can be smaller than the Peano4 dimensions
210HYDRO_DIMENSIONS = hydro_dimensions
211
212# Particle number along 1 dimension
213HYDRO_PART_NUMBER = args.particle_number
214
215# Time integration parameters
216GLOBAL_TIME_STEP_SIZE = args.timestep_size
217CFL_CONSTANT = args.cfl_factor
218
219# EoS parameter ---------------------------------------------------------------
220gamma_hydro_list = [str(5 / 3), str(7 / 5), str(4 / 3), str(2 / 1)]
221gamma_hydro_list_symbols = [
222 "HYDRO_GAMMA_5_3",
223 "HYDRO_GAMMA_7_5",
224 "HYDRO_GAMMA_4_3",
225 "HYDRO_GAMMA_2_1",
226]
227GAMMA = gamma_hydro_list[0]
228GAMMA_HYDRO_SYMBOL = gamma_hydro_list_symbols[0]
229
230# SPH kernel -------------------------------------------------------
231
232kernel = args.kernel
233KERNEL_SYMBOL = sphtools.sph_kernel_macro_name[kernel]
234KERNEL_SUPPORT_RAD = sphtools.sph_kernel_H_over_h[HYDRO_DIMENSIONS - 1][kernel]
235
236hydro_H_max = max_cell_size / 2
237
238dx = domain_size[0] / args.particle_number
239if hydro_H_max < 3.0 * dx:
240 raise ValueError("Too small hydro_H_max", 3.0 * dx, hydro_H_max)
241hydro_h_max = exaparty.api.sphtools.sph_kernel_get_smoothing_length_from_interaction_radius(
242 hydro_H_max, kernel, hydro_dimensions
243)
244particle.h_hydro_max = hydro_h_max
245
246# particle.h_hydro_min = 1e-6
247# particle.h_max_iterations = 10
248# particle.h_tolerance = 1e-4
249# particle.eta_factor = 1.2348
250# particle.beta_av = 3.0
251# particle.alpha_av = 0.8
252
253# IMPORTANT: Reduce the mantissa size for particle attributes -------------------
254# Native size is 53 (double precision)
255if args.mantissa_size > 0:
256 particle.mass.valid_mantissa_bits = args.mantissa_size
257 particle.velocity.valid_mantissa_bits = args.mantissa_size
258 particle.acceleration.valid_mantissa_bits = args.mantissa_size
259 particle.density.valid_mantissa_bits = args.mantissa_size
260 particle.pressure.valid_mantissa_bits = args.mantissa_size
261 particle.smoothL.valid_mantissa_bits = args.mantissa_size
262 particle.u.valid_mantissa_bits = args.mantissa_size
263 particle.uDot.valid_mantissa_bits = args.mantissa_size
264 particle.f.valid_mantissa_bits = args.mantissa_size
265 particle.wcount_dh.valid_mantissa_bits = args.mantissa_size
266 particle.rho_dh.valid_mantissa_bits = args.mantissa_size
267 particle.hleft.valid_mantissa_bits = args.mantissa_size
268 particle.hright.valid_mantissa_bits = args.mantissa_size
269 particle.smoothL_prev.valid_mantissa_bits = args.mantissa_size
270 particle.wcount.valid_mantissa_bits = args.mantissa_size
271 particle.hDot.valid_mantissa_bits = args.mantissa_size
272 particle.residual.valid_mantissa_bits = args.mantissa_size
273 particle.balsara.valid_mantissa_bits = args.mantissa_size
274 particle.rot_v.valid_mantissa_bits = args.mantissa_size
275 particle.div_v.valid_mantissa_bits = args.mantissa_size
276 particle.v_sig_AV.valid_mantissa_bits = args.mantissa_size
277 particle.soundSpeed.valid_mantissa_bits = args.mantissa_size
278 particle.v_full.valid_mantissa_bits = args.mantissa_size
279 particle.u_full.valid_mantissa_bits = args.mantissa_size
280
281particle.data.expose_all_attributes_in_header_file()
282
283# deploy particle properties
284# This needs to be done if you're changing any of the default values.
285# Otherwise, the changes won't propagate into dastgen.
286particle.set_parameters()
287
288# Add particle to the ExaParty project --------------------------------------------
289# Notice that you any change to the particle will not take effect after adding
290# the particle_set to the project
291particle_set = project.add_particle_species(particle)
292
293if args.mode == "release":
294 build_mode = peano4.api.output.CompileMode.RELEASE
295if args.mode == "stats":
296 build_mode = peano4.api.output.CompileMode.STATS
297if args.mode == "asserts":
298 build_mode = peano4.api.output.CompileMode.ASSERTS
299if args.mode == "trace":
300 build_mode = peano4.api.output.CompileMode.TRACE
301if args.mode == "debug":
302 build_mode = peano4.api.output.CompileMode.DEBUG
303
304# Set Peano4 simulation parameters ---------------------------------------------
305project.set_global_simulation_parameters(
306 dimensions=dimensions,
307 offset=offset,
308 domain_size=domain_size,
309 min_end_time=args.end_time,
310 max_end_time=0.0,
311 first_plot_time_stamp=0.0,
312 time_in_between_plots=args.plot_delta,
313 periodic_BC=periodic_boundary_conditions,
314 plotter_precision=8,
315)
316
317# Set realisation
318realisation = args.realisation.split(".")
319parallelisation = realisation[0]
320storage = realisation[1]
321sorting = realisation[2]
322kernel_optimisation = realisation[3]
323
324project.set_realisation(
325 parallelisation=parallelisation,
326 storage=storage,
327 sorting=sorting,
328 kernel_optimisation=kernel_optimisation,
329)
330
331project.set_Peano4_installation(args.peanodir, build_mode)
332
333project.set_load_balancing(
334 "toolbox::loadbalancing::strategies::SpreadOutOnceGridStagnates",
335 f"new toolbox::loadbalancing::DefaultConfiguration({args.trees})",
336)
337
338
339
342
343# Noh problem (2D) snippet --------------------------------------------------
344# The particle attributes are set via an initalisation snippet that sets
345# the initial conditions specific for this problem, i.e. the velocity field
346# that converges towards the center of the domain and that generates the
347# collapse.
348
349ICs = exaparty.api.scenario.NohProblemIC(dimensions=HYDRO_DIMENSIONS)
350initialisation_snippet = ICs.initialisation_snippet
351
352project.algorithm_step_initial_conditions.add_action_set(
354 particle_set=particle_set,
355 initialisation_call=initialisation_snippet,
356 distance_between_particles_along_one_axis=(
357 domain_size[0] / (args.particle_number)
358 ),
359 additional_includes="""
360#include "exaparty/kernels/legacy/equation_of_state.h"
361#include "exaparty/kernels/legacy/kernel_hydro.h"
362""",
363 )
364)
365
366
390 "particles",
391 particle_set,
392 "globaldata::{}::getSpecies().getMinTimeStamp()".format(particle.name),
393)
394particle_plotter.add_attribute_to_plot(particle.velocity, dimensions)
395particle_plotter.add_attribute_to_plot(particle.acceleration, dimensions)
396particle_plotter.add_attribute_to_plot(particle.mass, 1)
397particle_plotter.add_attribute_to_plot(particle.density, 1)
398particle_plotter.add_attribute_to_plot(particle.pressure, 1)
399particle_plotter.add_attribute_to_plot(particle.u, 1)
400particle_plotter.add_attribute_to_plot(particle.smoothL, 1)
401if args.mode == "asserts" or args.mode == "debug":
402 particle_plotter.add_attribute_to_plot(particle.partid, 1)
403 particle_plotter.add_attribute_to_plot(particle.density_neighbourcount, 1)
404 particle_plotter.add_attribute_to_plot(particle.force_neighbourcount, 1)
405project.algorithm_step_plot.add_action_set(particle_plotter)
406
407
408
419
420peano4_project = project.generate_Peano4_project(verbose=args.verbose)
421
422# Some sanity checks ----------------------------------------------------------
423if GAMMA not in gamma_hydro_list:
424 print(f"Please check the value of GAMMA. You have chosen: {GAMMA}")
425
426print("-----------------------------------------------------------------------")
427print("SPH parameters summary:")
428print(f"Effective dimensions of the Simulation: {HYDRO_DIMENSIONS}")
429print(f"Global time-step size: {GLOBAL_TIME_STEP_SIZE}")
430print(f"Number of particles (1D): {HYDRO_PART_NUMBER}")
431print(f"Adiabatic index: {GAMMA}")
432print(f"Smoothing length free factor: {particle.eta_factor}")
433print("-----------------------------------------------------------------------")
434
435
436# Export Constants.h file ------------------------------------------------------
437peano4_project.constants.export_const_with_type(
438 "HYDRO_DIMENSIONS", str(HYDRO_DIMENSIONS), "double"
439)
440peano4_project.constants.export_const_with_type(
441 "HYDRO_PART_NUMBER", str(HYDRO_PART_NUMBER), "double"
442)
443peano4_project.constants.export_const_with_type(
444 "GLOBAL_TIME_STEP_SIZE", str(GLOBAL_TIME_STEP_SIZE), "double"
445)
446peano4_project.constants.export_const_with_type("GAMMA", GAMMA, "double")
447
448# Export symbols for compilation (e.g. for SPH kernel) -----------------------
449peano4_project.output.makefile.add_CXX_flag(
450 "-D" + "HYDRO_DIMENSION=" + str(HYDRO_DIMENSIONS)
451)
452peano4_project.output.makefile.add_CXX_flag("-D" + GAMMA_HYDRO_SYMBOL)
453peano4_project.output.makefile.add_CXX_flag("-D" + KERNEL_SYMBOL)
454
455
458
459# If we want to start a project from scratch, we may want to remove some of the generated code
460if args.clean_temporary_files:
461 dirs = ["vertexdata/", "repositories/", "globaldata/", "observers/"]
462 for dir in dirs:
463 shutil.rmtree(dir)
464
465# It is safe (and recommended) to overwrite any existing main file, since this
466# is generated automatically by the ExaParty graph compiler.
467peano4_project.generate(
468 overwrite=peano4.api.output.Overwrite.Always, throw_away_data_after_generation=True
469)
470peano4_project.build(make_clean_first=True, number_of_parallel_builds=args.j)
471
472if args.clean_temporary_files:
473 # remove output files from previous runs
474 output_files = [
475 f
476 for f in os.listdir(".")
477 if f.endswith(".peano-patch-file") or f.endswith(".vtu") or f.endswith(".pvd")
478 ]
479 for f in output_files:
480 os.remove(f)
ExaParty project.
Definition Project.py:27
Initialisation snippet for the Noh problem in different spatial dimensions.
Definition NohProblem.py:5
This file is part of the ExaParty project.
Definition __init__.py:1
parse_args()
Parse user input.
Definition noh.py:18