33def run_case(case, DH, sweeps=60, gpu_dt=None, advect=True):
34 rho_f, mu_si, u_inf, ratio_exp, Re = CASES[case]
37 NX = int(np.ceil((100 / 15 * DH + 2 * WALL) / 8) * 8)
38 NY = int(np.ceil((160 / 15 * DH + 2 * WALL) / 8) * 8)
39 WX = (NX - 100 / 15 * DH) / 2
40 WY = (NY - 160 / 15 * DH) / 2
42 GSTAR = G_SI * D_SI / u_inf ** 2 * USTAR ** 2 / DH
43 RATIO = RHO_P_SI / rho_f
46 tau = RATIO * DH * Re / (18 * USTAR)
47 dt = gpu_dt
if gpu_dt
else min(max(tau / 12, 1.0), 0.35 / USTAR / 4)
48 b = geom.SceneBuilder()
49 slab = b.add_leaf(
"box", [NX * 0.7, NY * 0.7, NX * 0.7])
50 cavity = b.add_leaf(
"box", [(NX - 2 * WX) / 2, (NY - 2 * WY) / 2, (NX - 2 * WX) / 2])
51 tank = b.add_difference(slab, cavity)
52 sph = b.add_leaf(
"sphere", [DH / 2])
53 ni, nr, _, _ = b.encode()
56 y0 = WY + OFF + 8.5 * DH
57 ii = np.zeros((2, KI_I), dtype=np.int32); ir = np.zeros((2, KI_R))
58 ii[0] = (tank, -1); ir[0, 0:3] = (0.5 * NX + OFF, 0.5 * NY + OFF, 0.5 * NX + OFF)
59 ir[0, 6] = 1.0; ir[0, 7] = 1.0
60 ii[1] = (sph, -1); ir[1, 0:3] = (x0, y0, x0); ir[1, 6] = 1.0; ir[1, 7] = 1.0
61 s = sdflow.Solver(NX, NY, NX)
62 s.set_rho(1.0); s.set_mu(NU); s.set_dt(dt); s.set_advection(advect)
63 s.set_velocity_solver_params(sweeps); s.set_pressure_solver_params(20)
64 s.set_pressure_multigrid(
True, levels=4)
65 s.set_scene(np.asarray(ni, np.int32), np.asarray(nr, float), ii.ravel(), ir.ravel(),
67 s.set_solid_from_scene(
True)
69 m = RATIO * (np.pi / 6) * DH ** 3
70 Vp = (np.pi / 6) * DH ** 3
77 d = pdem.Simulation(8)
78 d.set_gravity(0.0, 0.0, 0.0)
79 d.set_sphere_shape(1.0)
80 d.set_positions(np.array([[x0, y0, x0]], dtype=np.float32))
81 d.set_inv_mass(np.array([1.0 / (m + ma)], dtype=np.float32))
82 d.set_inv_inertia(np.array([[0, 0, 0]], dtype=np.float32))
83 Fg = (RATIO - 1.0) * Vp * GSTAR
86 kmax = int(2.2 * (8.5 * DH / (0.8 * USTAR)) / dt)
87 t0 = time.time(); tr = []; vpk = 0.0; a_prev = np.zeros(3)
89 p = np.asarray(d.get_positions())[0].astype(float)
90 v = np.asarray(d.get_velocities())[0].astype(float)
91 s.set_instance_transform(1, p.tolist())
92 s.set_instance_motion(1, lin_vel=v.tolist())
93 s.rebuild_geometry(); s.step()
94 F = np.asarray(s.hydro_force_torque_reaction())[0][1].astype(float)
97 d.set_external_forces(np.array([F], dtype=np.float32))
100 a_prev = (np.asarray(d.get_velocities())[0].astype(float) - v) / dt
101 tr.append(((k + 1) * dt, p[1] - (WY + OFF) - DH / 2, v[1]))
102 vpk = max(vpk, -v[1])
103 if tr[-1][1] < 0.5 * DH:
105 if vpk > 0.3 * USTAR
and -v[1] < 0.45 * vpk:
108 return dict(t=tr[:, 0], gap=tr[:, 1] / DH, v=tr[:, 2] / USTAR, case=case, DH=DH,
109 ratio_exp=ratio_exp, Re=Re, u_inf=u_inf, wall=time.time() - t0,
110 nstep=len(tr), dt=dt)
115 rho_f, mu_si, u_inf, ratio_exp, Re = CASES[case]
117 GSTAR = G_SI * D_SI / u_inf ** 2 * USTAR ** 2 / DH
118 RATIO = RHO_P_SI / rho_f
119 tau = RATIO * DH * Re / (18 * USTAR)
120 dt = min(max(tau / 12, 1.0), 0.35 / USTAR / 4)
121 b = geom.SceneBuilder()
122 sph = b.add_leaf(
"sphere", [DH / 2])
123 ni, nr, _, _ = b.encode()
125 ii = np.zeros((1, KI_I), dtype=np.int32); ir = np.zeros((1, KI_R))
126 ii[0] = (sph, -1); ir[0, 0:3] = (x0, x0, x0); ir[0, 6] = 1.0; ir[0, 7] = 1.0
127 s = sdflow.Solver(N, N, N)
128 s.set_rho(1.0); s.set_mu(NU); s.set_dt(dt); s.set_advection(advect)
129 s.set_velocity_solver_params(60); s.set_pressure_solver_params(20)
130 s.set_pressure_multigrid(
True, levels=4)
131 s.set_scene(np.asarray(ni, np.int32), np.asarray(nr, float), ii.ravel(), ir.ravel(),
133 s.set_solid_from_scene(
True)
134 _Fg = (RATIO - 1.0) * (np.pi / 6) * DH ** 3 * GSTAR
135 s.set_body_force(0.0, _Fg / (N ** 3), 0.0)
136 m = RATIO * (np.pi / 6) * DH ** 3
137 Vp = (np.pi / 6) * DH ** 3
139 d = pdem.Simulation(8)
140 d.set_gravity(0.0, 0.0, 0.0); d.set_sphere_shape(1.0)
141 d.set_positions(np.array([[x0, x0, x0]], dtype=np.float32))
142 d.set_inv_mass(np.array([1.0 / (m + ma)], dtype=np.float32))
143 d.set_inv_inertia(np.array([[0, 0, 0]], dtype=np.float32))
144 Fg = (RATIO - 1.0) * Vp * GSTAR
145 a_prev = np.zeros(3); vs = []
146 for k
in range(nstep):
147 p = np.asarray(d.get_positions())[0].astype(float)
148 v = np.asarray(d.get_velocities())[0].astype(float)
149 s.set_instance_transform(0, p.tolist())
150 s.set_instance_motion(0, lin_vel=v.tolist())
151 s.rebuild_geometry(); s.step()
152 F = np.asarray(s.hydro_force_torque_reaction())[0][0].astype(float)
155 d.set_external_forces(np.array([F], dtype=np.float32))
158 a_prev = (np.asarray(d.get_velocities())[0].astype(float) - v) / dt
159 vs.append(-v[1] / USTAR)
160 if k > 400
and abs(vs[-1] - vs[-200]) < 5e-4 * abs(vs[-1]):
162 c = (np.pi / 6) * DH ** 3 / N ** 3
163 hasi = 1.0 - 1.7601 * c ** (1 / 3)
164 print(
"%s unbounded N=%d: plateau=%.4f Hasimoto-corrected expectation=%.4f steps=%d"
165 % (case, N, vs[-1], hasi, len(vs)))