|
pnm 1.0.3
peclet.pnm — pore-network extraction from SDF geometry (Kokkos)
|
Classes | |
| struct | FlatFaces |
| Per-face field accessors for the film-attachment sweep: label / pair key of face (cell e, d). More... | |
| struct | SplitFaces |
| struct | ThroatSlots |
| Global unique (patch root, pair key) list -> the throat list ordered by (pair, root fid), the sorted root keys and the (key position -> throat slot) map for the device lookup. More... | |
Typedefs | |
| using | MD3 = Kokkos::MDRangePolicy< Exec, Kokkos::Rank< 3 > > |
| using | R1 = Kokkos::RangePolicy< Exec > |
Functions | |
| template<class Geo > | |
| MD3 | ownedRange (const Exec &space, const Geo &geo) |
| The owned box of a geometry as an MDRange policy. | |
| template<class Geo , class SdfView > | |
| bool | isPeak (const Geo &g, const SdfView &sdf, int lx, int ly, int lz, float cv, Index cgid) |
| Local SDF maximum under the global (sdf, gid) lexicographic order (26-neighbourhood). | |
| template<class Geo , class SdfView > | |
| Pore | poreAt (const Geo &g, const SdfView &sdf, int lx, int ly, int lz, float ox, float oy, float oz, float sx, float sy, float sz) |
| The pore record at a peak: sub-voxel position by the SDF^2-weighted centroid of the 3^3 neighbourhood (positive part only), in global (wrapped) integer coords, radius = sdf there. | |
| template<class Geo , class SdfView > | |
| Index | steepest (const Geo &g, const SdfView &sdf, int lx, int ly, int lz, Index cgid, bool ascent) |
Steepest 26-neighbour under the (sdf, gid) lexicographic order: ascent (pores) or descent (solids); returns the neighbour's gid, or cgid itself at a peak. | |
| template<class Geo , class FieldView > | |
| double | trilinear (const Geo &g, const FieldView &p, const double gp[3]) |
| Trilinear interpolation of a cell-centered periodic field at grid position gp (in cells). | |
| bool | facesAdjacent (int dx, int dy, int dz, int d, int d2) |
| Face adjacency of the per-patch throat CCL: two faces (cell offset (dx,dy,dz), directions d and d2) connect when their doubled center offset satisfies |2*dc + e_d2 - e_d|^2 <= 8 — a generous edge/corner adjacency in pure integer arithmetic (periodic-safe, decomposition- independent). | |
| template<class KeyView > | |
| Index | bsearchKey (const KeyView &keys, Index nkeys, typename KeyView::non_const_value_type key) |
| Device binary search over a sorted key view; returns the position or -1. | |
| template<class Geo , class SdfView , class PoreView , class CountView > | |
| void | detectPores (const Exec &space, const Geo &geo, const SdfView &sdf, std::array< float, 3 > origin, std::array< float, 3 > spacing, const PoreView &pores, const CountView &counter, int maxPores) |
Emit the owned peaks (local SDF maxima, sdf > 0) as Pore records into pores (atomic slot counter counter, capacity maxPores). | |
| template<class Geo , class SdfView , class ParentView > | |
| void | initMarkers (const Exec &space, const Geo &geo, const SdfView &sdf, float thr, const ParentView &parent) |
| Deep-solid markers: parent(o) = o where sdf < thr, else -1 (owned-dense). | |
| template<class ParentView > | |
| void | cclFlatten (const Exec &space, const ParentView &parent, std::size_t n) |
| Path compression: every labelled entry points at its root. | |
| template<class Geo , class ParentView , class FlagView > | |
| void | cclMergeMarkers (const Exec &space, const Geo &geo, const ParentView &parent, const FlagView &changed) |
| One union sweep of the marker CCL (26-connectivity, 13 forward neighbours, union-by-min via atomic_min on the larger root). | |
| template<class ParentView , class FlagView , class MergeFn > | |
| void | cclFixpoint (const Exec &space, const ParentView &parent, std::size_t n, const FlagView &changed, const MergeFn &merge) |
Union-find to fixpoint: merge() launches one union sweep (setting changed), then a flatten; repeat until a sweep changes nothing. | |
| template<class Geo , class SdfView , class LabelView , class FlagView > | |
| void | floodSweep (const Exec &space, const Geo &geo, const SdfView &sdf, const LabelView &labels, const LabelView &labelsN, const FlagView &changed) |
One Jacobi flood sweep: every unlabelled solid voxel takes the smallest labelled 26-neighbour (reads labels, writes labelsN; the caller swaps). | |
| template<class Geo , class SdfView , class LabelView , class FlagView , class SyncFn > | |
| void | floodFixpoint (const Exec &space, const Geo &geo, const SdfView &sdf, LabelView &labels, LabelView &labelsN, const FlagView &changed, const SyncFn &sync) |
| Jacobi flood to fixpoint. | |
| template<class SdfView , class EmitFn > | |
| void | gradientWalk (const Exec &space, const GridGeo &geo, const SdfView &sdf, bool ascentAll, const EmitFn &emit) |
Single-rank gradient walk: from every owned cell follow the steepest neighbour (ascent for pores, descent for solids; ascentAll = ascent from every cell, the flow-basin variant) for at most 512 steps; emit(o, walker) receives the end point (a gid == field index here). | |
| template<class Geo , class SdfView , class TargetView , class ChaseFn , class FinalFn , class PeakFn > | |
| void | forestInit (const Exec &space, const Geo &geo, const SdfView &sdf, const TargetView &target, const ChaseFn &chase, const FinalFn &finalOf, const PeakFn &peakOf) |
| Steepest-neighbour forest for the hold-at-ghost root resolution. | |
| template<class Geo , class TargetView > | |
| int | resolveHoldAtGhost (const Exec &space, const Geo &geo, const TargetView &target) |
| One round of pointer jumping with the hold-at-ghost invariant: chase within the field, adopt a finalized (negative) value, or HOLD at the last in-field cell when the next hop leaves the field (never store a gid the field cannot reach — that strands the chase outside the ghost ring). | |
| template<class Geo , class SegView , class PairView , class CountView > | |
| void | boundaryPairs (const Exec &space, const Geo &geo, const SegView &seg, const PairView &pairs, const CountView &cnt, Index maxPairs) |
Boundary pairs: for every owned cell, the (min,max) label pairs across its +x/+y/+z faces where the label changes, appended to the interleaved pairs (atomic cnt, capacity maxPairs). | |
| template<class PairView > | |
| std::vector< std::pair< int, int > > | uniquePairs (const PairView &pairs, std::size_t count) |
| Interleaved device pairs -> host (l1,l2) list, sorted and unique. | |
| template<class Geo , class SegView > | |
| int | maxLabel (const Exec &space, const Geo &geo, const SegView &seg) |
| The largest label over the owned box (= the number of pore labels). | |
| template<class Geo , class LabView , class SdfView , class OpenView , class CoreView , class ParentView , class PairView > | |
| void | faceInit (const Exec &space, const Geo &geo, const LabView &flowLab, const SdfView &sdf, const OpenView &ox, const OpenView &oy, const OpenView &oz, bool hasOpen, const CoreView &core, const ParentView &parent, const PairView &fpair) |
| Interface predicate + CORE tier per owned face: an interface face separates two different positive flow-basin labels with positive openness; CORE = both cells fluid-centered (sdf > 0), which defines the patches by CCL; the rest are FILM faces that attach later. | |
| template<class Geo , class ParentView , class PairView , class FlagView > | |
| void | faceMerge (const Exec &space, const Geo &geo, const ParentView &parent, const PairView &fpair, const FlagView &changed) |
| One union sweep of the face CCL over the faces with parent >= 0 (same pair key + adjacency; owned-owned adjacency only, see cclMergeMarkers). | |
| template<class Geo , class ParentView , class MinView > | |
| void | faceMinGid (const Exec &space, const Geo &geo, const ParentView &parent, const MinView &mg) |
| Per-component minimum GLOBAL face id (3*gid+d) of the local face CCL, keyed by the component root: the decomposition-independent patch label. | |
| template<class ParentView , class PairView , class LabView , class RootFn > | |
| void | faceLabelCore (const Exec &space, std::size_t nf, const ParentView &parent, const PairView &fpair, const LabView &faceLab, const RootFn &rootOf) |
| Core-tier labels: faceLab = rootOf(parent) for the CCL'd faces, kSent for the remaining interface (film) faces, -1 for non-interface faces. | |
| template<class ParentView , class LabView , class RootFn > | |
| void | faceLabelLeftover (const Exec &space, std::size_t nf, const ParentView &parent, const LabView &faceLab, const RootFn &rootOf) |
| Leftover-tier labels: the still-kSent films (their own CCL tier) get rootOf(parent). | |
| template<class ParentView , class LabView > | |
| void | leftoverInit (const Exec &space, std::size_t nf, const LabView &faceLab, const ParentView &parent) |
| Leftover tier init: parent = f for the films no core patch reached, -1 otherwise. | |
| template<class Geo , class LabView , class PairView , class CoreView , class NbLab , class NbPair , class FlagView > | |
| void | filmAttachSweep (const Exec &space, const Geo &geo, const LabView &faceLab, const PairView &fpair, const CoreView &core, const NbLab &nbLab, const NbPair &nbPair, const FlagView &changed) |
One Jacobi min-propagation sweep of the film attachment: every film face (interface, not core) takes the minimum attached label among its adjacent same-pair faces (nbLab(e, d) / nbPair(e, d) read the neighbour faces — flat single-rank, per-direction exchanged fields on a block). | |
| ThroatSlots | throatSlots (std::vector< std::pair< Index, Index > > rootPair) |
| template<class Geo , class LabView , class FieldView , class OpenView , class FaceLabView , class KeyView , class SlotView , class AncView , class AccView > | |
| void | throatFlux (const Exec &space, const Geo &geo, const LabView &flowLab, const FieldView &u, const FieldView &v, const FieldView &w, const OpenView &ox, const OpenView &oy, const OpenView &oz, bool hasOpen, const FaceLabView &faceLab, const KeyView &keyD, const SlotView &slotD, std::size_t nt, const AncView &ancX, const AncView &ancY, const AncView &ancZ, std::array< float, 3 > origin, std::array< float, 3 > spacing, std::array< int, 3 > gdims, const AccView &Q, const AccView &A, const AccView &Cx, const AccView &Cy, const AccView &Cz, const AccView &resid) |
Accumulate over every owned +face where the flow-basin label changes: the openness-weighted MAC flux o·u·A into the per-pore residual (signed) and, for interface faces of a throat patch, into the throat's flow (positive lower -> higher label), open area and area-weighted centroid (min-imaged relative to the LOWER pore's peak-voxel anchor anc{X,Y,Z} — integer-derived, so the periodic-image branch is deterministic under FMA wobble). | |
| std::vector< double > | throatPressureDrops (const std::vector< std::pair< int, int > > &throats, const std::vector< Pore > &pores, const std::vector< double > &porePressure, const std::vector< double > &throatArea, const std::vector< double > &Cx, const std::vector< double > &Cy, const std::vector< double > &Cz, const std::vector< double > &ancX, const std::vector< double > &ancY, const std::vector< double > &ancZ, std::array< float, 3 > spacing, std::array< int, 3 > gdims, std::array< double, 3 > grad_p) |
| Total-pressure drop per throat: periodic parts + the macroscopic gradient along the throat- anchored two-leg min-image path i -> throat centroid -> j. | |
Variables | |
| constexpr Index | kSent = 0x7ffffffffffffffeLL |
| Film-face sentinel of the per-patch throat labelling: "interface face awaiting attachment". | |
| using pnm::kernels::MD3 = typedef Kokkos::MDRangePolicy<Exec, Kokkos::Rank<3> > |
Definition at line 196 of file pore_kernels.hpp.
| using pnm::kernels::R1 = typedef Kokkos::RangePolicy<Exec> |
Definition at line 197 of file pore_kernels.hpp.
The owned box of a geometry as an MDRange policy.
Definition at line 201 of file pore_kernels.hpp.
Referenced by boundaryPairs(), cclMergeMarkers(), detectPores(), faceInit(), faceMerge(), faceMinGid(), filmAttachSweep(), floodSweep(), forestInit(), initMarkers(), pnm::detail_mpi::packInner(), pnm::detail_mpi::stageInner(), and throatFlux().
| bool pnm::kernels::isPeak | ( | const Geo & | g, |
| const SdfView & | sdf, | ||
| int | lx, | ||
| int | ly, | ||
| int | lz, | ||
| float | cv, | ||
| Index | cgid | ||
| ) |
Local SDF maximum under the global (sdf, gid) lexicographic order (26-neighbourhood).
Definition at line 214 of file pore_kernels.hpp.
Referenced by detectPores().
| Pore pnm::kernels::poreAt | ( | const Geo & | g, |
| const SdfView & | sdf, | ||
| int | lx, | ||
| int | ly, | ||
| int | lz, | ||
| float | ox, | ||
| float | oy, | ||
| float | oz, | ||
| float | sx, | ||
| float | sy, | ||
| float | sz | ||
| ) |
The pore record at a peak: sub-voxel position by the SDF^2-weighted centroid of the 3^3 neighbourhood (positive part only), in global (wrapped) integer coords, radius = sdf there.
Definition at line 232 of file pore_kernels.hpp.
Referenced by detectPores().
| Index pnm::kernels::steepest | ( | const Geo & | g, |
| const SdfView & | sdf, | ||
| int | lx, | ||
| int | ly, | ||
| int | lz, | ||
| Index | cgid, | ||
| bool | ascent | ||
| ) |
Steepest 26-neighbour under the (sdf, gid) lexicographic order: ascent (pores) or descent (solids); returns the neighbour's gid, or cgid itself at a peak.
Ties on value go to the larger gid.
Definition at line 262 of file pore_kernels.hpp.
Referenced by forestInit(), and gradientWalk().
Trilinear interpolation of a cell-centered periodic field at grid position gp (in cells).
Definition at line 292 of file pore_kernels.hpp.
Face adjacency of the per-patch throat CCL: two faces (cell offset (dx,dy,dz), directions d and d2) connect when their doubled center offset satisfies |2*dc + e_d2 - e_d|^2 <= 8 — a generous edge/corner adjacency in pure integer arithmetic (periodic-safe, decomposition- independent).
Definition at line 315 of file pore_kernels.hpp.
Referenced by faceMerge(), and filmAttachSweep().
| Index pnm::kernels::bsearchKey | ( | const KeyView & | keys, |
| Index | nkeys, | ||
| typename KeyView::non_const_value_type | key | ||
| ) |
Device binary search over a sorted key view; returns the position or -1.
Definition at line 324 of file pore_kernels.hpp.
Referenced by pnm::detail_mpi::applyRemap(), and throatFlux().
|
inline |
Emit the owned peaks (local SDF maxima, sdf > 0) as Pore records into pores (atomic slot counter counter, capacity maxPores).
Definition at line 363 of file pore_kernels.hpp.
References isPeak(), ownedRange(), and poreAt().
Referenced by pnm::extractPoresView().
|
inline |
Deep-solid markers: parent(o) = o where sdf < thr, else -1 (owned-dense).
Definition at line 390 of file pore_kernels.hpp.
References ownedRange().
Referenced by pnm::segmentVolumeView().
|
inline |
Path compression: every labelled entry points at its root.
Definition at line 404 of file pore_kernels.hpp.
Referenced by cclFixpoint().
|
inline |
One union sweep of the marker CCL (26-connectivity, 13 forward neighbours, union-by-min via atomic_min on the larger root).
Owned-owned adjacency only: a periodic neighbour is owned single-rank; a block's cross-block pairs go through its boundary graph.
Definition at line 422 of file pore_kernels.hpp.
References ownedRange().
Referenced by pnm::segmentVolumeView().
|
inline |
Union-find to fixpoint: merge() launches one union sweep (setting changed), then a flatten; repeat until a sweep changes nothing.
Definition at line 461 of file pore_kernels.hpp.
References cclFlatten(), and pnm::readScalar().
Referenced by pnm::segmentVolumeView().
|
inline |
One Jacobi flood sweep: every unlabelled solid voxel takes the smallest labelled 26-neighbour (reads labels, writes labelsN; the caller swaps).
Labels are voxel ids in the field's label type.
Definition at line 476 of file pore_kernels.hpp.
References ownedRange().
Referenced by floodFixpoint().
|
inline |
Jacobi flood to fixpoint.
Double-buffered: each sweep reads only the previous sweep's labels, so the result is DETERMINISTIC (an in-place sweep could observe same-sweep writes — a device race) and sweep-for-sweep identical between the single-rank and the distributed pipeline. sync(localChanged) -> globalChanged lets a block Allreduce the flag and exchange its ghosts between sweeps (identity single-rank). labels holds the result on return (the views are swapped per sweep).
Definition at line 513 of file pore_kernels.hpp.
References floodSweep(), and pnm::readScalar().
Referenced by pnm::segmentVolumeView().
|
inline |
Single-rank gradient walk: from every owned cell follow the steepest neighbour (ascent for pores, descent for solids; ascentAll = ascent from every cell, the flow-basin variant) for at most 512 steps; emit(o, walker) receives the end point (a gid == field index here).
GridGeo only — the walk itself does not distribute (its RESULT is the forest root that forestInit + resolveHoldAtGhost compute on a block).
Definition at line 535 of file pore_kernels.hpp.
References steepest().
Referenced by pnm::segmentVolumeView().
|
inline |
Steepest-neighbour forest for the hold-at-ghost root resolution.
target(e) per owned cell: cells with chase(e) false finalize immediately as finalOf(e, gid); chasing cells store the gid of their steepest ascent neighbour, or peakOf(e, gid) when they are a peak. (Negative values are the finalized encoding; a non-negative value is a pending gid.)
Definition at line 562 of file pore_kernels.hpp.
References ownedRange(), and steepest().
|
inline |
One round of pointer jumping with the hold-at-ghost invariant: chase within the field, adopt a finalized (negative) value, or HOLD at the last in-field cell when the next hop leaves the field (never store a gid the field cannot reach — that strands the chase outside the ghost ring).
Returns the number of owned cells still pending.
Definition at line 586 of file pore_kernels.hpp.
Referenced by pnm::detail_mpi::resolveToFixpoint().
|
inline |
Boundary pairs: for every owned cell, the (min,max) label pairs across its +x/+y/+z faces where the label changes, appended to the interleaved pairs (atomic cnt, capacity maxPairs).
Definition at line 630 of file pore_kernels.hpp.
References ownedRange().
Referenced by pnm::extractTopologyView().
|
inline |
Interleaved device pairs -> host (l1,l2) list, sorted and unique.
Definition at line 654 of file pore_kernels.hpp.
References pnm::downloadN().
Referenced by pnm::extractTopologyView().
The largest label over the owned box (= the number of pore labels).
Definition at line 666 of file pore_kernels.hpp.
|
inline |
Interface predicate + CORE tier per owned face: an interface face separates two different positive flow-basin labels with positive openness; CORE = both cells fluid-centered (sdf > 0), which defines the patches by CCL; the rest are FILM faces that attach later.
Writes (owned- dense 3*o+d) core, parent (= f for core faces, -1 otherwise) and fpair ((lo<<32|hi) pair key, -1 for a non-interface face).
Definition at line 694 of file pore_kernels.hpp.
References ownedRange().
|
inline |
One union sweep of the face CCL over the faces with parent >= 0 (same pair key + adjacency; owned-owned adjacency only, see cclMergeMarkers).
Definition at line 723 of file pore_kernels.hpp.
References facesAdjacent(), and ownedRange().
|
inline |
Per-component minimum GLOBAL face id (3*gid+d) of the local face CCL, keyed by the component root: the decomposition-independent patch label.
mg must be pre-filled with a large value.
Definition at line 769 of file pore_kernels.hpp.
References ownedRange().
|
inline |
Core-tier labels: faceLab = rootOf(parent) for the CCL'd faces, kSent for the remaining interface (film) faces, -1 for non-interface faces.
rootOf(parentValue) maps a component root to its patch label (identity single-rank; the min global fid of faceMinGid on a block).
Definition at line 787 of file pore_kernels.hpp.
References kSent.
|
inline |
Leftover-tier labels: the still-kSent films (their own CCL tier) get rootOf(parent).
Definition at line 798 of file pore_kernels.hpp.
References kSent.
|
inline |
Leftover tier init: parent = f for the films no core patch reached, -1 otherwise.
Definition at line 810 of file pore_kernels.hpp.
References kSent.
|
inline |
One Jacobi min-propagation sweep of the film attachment: every film face (interface, not core) takes the minimum attached label among its adjacent same-pair faces (nbLab(e, d) / nbPair(e, d) read the neighbour faces — flat single-rank, per-direction exchanged fields on a block).
A film can never bridge two core patches: it only ever adopts, never unions.
Definition at line 825 of file pore_kernels.hpp.
References facesAdjacent(), kSent, and ownedRange().
|
inline |
Definition at line 869 of file pore_kernels.hpp.
|
inline |
Accumulate over every owned +face where the flow-basin label changes: the openness-weighted MAC flux o·u·A into the per-pore residual (signed) and, for interface faces of a throat patch, into the throat's flow (positive lower -> higher label), open area and area-weighted centroid (min-imaged relative to the LOWER pore's peak-voxel anchor anc{X,Y,Z} — integer-derived, so the periodic-image branch is deterministic under FMA wobble).
Definition at line 897 of file pore_kernels.hpp.
References bsearchKey(), and ownedRange().
|
inline |
Total-pressure drop per throat: periodic parts + the macroscopic gradient along the throat- anchored two-leg min-image path i -> throat centroid -> j.
Every position term cancels except the integer periodic image count k, decided in SNAPPED integer-cell arithmetic (peak-voxel anchors + the bias-rounded throat centroid) so float wobble can never flip the image branch. (A single min-image between the pore centers is ambiguous at exactly half the period.)
Definition at line 970 of file pore_kernels.hpp.
Film-face sentinel of the per-patch throat labelling: "interface face awaiting attachment".
Definition at line 206 of file pore_kernels.hpp.
Referenced by faceLabelCore(), faceLabelLeftover(), filmAttachSweep(), and leftoverInit().