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

flow — VoF rung V2a (WO-J): the bridge between the solver's G = 2 block and the colour field's own g = 3 working block, plus the colour field's ghost policy. More...

#include <Kokkos_Core.hpp>
#include "mac_stencils.hpp"
#include "policy.hpp"

Go to the source code of this file.

Namespaces

namespace  peclet
 
namespace  peclet::flow
 
namespace  peclet::flow::vof
 

Functions

void peclet::flow::vof::copyFaceVelocity (SField dst, I3 de, int dg, SField src, I3 se, int sg, int dir)
 Embed the ENTIRE source extended block (inner + its sg ghost layers) into a LARGER destination extended block, converting the staggered face index of velocity component dir from the solver's low-face convention to the advector's high-face convention:
 
void peclet::flow::vof::copyAdvectedVelocity (SField dst, I3 de, int dg, SField src, I3 se, int sg, int dir, I3 n)
 The INVERSE of copyFaceVelocity, restricted to the inner region: bring a face-indexed field back from the advector's g = 3 block to the solver's G = 2 block, undoing the high-face -> low-face shift.
 
void peclet::flow::vof::periodicFill (SField f, I3 e, int g, bool px, bool py, bool pz)
 Periodic wrap of a single-block extended field at ghost width g (the single-rank ghost path; under MPI core::halo::GridHalo does this and the cross-rank exchange in one call).
 
void peclet::flow::vof::clampFill (SField f, I3 e, int g, I3 o, I3 gs, bool px, bool py, bool pz, int skip=0)
 Zero-gradient (Neumann) fill of the ghost cells that lie OUTSIDE the global domain on a non-periodic axis: each such cell takes the value at its globally CLAMPED index.
 

Detailed Description

flow — VoF rung V2a (WO-J): the bridge between the solver's G = 2 block and the colour field's own g = 3 working block, plus the colour field's ghost policy.

suite/docs/VOF_PLAN.md §3 design rule 1 keeps the solver's global G = 2 untouched and gives the colour field its own, wider halo. That leaves exactly two block extents in play and every bridge between them is a place to get an offset wrong — the functions here are that bridge, kept in one file so there is one place to read.

Two kinds of transfer are needed and they are NOT the same:

  • inner-region only (the colour field itself). The two blocks disagree about how many ghost layers they have but agree about the inner cells; each block's ghosts are then filled by that block's OWN policy. IbmSolver::copyInner already does this both ways, so nothing here.
  • whole source block embedded in the destination (the face velocities). The advector reads the face velocity one cell OUTSIDE its inner region (the -d face of the first inner cell is a ghost cell's +d face), and the solver's velocity block carries exactly those values in its own ghost ring once fillVelGhosts has run. copyFaceVelocity places the whole G = 2 block (inner + both ghost layers) inside the g = 3 block, so the advector's ghost layers hold real face velocities and only the outermost layer — which no kernel reads — is left alone.

The two codes index a staggered face differently and the shift is load-bearing. In flow, u(i) is the low (-x) face of cell i: projectCorrect writes u(i) -= phi(i) - phi(i-sx) (the gradient between cells i-1 and i) and divergOpen forms d(i) = ox(i+sx)*u(i+sx) - ox(i)*u(i). In WyAdvector, uf(i) is the high (+x) face of cell i: wyFaceFlux(u(p), p, sd, …) fluxes from p into p+sd, and the dilation term is u(i) - u(i-sd). So the bridge must shift by one cell ALONG the component's own axis:

u_advector(i) = u_solver(i + s_d)

Getting this wrong is invisible in a uniform flow and invisible in the discrete divergence of EACH AXIS SEPARATELY (the shifted x-difference is still the solver's exact zero, just evaluated at cell i-1) — but the advector sums the three axes AT ONE CELL, and the unshifted bridge hands it div_x(i-1) + div_y(i-s_y) + div_z(i-s_z), three different cells whose sum the projection never constrained. Weymouth-Yue then adds H(C-½) times that non-zero "divergence" to every full cell's budget: MEASURED with the shift omitted, a sheared ratio-10 sphere over 1000 coupled steps gained 35 % of its volume while the solver's own max|div(open·u)| read 7e-11. That is the failure mode to remember — the conservation gate catches it and nothing else does.

The ghost fills are the production twins of the ones the V1 test harness uses (tests/kokkos/vof_advect_scenes.hpp), including WO-E finding 2: the non-periodic fill must take the value at the globally clamped index, never sequential zero-gradient axis passes over the block, or the fill is decomposition-DEPENDENT and the difference reaches the colour field through the MYC stencil of the inner corner cell.

Definition in file colour_field.hpp.