Skip to content

Commit 68eb2cf

Browse files
committed
add python mesh functions using gmsh. Special attention is given to geometries for which we can generate symmetric mesh. This is crucial in certain applications to avoid artificial effects due non uniform mesh.
1 parent 4631648 commit 68eb2cf

File tree

4 files changed

+2135
-390
lines changed

4 files changed

+2135
-390
lines changed
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
import os
2+
import sys
3+
import numpy as np
4+
5+
#sys.path.append('<Path to PeriDEM source>/tools/python_utils')
6+
from gmsh_particles import *
7+
from util import *
8+
9+
def create_input_file(inp_dir, pp_tag):
10+
"""Generates input file for two-particle test"""
11+
12+
sim_inp_dir = str(inp_dir)
13+
14+
R1 = 0.001
15+
mesh_size = R1 / 8.
16+
horizon = 2.2 * mesh_size
17+
particle_dist = 0.9*mesh_size #horizon # surface to surface distance
18+
19+
## particle 1 rectangle
20+
Lx, Ly = 4*R1, 3*mesh_size
21+
rect_center = [R1, 0., 0.]
22+
23+
## particle 2 circle
24+
cir_center = [R1, rect_center[1] + 0.5*Ly + particle_dist + R1, 0.]
25+
26+
## assign free fall velocity to second particle
27+
high_impact = False
28+
free_fall_vel = [0., -0.1, 0.]
29+
if high_impact:
30+
free_fall_vel = [0., -4., 0.] # high impact velocity
31+
32+
## time
33+
final_time = 0.01
34+
num_steps = 50000
35+
if high_impact:
36+
final_time = 0.0002
37+
num_steps = 10000
38+
# final_time = 0.00002
39+
# num_steps = 2
40+
num_outputs = 100
41+
dt_out_n = num_steps / num_outputs
42+
perform_out = True
43+
44+
## material
45+
poisson1 = 0.25
46+
rho1 = 1200.
47+
K1 = 2.16e+7
48+
E1 = get_E(K1, poisson1)
49+
G1 = get_G(E1, poisson1)
50+
Gc1 = 50.
51+
52+
poisson2 = 0.25
53+
rho2 = 1200.
54+
K2 = 2.16e+7
55+
E2 = get_E(K2, poisson2)
56+
G2 = get_G(E2, poisson2)
57+
Gc2 = 50.
58+
59+
## contact
60+
# R_contact = 0.95 * mesh_size
61+
# R_contact = 1.74e-04
62+
R_contact_factor = 0.95
63+
64+
# Kn_V_max = 7.385158e+05
65+
# Kn = np.power(Kn_V_max, 2)
66+
# compute from bulk modulus
67+
68+
# from bulk modulus
69+
Kn_11 = 18. * get_eff_k(K1, K1) / (np.pi * np.power(horizon, 5))
70+
Kn_22 = 18. * get_eff_k(K2, K2) / (np.pi * np.power(horizon, 5))
71+
Kn_12 = 18. * get_eff_k(K1, K2) / (np.pi * np.power(horizon, 5))
72+
73+
beta_n_eps = 0.9
74+
friction_coeff = 0.5
75+
damping_active = False
76+
friction_active = False
77+
beta_n_factor = 10.
78+
Kn_factor = 0.1
79+
80+
## gravity
81+
gravity_active = True
82+
gravity = [0., -10., 0.]
83+
84+
## neighbor search details
85+
neigh_search_factor = 2.
86+
neigh_search_interval = 1
87+
neigh_search_criteria = "simple_all"
88+
89+
### ---------------------------------------------------------------- ###
90+
# generate mesh and particle location data
91+
### ---------------------------------------------------------------- ###
92+
plocf = open(inp_dir + 'particle_locations_' + str(pp_tag) + '.csv','w')
93+
plocf.write("i, x, y, z, r, o\n")
94+
plocf.write("%d, %Lf, %Lf, %Lf, %Lf, %Lf\n" % (0, rect_center[0], rect_center[1], rect_center[2], Lx, 0.))
95+
plocf.write("%d, %Lf, %Lf, %Lf, %Lf, %Lf\n" % (1, cir_center[0], cir_center[1], cir_center[2], R1, 0.))
96+
plocf.close()
97+
98+
zones_mesh_fnames = ["mesh_rect_1", "mesh_cir_2"]
99+
100+
# generate mesh for particle 1
101+
rectangle_mesh_symmetric(xc = [0., 0., 0.], Lx = Lx, Ly = Ly, h = mesh_size, filename = zones_mesh_fnames[0] + "_" + str(pp_tag), vtk_out = True, symmetric_mesh = True)
102+
103+
# generate mesh for particle 2
104+
circle_mesh_symmetric(xc = [0., 0., 0.], r = R1, h = mesh_size, filename = zones_mesh_fnames[1] + "_" + str(pp_tag), vtk_out = True, symmetric_mesh = True)
105+
106+
os.system("mkdir -p ../out")
107+
108+
### ---------------------------------------------------------------- ###
109+
# generate YAML file
110+
### ---------------------------------------------------------------- ###
111+
# print('\nGenerating imput file\n')
112+
inpf = open(sim_inp_dir + 'input_' + str(pp_tag) + '.yaml','w')
113+
inpf.write("Model:\n")
114+
inpf.write(" Dimension: 2\n")
115+
inpf.write(" Discretization_Type:\n")
116+
inpf.write(" Spatial: finite_difference\n")
117+
inpf.write(" Time: central_difference\n")
118+
inpf.write(" Final_Time: %4.6e\n" % (final_time))
119+
inpf.write(" Time_Steps: %d\n" % (num_steps))
120+
121+
#
122+
# container info
123+
#
124+
inpf.write("Container:\n")
125+
inpf.write(" Geometry:\n")
126+
inpf.write(" Type: rectangle\n")
127+
contain_params = [rect_center[0] - 0.5*Lx, rect_center[1] - 0.5*Ly, 0., rect_center[0] + 0.5*Lx, rect_center[1] + 0.5*Ly + particle_dist + 2*R1, 0.]
128+
inpf.write(" Parameters: " + print_dbl_list(contain_params))
129+
130+
#
131+
# zone info
132+
#
133+
inpf.write("Zone:\n")
134+
inpf.write(" Zones: 2\n")
135+
136+
## zone 1 (bottom particle)
137+
inpf.write(" Zone_1:\n")
138+
inpf.write(" Is_Wall: false\n")
139+
140+
## zone 2 (top particle)
141+
inpf.write(" Zone_2:\n")
142+
inpf.write(" Is_Wall: false\n")
143+
144+
#
145+
# particle info
146+
#
147+
inpf.write("Particle:\n")
148+
inpf.write(" Zone_1:\n")
149+
inpf.write(" Type: rectangle\n")
150+
inpf.write(" Parameters: " + print_dbl_list([Lx, Ly, rect_center[0], rect_center[1], rect_center[2]]))
151+
inpf.write(" Zone_2:\n")
152+
inpf.write(" Type: circle\n")
153+
p2_geom = [R1, cir_center[0], cir_center[1], cir_center[2]]
154+
inpf.write(" Parameters: " + print_dbl_list(p2_geom))
155+
156+
#
157+
# particle generation
158+
#
159+
inpf.write("Particle_Generation:\n")
160+
inpf.write(" From_File: particle_locations_" + str(pp_tag) + ".csv\n")
161+
inpf.write(" File_Data_Type: loc_rad_orient\n")
162+
163+
#
164+
# Mesh info
165+
#
166+
inpf.write("Mesh:\n")
167+
168+
for i in range(len(zones_mesh_fnames)):
169+
inpf.write(" Zone_%d:\n" % (i+1))
170+
inpf.write(" File: %s\n" % (zones_mesh_fnames[i] + "_" + str(pp_tag) + ".msh"))
171+
172+
# Contact info
173+
inpf.write("Contact:\n")
174+
175+
## 11
176+
write_contact_zone_part(inpf, R_contact_factor, damping_active, friction_active, beta_n_eps, friction_coeff, Kn_factor, beta_n_factor, "11", Kn_11)
177+
178+
## copy from 11
179+
copy_contact_zone(inpf, [12, 22], [1, 1])
180+
181+
# Neighbor info
182+
inpf.write("Neighbor:\n")
183+
inpf.write(" Update_Criteria: %s\n" % (neigh_search_criteria))
184+
inpf.write(" Search_Factor: %4.e\n" % (neigh_search_factor))
185+
inpf.write(" Search_Interval: %d\n" % (neigh_search_interval))
186+
187+
# Material info
188+
inpf.write("Material:\n")
189+
190+
## zone 1
191+
write_material_zone_part(inpf, "1", horizon, rho1, K1, G1, Gc1)
192+
193+
## zone 2
194+
inpf.write(" Zone_2:\n")
195+
inpf.write(" Copy_Material_Data: 1\n")
196+
197+
#
198+
# Force
199+
#
200+
if gravity_active == True:
201+
inpf.write("Force_BC:\n")
202+
inpf.write(" Gravity: " + print_dbl_list(gravity))
203+
204+
#
205+
# IC
206+
#
207+
inpf.write("IC:\n")
208+
inpf.write(" Constant_Velocity:\n")
209+
inpf.write(" Velocity_Vector: " + print_dbl_list(free_fall_vel))
210+
inpf.write(" Particle_List: [1]\n")
211+
212+
#
213+
# Displacement
214+
#
215+
inpf.write("Displacement_BC:\n")
216+
inpf.write(" Sets: 1\n")
217+
218+
inpf.write(" Set_1:\n")
219+
inpf.write(" Particle_List: [0]\n")
220+
inpf.write(" Direction: [1,2]\n")
221+
inpf.write(" Time_Function:\n")
222+
inpf.write(" Type: constant\n")
223+
inpf.write(" Parameters:\n")
224+
inpf.write(" - 0.0\n")
225+
inpf.write(" Spatial_Function:\n")
226+
inpf.write(" Type: constant\n")
227+
inpf.write(" Zero_Displacement: true\n")
228+
229+
#
230+
# Output info
231+
#
232+
inpf.write("Output:\n")
233+
inpf.write(" Path: ../out/\n")
234+
inpf.write(" Tags:\n")
235+
inpf.write(" - Displacement\n")
236+
inpf.write(" - Velocity\n")
237+
inpf.write(" - Force\n")
238+
inpf.write(" - Force_Density\n")
239+
inpf.write(" - Damage_Z\n")
240+
inpf.write(" - Damage\n")
241+
inpf.write(" - Nodal_Volume\n")
242+
inpf.write(" - Zone_ID\n")
243+
inpf.write(" - Particle_ID\n")
244+
inpf.write(" - Fixity\n")
245+
inpf.write(" - Force_Fixity\n")
246+
inpf.write(" - Contact_Nodes\n")
247+
inpf.write(" - No_Fail_Node\n")
248+
inpf.write(" - Boundary_Node_Flag\n")
249+
inpf.write(" - Theta\n")
250+
inpf.write(" Output_Interval: %d\n" % (dt_out_n))
251+
inpf.write(" Compress_Type: zlib\n")
252+
inpf.write(" Perform_FE_Out: false\n")
253+
if perform_out:
254+
inpf.write(" Perform_Out: true\n")
255+
else:
256+
inpf.write(" Perform_Out: false\n")
257+
inpf.write(" Test_Output_Interval: %d\n" % (dt_out_n))
258+
259+
inpf.write(" Debug: 3\n")
260+
inpf.write(" Tag_PP: %d\n" %(int(pp_tag)))
261+
262+
# close file
263+
inpf.close()
264+
265+
##-------------------------------------------------------##
266+
##-------------------------------------------------------##
267+
if __name__ == "__main__":
268+
inp_dir = './'
269+
pp_tag = 0
270+
if len(sys.argv) > 1:
271+
pp_tag = int(sys.argv[1])
272+
273+
create_input_file(inp_dir, pp_tag)

0 commit comments

Comments
 (0)