33def run(vmg, dt, fx, n_steps, vlevels=3, vcycles=10, to_steady=False):
35 s = sdflow.Solver(N, N, N)
39 s.set_body_force(fx, 0.0, 0.0)
41 s.set_implicit_advection(
True)
42 s.set_outer_iterations(3)
43 s.set_velocity_solver_params(80)
45 s.set_velocity_multigrid(
True, vlevels, vcycles)
46 s.set_pressure_pcg(
True, max_iter=120, rtol=1e-9)
47 s.set_solid(sdf, cutcell_pressure=
True, pressure_coarse=
"galerkin")
49 for it
in range(n_steps):
52 if not np.isfinite(u).all():
55 if to_steady
and it > 8
and abs(um - prev) < 1e-7 * (abs(um) + 1e-15):
62 print(
"=== upwind-convective velocity-MG: high-Re stability + RB-GS equivalence ===")
65 print(
" (1) high Re: dt=5, fx=0.02 (U~2 -> CFL >> 1, operator advection-dominated)")
66 ur =
run(vmg=
False, dt=5.0, fx=0.02, n_steps=30)
67 uv =
run(vmg=
True, dt=5.0, fx=0.02, n_steps=30)
68 rbgs_ok = ur
is not None and np.isfinite(ur).all()
69 vmg_ok = uv
is not None and np.isfinite(uv).all()
and uv.max() < 1e3
70 print(f
" RB-GS implicit-FOU : {'finite, U_max=%.3f' % ur.max() if rbgs_ok else 'unstable'}")
71 print(f
" vel-MG implicit-FOU: {'finite, U_max=%.3f' % uv.max() if vmg_ok else 'unstable'}")
74 print(
" (2) moderate Re: dt=5, fx=2e-4 (steady) -> RB-GS vs vel-MG agree")
75 ur2 =
run(vmg=
False, dt=5.0, fx=2e-4, n_steps=400, to_steady=
True)
76 uv2 =
run(vmg=
True, dt=5.0, fx=2e-4, n_steps=400, to_steady=
True)
77 rel_max = abs(uv2.max() - ur2.max()) / ur2.max()
78 rel_mean = abs(uv2.mean() - ur2.mean()) / abs(ur2.mean())
79 print(f
" RB-GS U_max={ur2.max():.6f} U_mean={ur2.mean():.6e}")
80 print(f
" vel-MG U_max={uv2.max():.6f} U_mean={uv2.mean():.6e}")
81 print(f
" diff: U_max {rel_max*100:.3f}% U_mean {rel_mean*100:.3f}%")
83 ok = rbgs_ok
and vmg_ok
and rel_max < 0.01
and rel_mean < 0.01
84 print(f
" result: {'PASS' if ok else 'FAIL'} (upwind vel-MG stable at high Re; "
85 f
"matches RB-GS at steady to <1%)")
86 sys.exit(0
if ok
else 1)