21R_REF = {0: 0.001, 1: 0.001, 2: 0.001, 3: 0.003, 4: 0.003, 5: 0.003}
66 """Signed-volume centroid of circle(+)-circle(-)-rectangle(+) wall."""
67 r_out, cx0, cy0, cz0 = params[0], params[1], params[2], params[3]
68 r_in, cx1, cy1, cz1 = params[4], params[5], params[6], params[7]
69 x0, y0, z0, x1, y1, z1 = params[8:14]
70 a_out = math.pi * r_out * r_out
71 a_in = math.pi * r_in * r_in
72 a_rect = abs(x1 - x0) * abs(y1 - y0)
73 vol = a_out - a_in + a_rect
74 cx = (a_out * cx0 - a_in * cx1 + a_rect * 0.5 * (x0 + x1)) / vol
75 cy = (a_out * cy0 - a_in * cy1 + a_rect * 0.5 * (y0 + y1)) / vol
76 cz = (a_out * cz0 - a_in * cz1 + a_rect * 0.5 * (z0 + z1)) / vol
81 a, b = min(i, j), max(i, j)
83 "Contact_Radius_Factor": 0.95,
87 "K": 2.0 * K_MAT[a] * K_MAT[b] / (K_MAT[a] + K_MAT[b]),
89 "Friction_Coeff": 0.5,
90 "Kn_Factor": KN_FACTOR,
91 "Beta_n_Factor": 100.0,
112 output_interval: int,
113 omega: float = -20.0 * math.pi,
117 with CSV.open()
as f:
120 parts = [p.strip()
for p
in line.split(
",")]
123 zi = int(float(parts[0]))
124 x, y, z = float(parts[1]), float(parts[2]), float(parts[3])
125 r, o = float(parts[4]), float(parts[5])
127 if math.hypot(x, y) + r > R_IN - 1.0e-6:
129 f
"IC overlap: particle zone={zi} at ({x},{y}) r={r} "
130 f
"extends past R_in={R_IN}"
140 "mat_id": 1
if large
else 0,
141 "contact_id": 1
if large
else 0,
145 wall_id = len(particles)
162 gen = {
"Method":
"From_File",
"Random_Rotation":
False,
"Data": {
"N": len(particles)}}
163 for i, p
in enumerate(particles):
164 gen[
"Data"][str(i)] = p
168 "Set_1": {
"Type":
"circle",
"Parameters": [0.001, 0.0, 0.0, 0.0]},
169 "Set_2": {
"Type":
"triangle",
"Parameters": [0.001, 0.0, 0.0, 0.0]},
170 "Set_3": {
"Type":
"drum2d",
"Parameters": [0.001, 0.0004, 0.0, 0.0, 0.0]},
171 "Set_4": {
"Type":
"circle",
"Parameters": [0.003, 0.0, 0.0, 0.0]},
172 "Set_5": {
"Type":
"triangle",
"Parameters": [0.003, 0.0, 0.0, 0.0]},
173 "Set_6": {
"Type":
"drum2d",
"Parameters": [0.003, 0.0012, 0.0, 0.0, 0.0]},
176 "Vec_type": [
"circle",
"circle",
"rectangle"],
177 "Vec_flag": [
"plus",
"minus",
"plus"],
178 "Parameters": WALL_PARAMS,
183 for i, name
in enumerate(MESH_FILES):
184 mesh[f
"Set_{i + 1}"] = {
"File": str((MESH / name).resolve())}
188 "Damping_Law":
"off",
189 "Friction_Law":
"coulomb_simple",
190 "Correct_Volume":
False,
193 for j
in range(i, 3):
199 "Final_Time": final_time,
200 "Time_Steps": time_steps,
201 "Discretization_Type": {
202 "Spatial":
"finite_difference",
203 "Time":
"central_difference",
205 "Populate_ElementNodeConnectivity":
True,
206 "Quad_Approximation_Order": 2,
207 "Particle_Sim_Type":
"Multi_Particle",
210 "Bond_Break":
"tension",
211 "Self_Contact":
"none",
212 "Wall_Contact":
"meshed",
215 "Path": out_path
if out_path.endswith(
"/")
else out_path +
"/",
227 "Output_Interval": output_interval,
229 "Perform_FE_Out":
False,
230 "Compress_Type":
"zlib",
231 "File_Format":
"vtu",
232 "Test_Output_Interval": max(1, output_interval // 10),
234 "PVD_Collection":
True,
236 "Force_BC": {
"Gravity": [0.0, -10.0, 0.0]},
240 "Particle_List": [wall_id],
244 "Parameters": [omega, 0.0, 0.0, 0.0],
246 "Spatial_Function": {
"Type":
"rotation"},
247 "Zero_Displacement":
False,
250 "Particle": particle_geom,
255 "Set_1":
material(horizon, 1.0e4, 6.0e3, 50.0),
256 "Set_2":
material(horizon, 1.0e5, 6.0e4, 100.0),
260 "Update_Criteria":
"simple_all",
261 "Search_Factor": 10.0,
262 "Search_Interval": 40,
263 "Near_Bd_Nodes_Tol": 0.5,
265 "Particle_Generation": gen,