Peano
Loading...
Searching...
No Matches
makeIC-multiscale.py
Go to the documentation of this file.
1import h5py
2import argparse
3import numpy as np
4
5"""!
6Generates 1D uniform particle distribution with randomized small displacements.
7"Multiscale" variant: Create a region of particles with very high density to
8trigger multilevel interactions with sparse regions
9"""
10
11fileName = "test_sml_multiscale_1D.hdf5"
12boxSize = 1.0
13
14parser = argparse.ArgumentParser(description="SPH benchmarking script")
15parser.add_argument(
16 "-np",
17 "--particle-number",
18 dest="particle_number",
19 required=True,
20 type=int,
21 help="Particle number (1D)",
22)
23parser.add_argument(
24 "-s",
25 "--seed",
26 dest="random_seed",
27 required=True,
28 type=int,
29 help="Seed for RNG",
30)
31parser.add_argument(
32 "-p",
33 "--plot",
34 dest="plot",
35 action="store_true",
36 default=False,
37 help="Plot historgram of particle positions",
38)
39parser.add_argument(
40 "-dx",
41 "--displacement",
42 dest="max_displacement",
43 required=False,
44 default=0.2499,
45 type=float,
46 help="Maximal displacement in units of interparticle distance",
47)
48
49
50args = parser.parse_args()
51npart = args.particle_number
52seed = args.random_seed
53max_displacement = args.max_displacement
54
55
56# ---------------------------------------------------
57
58# Build the arrays
59npart_tot = 4 * npart
60coords = np.zeros((npart_tot, 3))
61v = np.zeros((npart_tot, 3))
62ids = np.linspace(1, npart_tot, npart_tot)
63m = np.ones(npart_tot)
64h = np.ones(npart_tot) * 4.0 * boxSize / npart_tot # just a first guess.
65u = np.ones(npart_tot)
66
67rng = np.random.RandomState(seed=seed)
68
69
70def get_coords(box_min, box_max, npart):
71 """
72 Generate coordinates for particles between box_min and box_max
73 """
74
75 dx = (box_max - box_min) / npart
76
77 new_coords = np.zeros((npart, 3))
78 # Get uniform coordinates.
79 for i in range(npart):
80 new_coords[i, 0] = box_min + (i + 0.5) * dx
81
82 # Now randomize them a bit.
83 # Taking a completely randomly sampled particle distribution may lead
84 # to trouble the codes aren't set up to handle, such as particles which
85 # are either too close or too far from each other. So use a somewhat
86 # regular distribution instead, by randomly displacing an initially
87 # uniform particle distribution.
88
89 # rng.random returns random numbers in [0, 1). Scale that.
90 displacement = (2.0 * rng.random((npart, 1)) - 1.0) * max_displacement * dx
91 new_coords[:, 0] += displacement[:, 0]
92
93 return new_coords
94
95
96# Now generate actual coordinates
97# First the "background"
98new_coords = get_coords(0.0, boxSize, npart)
99coords[:npart, 0] = new_coords[:, 0]
100new_coords = get_coords(1.0 / 3.0, 5.0 / 6 * boxSize, npart)
101coords[npart : 2 * npart, 0] = new_coords[:, 0]
102new_coords = get_coords(3.0 / 6.0, 5.0 / 6 * boxSize, npart)
103coords[2 * npart : 3 * npart, 0] = new_coords[:, 0]
104new_coords = get_coords(4.0 / 6.0, 5.0 / 6 * boxSize, npart)
105coords[3 * npart :, 0] = new_coords[:, 0]
106
107
108if args.plot:
109 from matplotlib import pyplot as plt
110
111 plt.figure()
112 plt.subplot(121)
113 plt.plot(coords[:, 0], m, marker=".")
114 plt.subplot(122)
115 plt.hist(coords[:, 0], bins=200)
116 plt.show()
117
118
119# File
120file = h5py.File(fileName, "w")
121
122# Header
123grp = file.create_group("/Header")
124grp.attrs["BoxSize"] = boxSize
125grp.attrs["NumPart_Total"] = [npart_tot, 0, 0, 0, 0, 0]
126grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0]
127grp.attrs["NumPart_ThisFile"] = [npart_tot, 0, 0, 0, 0, 0]
128# This is an addition for this test to be able to estimate the search radius.
129grp.attrs["NumPart_base"] = [npart]
130grp.attrs["Time"] = 0.0
131grp.attrs["NumFilesPerSnapshot"] = 1
132grp.attrs["MassTable"] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
133grp.attrs["Flag_Entropy_ICs"] = 0
134grp.attrs["Dimension"] = 1
135
136# Non-swift additions
137grp.attrs["RandomSeed"] = seed
138grp.attrs["MaxDisplacement"] = max_displacement
139grp.attrs["NumpyVersion"] = np.__version__
140
141# Units
142grp = file.create_group("/Units")
143grp.attrs["Unit length in cgs (U_L)"] = 1.0
144grp.attrs["Unit mass in cgs (U_M)"] = 1.0
145grp.attrs["Unit time in cgs (U_t)"] = 1.0
146grp.attrs["Unit current in cgs (U_I)"] = 1.0
147grp.attrs["Unit temperature in cgs (U_T)"] = 1.0
148
149# Particle group
150grp = file.create_group("/PartType0")
151grp.create_dataset("Coordinates", data=coords, dtype="d")
152grp.create_dataset("Velocities", data=v, dtype="f")
153grp.create_dataset("Masses", data=m, dtype="f")
154grp.create_dataset("SmoothingLength", data=h, dtype="f")
155grp.create_dataset("InternalEnergy", data=u, dtype="f")
156grp.create_dataset("ParticleIDs", data=ids, dtype="L")
157
158
159file.close()
get_coords(box_min, box_max, npart)
Generate coordinates for particles between box_min and box_max.