flow
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
verify_chebyshev_sdflow.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# Chebyshev pressure driver (sdflow set_pressure_chebyshev): a communication-light alternative to MG-PCG
3# (Chebyshev semi-iteration preconditioned by one symmetric V-cycle, spectral bounds estimated once and
4# reused). Validation: it must converge to the SAME cut-cell Stokes solution as the default MG-PCG (same
5# operator, both Krylov/semi-iteration -> same fixed point). Scenario = the periodic sphere packing from
6# verify_periodic_spheres_sdflow.
7import sys, gc
8import numpy as np
9from peclet import flow as sdflow
10
11N, MU, DT, F = 32, 0.1, 60.0, 1e-3
12
13
14def packing_sdf(N, radius_frac=0.18):
15 R = N * radius_frac
16 gx = np.arange(N)
17 cs = [(c + 0.5) * N / 2.0 for c in (0, 1)]
18 X, Y, Z = np.meshgrid(gx, gx, gx, indexing="ij")
19 best = np.full((N, N, N), 1e30)
20 for sx in cs:
21 for sy in cs:
22 for sz in cs:
23 dx = X - sx; dx -= N * np.round(dx / N)
24 dy = Y - sy; dy -= N * np.round(dy / N)
25 dz = Z - sz; dz -= N * np.round(dz / N)
26 best = np.minimum(best, np.sqrt(dx * dx + dy * dy + dz * dz) - R)
27 return best
28
29
30def run(chebyshev, max_steps=200):
31 sdf = np.asfortranarray(packing_sdf(N))
32 s = sdflow.Solver(N, N, N)
33 s.set_rho(1.0); s.set_mu(MU); s.set_dt(DT)
34 s.set_body_force(F, 0.0, 0.0)
35 s.set_advection(False)
36 s.set_velocity_solver_params(80)
37 s.set_pressure_multigrid(True, 4)
38 if chebyshev:
39 s.set_pressure_chebyshev(True, 200, 1e-9)
40 s.set_solid(sdf, cutcell_pressure=True)
41 prev = 0.0
42 for it in range(max_steps):
43 s.step()
44 um = float(s.get_u().mean())
45 if it > 8 and abs(um - prev) < 3e-4 * (abs(um) + 1e-15):
46 break
47 prev = um
48 u = s.get_u()
49 k = MU * float(u.mean()) / F
50 div = s.max_open_divergence()
51 iters = s.last_pressure_iterations()
52 del s; gc.collect()
53 return k, div, float(u.max()), int(iters)
54
55
56def main():
57 print("=== Chebyshev pressure driver: converges to the MG-PCG cut-cell Stokes solution ===")
58 k_pcg, d_pcg, umax_pcg, it_pcg = run(chebyshev=False)
59 k_cb, d_cb, umax_cb, it_cb = run(chebyshev=True)
60 rel = abs(k_cb - k_pcg) / k_pcg
61 print(f" MG-PCG : k={k_pcg:.6e} div={d_pcg:.2e} last_iters={it_pcg}")
62 print(f" Chebyshev : k={k_cb:.6e} div={d_cb:.2e} last_iters={it_cb}")
63 print(f" |k_cheb - k_pcg|/k_pcg = {rel*100:.4f}%")
64 ok = (rel < 5e-3) and (d_cb < 1e-6 * umax_cb) and (it_cb > 0)
65 print(f" result: {'PASS' if ok else 'FAIL'} (Chebyshev == MG-PCG solution; incompressible)")
66 sys.exit(0 if ok else 1)
67
68
69if __name__ == "__main__":
70 main()
packing_sdf(N, radius_frac=0.18)
run(chebyshev, max_steps=200)