![]() |
OpenSWMM Engine
6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
|
The two-zone groundwater kernel (G-steps 3, 6-12, 14, 16). More...
#include "SubsurfaceSolver.hpp"#include "../data/MeshData.hpp"#include "../data/SolverOptions2D.hpp"#include "../data/SurfaceStateData.hpp"#include "../solver/InertialEdges.hpp"#include "../../data/NodeData.hpp"#include <algorithm>#include <cmath>#include <cstdio>Namespaces | |
| namespace | openswmm |
| namespace | openswmm::twoD |
The two-zone groundwater kernel (G-steps 3, 6-12, 14, 16).
Write total water per unit area as W = θ_s·h_g + S_col, with S_col the unsaturated column's storage. Each closure gives the same shape:
| closure | S_col | saturated equation |
|---|---|---|
| CLOSED_FORM | hᵤ, its own ODE | θ_s·ḣ_g = q₀ + lat/A − deep − node/A |
| SIGMA | Σ θ_j·L·Δσ | (θ_s − θ_bot)·ḣ_g = q₀_phys + … |
| ENSLAVED | hᵤ*(L), algebraic | (θ_s − θ(ψ=L))·ḣ_g = q⁺ + … |
The SIGMA row is the one the plan text writes with θ_s. It is wrong by exactly the handover: the column's bottom flux is f_bot = q₀_phys − θ_bot·L̇, and L̇ = −ḣ_g, so θ_s·ḣ_g = f_bot rearranges to (θ_s − θ_bot)·ḣ_g = q₀_phys. Same equation, but only the second form can be written down without also tracking f_bot, and only the second form conserves once the column retains water above a falling table.
ENSLAVED falls out of the same algebra: S_col = hᵤ*(L) gives Ṡ_col = d(hᵤ*)/dL · L̇ = −θ(ψ=L)·ḣ_g, since d(hᵤ*)/dL = θ(L) by the fundamental theorem. So the enslaved column contributes its top water content as a storage debit — no lag, no separate state, and q⁺ drives the table directly. This is the reduction plan step 14 asks for, and it is one line of code rather than a separate branch of physics.
fireCell runs: q₀ → saturated update → clamp → column sweep at the CLAMPED L̇ → apply the column's overflow/deficit → Dunne. Deriving L̇ from the clamped h_g is what makes the clamp harmless: the column and the saturated zone always agree on how far the table actually moved, so no water is created at h_g = z_s or destroyed at h_g = 0.