flow 0.4.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
Loading...
Searching...
No Matches
pressure_h_independence Namespace Reference

Functions

 velocity (nx, ny, nz, kind)
 
 main ()
 

Detailed Description

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.

Function Documentation

◆ velocity()

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().

◆ main()

pressure_h_independence.main ( )

Definition at line 100 of file pressure_h_independence.py.

References main(), and velocity().

Referenced by main().