26def run(H=32, L=224, Re=100.0, U=1.0, nz=4, max_steps=8000, dt=0.5):
27 """Run the developing-channel case and return its convergence diagnostics.
29 Uniform inflow at -x, outflow at +x, no-slip walls at +-y, periodic z; marches to steady state and
30 returns a dict with the mass-conservation error, max divergence, outlet u_max/U_mean ratio, the
31 outlet-profile rms against the parabola, and the developed pressure gradient. Returns None off root.
34 s = sdflow.Solver(L, H, nz)
35 s.set_rho(1.0); s.set_mu(nu); s.set_dt(dt); s.set_advection(
True)
36 s.set_domain_bc(
"-x",
"inflow", (U, 0.0, 0.0))
37 s.set_domain_bc(
"+x",
"outflow")
38 s.set_domain_bc(
"-y",
"wall"); s.set_domain_bc(
"+y",
"wall")
39 s.diagnostics.set_velocity_solver_params(60)
40 s.set_pressure_multigrid(
True, levels=8)
41 s.set_pressure_solver_params(80)
42 s.set_pressure_geometry(np.full((L, H, nz), 1e30))
46 for it
in range(max_steps):
50 m = float(u[L - 4, H // 2, nz // 2])
if s.rank() == 0
else 0.0
51 done = it > 1000
and abs(m - prev) < 1e-5 * (abs(m) + 1e-30)
53 if s.diagnostics.bcast_from_root(done):
56 u = s.get_u(); p = s.get_p(); div = s.max_open_divergence()
60 flux_in = float(u[2, :, nz // 2].sum())
61 flux_out = float(u[L - 3, :, nz // 2].sum())
62 mass_err = abs(flux_out - flux_in) / (abs(flux_in) + 1e-30)
64 prof = u[L - 4, :, nz // 2]
65 U_mean = float(prof.mean())
66 eta = (np.arange(H) + 0.5) / H
67 parab = 6.0 * U_mean * eta * (1.0 - eta)
68 prof_rms = float(np.sqrt(np.mean((prof - parab) ** 2)) / (abs(U_mean) + 1e-30))
69 ratio = float(prof.max() / (U_mean + 1e-30))
71 pc = p[:, H // 2, nz // 2]
72 x0, x1 = L // 2, L - 6
73 dpdx = float((pc[x1] - pc[x0]) / (x1 - x0))
74 dpdx_analytic = -12.0 * nu * U_mean / H**2
75 return dict(steps=steps, mass_err=mass_err, div=div, U_mean=U_mean, ratio=ratio,
76 prof_rms=prof_rms, dpdx=dpdx, dpdx_analytic=dpdx_analytic, Re=Re, H=H, L=L)