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",
"periodicBoundaryConditions2D"],
102 project_name=
"periodicBoundaryConditions2D",
103 executable=
"periodicBCTest2D",
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,
False]
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.} );
181 const double boxsize_x = """
182 + str(domain_size[0])
184 const double boxsize_y = """
185 + str(domain_size[1])
187 const double offset_x = """
190 const double offset_y = """
193 const double sq2_inv = std::sqrt(0.5);
196 if( particle->getX(0) < offset_x + 1./ 3. * boxsize_x ) {
198 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
200 particle->setV(0, -sq2_inv);
201 particle->setV(1, -sq2_inv);
203 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
205 particle->setV(0, -1.);
206 particle->setV(1, 0.);
210 particle->setV(0, -sq2_inv);
211 particle->setV(1, sq2_inv);
213 } else if( particle->getX(0) < offset_x + 2./ 3. * boxsize_x ) {
215 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
217 particle->setV(0,0.);
218 particle->setV(1,-1.);
220 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
222 particle->setV(0, 0.);
223 particle->setV(1, 0.);
227 particle->setV(0, 0.);
228 particle->setV(1, 1.);
233 if (particle->getX(1) < offset_y + 1./3. * boxsize_y) {
235 particle->setV(0, sq2_inv);
236 particle->setV(1, -sq2_inv);
238 } else if (particle->getX(1) < offset_y + 2./3. * boxsize_y) {
240 particle->setV(0, 1.);
241 particle->setV(1, 0.);
245 particle->setV(0,sq2_inv);
246 particle->setV(1,sq2_inv);
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.
255 double dx = boxsize_x / 1600.;
256 double dy = boxsize_y / 1600.;
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);
268 Return the rotation matrix associated with counterclockwise rotation about
269 the given axis by theta radians.
271 https://stackoverflow.com/questions/6802577/rotation-of-3d-vector
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
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],
289 scale=1.0, origin=[0.0, 0.0, 0.0], plane=0, random_shift=True, shift_scale=0.05
292 Draw a letter R consisting of 17 particles.
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:
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
306 returns: numpy array of 3D coordinates of 17 particles
331 result = np.zeros((R.shape[0], 3))
334 result[:, 0] = R[:, 0]
335 result[:, 1] = R[:, 1]
337 result[:, 1] = R[:, 0]
338 result[:, 2] = R[:, 1]
340 result[:, 0] = R[:, 0]
341 result[:, 2] = R[:, 1]
343 result[:, 0] = R[:, 0]
344 result[:, 1] = R[:, 1]
346 for i
in range(result.shape[0]):
347 result[i, :] = np.dot(rot, result[i, :])
350 shift = np.random.uniform(0, shift_scale, size=3)
354 result += np.array(origin)
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)
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)
372coords = np.concatenate((R1, R2, R3, R4, R5, R6, R7, R8), axis=0)
375project.algorithm_step_initial_conditions.add_action_set(
377 particle_set=particle_set,
378 initialisation_call=initialisation_snippet,
410 "globaldata::{}::getSpecies().getMinTimeStamp()".format(particle.name),
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)
426peano4_project = project.generate_Peano4_project(verbose=args.verbose)
427peano4_project.output.makefile.add_CXX_flag(
"-D" +
"HYDRO_DIMENSION=2")
429peano4_project.constants.export_const_with_type(
430 "GLOBAL_TIME_STEP_SIZE", str(args.timestep_size),
"double"
434if args.clean_temporary_directories:
435 dirs = [
"vertexdata/",
"repositories/",
"globaldata/",
"observers/"]
439peano4_project.generate(
440 overwrite=peano4.api.output.Overwrite.Always, throw_away_data_after_generation=
True
442peano4_project.build(make_clean_first=
True, number_of_parallel_builds=args.j)
447 for f
in os.listdir(
".")
448 if f.endswith(
".peano-patch-file")
or f.endswith(
".vtu")
or f.endswith(
".pvd")
450for 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.