7def print_bool(arg, prefix = ""):
 
   16def print_dbl(arg, prefix = ""):
 
   18  str = prefix + 
"%4.6e\n" % (arg)
 
   21def print_int(arg, prefix = ""):
 
   22  str = prefix + 
"%d\n" % (arg)
 
   25def print_dbl_list(arg, prefix = ""):
 
   29    str += 
"%4.6e" % (arg[i])
 
   37def print_int_list(arg, prefix = ""):
 
   41    str += 
"%d" % (arg[i])
 
   49def serialize_matrix_list(p):
 
   58def write_point_geo(geof, p_id, x, h):
 
   59    geof.write(
"Point(%d) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (p_id, x[0], x[1], x[2], h))
 
   62def write_line_geo(geof, l_id, p1_id, p2_id):
 
   63    geof.write(
"Line(%d) = {%d, %d};\n" % (l_id, p1_id, p2_id))
 
   66def write_cir_line_geo(geof, l_id, p1_id, p2_id, p3_id):
 
   67    geof.write(
"Circle(%d) = {%d, %d, %d};\n" % (l_id, p1_id, p2_id, p3_id))
 
   70def write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, zone_string, Kn):
 
   71  inpf.write(
"  Zone_%s:\n" % (zone_string))
 
   72  inpf.write(
"    Contact_Radius_Factor: %4.6e\n" % (R_contact_factor))
 
   74  if damping_active == 
False:
 
   75    inpf.write(
"    Damping_On: false\n")
 
   76  if friction_active == 
False:
 
   77    inpf.write(
"    Friction_On: false\n")
 
   79  inpf.write(
"    Kn: %4.6e\n" % (Kn))
 
   80  inpf.write(
"    Epsilon: %4.6e\n" % (beta_n_eps))
 
   81  inpf.write(
"    Friction_Coeff: %4.6e\n" % (friction_coeff))
 
   82  inpf.write(
"    Kn_Factor: %4.6e\n" % (Kn_factor))
 
   83  inpf.write(
"    Beta_n_Factor: %4.6e\n" % (beta_n_factor))
 
   85def write_material_zone_part(inpf, zone_string, horizon, rho, K, G, Gc):
 
   86  inpf.write(
"  Zone_%s:\n" % (zone_string))
 
   87  inpf.write(
"    Type: PDState\n")
 
   88  inpf.write(
"    Horizon: %4.6e\n" % (horizon))
 
   89  inpf.write(
"    Density: %4.6e\n" % (rho))
 
   90  inpf.write(
"    Compute_From_Classical: true\n")
 
   91  inpf.write(
"    K: %4.6e\n" % (K))
 
   92  inpf.write(
"    G: %4.6e\n" % (G))
 
   93  inpf.write(
"    Gc: %4.6e\n" % (Gc))
 
   94  inpf.write(
"    Influence_Function:\n")
 
   95  inpf.write(
"      Type: 1\n")
 
   97def copy_contact_zone(inpf, zone_numbers, zone_copy_from):
 
   98  for s 
in zone_numbers:
 
   99    inpf.write(
"  Zone_%d:\n" % (s))
 
  100    inpf.write(
"    Copy_Contact_Data: " + print_int_list(zone_copy_from))
 
  103  return 3. * K * (1. - 2. * nu)
 
  106  return E / (2. * (1. + nu))
 
  109def get_eff_k(k1, k2):
 
  110  return 2. * k1 * k2 / (k1 + k2)
 
  117def get_center(p1, p2):
 
  118  return [0.5*(p1[i] + p2[i]) 
for i 
in range(3)]
 
  120def rotate(p, theta, axis):
 
  123  axis_np = np.array(axis)
 
  129  p_dot_n = np.dot(p_np,axis_np)
 
  132  n_cross_p = np.cross(axis_np, p_np)
 
  134  return (1. - ct) * p_dot_n * axis_np + ct * p_np + st * n_cross_p
 
  136def get_ref_rect_points(center, L, W, add_center = False):
 
  140    points.append(center)
 
  142  points.append([center[0] - 0.5*L, center[1] - 0.5*W, center[2]])
 
  143  points.append([center[0] + 0.5*L, center[1] - 0.5*W, center[2]])
 
  144  points.append([center[0] + 0.5*L, center[1] + 0.5*W, center[2]])
 
  145  points.append([center[0] - 0.5*L, center[1] + 0.5*W, center[2]])
 
  149def get_ref_triangle_points(center, radius, add_center = False):
 
  168  cp = np.cos(np.pi/6.)
 
  169  sp = np.sin(np.pi/6.)
 
  173    points.append([sim_Cx, sim_Cy, sim_Cz])
 
  174  points.append([sim_Cx, sim_Cy + sim_radius, sim_Cz])
 
  175  points.append([sim_Cx - sim_radius*cp, sim_Cy - sim_radius*sp, sim_Cz])
 
  176  points.append([sim_Cx + sim_radius*cp, sim_Cy - sim_radius*sp, sim_Cz])
 
  180def get_ref_hex_points(center, radius, add_center = False):
 
  205  rotate_axis = [0., 0., 1.]
 
  209    points.append(center)
 
  212    xi = rotate(axis, i*np.pi/3., rotate_axis)
 
  213    points.append([center[i] + radius * xi[i] 
for i 
in range(3)])
 
  217def get_ref_drum_points(center, radius, width, add_center = False):
 
  242  rotate_axis = [0., 0., 1.]
 
  244  x1 = rotate(axis, np.pi/3., rotate_axis)
 
  245  x2 = rotate(axis, -np.pi/3., rotate_axis)
 
  249    points.append(center)
 
  252  points.append([center[i] + width*0.5*axis[i] 
for i 
in range(3)])
 
  254  points.append([center[i] + radius*x1[i] 
for i 
in range(3)])
 
  256  points.append([center[i] + radius*x1[i] - radius*axis[i] 
for i 
in range(3)])
 
  258  points.append([center[i] - width*0.5*axis[i] 
for i 
in range(3)])
 
  260  v6 = [center[i] + radius*x2[i] 
for i 
in range(3)]
 
  261  points.append([v6[i] - radius*axis[i] 
for i 
in range(3)])
 
  267def does_rect_intersect_rect(r1, r2, padding):
 
  270  r1_padding = [r1[0] - padding, r1[1] - padding, r1[2], r1[3] + padding, r1[4] + padding, r1[5]]
 
  272  return r1_padding[0] < r2[3] 
and r1_padding[3] > r2[0] 
and r1_padding[1] < r2[4] 
and r1_padding[4] > r2[1]
 
  274def does_rect_intersect_rect_use_pair_coord(r1, r2, padding):
 
  277  p1_r1_padding = [r1[0][0] - padding, r1[0][1] - padding, r1[0][2]]
 
  278  p2_r1_padding = [r1[1][0] + padding, r1[1][1] + padding, r1[0][2]]
 
  283  return p1_r1_padding[0] < p2_r2[0] 
and p2_r1_padding[0] > p1_r2[0] 
and p1_r1_padding[1] < p2_r2[1] 
and p2_r1_padding[1] > p1_r2[1]
 
  286def does_particle_intersect_rect(p, r2, padding):
 
  289  pc = [p[1], p[2], p[3]]
 
  290  p_rect = [pc[0] - pr, pc[1] - pr, pc[2], pc[1] + pr, pc[2] + pr, pc[2]]
 
  292  return does_rect_intersect_rect(p_rect, r2, padding)
 
  294def does_particle_intersect(p, particles, rect, padding):
 
  298  p_center = [p[i+1] 
for i 
in range(3)]
 
  300  p_rect = [p_center[0] - p_r, p_center[1] - p_r, p_center[2], p_center[0] + p_r, p_center[1] + p_r, p_center[2]]
 
  302  if p_rect[0] < rect[0] + padding 
or p_rect[1] < rect[1] + padding 
or p_rect[3] > rect[3] - padding 
or p_rect[4] > rect[4] - padding:
 
  306    pq = np.array([p[i+1] - q[i+1] 
for i 
in range(3)])
 
  307    if np.linalg.norm(pq) <= p[-1] + q[-1] + padding:
 
  313def particle_locations(inp_dir, pp_tag, center, padding, max_y, mesh_size, R1, R2, id_choices1, id_choices2, N1, N2, rect, z_coord, add_orient = True):
 
  316  sim_inp_dir = str(inp_dir)
 
  318  """Generate particle location data""" 
  325  rect_L = rect[3] - rect[0]
 
  326  rect_W = rect[4] - rect[1]
 
  328  if method_to_use == 0:
 
  332    while pcount < N2 
and count < 100*N2:
 
  334        print(
'large particle iter = ', count)
 
  337      r = R2 + np.random.uniform(-0.1 * R2, 0.1 * R2)
 
  338      x = center[0] + np.random.uniform(-0.5*rect_L + R2 + padding, 0.5*rect_L - R2- padding)
 
  339      y = np.random.uniform(-0.5*rect_W + R2+padding, max_y - R2-padding)
 
  340      p_zone = id_choices2[select_count % len(id_choices2)]
 
  341      p = [p_zone, x, y, center[2], r]
 
  344      pintersect = does_particle_intersect(p, particles, rect_L, rect_W, center, padding)
 
  346      if pintersect == 
False:
 
  356    while pcount < N1 
and count < 100*N1:
 
  358        print(
'small particle iter = ', count)
 
  361      r = R1 + np.random.uniform(-0.1 * R1, 0.1 * R1)
 
  362      x = center[0] + np.random.uniform(-0.5*rect_L + R1 + padding, 0.5*rect_L - R1- padding)
 
  363      y = np.random.uniform(-0.5*rect_W + R1 + padding, max_y - R1 - padding)
 
  367      p_zone = id_choices1[select_count % len(id_choices1)]
 
  368      p = [p_zone, x,y,center[2], r]
 
  371      pintersect = does_particle_intersect(p, particles, rect_L, rect_W, center, padding)
 
  373      if pintersect == 
False:
 
  380  elif method_to_use == 1:
 
  387    rows = int((max_y - rect[1]) / (2. * check_r))
 
  388    cols = int(rect_L / (2. * check_r))
 
  390    print(rows, cols, N1, N2)
 
  398    x_old_right = rect[3]
 
  408    cy_accptd.append(y_old)
 
  414    for i 
in range(rows):
 
  415      print(
'row = {}'.format(i), flush=
True)
 
  418        y_old = get_max(cy_accptd) + get_max(row_rads)
 
  429      if y_old + padding + get_max(row_rads) < max_y:
 
  433          if num_p_cols > cols - 1 
or j > 100*(N1 + N2):
 
  436          if counter1 >= N1 
and counter2 >= N2:
 
  442            x_old_right = rect[3] 
 
  445          p_type = np.random.choice([0,1], size=1)[0]
 
  456            p_zone = np.random.choice(id_choices1, size=1)[0]
 
  458            p_zone = np.random.choice(id_choices2, size=1)[0]
 
  461          r = r0 + np.random.uniform(-0.1 * r0, 0.1 * r0)
 
  466            rph = np.random.uniform(-0.1 * r0, 0.05 * r0)
 
  467            rpv = np.random.uniform(-0.05 * r0, 0.05 * r0)
 
  468            cx0 = x_old_right - padding - r
 
  470            cy = y_old + padding + r + rpv
 
  473            rph = np.random.uniform(-0.05 * r0, 0.1 * r0)
 
  474            rpv = np.random.uniform(-0.05 * r0, 0.05 * r0)
 
  475            cx0 = x_old + padding + r 
 
  477            cy = y_old + padding + r + rpv          
 
  480          p = [p_zone, cx, cy, cz, r]
 
  485          pintersect = does_particle_intersect(p, particles, rect, padding)
 
  487          if pintersect == 
False:
 
  488            print(i, p, flush=
True)
 
  490            row_rads.append(p[4])
 
  494              x_old_right = cx - p[4]
 
  509  inpf = open(inp_dir + 
'particle_locations_' + str(pp_tag) + 
'.csv',
'w')
 
  511    inpf.write(
"i, x, y, z, r, o\n")
 
  514      inpf.write(
"%d, %Lf, %Lf, %Lf, %Lf, %Lf\n" % (int(p[0]), p[1], p[2], p[3], p[4], np.random.uniform(0., 2.*np.pi)))
 
  517    inpf.write(
"i, x, y, z, r\n")
 
  519      inpf.write(
"%d, %Lf, %Lf, %Lf, %Lf\n" % (int(p[0]), p[1], p[2], p[3], p[4]))
 
  531      points.append([p[1], p[2], p[3]])
 
  533      zones.append(int(p[0]))
 
  535    points = np.array(points)
 
  536    rads = np.array(rads)
 
  537    zones = np.array(zones)
 
  538    mesh = pv.PolyData(points)
 
  539    mesh[
"radius"] = rads
 
  541    pv.save_meshio(sim_inp_dir + 
'particle_locations_' + str(pp_tag) + 
'.vtu', mesh)
 
  543  print(
'number of particles created = {}'.format(len(particles)), flush=
True)
 
  545  return len(particles), particles
 
  547def particle_locations_old(inp_dir, pp_tag, center, padding, max_y, mesh_size, R1, R2, id_choices1, id_choices2, N1, N2, rect, z_coord, add_orient = True):
 
  549  """Generate particle location data""" 
  552  def does_intersect_old(p, r, R, particles, padding):
 
  556      pq = np.array([p[i] - q[i] 
for i 
in range(3)])
 
  557      if np.linalg.norm(pq) <= r + R + padding:
 
  563  def does_intersect_rect_old(p, r, particles, padding, rect):
 
  566    pr = [p[0] - r, p[1] - r, p[2], p[0] + r, p[1] + r, p[2]]
 
  568    if pr[0] < rect[0] + padding 
or pr[1] < rect[1] + padding 
or pr[3] > rect[3] - padding 
or pr[4] > rect[4] - padding:
 
  598  rows = int((rect[3] - rect[0])/ check_r)
 
  599  cols = int((rect[4] - rect[1])/ check_r)
 
  605  x_old_right = rect[3]
 
  618  for i 
in range(rows):
 
  621      y_old = cy + get_max(row_rads)
 
  630    while num_p_cols < cols - 1 
and j < 500:
 
  635        x_old_right = rect[3] 
 
  645        p_zone = np.random.choice(id_choices1, size=1)[0]
 
  647        p_zone = np.random.choice(id_choices2, size=1)[0]
 
  650      r = r0 + np.random.uniform(-0.1 * r0, 0.1 * r0)
 
  655      rph = np.random.uniform(-0.1 * r0, 0.1 * r0)
 
  657      cx0 = x_old + pad + r 
 
  661        cx0 = x_old_right - pad - r
 
  667      inters = does_intersect_rect_old([cx, cy, cz], r, particles, pad, rect)
 
  668      inters_parts = does_intersect_old
 
  671        particles.append([float(p_zone), cx, cy, cz, r])
 
  686  inpf = open(inp_dir + 
'particle_locations_' + str(pp_tag) + 
'.csv',
'w')
 
  688    inpf.write(
"i, x, y, z, r, o\n")
 
  691      inpf.write(
"%d, %Lf, %Lf, %Lf, %Lf, %Lf\n" % (int(p[0]), p[1], p[2], p[3], p[4], np.random.uniform(0., 2.*np.pi)))
 
  694    inpf.write(
"i, x, y, z, r\n")
 
  696      inpf.write(
"%d, %Lf, %Lf, %Lf, %Lf\n" % (int(p[0]), p[1], p[2], p[3], p[4]))
 
  708      points.append([p[1], p[2], p[3]])
 
  710      zones.append(int(p[0]))
 
  712    points = np.array(points)
 
  713    rads = np.array(rads)
 
  714    zones = np.array(zones)
 
  715    mesh = pv.PolyData(points)
 
  716    mesh[
"radius"] = rads
 
  718    pv.save_meshio(sim_inp_dir + 
'particle_locations_' + str(pp_tag) + 
'.vtu', mesh)
 
  720  print(
'number of particles created = {}'.format(len(particles)))
 
  722  return len(particles), particles
 
  725def generate_cir_particle_gmsh_input(inp_dir, filename, center, radius, mesh_size, pp_tag):
 
  727  sim_inp_dir = str(inp_dir)
 
  741  geof = open(sim_inp_dir + filename + 
'_' + str(pp_tag) + 
'.geo',
'w')
 
  742  geof.write(
"cl__1 = 1;\n")
 
  743  geof.write(
"Mesh.MshFileVersion = 2.2;\n")
 
  748  geof.write(
"Point(1) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Cx, sim_Cy, sim_Cz, sim_h));
 
  749  geof.write(
"Point(2) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Cx + sim_radius, sim_Cy, sim_Cz, sim_h))
 
  750  geof.write(
"Point(3) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Cx - sim_radius, sim_Cy, sim_Cz, sim_h))
 
  751  geof.write(
"Point(4) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Cx, sim_Cy + sim_radius, sim_Cz, sim_h))
 
  752  geof.write(
"Point(5) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Cx, sim_Cy - sim_radius, sim_Cz, sim_h))
 
  757  geof.write(
"Circle(1) = {2, 1, 4};\n")
 
  758  geof.write(
"Circle(2) = {4, 1, 3};\n")
 
  759  geof.write(
"Circle(3) = {3, 1, 5};\n")
 
  760  geof.write(
"Circle(4) = {5, 1, 2};\n")
 
  765  geof.write(
"Line Loop(1) = {2, 3, 4, 1};\n")
 
  770  geof.write(
"Plane Surface(1) = {1};\n")
 
  779  geof.write(
"Point{1} In Surface {1};")
 
  785def generate_hex_particle_gmsh_input(inp_dir, filename, center, radius, mesh_size, pp_tag):
 
  787  sim_inp_dir = str(inp_dir)
 
  789  points = get_ref_hex_points(center, radius, 
True)
 
  794  geof = open(sim_inp_dir + filename + 
'_' + str(pp_tag) + 
'.geo',
'w')
 
  795  geof.write(
"cl__1 = 1;\n")
 
  796  geof.write(
"Mesh.MshFileVersion = 2.2;\n")
 
  803    sts = 
"Point({}) = ".format(i+1)
 
  805    sts += 
"{}, {}, {}, {}".format(p[0], p[1], p[2], mesh_size)
 
  812  geof.write(
"Line(1) = {2, 3};\n")
 
  813  geof.write(
"Line(2) = {3, 4};\n")
 
  814  geof.write(
"Line(3) = {4, 5};\n")
 
  815  geof.write(
"Line(4) = {5, 6};\n")
 
  816  geof.write(
"Line(5) = {6, 7};\n")
 
  817  geof.write(
"Line(6) = {7, 2};\n")
 
  822  geof.write(
"Line Loop(1) = {1, 2, 3, 4, 5, 6};\n")
 
  827  geof.write(
"Plane Surface(1) = {1};\n")
 
  836  geof.write(
"Point{1} In Surface {1};")
 
  842def generate_tri_particle_gmsh_input(inp_dir, filename, center, radius, mesh_size, pp_tag):
 
  844  sim_inp_dir = str(inp_dir)
 
  847  points = get_ref_triangle_points(center, radius, 
True)
 
  852  geof = open(sim_inp_dir + filename + 
'_' + str(pp_tag) + 
'.geo',
'w')
 
  853  geof.write(
"cl__1 = 1;\n")
 
  854  geof.write(
"Mesh.MshFileVersion = 2.2;\n")
 
  861    sts = 
"Point({}) = ".format(i+1)
 
  863    sts += 
"{}, {}, {}, {}".format(p[0], p[1], p[2], mesh_size)
 
  870  geof.write(
"Line(1) = {2, 3};\n")
 
  871  geof.write(
"Line(2) = {3, 4};\n")
 
  872  geof.write(
"Line(3) = {4, 2};\n")
 
  877  geof.write(
"Line Loop(1) = {1, 2, 3};\n")
 
  882  geof.write(
"Plane Surface(1) = {1};\n")
 
  891  geof.write(
"Point{1} In Surface {1};")
 
  897def generate_drum2d_particle_gmsh_input(inp_dir, filename, center, radius, width, mesh_size, pp_tag):
 
  899  sim_inp_dir = str(inp_dir)
 
  902  points = get_ref_drum_points(center, radius, width, 
True)
 
  907  geof = open(sim_inp_dir + filename + 
'_' + str(pp_tag) + 
'.geo',
'w')
 
  908  geof.write(
"cl__1 = 1;\n")
 
  909  geof.write(
"Mesh.MshFileVersion = 2.2;\n")
 
  916    sts = 
"Point({}) = ".format(i+1)
 
  918    sts += 
"{}, {}, {}, {}".format(p[0], p[1], p[2], mesh_size)
 
  925  geof.write(
"Line(1) = {2, 3};\n")
 
  926  geof.write(
"Line(2) = {3, 4};\n")
 
  927  geof.write(
"Line(3) = {4, 5};\n")
 
  928  geof.write(
"Line(4) = {5, 6};\n")
 
  929  geof.write(
"Line(5) = {6, 7};\n")
 
  930  geof.write(
"Line(6) = {7, 2};\n")
 
  935  geof.write(
"Line Loop(1) = {1, 2, 3, 4, 5, 6};\n")
 
  940  geof.write(
"Plane Surface(1) = {1};\n")
 
  949  geof.write(
"Point{1} In Surface {1};")
 
  954def generate_rect_container_gmsh_input(inp_dir, filename, pi1, pi2, dx, dy, mesh_size, pp_tag):
 
  956  sim_inp_dir = str(inp_dir)
 
  958  innr_pts = get_ref_rect_points(get_center(pi1, pi2), pi2[0] - pi1[0], pi2[1] - pi1[1])
 
  960  outr_pts = get_ref_rect_points(get_center(pi1, pi2), pi2[0] - pi1[0] + 2*dx, pi2[1] - pi1[1] + 2*dy)
 
  968  geof = open(sim_inp_dir + filename + 
'_' + str(pp_tag) + 
'.geo',
'w')
 
  969  geof.write(
"cl__1 = 1;\n")
 
  970  geof.write(
"Mesh.MshFileVersion = 2.2;\n")
 
  975    p_id = write_point_geo(geof, p_id, outr_pts[i], h)
 
  978    p_id = write_point_geo(geof, p_id, innr_pts[i], h)
 
  982  l_id = write_line_geo(geof, l_id, 1, 2)
 
  983  l_id = write_line_geo(geof, l_id, 2, 3)
 
  984  l_id = write_line_geo(geof, l_id, 3, 4)
 
  985  l_id = write_line_geo(geof, l_id, 4, 1)
 
  987  l_id = write_line_geo(geof, l_id, 5, 6)
 
  988  l_id = write_line_geo(geof, l_id, 6, 7)
 
  989  l_id = write_line_geo(geof, l_id, 7, 8)
 
  990  l_id = write_line_geo(geof, l_id, 8, 5)
 
  993  geof.write(
"Line Loop(9) = {1, 2, 3, 4};\n")
 
  994  geof.write(
"Line Loop(10) = {5, 6, 7, 8};\n")
 
  997  geof.write(
"Plane Surface(11) = {9, 10};\n")
 
 1002def generate_rigid_rect_container_moving_wall_setup_gmsh_input(inp_dir, filename, outer_rect, inner_rect, mesh_size, pp_tag):
 
 1004  sim_inp_dir = str(inp_dir)
 
 1007  sim_Lx_out1 = outer_rect[0]
 
 1008  sim_Ly_out1 = outer_rect[1]
 
 1009  sim_Lz_out1 = outer_rect[2]
 
 1010  sim_Lx_out2 = outer_rect[3]
 
 1011  sim_Ly_out2 = outer_rect[4]
 
 1012  sim_Lz_out2 = outer_rect[5]
 
 1015  sim_Lx_in1 = inner_rect[0]
 
 1016  sim_Ly_in1 = inner_rect[1]
 
 1017  sim_Lz_in1 = inner_rect[2]
 
 1018  sim_Lx_in2 = inner_rect[3]
 
 1019  sim_Ly_in2 = inner_rect[4]
 
 1020  sim_Lz_in2 = inner_rect[5]
 
 1028  geof = open(sim_inp_dir + filename + 
'_' + str(pp_tag) + 
'.geo',
'w')
 
 1029  geof.write(
"cl__1 = 1;\n")
 
 1030  geof.write(
"Mesh.MshFileVersion = 2.2;\n")
 
 1054  geof.write(
"Point(1) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out1, sim_Ly_out1, sim_Lz_out1, sim_h))
 
 1055  geof.write(
"Point(2) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out2, sim_Ly_out1, sim_Lz_out1, sim_h))
 
 1056  geof.write(
"Point(3) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out2, sim_Ly_out2, sim_Lz_out1, sim_h))
 
 1057  geof.write(
"Point(4) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out1, sim_Ly_out2, sim_Lz_out1, sim_h))
 
 1059  geof.write(
"Point(5) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_in1, sim_Ly_in1, sim_Lz_in1, sim_h))
 
 1060  geof.write(
"Point(6) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_in2, sim_Ly_in1, sim_Lz_in1, sim_h))
 
 1061  geof.write(
"Point(7) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_in2, sim_Ly_out2, sim_Lz_in1, sim_h))
 
 1062  geof.write(
"Point(8) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_in1, sim_Ly_out2, sim_Lz_in1, sim_h))
 
 1067  geof.write(
"Line(1) = {1, 2};\n")
 
 1068  geof.write(
"Line(2) = {2, 3};\n")
 
 1069  geof.write(
"Line(3) = {3, 7};\n")
 
 1070  geof.write(
"Line(4) = {7, 6};\n")
 
 1071  geof.write(
"Line(5) = {6, 5};\n")
 
 1072  geof.write(
"Line(6) = {5, 8};\n")
 
 1073  geof.write(
"Line(7) = {8, 4};\n")
 
 1074  geof.write(
"Line(8) = {4, 1};\n")
 
 1079  geof.write(
"Line Loop(1) = {1, 2, 3, 4, 5, 6, 7, 8};\n")
 
 1084  geof.write(
"Plane Surface(1) = {1};\n")
 
 1089  tag = 
'"' + 
"a" + 
'"' 
 1090  geof.write(
"Physical Surface(%s) = {1};\n" % (tag))
 
 1096def generate_moving_rect_wall_gmsh_input(inp_dir, filename, rectangle, mesh_size, pp_tag):
 
 1098  sim_inp_dir = str(inp_dir)
 
 1101  sim_Lx_out1 = rectangle[0]
 
 1102  sim_Ly_out1 = rectangle[1]
 
 1103  sim_Lz_out1 = rectangle[2]
 
 1104  sim_Lx_out2 = rectangle[3]
 
 1105  sim_Ly_out2 = rectangle[4]
 
 1106  sim_Lz_out2 = rectangle[5]
 
 1114  geof = open(sim_inp_dir + filename + 
'_' + str(pp_tag) + 
'.geo',
'w')
 
 1115  geof.write(
"cl__1 = 1;\n")
 
 1116  geof.write(
"Mesh.MshFileVersion = 2.2;\n")
 
 1121  geof.write(
"Point(1) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out1, sim_Ly_out1, sim_Lz_out1, sim_h));
 
 1122  geof.write(
"Point(2) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out2, sim_Ly_out1, sim_Lz_out1, sim_h))
 
 1123  geof.write(
"Point(3) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out2, sim_Ly_out2, sim_Lz_out1, sim_h))
 
 1124  geof.write(
"Point(4) = {%4.6e, %4.6e, %4.6e, %4.6e};\n" % (sim_Lx_out1, sim_Ly_out2, sim_Lz_out1, sim_h))
 
 1129  geof.write(
"Line(1) = {1, 2};\n")
 
 1130  geof.write(
"Line(2) = {2, 3};\n")
 
 1131  geof.write(
"Line(3) = {3, 4};\n")
 
 1132  geof.write(
"Line(4) = {4, 1};\n")
 
 1137  geof.write(
"Line Loop(1) = {1, 2, 3, 4};\n")
 
 1142  geof.write(
"Plane Surface(1) = {1};\n")
 
 1147  tag = 
'"' + 
"a" + 
'"' 
 1148  geof.write(
"Physical Surface(%s) = {1};\n" % (tag))
 
 1153def create_input_file(inp_dir, pp_tag):
 
 1154  """Generates input file for two-particle test""" 
 1156  sim_inp_dir = str(inp_dir)
 
 1170  center = [0., 0., 0.]
 
 1174  mesh_size = R_small / 5.
 
 1175  horizon = 2 * mesh_size
 
 1178  Lin, Win = 0.05, 0.04
 
 1179  L, W = Lin + 1.5*horizon, Win + 1.5*horizon
 
 1181  in_rect = [center[0] - 0.5*Lin, center[1] - 0.5*Win, center[2], center[0] + 0.5*Lin, center[1] + 0.5*Win, center[2]]
 
 1182  out_rect = [center[0] - 0.5*L, center[1] - 0.5*W, center[2], center[0] + 0.5*L, center[1] + 0.5*W, center[2]]
 
 1185  moving_wall_y = 0.5*Win - 1.5*horizon
 
 1186  moving_rect = [center[0] - 0.5*Lin, center[1] + moving_wall_y, center[2], center[0] + 0.5*Lin, center[1] + moving_wall_y + 1.5*horizon, center[2]]
 
 1190  remove_rect_from_out_rect = [in_rect[0], in_rect[1], in_rect[2], in_rect[3], out_rect[4], in_rect[5]]
 
 1191  if moving_rect[4] > out_rect[4]:
 
 1192    remove_rect_from_out_rect[4] = out_rect[4]
 
 1194  fixed_container_params = []
 
 1196    fixed_container_params.append(a)
 
 1197  for a 
in remove_rect_from_out_rect:
 
 1198    fixed_container_params.append(a)
 
 1201  contain_rect = out_rect
 
 1204  small_circle = [R_small, center[0], center[1], center[2]]
 
 1206  small_triangle = small_circle
 
 1208  w_small_drum2d = R_small * 0.2
 
 1209  small_drum2d = [R_small, w_small_drum2d, center[0], center[1], center[2]]
 
 1211  small_hex = small_circle
 
 1214  large_circle = [R_large, center[0], center[1], center[2]]
 
 1216  large_triangle = large_circle
 
 1218  w_large_drum2d = R_large* 0.2
 
 1219  large_drum2d = [R_large, w_large_drum2d, center[0], center[1], center[2]]
 
 1221  large_hex = large_circle
 
 1230  dt_out_n = num_steps / num_outputs
 
 1231  test_dt_out_n = dt_out_n / 10
 
 1238  E_wall = get_E(K_wall, poisson_wall)
 
 1239  G_wall = get_G(E_wall, poisson_wall)
 
 1243  poisson_small = poisson_wall
 
 1245  E_small = get_E(K_small, poisson_small)
 
 1246  G_small = get_G(E_small, poisson_small)
 
 1249  rho_large = rho_small
 
 1250  poisson_large = poisson_small
 
 1259  R_contact_factor = 0.95
 
 1266  Kn_small_small = 18. * get_eff_k(K_small, K_small) / (np.pi * np.power(horizon, 5))
 
 1267  Kn_large_large = 18. * get_eff_k(K_large, K_large) / (np.pi * np.power(horizon, 5))
 
 1268  Kn_wall_wall = 18. * get_eff_k(K_wall, K_wall) / (np.pi * np.power(horizon, 5))
 
 1269  Kn_small_large = 18. * get_eff_k(K_small, K_large) / (np.pi * np.power(horizon, 5))
 
 1270  Kn_small_wall = 18. * get_eff_k(K_small, K_wall) / (np.pi * np.power(horizon, 5))
 
 1271  Kn_large_wall = 18. * get_eff_k(K_large, K_wall) / (np.pi * np.power(horizon, 5))
 
 1277  friction_coeff = 0.5
 
 1278  damping_active = 
False 
 1279  damping_active_floor = 
True 
 1280  friction_active = 
False  
 1281  beta_n_factor = 100.
 
 1285  gravity_active = 
True 
 1286  gravity = [0., -10., 0.]
 
 1289  neigh_search_factor = 10.
 
 1290  neigh_search_interval = 100
 
 1291  neigh_search_criteria = 
"simple_all" 
 1294  moving_wall_vert_velocity = -0.06
 
 1301  padding = 1.1 * R_contact_factor * mesh_size
 
 1302  max_y = moving_wall_y - 3*mesh_size
 
 1305  id_choices1 = [0, 1, 2, 3]
 
 1306  id_choices2 = [4, 5, 6, 7]
 
 1307  num_particles_zones_1_to_8, particles_zones_1_to_8 = particle_locations(inp_dir, pp_tag, center, padding, max_y, mesh_size, R_small, R_large, id_choices1, id_choices2, N1, N2, in_rect, z_coord = 0., add_orient = 
True)
 
 1310  zones_mesh_fnames = [
"mesh_cir_small", 
"mesh_tri_small", 
"mesh_drum2d_small", 
"mesh_hex_small", 
"mesh_cir_large", 
"mesh_tri_large", 
"mesh_drum2d_large", 
"mesh_hex_large", 
"mesh_fixed_container", 
"mesh_moving_container"]
 
 1313  generate_cir_particle_gmsh_input(inp_dir, zones_mesh_fnames[0], center, R_small, mesh_size, pp_tag)
 
 1314  generate_cir_particle_gmsh_input(inp_dir, zones_mesh_fnames[4], center, R_large, mesh_size, pp_tag)
 
 1317  generate_tri_particle_gmsh_input(inp_dir, zones_mesh_fnames[1], center, R_small, mesh_size, pp_tag)
 
 1318  generate_tri_particle_gmsh_input(inp_dir, zones_mesh_fnames[5], center, R_large, mesh_size, pp_tag)
 
 1321  generate_drum2d_particle_gmsh_input(inp_dir, zones_mesh_fnames[2], center, R_small, 2.*w_small_drum2d, mesh_size, pp_tag)
 
 1322  generate_drum2d_particle_gmsh_input(inp_dir, zones_mesh_fnames[6], center, R_large, 2.*w_large_drum2d, mesh_size, pp_tag)
 
 1325  generate_hex_particle_gmsh_input(inp_dir, zones_mesh_fnames[3], center, R_small, mesh_size, pp_tag)
 
 1326  generate_hex_particle_gmsh_input(inp_dir, zones_mesh_fnames[7], center, R_large, mesh_size, pp_tag)
 
 1329  generate_rigid_rect_container_moving_wall_setup_gmsh_input(inp_dir, zones_mesh_fnames[8], out_rect, in_rect, mesh_size, pp_tag)
 
 1331  generate_moving_rect_wall_gmsh_input(inp_dir, zones_mesh_fnames[9], moving_rect, mesh_size, pp_tag)
 
 1333  os.system(
"mkdir -p ../out")
 
 1335  for s 
in zones_mesh_fnames:
 
 1338    print(
"gmsh {}_{}.geo -2 &> /dev/null".format(s, pp_tag))
 
 1341    os.system(
"gmsh {}_{}.geo -2".format(s, pp_tag))
 
 1350  inpf = open(sim_inp_dir + 
'input_' + str(pp_tag) + 
'.yaml',
'w')
 
 1351  inpf.write(
"Model:\n")
 
 1352  inpf.write(
"  Dimension: 2\n")
 
 1353  inpf.write(
"  Discretization_Type:\n")
 
 1354  inpf.write(
"    Spatial: finite_difference\n")
 
 1355  inpf.write(
"    Time: central_difference\n")
 
 1356  inpf.write(
"  Final_Time: %4.6e\n" % (final_time))
 
 1357  inpf.write(
"  Time_Steps: %d\n" % (num_steps))
 
 1360  inpf.write(
"Container:\n")
 
 1361  inpf.write(
"  Geometry:\n")
 
 1362  inpf.write(
"    Type: rectangle\n")
 
 1363  inpf.write(
"    Parameters: " + print_dbl_list(contain_rect))
 
 1366  inpf.write(
"Zone:\n")
 
 1367  inpf.write(
"  Zones: 10\n")
 
 1370    inpf.write(
"  Zone_%d:\n" % (i+1))
 
 1372      inpf.write(
"    Is_Wall: true\n")
 
 1374      inpf.write(
"    Is_Wall: false\n")
 
 1377  inpf.write(
"Particle:\n")
 
 1378  inpf.write(
"  Test_Name: multi_particle_compressive_test\n")
 
 1380  particle_data = [[
'circle', small_circle], [
'triangle', small_triangle], [
'drum2d', small_drum2d], [
'hexagon', small_hex], [
'circle', large_circle], [
'triangle', large_triangle], [
'drum2d', large_drum2d], [
'hexagon', large_hex]]
 
 1381  for i 
in range(len(particle_data)):
 
 1382    inpf.write(
"  Zone_%d:\n" % (i+1))
 
 1383    inpf.write(
"    Type: %s\n" % (particle_data[i][0]))
 
 1384    inpf.write(
"    Parameters: " + print_dbl_list((particle_data[i][1])))
 
 1387  inpf.write(
"  Zone_9:\n")
 
 1388  inpf.write(
"    Is_Wall: true\n")
 
 1389  inpf.write(
"    Type: rectangle_minus_rectangle\n")
 
 1390  inpf.write(
"    Parameters: " + print_dbl_list(fixed_container_params))
 
 1391  inpf.write(
"    All_Dofs_Constrained: true\n")
 
 1392  inpf.write(
"    Create_Particle_Using_ParticleZone_GeomObject: true\n")
 
 1395  inpf.write(
"  Zone_10:\n")
 
 1396  inpf.write(
"    Is_Wall: true\n")
 
 1397  inpf.write(
"    Type: rectangle\n")
 
 1398  inpf.write(
"    Parameters: " + print_dbl_list(moving_rect))
 
 1399  inpf.write(
"    All_Dofs_Constrained: true\n")
 
 1400  inpf.write(
"    Create_Particle_Using_ParticleZone_GeomObject: true\n")
 
 1403  inpf.write(
"Particle_Generation:\n")
 
 1404  inpf.write(
"  From_File: particle_locations_" + str(pp_tag) + 
".csv\n")
 
 1405  inpf.write(
"  File_Data_Type: loc_rad_orient\n") 
 
 1408  inpf.write(
"Mesh:\n")
 
 1411    inpf.write(
"  Zone_%d:\n" % (i+1))
 
 1412    inpf.write(
"    File: %s\n" % (zones_mesh_fnames[i] + 
"_" + str(pp_tag) + 
".msh"))
 
 1415  inpf.write(
"Contact:\n")
 
 1418  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"11", Kn_small_small)
 
 1421  copy_contact_zone(inpf, [12, 13, 14], [1, 1])
 
 1424  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"15", Kn_small_large)
 
 1427  copy_contact_zone(inpf, [16, 17, 18], [1, 5])
 
 1430  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"19", Kn_small_wall)
 
 1433  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"110", Kn_small_wall)
 
 1436  copy_contact_zone(inpf, [22, 23, 24], [1, 1])
 
 1439  copy_contact_zone(inpf, [25, 26, 27, 28], [1, 5])
 
 1442  copy_contact_zone(inpf, [29], [1, 9])
 
 1445  copy_contact_zone(inpf, [210], [1, 10])
 
 1448  copy_contact_zone(inpf, [33, 34], [1, 1])
 
 1451  copy_contact_zone(inpf, [35, 36, 37, 38], [1, 5])
 
 1454  copy_contact_zone(inpf, [39], [1, 9])
 
 1457  copy_contact_zone(inpf, [310], [1, 10])
 
 1460  copy_contact_zone(inpf, [44], [1, 1])
 
 1463  copy_contact_zone(inpf, [45, 46, 47, 48], [1, 5])
 
 1466  copy_contact_zone(inpf, [49], [1, 9])
 
 1469  copy_contact_zone(inpf, [410], [1, 10])
 
 1472  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"55", Kn_large_large)
 
 1475  copy_contact_zone(inpf, [56, 57, 58], [5, 5])
 
 1478  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"59", Kn_large_wall)
 
 1481  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"510", Kn_large_wall)
 
 1484  copy_contact_zone(inpf, [66, 67, 68], [5, 5])
 
 1487  copy_contact_zone(inpf, [69], [5, 9])
 
 1490  copy_contact_zone(inpf, [610], [5, 10])
 
 1493  copy_contact_zone(inpf, [77, 78], [5, 5])
 
 1496  copy_contact_zone(inpf, [79], [5, 9])
 
 1499  copy_contact_zone(inpf, [710], [5, 10])
 
 1502  copy_contact_zone(inpf, [88], [5, 5])
 
 1505  copy_contact_zone(inpf, [89], [5, 9])
 
 1508  copy_contact_zone(inpf, [810], [5, 10])
 
 1511  write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, 
"99", Kn_wall_wall)
 
 1514  copy_contact_zone(inpf, [910], [9, 9])
 
 1517  copy_contact_zone(inpf, [1010], [9, 9])
 
 1520  inpf.write(
"Neighbor:\n")
 
 1521  inpf.write(
"  Update_Criteria: %s\n" % (neigh_search_criteria))
 
 1522  inpf.write(
"  Search_Factor: %4.e\n" % (neigh_search_factor))
 
 1523  inpf.write(
"  Search_Interval: %d\n" % (neigh_search_interval))
 
 1526  inpf.write(
"Material:\n")
 
 1529  write_material_zone_part(inpf, 
"1", horizon, rho_small, K_small, G_small, Gc_small)
 
 1532  inpf.write(
"  Zone_2:\n")
 
 1533  inpf.write(
"    Copy_Material_Data: 1\n")
 
 1536  inpf.write(
"  Zone_3:\n")
 
 1537  inpf.write(
"    Copy_Material_Data: 1\n")
 
 1540  inpf.write(
"  Zone_4:\n")
 
 1541  inpf.write(
"    Copy_Material_Data: 1\n")
 
 1544  write_material_zone_part(inpf, 
"5", horizon, rho_large, K_large, G_large, Gc_large)
 
 1547  inpf.write(
"  Zone_6:\n")
 
 1548  inpf.write(
"    Copy_Material_Data: 5\n")
 
 1551  inpf.write(
"  Zone_7:\n")
 
 1552  inpf.write(
"    Copy_Material_Data: 5\n")
 
 1555  inpf.write(
"  Zone_8:\n")
 
 1556  inpf.write(
"    Copy_Material_Data: 5\n")
 
 1559  write_material_zone_part(inpf, 
"9", horizon, rho_wall, K_wall, G_wall, Gc_wall)
 
 1562  inpf.write(
"  Zone_10:\n")
 
 1563  inpf.write(
"    Copy_Material_Data: 9\n")
 
 1566  if gravity_active == 
True:
 
 1567    inpf.write(
"Force_BC:\n")
 
 1568    inpf.write(
"  Gravity: " + print_dbl_list(gravity))
 
 1571  inpf.write(
"Displacement_BC:\n")
 
 1572  inpf.write(
"  Sets: 2\n")
 
 1574  inpf.write(
"  Set_1:\n")
 
 1576  inpf.write(
"    Particle_List: [%d]\n" % (num_particles_zones_1_to_8))
 
 1577  inpf.write(
"    Direction: [1,2]\n")
 
 1578  inpf.write(
"    Zero_Displacement: true\n")
 
 1580  inpf.write(
"  Set_2:\n")
 
 1582  inpf.write(
"    Particle_List: [%d]\n" % (num_particles_zones_1_to_8 + 1))
 
 1583  inpf.write(
"    Direction: [2]\n")
 
 1584  inpf.write(
"    Time_Function:\n")
 
 1585  inpf.write(
"      Type: linear\n")
 
 1586  inpf.write(
"      Parameters:\n")
 
 1587  inpf.write(
"        - %4.6e\n" % (moving_wall_vert_velocity))
 
 1588  inpf.write(
"    Spatial_Function:\n")
 
 1589  inpf.write(
"      Type: constant\n")
 
 1595  inpf.write(
"Output:\n")
 
 1596  inpf.write(
"  Path: ../out/\n")
 
 1597  inpf.write(
"  Tags:\n")
 
 1598  inpf.write(
"    - Displacement\n")
 
 1599  inpf.write(
"    - Velocity\n")
 
 1600  inpf.write(
"    - Force\n")
 
 1601  inpf.write(
"    - Force_Density\n")
 
 1602  inpf.write(
"    - Damage_Z\n")
 
 1603  inpf.write(
"    - Damage\n")
 
 1604  inpf.write(
"    - Nodal_Volume\n")
 
 1605  inpf.write(
"    - Zone_ID\n")
 
 1606  inpf.write(
"    - Particle_ID\n")
 
 1607  inpf.write(
"    - Fixity\n")
 
 1608  inpf.write(
"    - Force_Fixity\n")
 
 1609  inpf.write(
"    - Contact_Nodes\n")
 
 1610  inpf.write(
"    - No_Fail_Node\n")
 
 1611  inpf.write(
"    - Boundary_Node_Flag\n")
 
 1612  inpf.write(
"  Output_Interval: %d\n" % (dt_out_n))
 
 1613  inpf.write(
"  Compress_Type: zlib\n")
 
 1614  inpf.write(
"  Perform_FE_Out: false\n")
 
 1616    inpf.write(
"  Perform_Out: true\n")
 
 1618    inpf.write(
"  Perform_Out: false\n")
 
 1619  inpf.write(
"  Test_Output_Interval: %d\n" % (test_dt_out_n))
 
 1621  inpf.write(
"  Debug: 2\n")
 
 1622  inpf.write(
"  Tag_PP: %d\n" %(int(pp_tag)))
 
 1632if len(sys.argv) > 1:
 
 1633  pp_tag = int(sys.argv[1])
 
 1635create_input_file(inp_dir, pp_tag)