15parser = argparse.ArgumentParser(description=
"Test periodic boundary conditions")
17 "-j",
"--parallel-builds", dest=
"j", type=int, default=-1, help=
"Parallel builds"
30 dest=
"clean_temporary_directories",
32 help=
"Remove temporary directories before script starts",
40 help=
"End of simulation",
48 help=
"Global timestep size",
56 help=
"Plot delta (0 switches off)",
64 help=
"Cell size (default 0.1)",
70 default=
"../../../../",
71 help=
"Peano4 directory",
79 help=
"Switch on assertions",
87 help=
"Switch on debug assertions",
89args = parser.parse_args()
101 namespace=[
"tests",
"exaparty",
"periodicBoundaryConditions3D"],
102 project_name=
"periodicBoundaryConditions3D",
103 executable=
"periodicBCTest3D",
108 name=
"GenericParticle",
110 initial_time_step_size=args.timestep_size,
111 particles_per_cell=0,
112 min_h=args.cell_size,
114 add_partid=(
not args.asserts),
116particle_set = project.add_particle_species(particle)
120 build_mode = peano4.api.output.CompileMode.DEBUG
122 build_mode = peano4.api.output.CompileMode.ASSERTS
124 build_mode = peano4.api.output.CompileMode.RELEASE
127domain_size = [1, 1, 1]
128periodic_boundary_conditions = [
True,
True,
True]
130project.set_global_simulation_parameters(
131 dimensions=dimensions,
133 domain_size=domain_size,
134 min_end_time=args.end_time,
136 first_plot_time_stamp=0.0,
137 time_in_between_plots=args.plot_delta,
138 periodic_BC=periodic_boundary_conditions,
142project.set_load_balancing(
143 "toolbox::loadbalancing::strategies::SpreadOutHierarchically",
144 "new toolbox::loadbalancing::DefaultConfiguration()",
147project.set_Peano4_installation(args.peanodir, build_mode)
171search_radius = args.cell_size / 100.0
172initialisation_snippet = (
174 /* Internal search radius used by Peano.
175 * Not really used here. */
176 particle->setSearchRadius("""
179 particle->setA( {0., 0., 0.} );
181 const double boxsize_x = """
182 + str(domain_size[0])
184 const double boxsize_y = """
185 + str(domain_size[1])
187 const double boxsize_z = """
188 + str(domain_size[2])
190 const double offset_x = """
193 const double offset_y = """
196 const double offset_z = """
199 const double sq3 = std::sqrt(3);
200 const double sq2 = std::sqrt(2);
203 if( particle->getX(0) < offset_x + 1./ 3. * boxsize_x ) {
205 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
208 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
210 // Low left square, z ~ 0
212 particle->setV(0, -sq3);
213 particle->setV(1, -sq3);
214 particle->setV(2, -sq3);
216 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
218 // Low left square, z ~ 0.5
220 particle->setV(0, -sq2);
221 particle->setV(1, -sq2);
222 particle->setV(2, 0.);
226 // Low left square, z ~ 1.
228 particle->setV(0, -sq3);
229 particle->setV(1, -sq3);
230 particle->setV(2, sq3);
234 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
237 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
239 // Mid left square, z ~ 0
241 particle->setV(0, -sq2);
242 particle->setV(1, 0.);
243 particle->setV(2, -sq2);
245 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
247 // Mid left square, z ~ 0.5
249 particle->setV(0, 0.);
250 particle->setV(1, -1.);
251 particle->setV(2, 0.);
255 // Mid left square, z ~ 1.
257 particle->setV(0, -sq2);
258 particle->setV(1, 0.);
259 particle->setV(2, sq2);
266 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
268 // Top left square, z ~ 0
270 particle->setV(0, -sq3);
271 particle->setV(1, sq3);
272 particle->setV(2, -sq3);
274 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
276 // Top left square, z ~ 0.5
278 particle->setV(0, -sq2);
279 particle->setV(1, 0.);
280 particle->setV(2, -sq2);
284 // Top left square, z ~ 1.
286 particle->setV(0, -sq3);
287 particle->setV(1, sq3);
288 particle->setV(2, sq3);
292 } else if( particle->getX(0) < offset_x + 2./ 3. * boxsize_x ) {
294 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
295 // Low Center square, z ~ 0
297 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
299 // Low Center square, z ~ 0
301 particle->setV(0, 0.);
302 particle->setV(1, -sq2);
303 particle->setV(2, -sq2);
305 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
307 // Low Center square, z ~ 0.5
309 particle->setV(0, 0.);
310 particle->setV(1, -1.);
311 particle->setV(2, 0.);
315 // Low Center square, z ~ 1.
317 particle->setV(0, 0.);
318 particle->setV(1, -sq2);
319 particle->setV(2, sq2);
323 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
326 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
328 // Mid Center square, z ~ 0
330 particle->setV(0, 0.);
331 particle->setV(1, 0.);
332 particle->setV(2, -1.);
334 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
336 // Mid Center square, z ~ 0.5
338 particle->setV(0, 0.);
339 particle->setV(1, 0.);
340 particle->setV(2, 0.);
344 // Mid Center square, z ~ 1.
346 particle->setV(0, 0.);
347 particle->setV(1, 0.);
348 particle->setV(2, 1.);
355 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
357 // Top Center square, z ~ 0
359 particle->setV(0, 0);
360 particle->setV(1, sq2);
361 particle->setV(2, -sq2);
363 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
365 // Top Center square, z ~ 0.5
367 particle->setV(0, 0.);
368 particle->setV(1, 1.);
369 particle->setV(2, 0. );
373 // Top Center square, z ~ 1.
375 particle->setV(0, 0.);
376 particle->setV(1, sq2);
377 particle->setV(2, sq2);
384 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
387 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
389 // Low Right square, z ~ 0
391 particle->setV(0, sq3);
392 particle->setV(1, sq3);
393 particle->setV(2, -sq3);
395 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
397 // Low Right square, z ~ 0.5
399 particle->setV(0, sq2);
400 particle->setV(1, -sq2);
401 particle->setV(2, 0.);
405 // Low Right square, z ~ 1.
407 particle->setV(0, sq3);
408 particle->setV(1, -sq3);
409 particle->setV(2, sq3);
413 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
416 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
418 // Mid Right square, z ~ 0
420 particle->setV(0, sq2);
421 particle->setV(1, 0.);
422 particle->setV(2, -sq2);
424 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
426 // Mid Right square, z ~ 0.5
428 particle->setV(0, 0.);
429 particle->setV(1, 1.);
430 particle->setV(2, 0.);
434 // Mid Right square, z ~ 1.
436 particle->setV(0, sq2);
437 particle->setV(1, 0.);
438 particle->setV(2, sq2);
445 if (particle->getX(2) < offset_z + 1./3. * boxsize_z) {
447 // Top Right square, z ~ 0
449 particle->setV(0, sq3);
450 particle->setV(1, sq3);
451 particle->setV(2, -sq3);
453 } else if (particle->getX(2) < offset_z + 2./3. * boxsize_z) {
455 // Top Right square, z ~ 0.5
457 particle->setV(0, sq2);
458 particle->setV(1, sq2);
459 particle->setV(2, 0.);
463 // Top Right square, z ~ 1.
465 particle->setV(0, sq3);
466 particle->setV(1, sq3);
467 particle->setV(2, sq3);
473 // hack to get a somewhat flexible, but always unique
474 // and reproducible particle ID: Assume we have a 1600^3
475 // uniform grid particle distribution. (1600^3 is close)
476 // to the numeric limits of integers.
478 double dx = boxsize_x / 1600.;
479 double dy = boxsize_y / 1600.;
481 int i = (int) ((particle->getX(0) - offset_x) / dx + 0.5);
482 int j = (int) ((particle->getX(1) - offset_y) / dy + 0.5);
483 particle->setPartid(i + 1600*j);
491 Return the rotation matrix associated with counterclockwise rotation about
492 the given axis by theta radians.
494 https://stackoverflow.com/questions/6802577/rotation-of-3d-vector
496 axis = np.asarray(axis)
497 axis = axis / np.sqrt(np.dot(axis, axis))
498 a = np.cos(theta / 2.0)
499 b, c, d = -axis * np.sin(theta / 2.0)
500 aa, bb, cc, dd = a * a, b * b, c * c, d * d
501 bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
504 [aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
505 [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
506 [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc],
512 scale=1.0, origin=[0.0, 0.0, 0.0], plane=0, random_shift=True, shift_scale=0.05
515 Draw a letter R consisting of 17 particles.
517 scale: what the total size of the letter R should be.
518 origin: where to put lower left corner of R
519 plane: along which plane to put the letter:
523 3: rotate by 45deg around axis (1, 1, 1,)
524 perturb: Whether to randomly shift the resulting array
525 by up to `shift_scale`. Use this to avoid having
526 particles end up overlapping once the simulation
529 returns: numpy array of 3D coordinates of 17 particles
554 result = np.zeros((R.shape[0], 3))
557 result[:, 0] = R[:, 0]
558 result[:, 1] = R[:, 1]
560 result[:, 1] = R[:, 0]
561 result[:, 2] = R[:, 1]
563 result[:, 0] = R[:, 0]
564 result[:, 2] = R[:, 1]
566 result[:, 0] = R[:, 0]
567 result[:, 1] = R[:, 1]
569 for i
in range(result.shape[0]):
570 result[i, :] = np.dot(rot, result[i, :])
573 shift = np.random.uniform(0, shift_scale, size=3)
577 result += np.array(origin)
584R1 =
draw_R(scale=0.2, origin=[0.1, 0.4, 0.5], plane=0)
585R2 =
draw_R(scale=0.2, origin=[0.8, 0.4, 0.5], plane=0)
586R3 =
draw_R(scale=0.2, origin=[0.5, 0.1, 0.4], plane=1)
587R4 =
draw_R(scale=0.2, origin=[0.5, 0.8, 0.4], plane=1)
588R5 =
draw_R(scale=0.2, origin=[0.4, 0.5, 0.1], plane=2)
589R6 =
draw_R(scale=0.2, origin=[0.4, 0.5, 0.8], plane=2)
590R7 =
draw_R(scale=0.2, origin=[0.1, 0.1, 0.1], plane=3)
591R8 =
draw_R(scale=0.2, origin=[0.8, 0.1, 0.1], plane=3)
592R9 =
draw_R(scale=0.2, origin=[0.1, 0.8, 0.1], plane=3)
593R10 =
draw_R(scale=0.2, origin=[0.8, 0.8, 0.1], plane=3)
594R11 =
draw_R(scale=0.2, origin=[0.1, 0.1, 0.8], plane=3)
595R12 =
draw_R(scale=0.2, origin=[0.8, 0.1, 0.8], plane=3)
596R13 =
draw_R(scale=0.2, origin=[0.1, 0.8, 0.8], plane=3)
597R14 =
draw_R(scale=0.2, origin=[0.8, 0.8, 0.8], plane=3)
599coords = np.concatenate(
600 (R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14), axis=0
604project.algorithm_step_initial_conditions.add_action_set(
606 particle_set=particle_set,
607 initialisation_call=initialisation_snippet,
639 "globaldata::{}::getSpecies().getMinTimeStamp()".format(particle.name),
641particle_plotter.add_attribute_to_plot(particle.velocity, dimensions)
642particle_plotter.add_attribute_to_plot(particle.partid, 1)
643project.algorithm_step_plot.add_action_set(particle_plotter)
655peano4_project = project.generate_Peano4_project(verbose=args.verbose)
656peano4_project.output.makefile.add_CXX_flag(
"-D" +
"HYDRO_DIMENSION=3")
658peano4_project.constants.export_const_with_type(
659 "GLOBAL_TIME_STEP_SIZE", str(args.timestep_size),
"double"
663if args.clean_temporary_directories:
664 dirs = [
"vertexdata/",
"repositories/",
"globaldata/",
"observers/"]
668peano4_project.generate(
669 overwrite=peano4.api.output.Overwrite.Always, throw_away_data_after_generation=
True
671peano4_project.build(make_clean_first=
True, number_of_parallel_builds=args.j)
676 for f
in os.listdir(
".")
677 if f.endswith(
".peano-patch-file")
or f.endswith(
".vtu")
or f.endswith(
".pvd")
679for f
in output_files:
For constructor's time_stamp_evaluation argument.
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.