|
flow 0.4.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
|
Functions | |
| velocity (nx, ny, nz, kind) | |
| main () | |
Is the cut-cell pressure multigrid resolution-independent on a wall-bounded domain?
STATUS: NOT YET TRUSTWORTHY -- do not quote numbers from this script for the wall-bounded case.
It works as intended with periodic boundaries and for modes that vary only in the periodic
directions, but ANY wall-normal variation in the prescribed field makes the projection stall (no
residual reduction at all, even at rtol = 0.1), so no h-independence conclusion can be drawn yet.
See "What is known" at the bottom of this docstring before using it.
A weak-scaling ladder that refines a DNS confounds two things: the discrete operator getting harder
to solve, and the turbulence itself changing as it becomes better resolved. This isolates the first.
The method is the textbook h-independence test. Fix a CONTINUOUS problem -- one velocity field
defined as a function of the physical coordinates, whose divergence is therefore a fixed function --
and sample it on grids of increasing resolution over the SAME physical box. Solve the pressure
Poisson equation once at each resolution, from a zero initial guess, to a fixed relative tolerance.
A multigrid whose convergence rate is resolution-independent takes the same number of iterations at
every resolution; a rising count is the solver, not the physics.
The solve is driven through the ordinary solver path with advection off and mu = 0, so the predictor
leaves the prescribed field untouched (u* = u) and the projection sees exactly the divergence we
prescribed.
python scripts/pressure_h_independence.py --n 32,48,64,96
python scripts/pressure_h_independence.py --n 32,48,64,96 --rhs broadband
python scripts/pressure_h_independence.py --n 32,48,64 --bottom smoother # contrast
Options worth sweeping: --bottom (auto/smoother) shows whether the coarse level is implicated,
--levels caps the hierarchy, --periodic-y removes the walls to separate the wall treatment from the
rest of the operator.
Needs PYTHONPATH pointing at a flow build; single rank, no MPI required.
What is known, all measured at 192x32x64 with mu = 0, advection off, cold start:
phi = cos(2pi x) no walls or walls 7 iterations, |u| after ~ 6e-11
phi = cos(2pi x) cos(2pi z) walls 39 iterations
phi = cos(2pi x) cos(2pi y) PERIODIC y 5 iterations
phi = cos(2pi x) cos(2pi y) WALLS 500 (the cap; no progress at rtol 0.1)
random noise walls 10 iterations
Reichardt-like channel profile walls 5 iterations
So the harness itself is sound -- it projects a pure gradient field to 1e-11 -- and the solver is
plainly fine on real channel states (the production DNS converges in 4-6 iterations and reproduces
the MKM statistics). The stall is specific to a prescribed field that varies in the wall-normal
direction, and the most likely explanation is that the test field is not an admissible state rather
than a solver defect: a curl-free (pure gradient) field cannot satisfy both no-penetration and the
wall conditions simultaneously, so forcing its wall-normal component to zero at the wall face leaves
a component the Neumann projection cannot remove.
NEXT STEP (untried): drop the pure-gradient construction, which is what forces that conflict. Use a
general field that is NOT curl-free -- wall-normal component vanishing at both walls, tangential
components arbitrary -- and check it converges before trusting any refinement sweep. Alternatively,
sidestep prescribed fields entirely: take one converged DNS field, interpolate it to several
resolutions, and solve once at each. That uses only the validated path, at the cost of a
band-limited field on the finer grids.
| pressure_h_independence.velocity | ( | nx, | |
| ny, | |||
| nz, | |||
| kind | |||
| ) |
A prescribed field built as the DISCRETE gradient of a potential. Taking finite differences of a sampled potential -- rather than sampling an analytic velocity -- makes the discrete divergence exactly the discrete Laplacian of that potential, so the singular all-Neumann pressure problem is compatible to machine precision by construction. Sampling an analytic velocity instead leaves a small incompatible component, and the solve then stalls at a residual floor and never reaches its tolerance (it looks like divergence, and is not). The potential uses cos(m*pi*y), whose y-derivative vanishes at both walls, so the wall-normal velocity is zero there as the wall boundary condition requires. Wavelengths are fixed fractions of the box, so every resolution samples the SAME continuous problem -- the point of the test.
Definition at line 63 of file pressure_h_independence.py.
Referenced by main().
| pressure_h_independence.main | ( | ) |
Definition at line 100 of file pressure_h_independence.py.
References main(), and velocity().
Referenced by main().