|
flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
|
Functions | |
| zh_ref (phi) | |
| sphere_radius (phi) | |
| pseudo_dt (N) | |
| drag_K (umean, phi) | |
| march (step, umean) | |
| run_flow (flow, SolverCls, N, phi) | |
| amr_worker (N, phi) | |
| run_amr (N, phi) | |
| main () | |
Variables | |
| list | ZH_PHI = [0.000125, 0.001, 0.008, 0.027, 0.064, 0.125, 0.216, 0.343, 0.45, 0.5236] |
| list | ZH_K = [1.096, 1.212, 1.525, 2.008, 2.810, 4.292, 7.442, 15.4, 28.1, 42.1] |
| float | L = 1.0 |
| RHO | |
| MU | |
| F | |
| float | BETA = 6.0 |
| TOL_K | |
| CHECK_EVERY | |
| N_PASS | |
| MAX_STEPS | |
| float | RHO_SLOW = 0.997 |
| int | ROUNDOFF = 1e-11 |
Grid convergence of the Stokes permeability of a simple-cubic sphere array against Zick & Homsy,
comparing WHERE the superficial velocity U_sup = <u_x> is averaged:
* staggered -- peclet.flow.Solver: u lives on the MAC faces; <u_x> over that face field.
* collocated/cell -- peclet.flow.SolverColocated: <u_x> over the cell-centred velocity.
* collocated/FACE -- the same SolverColocated solve, <u_x> over its projected, divergence-free MAC
face field (get_uf). Only the averaging location differs from the cell column.
* amr/cell, amr/FACE -- peclet.amr.Flow on a UNIFORM octree (lmax = 0), cell mean and the mean of
its divergence-free face field. At lmax = 0 the octree is flow's brick, so
this is a cross-check of the collocated columns (amr's uniform-parity gate,
amr/tests/study/flow_parity, holds the two engines to 1e-5 on a ghost-
projected sphere). The two modules cannot share an interpreter (each
finalizes Kokkos under the other's Views), so the amr runs go to a subprocess.
Each solver runs its DEFAULT immersed-boundary scheme: staggered = the cut-cell (Robust-Scaled)
overlay; collocated and amr = AUTO, i.e. the fluid-only 'ghost' projection.
One sphere of volume fraction phi at the centre of a periodic unit cube (on a grid vertex for even N, as in
collocated_zh_schemes.py and amr's parity cases), rho = mu = 1, body force f = 1 along x, marched
to a steady state with the pseudo-time step at viscous number nu dt / h^2 = 6 (the cell-unit dt 60
at nu 0.1 the study was first run with), at most 1500 steps (a run that hits the cap is flagged
'*'). Drag: K = f L^3 / (6 pi mu R U_sup), error in % against the Z&H table.
Steady state (march(), the same test for every column): every 5 steps, d = the change of <u_x> over
the block and R = d / the previous block's d; a block passes when 0 < R < 1 and the geometric
remainder |d| / (1 - max(R, 0.997^5)) is below 1e-4 |<u_x>|, and three consecutive passes stop the
march. So the stopped K is within 1e-4 (relative; the resolution of the e% columns) of the
converged one, provided no mode slower than max(R, 0.997 per step) carries the remainder. Checked
against the geometric limit of 800-1200-step marches, every column at N = 14..48: the largest
|K_stop / K_inf - 1| is 7.4e-5 (collocated N = 16; gauge-exact there 8.1e-5), all others <= 6.1e-5.
Why a remainder test and not an increment test: the collocated march carries a slowly relaxing
(pi,0,0) pressure checkerboard (doc/collocated_invisible_subspace.md ยง11; instrument
collocated_checkerboard_tail.py) -- about 0.996 per step at N = 14..24, independent of dt, with an
N-dependent amplitude. The old test (|d| < 1e-6 |<u_x>| over 5 steps) waited 490 steps on it at
N = 14 and 16, and stopped falsely where two modes of opposite sign cross: collocated N = 18 at
step 45 with K off by 2.4e-4, staggered N = 24 and 32 at 4.6e-5 and 4.8e-5. The 0.997 floor keeps
a fast, cleanly contracting transient from hiding the slow tail beneath it.
Run (from flow/, OpenMP pool bounded; the amr columns need an amr build, otherwise they print --):
OMP_NUM_THREADS=8 OMP_PROC_BIND=false PYTHONPATH=<flow build> \\
PECLET_AMR_PYTHONPATH=<amr build> python tests/study/study_avg_velocity_spheres.py [phi] [N,N,..]
Defaults phi = 0.125, N = 16,24,32,48. AMR_MAX_N (default 48) caps the N the amr column runs at.
Result, 2026-10-01 (flow 5bcf353 + this stop test, amr 7bf183a, host-openmp -march=native,
8 threads), phi = 0.125, K_ZH = 4.292, N = 16,18,24,32,48, 3.6 min wall:
N | K_stag e% | K_co_cel e% | K_co_FAC e% | K_amr e% | K_amrFAC e% | steps s/c/a
16 | 4.2120 -1.86 | 4.2663 -0.60 | 4.2663 -0.60 | 4.2663 -0.60 | 4.2663 -0.60 | 75/395/395
18 | 4.2350 -1.33 | 4.2698 -0.52 | 4.2698 -0.52 | 4.2698 -0.52 | 4.2698 -0.52 | 175/335/335
24 | 4.2573 -0.81 | 4.2791 -0.30 | 4.2791 -0.30 | 4.2791 -0.30 | 4.2791 -0.30 | 135/90/90
32 | 4.2771 -0.35 | 4.2845 -0.18 | 4.2845 -0.18 | 4.2845 -0.18 | 4.2845 -0.18 | 200/145/145
48 | 4.2880 -0.09 | 4.2884 -0.08 | 4.2884 -0.08 | 4.2884 -0.08 | 4.2884 -0.08 | 280/280/280
* Every column under-predicts K and its error falls monotonically with N. Observed orders: staggered
2.4 (N 16 -> 32) and 3.1 (24 -> 48), collocated 1.8 and 1.8 -- about 2, as flow's ghost-projection
notes have it. The 24 -> 48 staggered figure is inflated: at -0.09 % the error is within ~8x of the
Z&H table's own last digit (4.292 +/- 0.0005, i.e. +/- 0.012 %).
* Face vs cell averaging no longer matters: under the ghost projection the two collocated means
agree to <= 1e-8 relative at every N (STUDY_DIAG prints them), although the fields differ
pointwise by up to 6e-3 of the mean. The question the study was written for -- the OLD collocated
scheme's cell average was biased at cut cells by its openness-aware centre correction and lost
~1 % per grid to staggered; does the face average recover it? -- is moot for the current default,
and on this case collocated is now the more accurate of the two at every N.
* amr at lmax = 0 reproduces flow collocated to all printed digits (the uniform-parity result).
* Against the old stop test (5bcf353's table) K moved by at most 1e-4: collocated N = 16
4.2664 -> 4.2663, staggered N = 24 4.2571 -> 4.2573 and N = 32 4.2770 -> 4.2771; the steps
went 70/490/490 -> 75/395/395 at N = 16, and 70/85 -> 135/90 at N = 24 (staggered had
stopped early on a sign change there).
History: written against the sdflow-era module names and the retired tpx_amr (later
peclet.core.amr) module; ported to the physical-domain API of peclet.flow and peclet.amr and moved
from scripts/ to tests/study/ on 2026-10-01. Two things changed in the port beyond the names: the
sphere sits at the box centre sampled at the solver's cell_centers() (the old cell-index sampling put
it half a cell off the vertex), and the amr column stops on the same steady-state test as flow
instead of after a fixed 100 steps.
| study_avg_velocity_spheres.zh_ref | ( | phi | ) |
Definition at line 101 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.sphere_radius | ( | phi | ) |
Definition at line 105 of file study_avg_velocity_spheres.py.
Referenced by amr_worker(), drag_K(), and run_flow().
| study_avg_velocity_spheres.pseudo_dt | ( | N | ) |
Definition at line 109 of file study_avg_velocity_spheres.py.
Referenced by amr_worker(), and run_flow().
| study_avg_velocity_spheres.drag_K | ( | umean, | |
| phi | |||
| ) |
Definition at line 114 of file study_avg_velocity_spheres.py.
References sphere_radius().
Referenced by main().
| study_avg_velocity_spheres.march | ( | step, | |
| umean | |||
| ) |
Step until the change of <u_x> still to come is below TOL_K (relative); see the docstring. The amr column's instrument. The flow column uses peclet.flow.march_to_steady(accelerate=False) with the same constants, which is this loop step for step (ctest march_to_steady, G0(b)). Every CHECK_EVERY steps, d = the change of <u_x> over the block and R = d / (the previous block's d). A block PASSES when the increments contract without changing sign (0 < R < 1) and the geometric remainder |d| / (1 - max(R, RHO_SLOW**CHECK_EVERY)) is below TOL_K |<u_x>| -- or when |d| is at round-off. N_PASS consecutive passes stop the march. The RHO_SLOW floor keeps a fast, cleanly contracting transient from hiding the slow tail beneath it; the sign and consecutive-pass conditions reject the dip where two modes of opposite sign cross.
Definition at line 118 of file study_avg_velocity_spheres.py.
Referenced by amr_worker().
| study_avg_velocity_spheres.run_flow | ( | flow, | |
| SolverCls, | |||
| N, | |||
| phi | |||
| ) |
(U_cell, U_face, steps, converged) of one flow solve at steady state.
Definition at line 153 of file study_avg_velocity_spheres.py.
References mean(), pseudo_dt(), and sphere_radius().
Referenced by main().
| study_avg_velocity_spheres.amr_worker | ( | N, | |
| phi | |||
| ) |
Subprocess body: one amr solve; prints a JSON line {u_cell, u_face, steps, converged}.
Definition at line 180 of file study_avg_velocity_spheres.py.
References march(), mean(), pseudo_dt(), and sphere_radius().
Referenced by main().
| study_avg_velocity_spheres.run_amr | ( | N, | |
| phi | |||
| ) |
Definition at line 200 of file study_avg_velocity_spheres.py.
Referenced by main().
| study_avg_velocity_spheres.main | ( | ) |
Definition at line 214 of file study_avg_velocity_spheres.py.
References amr_worker(), drag_K(), main(), run_amr(), and run_flow().
Referenced by main().
| list study_avg_velocity_spheres.ZH_PHI = [0.000125, 0.001, 0.008, 0.027, 0.064, 0.125, 0.216, 0.343, 0.45, 0.5236] |
Definition at line 89 of file study_avg_velocity_spheres.py.
| list study_avg_velocity_spheres.ZH_K = [1.096, 1.212, 1.525, 2.008, 2.810, 4.292, 7.442, 15.4, 28.1, 42.1] |
Definition at line 90 of file study_avg_velocity_spheres.py.
| float study_avg_velocity_spheres.L = 1.0 |
Definition at line 92 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.RHO |
Definition at line 93 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.MU |
Definition at line 93 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.F |
Definition at line 93 of file study_avg_velocity_spheres.py.
| float study_avg_velocity_spheres.BETA = 6.0 |
Definition at line 94 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.TOL_K |
Definition at line 96 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.CHECK_EVERY |
Definition at line 96 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.N_PASS |
Definition at line 96 of file study_avg_velocity_spheres.py.
| study_avg_velocity_spheres.MAX_STEPS |
Definition at line 96 of file study_avg_velocity_spheres.py.
| float study_avg_velocity_spheres.RHO_SLOW = 0.997 |
Definition at line 97 of file study_avg_velocity_spheres.py.
| int study_avg_velocity_spheres.ROUNDOFF = 1e-11 |
Definition at line 98 of file study_avg_velocity_spheres.py.