|
flow 1.3.0
Kokkos cut-cell IBM incompressible Navier-Stokes solver + pnm pore extraction
|
Curvature of the colour field on an extended (inner + ghost) block. More...
#include <curvature_field.hpp>
Classes | |
| struct | Stats |
Per-call census of the cascade over this block's inner region (LOCAL; a distributed caller sums them itself — the driver stays MPI-free, exactly as WyAdvector does). More... | |
| struct | Timing |
Public Types | |
| using | IField = Kokkos::View< int *, SMem > |
| using | MomCache = Kokkos::View< PvMoments *, SMem > |
Public Member Functions | |
| void | init (int nx, int ny, int nz, int ghost) |
| bool | ready () const |
| void | resetTiming () |
| const Timing & | timing () const |
| double | tick_ () const |
| void | addT_ (double &acc, double t0) |
| I3 | inner () const |
| I3 | extent () const |
| int | ghost () const |
| SField | kappa () const |
| SField | branch () const |
| SField | planeM (int d) const |
The PLIC planes the cascade reconstructed (planeM(d), planeAlpha()): for the block container's batched cascade (vof/block_batch.hpp), which drives the passes itself. | |
| SField | planeAlpha () const |
| IField | slotMap () const |
| The slot map of the moment cache (design G §5.2), for the batched cascade, which writes it with positions into its own chunk-level cache. | |
| void | copyTunablesFrom (const VofCurvature &src) |
Copy EVERY tunable above (the metric, the estimator knobs, the predicates, the clip, the diagnostic switches) from src – the one place a prototype reaches a cascade, so a new tunable is added here and nowhere else (review finding 1: the block path once dropped pureEps; the block ctest pins every field through this function). | |
| double | kappaClipValue () const |
| The bound the clip applies this call (0 = off). | |
| Stats | compute (SField c) |
| Compute the curvature over the inner region from a colour field on the SAME extended block. | |
| void | computeBegin (SField c) |
compute() in three parts, for a caller that runs MANY cascades (the block container): computeBegin (compaction, planes, tiers 1-2) on every cascade, ONE fallbackBatch launch of tier 3 over all of them, then computeEnd (clip + census) on every cascade. | |
| Stats | computeEnd () |
| VofCurvFallbackJob | fallbackJob (SField c) const |
This cascade's tier-3 share for fallbackBatch (worklist mode only: the job walks the compacted interfacial list computeBegin just built). | |
| void | compact (SField c) |
The two compaction scans: listG_ = every interfacial cell of the GROWN region (what reconstructPlanes reconstructs), listI_ = every interfacial cell of the INNER region (what the cascade runs on). | |
| void | reconstructPlanes (SField c) |
PLIC planes over the inner region grown by kPvHalf — every cell the 5^3 fit can read. | |
| void | heightPass (SField c) |
| Tiers 1 and 2. | |
| void | fallbackPass (SField c) |
| Tier 3, over the cells the height pass could not serve. | |
| long | clipPass () |
The admissibility clip (see kappaMax), over the same cells the cascade ran on: the compacted interfacial list in worklist mode, the inner region in dense mode. | |
| Stats | census () const |
Static Public Member Functions | |
| static void | fallbackBatch (const std::vector< VofCurvFallbackJob > &jobs) |
Tier 3 of many cascades in as few launches as possible: one kernel per kFallbackBatch jobs over their concatenated interfacial lists. | |
Public Attributes | |
| bool | useWorklist = true |
| bool | timingOn = false |
| Timing | tm |
| VofMetric | metric |
| The anisotropic cell metric (Phase 3). | |
| double | weightWidth = kPvWeightWidth |
Wendland support width d of the PV fit, in cell units (Han et al. §5: 2.5 with S = 5). | |
| double | pureEps = 0.0 |
Tolerance of the PURITY test that ends a height-function column (hfIsFull/hfIsEmpty), floored by core's kHfPureEps = 1e-10. | |
| double | monoTol = 1e-6 |
Tolerance of the column monotonicity test (hfColumnHeight). | |
| double | ptWeightWidth = kPtWeightWidth |
| Wendland support width of the tier-2b height-position fit, in cell units. | |
| double | cosMin = 0.2 |
Minimum n_p . n for a stencil polygon to enter the PV fit (pvFitAdd). | |
| double | interfaceEps = 0.0 |
| Wisp threshold on the interfacial predicate. | |
| bool | debugForceFallback = false |
| DIAGNOSTIC ONLY — disable tiers 1 and 2 so every interfacial cell goes to the PV fit. | |
| bool | debugSingleDirection = false |
| DIAGNOSTIC ONLY — disable tier 2 (the non-preferred column directions), so the branch census separates "the preferred direction alone" from "the direction cascade". | |
| bool | useMixedHeightFit = false |
| Tier 2b, and it ships OFF — a measured decision, see the WO-O findings entry. | |
| double | kappaMax = 0.0 |
Curvature admissibility clip (doc/vof_overlap_design.md §5.1, §11): after the cascade, every inner cell carrying a curvature (csfKappaDefined) gets |kappa| <= kappaMax, in INDEX units (1/hRef). | |
Static Public Attributes | |
| static constexpr int | kFallbackBatch = 16 |
Jobs per launch of fallbackBatch (the table rides in the kernel's functor by value). | |
Curvature of the colour field on an extended (inner + ghost) block.
Definition at line 411 of file curvature_field.hpp.
| using peclet::flow::vof::VofCurvature::IField = Kokkos::View<int*, SMem> |
Definition at line 413 of file curvature_field.hpp.
| using peclet::flow::vof::VofCurvature::MomCache = Kokkos::View<PvMoments*, SMem> |
Definition at line 414 of file curvature_field.hpp.
|
inline |
| ghost | must be >= 3 (the column reach); the colour block's kVofG is 3. |
Definition at line 433 of file curvature_field.hpp.
References ghost(), peclet::flow::I3::x, peclet::flow::I3::y, and peclet::flow::I3::z.
Referenced by peclet::flow::Solver< Grid >::buildVofBlock().
|
inline |
Definition at line 464 of file curvature_field.hpp.
Referenced by computeBegin().
|
inline |
Definition at line 488 of file curvature_field.hpp.
References tm.
Referenced by peclet::flow::Solver< Grid >::resetVofTiming().
Definition at line 489 of file curvature_field.hpp.
References tm.
Referenced by peclet::flow::Solver< Grid >::vofCurvatureTiming().
|
inline |
Definition at line 490 of file curvature_field.hpp.
References timingOn.
Referenced by compute(), computeBegin(), and computeEnd().
Definition at line 497 of file curvature_field.hpp.
References timingOn.
Referenced by compute(), computeBegin(), and computeEnd().
|
inline |
Definition at line 505 of file curvature_field.hpp.
Referenced by anderson_synthetic_maps.LinearMapSolver::monitor(), anderson_synthetic_maps.LinearMapSolver::monitor_exact(), anderson_synthetic_maps.LinearMapSolver::step(), anderson_oracle.AndersonOracle::step(), anderson_oracle.AndersonOracle::usq(), and anderson_oracle.AndersonOracle::wdot().
|
inline |
Definition at line 506 of file curvature_field.hpp.
|
inline |
Definition at line 507 of file curvature_field.hpp.
Referenced by init().
|
inline |
Definition at line 508 of file curvature_field.hpp.
Referenced by peclet::flow::Solver< Grid >::computeVofCurvature(), and peclet::flow::Solver< Grid >::pcUpdateCurvature().
|
inline |
Definition at line 509 of file curvature_field.hpp.
Referenced by peclet::flow::Solver< Grid >::computeVofCurvature().
|
inline |
The PLIC planes the cascade reconstructed (planeM(d), planeAlpha()): for the block container's batched cascade (vof/block_batch.hpp), which drives the passes itself.
Definition at line 512 of file curvature_field.hpp.
|
inline |
Definition at line 513 of file curvature_field.hpp.
|
inline |
The slot map of the moment cache (design G §5.2), for the batched cascade, which writes it with positions into its own chunk-level cache.
Definition at line 516 of file curvature_field.hpp.
|
inline |
Copy EVERY tunable above (the metric, the estimator knobs, the predicates, the clip, the diagnostic switches) from src – the one place a prototype reaches a cascade, so a new tunable is added here and nowhere else (review finding 1: the block path once dropped pureEps; the block ctest pins every field through this function).
Definition at line 622 of file curvature_field.hpp.
References cosMin, debugForceFallback, debugSingleDirection, interfaceEps, kappaMax, metric, monoTol, ptWeightWidth, pureEps, useMixedHeightFit, useWorklist, and weightWidth.
|
inline |
The bound the clip applies this call (0 = off).
Definition at line 637 of file curvature_field.hpp.
References kappaMax, and metric.
Referenced by clipPass().
Compute the curvature over the inner region from a colour field on the SAME extended block.
c's ghosts must be valid on entry (the caller's exchange); nothing here communicates.
Definition at line 641 of file curvature_field.hpp.
References addT_(), computeBegin(), computeEnd(), peclet::flow::vof::VofCurvature::Timing::fallback, fallbackPass(), tick_(), and tm.
Referenced by peclet::flow::Solver< Grid >::computeVofCurvature(), and peclet::flow::Solver< Grid >::pcUpdateCurvature().
compute() in three parts, for a caller that runs MANY cascades (the block container): computeBegin (compaction, planes, tiers 1-2) on every cascade, ONE fallbackBatch launch of tier 3 over all of them, then computeEnd (clip + census) on every cascade.
Each cell's tier-3 body reads only its own block's planes/colour and writes only its own kappa/branch, so the batch computes exactly what the per-cascade fallbackPass calls would: bit for bit.
Definition at line 654 of file curvature_field.hpp.
References addT_(), peclet::flow::vof::VofCurvature::Timing::compact, compact(), peclet::flow::vof::VofCurvature::Timing::height, heightPass(), peclet::flow::vof::VofCurvature::Timing::planes, ready(), reconstructPlanes(), tick_(), tm, and useWorklist.
Referenced by compute().
|
inline |
Definition at line 668 of file curvature_field.hpp.
References addT_(), peclet::flow::vof::VofCurvature::Timing::calls, peclet::flow::vof::VofCurvature::Timing::census, census(), peclet::flow::vof::VofCurvature::Timing::clip, clipPass(), tick_(), and tm.
Referenced by compute().
|
inline |
This cascade's tier-3 share for fallbackBatch (worklist mode only: the job walks the compacted interfacial list computeBegin just built).
Definition at line 681 of file curvature_field.hpp.
References cosMin, interfaceEps, metric, weightWidth, peclet::flow::I3::x, and peclet::flow::I3::y.
|
inlinestatic |
Tier 3 of many cascades in as few launches as possible: one kernel per kFallbackBatch jobs over their concatenated interfacial lists.
The per-cascade launches each put ~1e3 threads (one wave, a few warps per SM) on the device for the full latency of the 5^3 fit, one block after the other; batched they share that latency. Pure re-scheduling (see computeBegin).
Definition at line 710 of file curvature_field.hpp.
References peclet::flow::vof::curvFallbackCell(), peclet::flow::vof::curvFallbackTeam(), kFallbackBatch, peclet::flow::vof::kVofWarp, peclet::flow::vof::VofPvTeamScratch::shmem(), and tm.
Referenced by peclet::flow::vof::VofBlockSet::computeCsf().
The two compaction scans: listG_ = every interfacial cell of the GROWN region (what reconstructPlanes reconstructs), listI_ = every interfacial cell of the INNER region (what the cascade runs on).
Same predicate as the passes, so the compacted and dense paths visit exactly the same cells.
Definition at line 767 of file curvature_field.hpp.
References interfaceEps, peclet::flow::L3(), and peclet::flow::vof::vofIsInterface().
Referenced by computeBegin().
PLIC planes over the inner region grown by kPvHalf — every cell the 5^3 fit can read.
Reads colour at +/-1 around those, i.e. +/-(kPvHalf+1) = +/-3 overall.
Definition at line 824 of file curvature_field.hpp.
References peclet::flow::vof::curvMomentsBuild(), interfaceEps, peclet::flow::L3(), metric, useWorklist, peclet::flow::vof::vofIsInterface(), peclet::flow::vof::wyReconstructCell(), peclet::flow::I3::x, and peclet::flow::I3::y.
Referenced by computeBegin().
Tiers 1 and 2.
Writes kappa/branch for every inner cell; a cell the height functions cannot serve is left with branch = -1 for the fallback pass.
Definition at line 882 of file curvature_field.hpp.
References peclet::flow::vof::curvHeightCell(), debugForceFallback, debugSingleDirection, interfaceEps, peclet::flow::L3(), metric, monoTol, ptWeightWidth, pureEps, useMixedHeightFit, useWorklist, peclet::flow::I3::x, and peclet::flow::I3::y.
Referenced by computeBegin().
Tier 3, over the cells the height pass could not serve.
A plain guarded parallel_for rather than a compacted worklist: the branch is a minority at any usable resolution, so almost every warp exits at the guard, and the fallback's larger local state is confined to this kernel.
Definition at line 924 of file curvature_field.hpp.
References cosMin, peclet::flow::vof::curvFallbackCell(), interfaceEps, peclet::flow::L3(), metric, useWorklist, weightWidth, peclet::flow::I3::x, and peclet::flow::I3::y.
Referenced by compute().
|
inline |
The admissibility clip (see kappaMax), over the same cells the cascade ran on: the compacted interfacial list in worklist mode, the inner region in dense mode.
Returns the number of cells it bounded (an integer reduction: deterministic).
Definition at line 954 of file curvature_field.hpp.
References peclet::flow::vof::csfKappaDefined(), kappaClipValue(), peclet::flow::L3(), and useWorklist.
Referenced by computeEnd().
|
inline |
Definition at line 994 of file curvature_field.hpp.
References peclet::flow::L3().
Referenced by computeEnd().
Definition at line 485 of file curvature_field.hpp.
Referenced by clipPass(), computeBegin(), copyTunablesFrom(), fallbackPass(), heightPass(), reconstructPlanes(), peclet::flow::Solver< Grid >::setVofCurvatureWorklist(), and peclet::flow::Solver< Grid >::vofCurvatureWorklist().
Definition at line 486 of file curvature_field.hpp.
Referenced by addT_(), peclet::flow::Solver< Grid >::setVofTiming(), and tick_().
| Timing peclet::flow::vof::VofCurvature::tm |
Definition at line 487 of file curvature_field.hpp.
Referenced by compute(), computeBegin(), computeEnd(), fallbackBatch(), resetTiming(), and timing().
| VofMetric peclet::flow::vof::VofCurvature::metric |
The anisotropic cell metric (Phase 3).
Default {1,1,1} == the pre-Phase-3 arithmetic. Solver::pushVofMetric() sets it; the Wendland supports below are scaled by metric.maxH() so the 5^3 stencil's farthest cell along the LONG axis stays inside the support exactly as d = 2.5 cells does on a cubic grid.
Definition at line 523 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), fallbackJob(), fallbackPass(), gateSolverMetric(), heightPass(), kappaClipValue(), peclet::flow::Solver< Grid >::pushVofMetric(), reconstructPlanes(), and peclet::flow::vof::VofBlockSet::setMetric().
| double peclet::flow::vof::VofCurvature::weightWidth = kPvWeightWidth |
Wendland support width d of the PV fit, in cell units (Han et al. §5: 2.5 with S = 5).
Definition at line 525 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), fallbackJob(), fallbackPass(), peclet::flow::Solver< Grid >::setVofCurvatureWeightWidth(), and peclet::flow::Solver< Grid >::vofCurvatureWeightWidth().
| double peclet::flow::vof::VofCurvature::pureEps = 0.0 |
Tolerance of the PURITY test that ends a height-function column (hfIsFull/hfIsEmpty), floored by core's kHfPureEps = 1e-10.
Set this to the tolerance the COLOUR FIELD was advected at (WyAdvector::wispEps); Solver::computeVofCurvature does. The two must agree about what a pure cell is. When the advector is the looser of the two it treats a cell at 1 - O(1e-9) as pure – fluxing it algebraically instead of reconstructing it – so the colour field accumulates bulk cells in the band between the two tolerances, the column walk finds no pure end there, and the whole height-function tier degrades into the paraboloid fallback. It degrades SILENTLY: a fallback is a valid answer, so nothing fails, the curvature just gets worse as the run goes on. Measured on the mode-2 droplet (48^3, R = 8, mu = 0.0025, 2.5 periods) with the advector at 1e-8 and this at the 1e-10 floor: the HF tier fell 790 -> 134 cells over the run (37 % -> 89 % fallback) as 425 bulk cells drifted into the band, and the mode-2 damping rate came out 2.3x the shared-tolerance value.
Definition at line 540 of file curvature_field.hpp.
Referenced by peclet::flow::Solver< Grid >::computeVofCurvature(), copyTunablesFrom(), heightPass(), and peclet::flow::vof::VofBlockSet::setWispEps().
| double peclet::flow::vof::VofCurvature::monoTol = 1e-6 |
Tolerance of the column monotonicity test (hfColumnHeight).
Tight enough to reject a sub-grid blob inside a column, loose enough to ignore transport round-off.
Definition at line 543 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), and heightPass().
| double peclet::flow::vof::VofCurvature::ptWeightWidth = kPtWeightWidth |
Wendland support width of the tier-2b height-position fit, in cell units.
Definition at line 545 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), and heightPass().
| double peclet::flow::vof::VofCurvature::cosMin = 0.2 |
Minimum n_p . n for a stencil polygon to enter the PV fit (pvFitAdd).
Definition at line 547 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), fallbackJob(), and fallbackPass().
| double peclet::flow::vof::VofCurvature::interfaceEps = 0.0 |
Wisp threshold on the interfacial predicate.
A cell counts as carrying an interface only while eps < C < 1 - eps. DEFAULT 0, which is wyIsMixed verbatim (C > 0 && C < 1) and therefore byte-identical to the V3 rung as gated.
Why it exists (a V4 finding, WO-P). Weymouth-Yue leaves ROUND-OFF colour residue in cells the sweeps touched — measured on a static droplet after 10 steps: C down to -3e-35 and some 5200 extra cells at 0 < C < 1e-30 on a 64^3 grid, i.e. more cells than the interface itself has. Those cells satisfy wyIsMixed and the cascade dutifully produces a curvature for them, from a PLIC polygon of area ~0: measured |kappa| up to 1.2e+08 where the physical value is 0.125. On its own that is only a wrong number in a field nobody was reading. Under V4 it is fatal: a face between such a cell and a REAL interfacial cell has dC = O(1) and a face curvature (kappa_real + 1e8)/2, so the surface-tension force at that one face is eight orders too large. Measured on a 32^3 static droplet, unguarded: max|u| 4.5e-4 at step 1 -> 2.7e-1 by step 20, and at 96^3 the run trips the Weymouth-Yue CFL cap outright, while the SAME run with the curvature frozen at its (clean) initial value stays bounded at 4e-3.
Solver::setSurfaceTension therefore sets this to 1e-8 — the same wisp threshold WyAdvector::diagnostics already reports against. It changes nothing on an exact colour field (no cell of any gated V3 case lies in the band) and it is the guard the literature assumes when it says wisp cleanup is unavoidable once surface tension is on (VOF_PLAN §6, after Arrufat et al. 2021).
Definition at line 569 of file curvature_field.hpp.
Referenced by compact(), copyTunablesFrom(), peclet::flow::vof::VofBlockSet::debrisBatched(), peclet::flow::vof::VofBlockSet::debrisPassBatchImpl(), fallbackJob(), fallbackPass(), heightPass(), reconstructPlanes(), peclet::flow::Solver< Grid >::setSurfaceTension(), and peclet::flow::Solver< Grid >::setVofInterfaceEps().
DIAGNOSTIC ONLY — disable tiers 1 and 2 so every interfacial cell goes to the PV fit.
Used by the ctest to measure the fallback branch on its own; never enable it in production.
Definition at line 572 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), and heightPass().
DIAGNOSTIC ONLY — disable tier 2 (the non-preferred column directions), so the branch census separates "the preferred direction alone" from "the direction cascade".
Definition at line 575 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), and heightPass().
Tier 2b, and it ships OFF — a measured decision, see the WO-O findings entry.
The mixed height function (a paraboloid through the interface positions of whichever columns closed, PtFit) is implemented and correct, and on the exact-fraction sphere it takes over exactly the 19.5-59.6 % of interfacial cells that tier 1 cannot serve. Measured on that sphere at 16/32/64 with everything else identical:
tier 2b ON L1 2.83e-2 / 7.27e-3 / 4.21e-3 max 6.08e-2 / 4.64e-2 / 6.07e-2 tier 2b OFF L1 3.03e-2 / 5.94e-3 / 1.32e-3 max 5.01e-2 / 1.32e-2 / 3.79e-3 order L1 1.37 vs 2.26 max 0.00 vs 1.86
i.e. it destroys the convergence of the MAX error, on the very cells the PV fallback handles at second order. The mechanism is structural, not a parameter choice (four Wendland widths from 1.5 to 6.0 cells were swept; none converges in the max): its data set is the columns the height function could close, which is a slope-SELECTED subset. At a cell whose normal sits near an octant diagonal the corner columns on the steep side are exactly the ones that fail, so the surviving points sample the interface asymmetrically about the target and the quadratic fit acquires a lever-arm bias. That selection depends on the normal direction and not on h, so the bias is scale invariant — which is precisely the flat max-error curve above. The PV fallback is immune because a PLIC polygon exists in every mixed cell whatever the slope, so its 5^3 data set is symmetric.
Turning it on is therefore a measurement, not a configuration. Kept because it is the WO's specified tier 2 and because the mechanism above is worth being able to re-measure.
Definition at line 600 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), heightPass(), peclet::flow::Solver< Grid >::setVofCurvatureMixedHeightFit(), and peclet::flow::Solver< Grid >::vofCurvatureMixedHeightFit().
| double peclet::flow::vof::VofCurvature::kappaMax = 0.0 |
Curvature admissibility clip (doc/vof_overlap_design.md §5.1, §11): after the cascade, every inner cell carrying a curvature (csfKappaDefined) gets |kappa| <= kappaMax, in INDEX units (1/hRef).
0 (the class DEFAULT) is off – the single-field cascade never clips (§11: there it would bound LEGITIMATE curvature: under-resolved droplets, contact-line cells). The block container's prototype sets it ON. Negative means 1 / metric.minH(), which is 1 when hRef = min h: |kappa| <= 1/Delta is a sphere of R >= 2 Delta, the smallest the 7-cell height function can see at all, and it bounds every CSF face force by sigma |dC| / Delta^2 – the scale the Brackbill capillary step is built to hold. The value is written only where it CHANGES, so an unclipped field is bit-identical.
Why it exists: an interfacial cell of a marker with no body of that marker near it (DEBRIS, left where two markers overlapped) has no pure end in any height-function column, and the PLIC-volumetric fit is then made from a handful of corner-sliver polygons of total area ~0. The paraboloid through them is arbitrary: measured |kappa| = 273 and 428 per cell against a true 0.4 on channel_18, face forces 3-100x the physical ones, a one-step velocity blow-up.
Definition at line 617 of file curvature_field.hpp.
Referenced by copyTunablesFrom(), kappaClipValue(), and peclet::flow::vof::VofBlockSet::setKappaMax().
|
staticconstexpr |
Jobs per launch of fallbackBatch (the table rides in the kernel's functor by value).
Definition at line 704 of file curvature_field.hpp.
Referenced by fallbackBatch().