![]() |
OpenSWMM Engine
6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
|
Bit-exact geometry-table interpolation — the single source of truth. More...
Go to the source code of this file.
Classes | |
| struct | openswmm::xsect::LocateLut |
Namespaces | |
| namespace | openswmm |
| namespace | openswmm::xsect |
Functions | |
| double | openswmm::xsect::lookup_exact (double x, const double *t, int n) noexcept |
| Bit-exact transliteration of legacy xsect.c:lookup(). | |
| double | openswmm::xsect::lookup_fast (double x, const double *t, int n) noexcept |
| Reciprocal-multiply lookup (fast, NOT bit-exact — see §6). | |
| double | openswmm::xsect::norm_x (double depth, double param) noexcept |
| double | openswmm::xsect::norm_lookup (double depth, double param, const double *t, int n) noexcept |
| Mode-aware normalize + table lookup (bit-exact by default; §6 fast if opted in). | |
| int | openswmm::xsect::lut_bucket (const LocateLut &L, double y) noexcept |
| Bucket index for a value — the ONE expression used by both build and query. | |
| int | openswmm::xsect::locate_bisect (double y, const double *table, int jLast) noexcept |
| void | openswmm::xsect::build_locate_lut (LocateLut &L, const double *table, int jLast) noexcept |
| int | openswmm::xsect::locate_lut (double y, const double *table, int jLast, const LocateLut &L) noexcept |
LUT-accelerated locate() — returns the identical index for every input. | |
| int | openswmm::xsect::locate_maybe_lut (double y, const double *table, int jLast, const LocateLut *L) noexcept |
| Dispatch: use the map when one was built for this exact table extent. | |
| void | openswmm::xsect::build_invlookup_lut (LocateLut &L, const double *table, int n_items) noexcept |
Bit-exact geometry-table interpolation — the single source of truth.
lookup_exact() is an op-for-op transliteration of legacy src/legacy/engine/xsect.c:lookup(). It is shared by BOTH the per-element accessor (xsect::lookup) and the batch geometry kernels (XSectBatch.cpp) so the two paths can never drift. The circular / force-main hot path and every shared-table shape (egg, horseshoe, arch, ellipse, baskethandle, …) interpolate through this one routine.
Bit-exactness contract (see docs/plans/xsect_bitexact_vectorization.md):
x / delta), never a precomputed reciprocal (x * inv_delta): a*(1/b) != a/b in double.mul+add and silently diverges NEON from x86). The global -ffp-contract=off / /fp:precise presets stop the compiler from contracting; do not reintroduce std::fma/intrinsic FMA in callers. IEEE division is correctly rounded and identical on every platform, so this routine is bit-identical on Windows/MSVC, Linux, and macOS(arm64/x86).Preconditions (mirror legacy, whose callers guarantee them): x must be finite and in [0, 1] on entry (values > 1 are tolerated via the i >= n-1 early-out, matching legacy). static_cast<int> of a non-finite double is undefined behavior, so callers that can produce non-finite / negative x — e.g. a conduit normalized by a zero full-depth — MUST guard before calling (see xsect::lookup and the batch kernels).