5def print_bool(arg, prefix = ""):
14def print_dbl(arg, prefix = ""):
16 str = prefix +
"%4.6e\n" % (arg)
19def print_int(arg, prefix = ""):
20 str = prefix +
"%d\n" % (arg)
23def print_dbl_list(arg, prefix = ""):
27 str +=
"%4.6e" % (arg[i])
35def print_int_list(arg, prefix = ""):
39 str +=
"%d" % (arg[i])
47def does_intersect(p, r, R, particles, padding):
51 pq = np.array([p[i] - q[i]
for i
in range(3)])
52 if np.linalg.norm(pq) <= r + R + padding:
59 return 3. * K * (1. - 2. * nu)
62 return E / (2. * (1. + nu))
66 return 2. * k1 * k2 / (k1 + k2)
69def particle_locations(inp_dir, pp_tag, R1, R2, offset):
70 """Generate particle location data"""
73 sim_particles.append([0., R1, R1, 0., R1])
74 sim_particles.append([1., R1, 2. * R1 + R2 + offset, 0., R2])
76 inpf = open(inp_dir +
'particle_locations_' + str(pp_tag) +
'.csv',
'w')
77 inpf.write(
"i, x, y, z, r\n")
78 for p
in sim_particles:
79 inpf.write(
"%d, %Lf, %Lf, %Lf, %Lf\n" % (int(p[0]), p[1], p[2], p[3], p[4]))
83def particle_locations_orient(inp_dir, pp_tag, R1, R2, offset):
84 """Generate particle location data"""
87 sim_particles.append([0., R1, R1, 0., R1, 0.5*np.pi])
88 sim_particles.append([1., R1+1.*R2*np.sin(np.pi/3.), 2. * R1 + R2 + offset, 0., R2, 0.5*np.pi])
90 inpf = open(inp_dir +
'particle_locations_' + str(pp_tag) +
'.csv',
'w')
91 inpf.write(
"i, x, y, z, r, o\n")
92 for p
in sim_particles:
93 inpf.write(
"%d, %Lf, %Lf, %Lf, %Lf, %Lf\n" % (int(p[0]), p[1], p[2], p[3], p[4], p[5]))
97def rotate(p, theta, axis):
100 axis_np = np.array(axis)
106 p_dot_n = np.dot(p_np,axis_np)
109 n_cross_p = np.cross(axis_np, p_np)
111 return (1. - ct) * p_dot_n * axis_np + ct * p_np + st * n_cross_p
114def get_ref_drum_points(center, radius, width, add_center = False):
139 rotate_axis = [0., 0., 1.]
141 x1 = rotate(axis, np.pi/3., rotate_axis)
142 x2 = rotate(axis, -np.pi/3., rotate_axis)
146 points.append(center)
149 points.append([center[i] + width*0.5*axis[i]
for i
in range(3)])
151 points.append([center[i] + radius*x1[i]
for i
in range(3)])
153 points.append([center[i] + radius*x1[i] - radius*axis[i]
for i
in range(3)])
155 points.append([center[i] - width*0.5*axis[i]
for i
in range(3)])
157 v6 = [center[i] + radius*x2[i]
for i
in range(3)]
158 points.append([v6[i] - radius*axis[i]
for i
in range(3)])
165def generate_particle_gmsh_input(inp_dir, filename, center, radius, width, mesh_size, pp_tag):
167 sim_inp_dir = str(inp_dir)
170 points = get_ref_drum_points(center, radius, width,
True)
175 geof = open(sim_inp_dir + filename +
'_' + str(pp_tag) +
'.geo',
'w')
176 geof.write(
"cl__1 = 1;\n")
177 geof.write(
"Mesh.MshFileVersion = 2.2;\n")
184 sts =
"Point({}) = ".format(i+1)
186 sts +=
"{}, {}, {}, {}".format(p[0], p[1], p[2], mesh_size)
193 geof.write(
"Line(1) = {2, 3};\n")
194 geof.write(
"Line(2) = {3, 4};\n")
195 geof.write(
"Line(3) = {4, 5};\n")
196 geof.write(
"Line(4) = {5, 6};\n")
197 geof.write(
"Line(5) = {6, 7};\n")
198 geof.write(
"Line(6) = {7, 2};\n")
203 geof.write(
"Line Loop(1) = {1, 2, 3, 4, 5, 6};\n")
208 geof.write(
"Plane Surface(1) = {1};\n")
217 geof.write(
"Point{1} In Surface {1};")
224def create_input_file(inp_dir, pp_tag):
225 """Generates input file for two-particle test"""
227 sim_inp_dir = str(inp_dir)
230 center = [0., 0., 0.]
237 horizon = 3. * mesh_size
238 particle_dist = 0.001
246 dt_out_n = num_steps / num_outputs
253 E1 = get_E(K1, poisson1)
254 G1 = get_G(E1, poisson1)
260 E2 = get_E(K2, poisson2)
261 G2 = get_G(E2, poisson2)
267 R_contact_factor = 0.95
274 Kn_11 = 18. * get_eff_k(K1, K1) / (np.pi * np.power(horizon, 5))
275 Kn_22 = 18. * get_eff_k(K2, K2) / (np.pi * np.power(horizon, 5))
276 Kn_12 = 18. * get_eff_k(K1, K2) / (np.pi * np.power(horizon, 5))
280 damping_active =
True
281 friction_active =
False
285 gravity_active =
True
286 gravity = [0., -10., 0.]
289 free_fall_dist = particle_dist - horizon
290 free_fall_vel = [0., 0., 0.]
292 free_fall_vel[1] = -8.
295 neigh_search_factor = 10.
296 neigh_search_interval = 40
297 neigh_search_criteria =
"simple_all"
304 inpf = open(sim_inp_dir +
'input_' + str(pp_tag) +
'.yaml',
'w')
305 inpf.write(
"Model:\n")
306 inpf.write(
" Dimension: 2\n")
307 inpf.write(
" Discretization_Type:\n")
308 inpf.write(
" Spatial: finite_difference\n")
309 inpf.write(
" Time: central_difference\n")
310 inpf.write(
" Final_Time: %4.6e\n" % (final_time))
311 inpf.write(
" Time_Steps: %d\n" % (num_steps))
313 inpf.write(
"Policy:\n")
314 inpf.write(
" Enable_PostProcessing: true\n")
319 inpf.write(
"Zone:\n")
320 inpf.write(
" Zones: 2\n")
323 inpf.write(
" Zone_1:\n")
324 inpf.write(
" Is_Wall: false\n")
327 inpf.write(
" Zone_2:\n")
328 inpf.write(
" Is_Wall: false\n")
333 inpf.write(
"Container:\n")
334 inpf.write(
" Geometry:\n")
335 inpf.write(
" Type: rectangle\n")
336 contain_params = [0., 0., 0., 2.*R1, 2.*R1 + 2.*R2 + particle_dist, 0.]
338 contain_params[3] = 2.*R2
339 inpf.write(
" Parameters: " + print_dbl_list(contain_params))
344 inpf.write(
"Particle:\n")
345 inpf.write(
" Test_Name: two_particle\n")
346 inpf.write(
" Zone_1:\n")
347 inpf.write(
" Type: drum2d\n")
348 drum_axis = [1., 0., 0.]
349 drum1_neck_width = 0.5*R1
350 p1_geom = [R1, drum1_neck_width, center[0], center[1], center[2], drum_axis[0], drum_axis[1], drum_axis[2]]
351 inpf.write(
" Parameters: " + print_dbl_list(p1_geom))
352 inpf.write(
" Zone_2:\n")
353 inpf.write(
" Type: drum2d\n")
355 drum2_neck_width = 0.5*R2
356 p2_geom = [R2, drum2_neck_width, center[0], center[1], center[2], drum_axis[0], drum_axis[1], drum_axis[2]]
357 inpf.write(
" Parameters: " + print_dbl_list(p2_geom))
362 inpf.write(
"Particle_Generation:\n")
363 inpf.write(
" From_File: particle_locations_" + str(pp_tag) +
".csv\n")
365 inpf.write(
" File_Data_Type: loc_rad_orient\n")
370 inpf.write(
"Mesh:\n")
373 inpf.write(
" Zone_1:\n")
374 inpf.write(
" File: mesh_drum_1_" + str(pp_tag) +
".msh \n")
377 inpf.write(
" Zone_2:\n")
378 inpf.write(
" File: mesh_drum_2_" + str(pp_tag) +
".msh \n")
383 inpf.write(
"Contact:\n")
386 inpf.write(
" Zone_11:\n")
388 inpf.write(
" Contact_Radius_Factor: %4.6e\n" % (R_contact_factor))
390 if damping_active ==
False:
391 inpf.write(
" Damping_On: false\n")
392 if friction_active ==
False:
393 inpf.write(
" Friction_On: false\n")
395 inpf.write(
" Kn: %4.6e\n" % (Kn_11))
396 inpf.write(
" Epsilon: %4.6e\n" % (beta_n_eps))
397 inpf.write(
" Friction_Coeff: %4.6e\n" % (friction_coeff))
398 inpf.write(
" Kn_Factor: 1.0\n")
399 inpf.write(
" Beta_n_Factor: %4.6e\n" % (beta_n_factor))
402 inpf.write(
" Zone_12:\n")
403 inpf.write(
" Contact_Radius_Factor: %4.6e\n" % (R_contact_factor))
405 if damping_active ==
False:
406 inpf.write(
" Damping_On: false\n")
407 if friction_active ==
False:
408 inpf.write(
" Friction_On: false\n")
410 inpf.write(
" Kn: %4.6e\n" % (Kn_12))
411 inpf.write(
" Epsilon: %4.6e\n" % (beta_n_eps))
412 inpf.write(
" Friction_Coeff: %4.6e\n" % (friction_coeff))
413 inpf.write(
" Kn_Factor: 1.0\n")
414 inpf.write(
" Beta_n_Factor: %4.6e\n" % (beta_n_factor))
417 inpf.write(
" Zone_22:\n")
418 inpf.write(
" Contact_Radius_Factor: %4.6e\n" % (R_contact_factor))
420 if damping_active ==
False:
421 inpf.write(
" Damping_On: false\n")
422 if friction_active ==
False:
423 inpf.write(
" Friction_On: false\n")
425 inpf.write(
" Kn: %4.6e\n" % (Kn_22))
426 inpf.write(
" Epsilon: %4.6e\n" % (beta_n_eps))
427 inpf.write(
" Friction_Coeff: %4.6e\n" % (friction_coeff))
428 inpf.write(
" Kn_Factor: 1.0\n")
429 inpf.write(
" Beta_n_Factor: %4.6e\n" % (beta_n_factor))
432 inpf.write(
"Neighbor:\n")
433 inpf.write(
" Update_Criteria: %s\n" % (neigh_search_criteria))
434 inpf.write(
" Search_Factor: %4.e\n" % (neigh_search_factor))
435 inpf.write(
" Search_Interval: %d\n" % (neigh_search_interval))
440 inpf.write(
"Material:\n")
443 inpf.write(
" Zone_1:\n")
444 inpf.write(
" Type: PDState\n")
445 inpf.write(
" Horizon: %4.6e\n" % (horizon))
446 inpf.write(
" Density: %4.6e\n" % (rho1))
447 inpf.write(
" Compute_From_Classical: true\n")
448 inpf.write(
" K: %4.6e\n" % (K1))
449 inpf.write(
" G: %4.6e\n" % (G1))
450 inpf.write(
" Gc: %4.6e\n" % (Gc1))
451 inpf.write(
" Influence_Function:\n")
452 inpf.write(
" Type: 1\n")
455 inpf.write(
" Zone_2:\n")
456 inpf.write(
" Type: PDState\n")
457 inpf.write(
" Horizon: %4.6e\n" % (horizon))
458 inpf.write(
" Density: %4.6e\n" % (rho2))
459 inpf.write(
" Compute_From_Classical: true\n")
460 inpf.write(
" K: %4.6e\n" % (K2))
461 inpf.write(
" G: %4.6e\n" % (G2))
462 inpf.write(
" Gc: %4.6e\n" % (Gc2))
463 inpf.write(
" Influence_Function:\n")
464 inpf.write(
" Type: 1\n")
469 if gravity_active ==
True:
470 inpf.write(
"Force_BC:\n")
471 inpf.write(
" Gravity: " + print_dbl_list(gravity))
477 inpf.write(
" Constant_Velocity:\n")
478 inpf.write(
" Velocity_Vector: " + print_dbl_list(free_fall_vel))
479 inpf.write(
" Particle_List: [1]\n")
484 inpf.write(
"Displacement_BC:\n")
485 inpf.write(
" Sets: 1\n")
487 inpf.write(
" Set_1:\n")
488 inpf.write(
" Particle_List: [0]\n")
489 inpf.write(
" Direction: [1,2]\n")
490 inpf.write(
" Time_Function:\n")
491 inpf.write(
" Type: constant\n")
492 inpf.write(
" Parameters:\n")
493 inpf.write(
" - 0.0\n")
494 inpf.write(
" Spatial_Function:\n")
495 inpf.write(
" Type: constant\n")
496 inpf.write(
" Zero_Displacement: true\n")
501 inpf.write(
"Output:\n")
502 inpf.write(
" Path: ../out/\n")
503 inpf.write(
" Tags:\n")
504 inpf.write(
" - Displacement\n")
505 inpf.write(
" - Velocity\n")
506 inpf.write(
" - Force\n")
507 inpf.write(
" - Force_Density\n")
508 inpf.write(
" - Damage_Z\n")
509 inpf.write(
" - Damage\n")
510 inpf.write(
" - Nodal_Volume\n")
511 inpf.write(
" - Zone_ID\n")
512 inpf.write(
" - Particle_ID\n")
513 inpf.write(
" - Fixity\n")
514 inpf.write(
" - Force_Fixity\n")
515 inpf.write(
" - Contact_Nodes\n")
516 inpf.write(
" - No_Fail_Node\n")
517 inpf.write(
" - Boundary_Node_Flag\n")
518 inpf.write(
" - Theta\n")
520 inpf.write(
" Output_Interval: %d\n" % (dt_out_n))
521 inpf.write(
" Compress_Type: zlib\n")
522 inpf.write(
" Perform_FE_Out: false\n")
524 inpf.write(
" Perform_Out: true\n")
526 inpf.write(
" Perform_Out: false\n")
527 inpf.write(
" Test_Output_Interval: %d\n" % (dt_out_n))
529 inpf.write(
" Debug: 1\n")
530 inpf.write(
" Tag_PP: %d\n" %(int(pp_tag)))
541 particle_locations_orient(inp_dir, pp_tag, R1, R2, particle_dist - free_fall_dist)
543 p_mesh_fname = [
'mesh_drum_1',
'mesh_drum_2']
545 generate_particle_gmsh_input(inp_dir, p_mesh_fname[0], center, R1, drum1_neck_width, mesh_size, pp_tag)
546 generate_particle_gmsh_input(inp_dir, p_mesh_fname[1], center, R2, drum2_neck_width, mesh_size, pp_tag)
548 os.system(
"mkdir -p ../out")
550 for s
in p_mesh_fname:
553 print(
"gmsh {}_{}.geo -2".format(s, pp_tag))
555 os.system(
"gmsh {}_{}.geo -2".format(s, pp_tag))
564 pp_tag = int(sys.argv[1])
566create_input_file(inp_dir, pp_tag)