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

Functions

 cap_sphere (volume, theta_deg)
 
 cap_colour (nx, ny, nz, cx, cy, zw, R, theta_deg=90.0)
 
 max_u (s, zlo=None)
 
 relax (s, steps, cfl=0.15, dt_cap=None, probe=0)
 
 g1 (thetas=(30.0, 60.0, 90.0, 120.0, 150.0), ratio=1.0, steps=600, R=12.0, nx=64, nz=40, zw=4.25, sigma=1.0, oh=0.1, pivot=0, init_offset=0.0, init_abs=None)
 
 g1_domain (thetas=(60.0, 90.0, 120.0), ratio=1.0, steps=500, R=12.0, nx=64, nz=40, sigma=1.0, oh=0.1)
 
 g1_domain_vs_sdf (thetas=(60.0, 90.0, 120.0), steps=500, gate=1.0)
 
 g1_wall_placement (theta=60.0, steps=1200, fracs=(0.0, 0.25, 0.5, 0.75))
 
 lens_volume (Rs, Rc, d)
 
 drop_volume (Rs, Rc, d)
 
 cap_from_volume (Rs, V, theta_deg)
 
 theta_from_volume_apex (Rs, V, H)
 
 g2 (thetas=(60.0, 90.0, 120.0), steps=600, Rs=12.0, Rd=8.0, n=64, sigma=1.0, oh=0.1)
 
 box_sdf (ax, ay, az, xlo, xhi, zlo, zhi)
 
 g4 (theta=30.0, steps=4000, nx=80, ny=4, nz=96, gap=24, plate=4, sigma=1.0, ratio=10.0, drho_g=2.4e-3, zbath=40.0, zplate=(16.0, 88.0), mu=0.2)
 

Variables

int PRESS_MAXIT = 300
 
float DEG = math.pi / 180.0
 
list args = [a for a in sys.argv[1:] if not a.startswith("--")]
 
str quick = "--quick" in sys.argv
 
list which = args or ["g1", "g2"]
 
 steps
 
 ratio
 
 thetas
 
 init_abs
 

Detailed Description

WO-S (rung V5b) — the static contact angle on SDF solids: the gate battery, in Python.

Every gate prints its numbers; nothing is summarised into an adjective.

  G1  DROP ON A FLAT SDF WALL. A liquid cap on a flat wall at a HALF-INTEGER z (so the wall cells
      are genuinely cut) with surface tension and a prescribed theta, run to rest. The equilibrium
      of a wetting condition is a spherical cap, so the apparent angle is read off the cap
      relations: h from the colour column on the axis (weighted by the cell FLUID fraction, since C
      is a fraction of that), the conserved liquid volume V from `vof_diagnostics()['volume']`,
      then a = sqrt((6V/(pi h) - h^2)/3) and theta = 2 atan(h/a). Reading `a` off the first fluid
      plane instead biases it (that plane's colour is the mean over z in [z_wall, z_wall+eps], not
      the section AT the wall), and the bias grows as the cap flattens — both are printed.
      Reported alongside: the near-wall spurious Ca in the OPEN fluid and the raw max|u| including
      the wall band (WO-Q finding 8's open question), the band census, the volume drift and the
      pressure iteration count against its cap.

  G2  DROP ON AN SDF SPHERE. A liquid drop resting on a solid sphere of radius Rs. The equilibrium
      free surface is a spherical cap of radius Rc whose sphere meets the solid sphere at theta;
      the law of cosines gives the centre distance d^2 = Rs^2 + Rc^2 - 2 Rs Rc cos(theta) and the
      liquid volume is (4/3) pi Rc^3 minus the two-sphere lens, so (V, theta) -> Rc by a 1-D root
      solve. The run is measured the other way round: (V, apex height H = d + Rc) -> (Rc, d) ->
      theta.

  G4  CAPILLARY RISE / JURIN. Two SDF plates a gap `w` apart in a periodic box whose OUTER channel
      has width `w_out`, with a liquid bath below them and gravity. Both channels rise, so the
      measured level difference is Jurin's `2 sigma cos(theta) / (drho g) * (1/w - 1/w_out)`.

Usage:
    PYTHONPATH=$PWD/build_cuda python tests/study/vof_wetting.py [g1 g2 g4 ...]
    PYTHONPATH=$PWD/build_cuda python tests/study/vof_wetting.py g1 --quick

Function Documentation

◆ cap_sphere()

vof_wetting.cap_sphere (   volume,
  theta_deg 
)
The sphere (radius Rc, centre offset below the wall) whose spherical cap of contact angle
`theta` above the wall has the given volume: h = Rc(1 - cos t), a = Rc sin t, and
V = pi Rc^3 (1-cos t)^2 (2 + cos t)/3.

Definition at line 45 of file vof_wetting.py.

Referenced by cap_colour().

◆ cap_colour()

vof_wetting.cap_colour (   nx,
  ny,
  nz,
  cx,
  cy,
  zw,
  R,
  theta_deg = 90.0 
)
A liquid spherical cap of the same VOLUME as a hemisphere of radius R, resting on the wall
z = zw with contact angle `theta`, by 4^3 subsampling of the FLUID part of each cell (C is the
liquid fraction of the fluid volume, `VOF_PLAN` rule 2).

Definition at line 54 of file vof_wetting.py.

References cap_sphere().

Referenced by g1(), and g1_domain().

◆ max_u()

vof_wetting.max_u (   s,
  zlo = None 
)

Definition at line 70 of file vof_wetting.py.

Referenced by g1(), and relax().

◆ relax()

vof_wetting.relax (   s,
  steps,
  cfl = 0.15,
  dt_cap = None,
  probe = 0 
)
Run `steps` steps with a dt kept under the WY interface CFL and the capillary limit.

Definition at line 78 of file vof_wetting.py.

References max_u().

Referenced by g1(), g1_domain(), g2(), and g4().

◆ g1()

vof_wetting.g1 (   thetas = (30.0, 60.0, 90.0, 120.0, 150.0),
  ratio = 1.0,
  steps = 600,
  R = 12.0,
  nx = 64,
  nz = 40,
  zw = 4.25,
  sigma = 1.0,
  oh = 0.1,
  pivot = 0,
  init_offset = 0.0,
  init_abs = None 
)
`init_offset`: the initial cap is at `theta_set + init_offset` (clamped to [10,170]) so the
run has to MOVE the contact line to the prescribed angle; `init_abs` overrides it with a fixed
initial angle (90 = the hemisphere, the largest excursion).

`zw` is a QUARTER-integer, not the half-integer the work order asks for, and that is a measured
correction rather than a convenience: at exactly k + 1/2 the tangential MAC faces of the
wall-adjacent cell sit ON the SDF zero level, `buildOpenness` (sdf > 0 is fluid) closes them,
and the cell is tangentially isolated — the contact line then cannot move at all and the
unrelieved Young force appears as a large velocity on those closed-face DOFs. At k + 1/4 the
wall cell is still genuinely CUT (eps = 3/4, face openness 3/4) and the contact line is mobile.
See the WO-S findings and `g1_wall_placement`.

Definition at line 103 of file vof_wetting.py.

References cap_colour(), max_u(), and relax().

Referenced by g1_domain_vs_sdf(), and g1_wall_placement().

◆ g1_domain()

vof_wetting.g1_domain (   thetas = (60.0, 90.0, 120.0),
  ratio = 1.0,
  steps = 500,
  R = 12.0,
  nx = 64,
  nz = 40,
  sigma = 1.0,
  oh = 0.1 
)
ISSUES sweep item 3. The G1 scene with the wall as a DOMAIN FACE (bc type 1) instead of an
SDF slab: the wall plane is z = 0 exactly, the wall-adjacent cell is WHOLE (no cut cell at
all), and the theta band is the colour block's three ghost layers below z = 0.

Reference: `g1` on the same drop against an SDF wall at a quarter-integer z. The two are
different discretisations of the same physics -- one cuts the wall cell, the other does not --
so the gate is agreement, not identity.

Definition at line 176 of file vof_wetting.py.

References cap_colour(), and relax().

Referenced by g1_domain_vs_sdf().

◆ g1_domain_vs_sdf()

vof_wetting.g1_domain_vs_sdf (   thetas = (60.0, 90.0, 120.0),
  steps = 500,
  gate = 1.0 
)
The ISSUES-sweep item-3 gate: the domain-wall equilibrium against the SDF-wall one.

Definition at line 229 of file vof_wetting.py.

References g1(), and g1_domain().

◆ g1_wall_placement()

vof_wetting.g1_wall_placement (   theta = 60.0,
  steps = 1200,
  fracs = (0.0, 0.25, 0.5, 0.75) 
)
WHERE the SDF wall sits inside the cell decides whether the contact line can move at all.
One theta, four wall placements, everything else identical; the run starts from a hemisphere so
the contact line HAS to travel.

Definition at line 246 of file vof_wetting.py.

References g1().

◆ lens_volume()

vof_wetting.lens_volume (   Rs,
  Rc,
  d 
)
Volume of the intersection of spheres (0, Rs) and (d, Rc).

Definition at line 257 of file vof_wetting.py.

Referenced by drop_volume().

◆ drop_volume()

vof_wetting.drop_volume (   Rs,
  Rc,
  d 
)

Definition at line 268 of file vof_wetting.py.

References lens_volume().

Referenced by cap_from_volume(), and theta_from_volume_apex().

◆ cap_from_volume()

vof_wetting.cap_from_volume (   Rs,
  V,
  theta_deg 
)
(V, theta) -> the cap sphere radius Rc and centre distance d (the reference shape).

Definition at line 272 of file vof_wetting.py.

References drop_volume().

Referenced by g2().

◆ theta_from_volume_apex()

vof_wetting.theta_from_volume_apex (   Rs,
  V,
  H 
)
(V, apex height H = d + Rc) -> (Rc, d, theta).

Definition at line 287 of file vof_wetting.py.

References drop_volume().

Referenced by g2().

◆ g2()

vof_wetting.g2 (   thetas = (60.0, 90.0, 120.0),
  steps = 600,
  Rs = 12.0,
  Rd = 8.0,
  n = 64,
  sigma = 1.0,
  oh = 0.1 
)

Definition at line 303 of file vof_wetting.py.

References cap_from_volume(), relax(), and theta_from_volume_apex().

◆ box_sdf()

vof_wetting.box_sdf (   ax,
  ay,
  az,
  xlo,
  xhi,
  zlo,
  zhi 
)

Definition at line 365 of file vof_wetting.py.

Referenced by g4().

◆ g4()

vof_wetting.g4 (   theta = 30.0,
  steps = 4000,
  nx = 80,
  ny = 4,
  nz = 96,
  gap = 24,
  plate = 4,
  sigma = 1.0,
  ratio = 10.0,
  drho_g = 2.4e-3,
  zbath = 40.0,
  zplate = (16.0, 88.0),
  mu = 0.2 
)
Jurin. Plates of thickness `plate` bounding a gap `gap` wide; the periodic OUTER channel is
`nx - gap - 2*plate` wide. Both menisci rise, so the reference is the DIFFERENCE.

Definition at line 372 of file vof_wetting.py.

References box_sdf(), and relax().

Variable Documentation

◆ PRESS_MAXIT

int vof_wetting.PRESS_MAXIT = 300

Definition at line 40 of file vof_wetting.py.

◆ DEG

float vof_wetting.DEG = math.pi / 180.0

Definition at line 41 of file vof_wetting.py.

◆ args

list vof_wetting.args = [a for a in sys.argv[1:] if not a.startswith("--")]

Definition at line 435 of file vof_wetting.py.

◆ quick

str vof_wetting.quick = "--quick" in sys.argv

Definition at line 436 of file vof_wetting.py.

◆ which

list vof_wetting.which = args or ["g1", "g2"]

Definition at line 437 of file vof_wetting.py.

◆ steps

vof_wetting.steps

Definition at line 440 of file vof_wetting.py.

◆ ratio

vof_wetting.ratio

Definition at line 442 of file vof_wetting.py.

◆ thetas

vof_wetting.thetas

Definition at line 447 of file vof_wetting.py.

◆ init_abs

vof_wetting.init_abs

Definition at line 447 of file vof_wetting.py.