|
flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
|
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...
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. | |
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:
IbmSolver::copyInner already does this both ways, so nothing here.-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.