89ZH_PHI = [0.000125, 0.001, 0.008, 0.027, 0.064, 0.125, 0.216, 0.343, 0.45, 0.5236]
90ZH_K = [1.096, 1.212, 1.525, 2.008, 2.810, 4.292, 7.442, 15.4, 28.1, 42.1]
93RHO, MU, F = 1.0, 1.0, 1.0
96TOL_K, CHECK_EVERY, N_PASS, MAX_STEPS = 1e-4, 5, 3, 1500
154 """(U_cell, U_face, steps, converged) of one flow solve at steady state."""
155 s = SolverCls((N, N, N), extent=(L, L, L))
156 s.set_rho(RHO); s.set_mu(MU); s.set_dt(
pseudo_dt(N))
157 s.set_body_force((F, 0.0, 0.0)); s.set_advection(
False)
158 s.diagnostics.set_velocity_solver_params(200)
159 s.set_pressure_multigrid(
True, levels=max(2, int(np.log2(N)) - 1))
160 s.set_pressure_pcg(
True, max_iter=200, rtol=1e-8)
161 cx, cy, cz = s.cell_centers()
162 X, Y, Z = np.meshgrid(cx, cy, cz, indexing=
"ij")
164 sdf = np.sqrt((X - c) ** 2 + (Y - c) ** 2 + (Z - c) ** 2) -
sphere_radius(phi)
165 s.set_solid(np.asfortranarray(sdf), cutcell_pressure=
True)
168 res = flow.march_to_steady(s,
lambda: float(s.get_u().
mean()), rtol=TOL_K,
169 max_steps=MAX_STEPS, accelerate=
False, check_every=CHECK_EVERY,
170 num_passes=N_PASS, slow_rate=RHO_SLOW, roundoff=ROUNDOFF)
171 steps, ok = res.steps, res.converged
172 u, uf = s.get_u(), s.get_uf()
173 if os.environ.get(
"STUDY_DIAG")
and SolverCls
is flow.SolverColocated:
175 print(f
" [diag N={N}] max|uf-u_cell| = {np.abs(uf - u).max():.3e} "
176 f
"(means: cell {float(u.mean()):.8e} face {float(uf.mean()):.8e})", flush=
True)
177 return float(u.mean()), float(uf.mean()), steps, ok
181 """Subprocess body: one amr solve; prints a JSON line {u_cell, u_face, steps, converged}."""
182 from peclet
import amr
183 oct_ = amr.Octree(cells=[N, N, N], lmax=0, origin=[0.0, 0.0, 0.0], extent=[L, L, L])
184 fl = amr.Flow(oct_, density=RHO, viscosity=MU, dt=
pseudo_dt(N))
185 fl.set_body_force(F, 0.0, 0.0); fl.set_advection(
False)
186 fl.set_pressure_tolerance(1e-8)
188 fl.set_solid_spheres(np.array([[c, c, c]]), np.array([
sphere_radius(phi)]), periodic=
True)
189 steps, ok =
march(
lambda: fl.step(mom_iters=200, pres_iters=200),
190 lambda: float(fl.velocity(0).
mean()))
194 assert ff.size == 6 * fl.num_leaves,
"expected six faces per leaf at lmax = 0"
196 print(json.dumps({
"u_cell": float(fl.velocity(0).
mean()),
"u_face": float(np.mean(uf)),
197 "steps": steps,
"converged": ok}))
215 sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),
"..",
"..",
217 from _bootstrap
import ensure_flow
220 phi = float(sys.argv[1])
if len(sys.argv) > 1
else 0.125
221 Ns = [int(x)
for x
in sys.argv[2].split(
",")]
if len(sys.argv) > 2
else [16, 24, 32, 48]
222 amr_max = int(os.environ.get(
"AMR_MAX_N",
"48"))
227 return f
"{K:8.4f} {100 * (K - kref) / kref:+6.2f}"
230 return "" if ok
else "*"
232 print(f
"=== Stokes permeability, SC sphere array (phi={phi}, Z&H K_ref={kref:.4f}) ===")
233 print(f
"{'N':>4} | {'K_stag':>8} {'e%':>6} | {'K_co_cel':>8} {'e%':>6} | {'K_co_FAC':>8} {'e%':>6}"
234 f
" | {'K_amr':>8} {'e%':>6} | {'K_amrFAC':>8} {'e%':>6} | steps s/c/a")
237 us, _, ns, oks =
run_flow(flow, flow.Solver, N, phi)
238 uc, uf, nc, okc =
run_flow(flow, flow.SolverColocated, N, phi)
239 a =
run_amr(N, phi)
if N <= amr_max
else None
241 amr_cols, na = f
"{'--':>8} {'--':>6} | {'--':>8} {'--':>6}",
"--"
243 amr_cols = f
"{col(a['u_cell'])} | {col(a['u_face'])}"
244 na = f
"{a['steps']}{flag(a['converged'])}"
245 print(f
"{N:4d} | {col(us)} | {col(uc)} | {col(uf)} | {amr_cols} | "
246 f
"{ns}{flag(oks)}/{nc}{flag(okc)}/{na} [{time.time() - t0:.0f}s]", flush=
True)