Peano
Loading...
Searching...
No Matches
test_periodic_BC-2D.py
Go to the documentation of this file.
1import os
2import argparse
3import numpy as np
4
5import peano4.api
6import exaparty
7import dastgen2
8
9import shutil
10
11
14
15parser = argparse.ArgumentParser(description="Test periodic boundary conditions")
16parser.add_argument(
17 "-j", "--parallel-builds", dest="j", type=int, default=-1, help="Parallel builds"
18)
19parser.add_argument(
20 "-v",
21 "--verbose",
22 dest="verbose",
23 action="store_true",
24 default=False,
25 help="Verbose",
26)
27parser.add_argument(
28 "-c",
29 "--clean",
30 dest="clean_temporary_directories",
31 action="store_true",
32 help="Remove temporary directories before script starts",
33)
34parser.add_argument(
35 "-et",
36 "--end-time",
37 dest="end_time",
38 type=float,
39 default=1.0,
40 help="End of simulation",
41)
42parser.add_argument(
43 "-dt",
44 "--timestep-size",
45 dest="timestep_size",
46 type=float,
47 default=1e-3,
48 help="Global timestep size",
49)
50parser.add_argument(
51 "-plot",
52 "--plot-delta",
53 dest="plot_delta",
54 type=float,
55 default=0.01,
56 help="Plot delta (0 switches off)",
57)
58parser.add_argument(
59 "-cs",
60 "--cell-size",
61 dest="cell_size",
62 type=float,
63 default=0.1,
64 help="Cell size (default 0.1)",
65)
66parser.add_argument(
67 "-pd",
68 "--peano-dir",
69 dest="peanodir",
70 default="../../../../",
71 help="Peano4 directory",
72)
73parser.add_argument(
74 "-asserts",
75 "--asserts",
76 dest="asserts",
77 action="store_true",
78 default=False,
79 help="Switch on assertions",
80)
81parser.add_argument(
82 "-d",
83 "--debug",
84 dest="debug",
85 action="store_true",
86 default=False,
87 help="Switch on debug assertions",
88)
89args = parser.parse_args()
90
91
92
95
96dimensions = 2
97hydro_dimensions = 2
98
99
101 namespace=["tests", "exaparty", "periodicBoundaryConditions2D"],
102 project_name="periodicBoundaryConditions2D",
103 executable="periodicBCTest2D",
104)
105
106
108 name="GenericParticle",
109 cfl_factor=0.9,
110 initial_time_step_size=args.timestep_size,
111 particles_per_cell=0,
112 min_h=args.cell_size,
113 max_h=0.3,
114 add_partid=(not args.asserts),
115)
116particle_set = project.add_particle_species(particle)
117
118
119if args.debug:
120 build_mode = peano4.api.output.CompileMode.DEBUG
121elif args.asserts:
122 build_mode = peano4.api.output.CompileMode.ASSERTS
123else:
124 build_mode = peano4.api.output.CompileMode.RELEASE
125
126offset = [0, 0, 0]
127domain_size = [1, 1, 1]
128periodic_boundary_conditions = [True, True, False] # Periodic BC
129
130project.set_global_simulation_parameters(
131 dimensions=dimensions,
132 offset=offset,
133 domain_size=domain_size,
134 min_end_time=args.end_time,
135 max_end_time=0.0,
136 first_plot_time_stamp=0.0,
137 time_in_between_plots=args.plot_delta,
138 periodic_BC=periodic_boundary_conditions,
139 plotter_precision=8, # plotter precision
140)
141
142project.set_load_balancing(
143 "toolbox::loadbalancing::strategies::SpreadOutHierarchically",
144 "new toolbox::loadbalancing::DefaultConfiguration()",
145)
146
147project.set_Peano4_installation(args.peanodir, build_mode)
148
149
150
155
156particle_force = ""
157
158# particle.cell_kernel = particle_force
159
160
161
171search_radius = args.cell_size / 100.0
172initialisation_snippet = (
173 """
174 /* Internal search radius used by Peano.
175 * Not really used here. */
176 particle->setSearchRadius("""
177 + str(search_radius)
178 + """);
179 particle->setA( {0., 0.} );
180
181 const double boxsize_x = """
182 + str(domain_size[0])
183 + """;
184 const double boxsize_y = """
185 + str(domain_size[1])
186 + """;
187 const double offset_x = """
188 + str(offset[0])
189 + """;
190 const double offset_y = """
191 + str(offset[1])
192 + """;
193 const double sq2_inv = std::sqrt(0.5);
194
195
196 if( particle->getX(0) < offset_x + 1./ 3. * boxsize_x ) {
197
198 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
199 // Low left square
200 particle->setV(0, -sq2_inv);
201 particle->setV(1, -sq2_inv);
202
203 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
204 // Mid left square
205 particle->setV(0, -1.);
206 particle->setV(1, 0.);
207
208 } else {
209 // Top left square
210 particle->setV(0, -sq2_inv);
211 particle->setV(1, sq2_inv);
212 }
213 } else if( particle->getX(0) < offset_x + 2./ 3. * boxsize_x ) {
214
215 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
216 // Low center square
217 particle->setV(0,0.);
218 particle->setV(1,-1.);
219
220 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
221 // Mid center square
222 particle->setV(0, 0.);
223 particle->setV(1, 0.);
224
225 } else {
226 // Top center square
227 particle->setV(0, 0.);
228 particle->setV(1, 1.);
229 }
230
231 } else {
232
233 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
234 // Low right square
235 particle->setV(0, sq2_inv);
236 particle->setV(1, -sq2_inv);
237
238 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
239 // Mid right square
240 particle->setV(0, 1.);
241 particle->setV(1, 0.);
242
243 } else {
244 // Top right square
245 particle->setV(0,sq2_inv);
246 particle->setV(1,sq2_inv);
247 }
248 }
249
250 // hack to get a somewhat flexible, but always unique
251 // and reproducible particle ID: Assume we have a 1600^3
252 // uniform grid particle distribution. (1600^3 is close)
253 // to the numeric limits of integers.
254
255 double dx = boxsize_x / 1600.;
256 double dy = boxsize_y / 1600.;
257
258 int i = (int) ((particle->getX(0) - offset_x) / dx + 0.5);
259 int j = (int) ((particle->getX(1) - offset_y) / dy + 0.5);
260 particle->setPartid(i + 1600*j);
261
262"""
263)
264
265
266def rotation_matrix(axis, theta):
267 """
268 Return the rotation matrix associated with counterclockwise rotation about
269 the given axis by theta radians.
270
271 https://stackoverflow.com/questions/6802577/rotation-of-3d-vector
272 """
273 axis = np.asarray(axis)
274 axis = axis / np.sqrt(np.dot(axis, axis))
275 a = np.cos(theta / 2.0)
276 b, c, d = -axis * np.sin(theta / 2.0)
277 aa, bb, cc, dd = a * a, b * b, c * c, d * d
278 bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
279 return np.array(
280 [
281 [aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
282 [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
283 [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc],
284 ]
285 )
286
287
289 scale=1.0, origin=[0.0, 0.0, 0.0], plane=0, random_shift=True, shift_scale=0.05
290):
291 """
292 Draw a letter R consisting of 17 particles.
293
294 scale: what the total size of the letter R should be.
295 origin: where to put lower left corner of R
296 plane: along which plane to put the letter:
297 0: x-y plane.
298 1: y-z plane.
299 2: x-z plane.
300 3: rotate by 45deg around axis (1, 1, 1,)
301 perturb: Whether to randomly shift the resulting array
302 by up to `shift_scale`. Use this to avoid having
303 particles end up overlapping once the simulation
304 is running.
305
306 returns: numpy array of 3D coordinates of 17 particles
307 """
308
309 points = [
310 [0.0, 0.0],
311 [0.0, 0.2],
312 [0.0, 0.4],
313 [0.0, 0.6],
314 [0.0, 0.8],
315 [0.0, 1.0],
316 [0.1, 1.0],
317 [0.2, 0.95],
318 [0.3, 0.8],
319 [0.2, 0.625],
320 [0.05, 0.6],
321 [0.1, 0.5],
322 [0.15, 0.4],
323 [0.2, 0.3],
324 [0.25, 0.2],
325 [0.3, 0.1],
326 [0.35, 0.0],
327 ]
328
329 R = np.array(points)
330
331 result = np.zeros((R.shape[0], 3))
332
333 if plane == 0:
334 result[:, 0] = R[:, 0]
335 result[:, 1] = R[:, 1]
336 elif plane == 1:
337 result[:, 1] = R[:, 0]
338 result[:, 2] = R[:, 1]
339 elif plane == 2:
340 result[:, 0] = R[:, 0]
341 result[:, 2] = R[:, 1]
342 elif plane == 3:
343 result[:, 0] = R[:, 0]
344 result[:, 1] = R[:, 1]
345 rot = rotation_matrix([1.0, 1.0, 1], np.pi / 4.0)
346 for i in range(result.shape[0]):
347 result[i, :] = np.dot(rot, result[i, :])
348
349 if random_shift:
350 shift = np.random.uniform(0, shift_scale, size=3)
351 result += shift
352
353 result *= scale
354 result += np.array(origin)
355
356 return result
357
358
359# Generate coorinates.
360
361R1 = draw_R(scale=0.2, origin=[0.1, 0.4, 0.5], plane=0)
362R2 = draw_R(scale=0.2, origin=[0.7, 0.4, 0.5], plane=0)
363R3 = draw_R(scale=0.2, origin=[0.4, 0.1, 0.5], plane=0)
364R4 = draw_R(scale=0.2, origin=[0.4, 0.7, 0.5], plane=0)
365
366R5 = draw_R(scale=0.2, origin=[0.1, 0.1, 0.5], plane=0)
367R6 = draw_R(scale=0.2, origin=[0.1, 0.7, 0.5], plane=0)
368R7 = draw_R(scale=0.2, origin=[0.7, 0.1, 0.5], plane=0)
369R8 = draw_R(scale=0.2, origin=[0.7, 0.7, 0.5], plane=0)
370
371
372coords = np.concatenate((R1, R2, R3, R4, R5, R6, R7, R8), axis=0)
373
374
375project.algorithm_step_initial_conditions.add_action_set(
377 particle_set=particle_set,
378 initialisation_call=initialisation_snippet,
379 coordinates=coords,
380 )
381)
382
383
384
408 "particles",
409 particle_set,
410 "globaldata::{}::getSpecies().getMinTimeStamp()".format(particle.name),
411)
412particle_plotter.add_attribute_to_plot(particle.velocity, dimensions)
413particle_plotter.add_attribute_to_plot(particle.partid, 1)
414project.algorithm_step_plot.add_action_set(particle_plotter)
415
416
417
426peano4_project = project.generate_Peano4_project(verbose=args.verbose)
427peano4_project.output.makefile.add_CXX_flag("-D" + "HYDRO_DIMENSION=2")
428
429peano4_project.constants.export_const_with_type(
430 "GLOBAL_TIME_STEP_SIZE", str(args.timestep_size), "double"
431)
432
433# If we want to start a project from scratch, we may want to remove some of the generated code
434if args.clean_temporary_directories:
435 dirs = ["vertexdata/", "repositories/", "globaldata/", "observers/"]
436 for dir in dirs:
437 shutil.rmtree(dir)
438
439peano4_project.generate(
440 overwrite=peano4.api.output.Overwrite.Always, throw_away_data_after_generation=True
441)
442peano4_project.build(make_clean_first=True, number_of_parallel_builds=args.j)
443
444# remove output files from previous runs
445output_files = [
446 f
447 for f in os.listdir(".")
448 if f.endswith(".peano-patch-file") or f.endswith(".vtu") or f.endswith(".pvd")
449]
450for f in output_files:
451 os.remove(f)
ExaParty project.
Definition Project.py:27
rotation_matrix(axis, theta)
Return the rotation matrix associated with counterclockwise rotation about the given axis by theta ra...
draw_R(scale=1.0, origin=[0.0, 0.0, 0.0], plane=0, random_shift=True, shift_scale=0.05)
Draw a letter R consisting of 17 particles.