OpenSWMM Engine  6.0.0-alpha.1
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.1)
Loading...
Searching...
No Matches
openswmm::twoD Namespace Reference

Classes

struct  BoundaryData
 SoA storage for per-edge boundary conditions. More...
 
struct  CouplingPoint
 Descriptor for a single coupling point between 2D and 1D. More...
 
struct  MeshData
 SoA storage for 2D triangular mesh geometry and topology. More...
 
struct  SolverOptions2D
 Configuration for the 2D surface routing CVODE solver. More...
 
class  SurfaceRouter2D
 Top-level orchestrator for the 2D surface routing module. More...
 
struct  SurfaceStateData
 SoA storage for 2D surface routing state variables. More...
 

Enumerations

enum class  BoundaryType : int8_t {
  WALL = 0 ,
  NORMAL_FLOW = 1 ,
  SPECIFIED_STAGE = 2 ,
  SPECIFIED_FLOW = 3 ,
  RATING_CURVE = 4
}
 Boundary condition types for 2D mesh edges. More...
 
enum class  LinearSolverType : int8_t {
  GMRES = 0 ,
  BICGSTAB = 1 ,
  TFQMR = 2
}
 Krylov linear solver selector for the BDF + Newton + Krylov stack. More...
 
enum class  PreconditionerType : int8_t {
  NONE = 0 ,
  JACOBI = 1 ,
  ILU = 2
}
 Preconditioner selector for the Krylov inner solver. More...
 

Functions

std::vector< CouplingPointbuildCouplingPoints (const MeshData &mesh, const SimulationContext &ctx)
 Build the list of coupling points from mesh coupling maps.
 
void computeCouplingExchange (const std::vector< CouplingPoint > &cps, const MeshData &mesh, SurfaceStateData &state, SimulationContext &ctx, const SolverOptions2D &opts, double dt)
 Compute exchange flows at all coupling points and inject into forcing API.
 
void updateOutfallBoundaries (const std::vector< CouplingPoint > &cps, const MeshData &mesh, const SurfaceStateData &state, SimulationContext &ctx)
 Update outfall boundary depths from 2D surface heads.
 
void transferOutfallDischarges (const std::vector< CouplingPoint > &cps, const MeshData &mesh, SurfaceStateData &state, const SimulationContext &ctx, double dt)
 Transfer outfall discharges into 2D coupling cells.
 
std::string parse2DOptionsLine (const std::vector< std::string > &tokens, SolverOptions2D &opts)
 Parse a single line from the [2D_OPTIONS] section.
 
std::string parse2DVertexLine (const std::vector< std::string > &tokens, MeshData &mesh)
 Parse a single line from the [2D_VERTICES] section.
 
std::string parse2DTriangleLine (const std::vector< std::string > &tokens, MeshData &mesh)
 Parse a single line from the [2D_TRIANGLES] section.
 
std::string parse2DVertexNodeMapLine (const std::vector< std::string > &tokens, MeshData &mesh)
 Parse a single line from the [2D_VERTEX_NODE_MAP] section.
 
std::string parse2DTriangleNodeMapLine (const std::vector< std::string > &tokens, MeshData &mesh)
 Parse a single line from the [2D_TRIANGLE_NODE_MAP] section.
 
std::string parse2DBoundaryConditionsLine (const std::vector< std::string > &tokens, std::vector< SurfaceRouter2D::PendingBoundaryRow > &pending_rows)
 V-E3 — parse a single line from the [2D_BOUNDARY_CONDITIONS] section into a SurfaceRouter2D::PendingBoundaryRow appended to pending_rows.
 
void register2DSections (MeshData &mesh, SolverOptions2D &options, std::vector< SurfaceRouter2D::PendingBoundaryRow > &pending_bc_rows, input::SectionRegistry &registry)
 Register all 2D input section handlers with the section registry.
 
std::string load2DMeshExternalFile (MeshData &mesh, SolverOptions2D &opts, std::vector< SurfaceRouter2D::PendingBoundaryRow > &pending_bc_rows, const std::string &mesh_file, const std::string &inp_base_dir)
 Load 2D mesh sections from an external file.
 
void buildMeshTopology (MeshData &mesh)
 Build mesh topology and precompute geometry from raw vertex/triangle data.
 
std::string validateMesh (const MeshData &mesh)
 Validate mesh data for consistency.
 
void recomputeVertexZDependents (MeshData &mesh, int vidx)
 Recompute Z-derived per-triangle / per-edge geometry for triangles incident to a vertex whose Z just changed.
 
void buildVertexStencils (MeshData &mesh)
 Build pseudo-Laplacian reconstruction stencils for all vertices.
 
void reconstructVertexHeads (const MeshData &mesh, SurfaceStateData &state)
 Reconstruct head values at vertices from cell-centred heads.
 
void computeUnlimitedGradients (const MeshData &mesh, SurfaceStateData &state)
 Compute unlimited gradients for all triangles via Green-Gauss theorem.
 
void computeLimitedGradients (const MeshData &mesh, SurfaceStateData &state, double epsilon)
 Apply Jawahar-Kamath slope limiter (Eq. [23]–[24]).
 
void computeEdgeFluxes (const MeshData &mesh, SurfaceStateData &state, const SolverOptions2D &opts)
 Compute edge fluxes for all triangles.
 
void assembleRHS (const MeshData &mesh, const SurfaceStateData &state, double *ydot)
 Assemble the RHS of the ODE system: dψ/dt for each triangle.
 

Enumeration Type Documentation

◆ BoundaryType

enum class openswmm::twoD::BoundaryType : int8_t
strong

Boundary condition types for 2D mesh edges.

SPECIFIED_FLOW (3) and RATING_CURVE (4) added per GUI plan §V V-E4 / V-E5. Storage + C API only at this revision — the FV-SWE flux integration for non-Wall BCs is deferred to a follow-up slice (V-E-FLUX). Today the solver treats every boundary edge as Wall regardless of type (see SurfaceFluxCalculator::computeEdgeFluxes line 131).

Enumerator
WALL 

Zero-flux wall (default)

NORMAL_FLOW 

Manning outflow using bed slope.

SPECIFIED_STAGE 

Prescribed water surface elevation (constant or TS)

SPECIFIED_FLOW 

Prescribed discharge per metre of edge (constant or TS)

RATING_CURVE 

Stage → flow lookup (curve registry index)

◆ LinearSolverType

enum class openswmm::twoD::LinearSolverType : int8_t
strong

Krylov linear solver selector for the BDF + Newton + Krylov stack.

Phase 1 wires GMRES only; BICGSTAB and TFQMR are kept as enum values to preserve the input-file parsing surface and to mark slots reserved for possible Phase 2 work, but selecting them today triggers a clear runtime error in CvodeSurfaceSolver::initialize().

GMRES is the canonical choice for the elliptic-flavoured diffusive-wave Jacobian and pairs cleanly with multigrid preconditioners (the Phase 2 BoomerAMG path); the other two Krylov methods would only earn their keep for problem classes we do not currently solve.

Enumerator
GMRES 

Phase 1: WIRED (SUNLinSol_SPGMR).

BICGSTAB 

Reserved; rejected at initialize() in Phase 1.

TFQMR 

Reserved; rejected at initialize() in Phase 1.

◆ PreconditionerType

enum class openswmm::twoD::PreconditionerType : int8_t
strong

Preconditioner selector for the Krylov inner solver.

Phase 1 wires NONE (no preconditioning) and JACOBI (per-cell diagonal approximation rebuilt each Jacobian refresh). ILU and AMG are reserved for the Phase 2 hypre/BoomerAMG integration; selecting them today triggers a clear runtime error in CvodeSurfaceSolver::initialize().

Tier rationale (see also the Phase 1/2 discussion in docs/2D_KNOWN_STIFFNESS_ISSUE.md):

  • NONE : baseline; useful for measuring how much the Jacobi heuristic actually buys at a given mesh size.
  • JACOBI : O(n) setup, O(n) apply, embarrassingly parallel. Effective while the Newton matrix M = I − γJ is diagonally dominant; expected to scale acceptably to ~10k–50k cells.
  • ILU : O(nnz) setup + apply via KLU. Better convergence per Krylov iteration than JACOBI but still asymptotically non-scalable on this elliptic operator. Not implemented.
  • AMG : O(n) setup amortised, near-constant Krylov iterations regardless of mesh size. The only scalable option past ~100k cells. Requires hypre/BoomerAMG. Not yet wired.
Enumerator
NONE 

Phase 1: WIRED (no preconditioning).

JACOBI 

Phase 1: WIRED (diagonal heuristic).

ILU 

Reserved; rejected at initialize() in Phase 1.

Function Documentation

◆ assembleRHS()

void openswmm::twoD::assembleRHS ( const MeshData mesh,
const SurfaceStateData state,
double *  ydot 
)

Assemble the RHS of the ODE system: dψ/dt for each triangle.

Combines edge fluxes, rainfall, and coupling fluxes into the net rate of change of depth for each cell: dψ_i/dt = (1/A_i) Σ_j F_j + rainfall_i + coupling_flux_i

Parameters
meshMesh geometry.
stateSurface state.
ydotOutput: dψ/dt for each triangle (size = n_triangles).
Here is the call graph for this function:

◆ buildCouplingPoints()

std::vector< CouplingPoint > openswmm::twoD::buildCouplingPoints ( const MeshData mesh,
const SimulationContext ctx 
)

Build the list of coupling points from mesh coupling maps.

Resolves vertex/triangle → node mappings into CouplingPoint descriptors. Must be called after node names are resolved to indices.

Parameters
meshMesh data with coupling maps populated.
ctxSimulation context (for node type and outfall queries).
Returns
Vector of coupling points.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildMeshTopology()

void openswmm::twoD::buildMeshTopology ( MeshData mesh)

Build mesh topology and precompute geometry from raw vertex/triangle data.

Must be called after parsing is complete and before solver initialization. Populates: tri_nbr*, tri_area, tri_c*, edge_length, edge_n*, edge_m*.

Parameters
meshThe mesh data with vx/vy/vz and tri_v0/v1/v2 already populated.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildVertexStencils()

void openswmm::twoD::buildVertexStencils ( MeshData mesh)

Build pseudo-Laplacian reconstruction stencils for all vertices.

For each vertex, collects all triangles sharing that vertex, computes moments (I_xx, I_yy, I_xy, R_x, R_y), Lagrange multipliers (λ_x, λ_y), and weights. Stores results in mesh.vert_stencil_ptr/idx/wt (CSR format).

Parameters
meshThe mesh (must have topology already built).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ computeCouplingExchange()

void openswmm::twoD::computeCouplingExchange ( const std::vector< CouplingPoint > &  cps,
const MeshData mesh,
SurfaceStateData state,
SimulationContext ctx,
const SolverOptions2D opts,
double  dt 
)

Compute exchange flows at all coupling points and inject into forcing API.

For each coupling point:

  1. Computes head difference Δh = h_2d - h_swmm
  2. Applies orifice equation: Q = Cd * A * sign(Δh) * sqrt(2g|Δh|)
  3. Handles outfall boundary feedback and flap gates
  4. Suppresses ponding at coupled nodes
  5. Injects Q into forcing API as lateral inflow (ADD, RESET)
  6. Records coupling flux back into 2D state
Parameters
cpsCoupling points.
meshMesh data.
state2D surface state.
ctxSimulation context (node heads, forcing API, mass balance).
opts2D solver options (uses dry_depth as the wet/dry threshold).
dtCurrent SWMM routing timestep (s).
Here is the caller graph for this function:

◆ computeEdgeFluxes()

void openswmm::twoD::computeEdgeFluxes ( const MeshData mesh,
SurfaceStateData state,
const SolverOptions2D opts 
)

Compute edge fluxes for all triangles.

For each edge, reconstructs head at the edge from the upstream cell using the limited gradient, computes diffusive conductance, and evaluates the normal flux. Boundary edges use zero-flux (wall) condition.

Parameters
meshMesh geometry.
stateSurface state (reads depth, head, limited gradients; writes edge_flux).
optsSolver options (dry_depth).
Here is the call graph for this function:

◆ computeLimitedGradients()

void openswmm::twoD::computeLimitedGradients ( const MeshData mesh,
SurfaceStateData state,
double  epsilon 
)

Apply Jawahar-Kamath slope limiter (Eq. [23]–[24]).

Computes continuously differentiable limited gradients from the unlimited gradients of a cell and its neighbours.

Parameters
meshMesh geometry (for neighbour lookup).
stateSurface state (reads grad_hx/hy, writes grad_hx_lim/hy_lim).
epsilonLimiter epsilon (small positive, typically 1e-6).
Here is the call graph for this function:

◆ computeUnlimitedGradients()

void openswmm::twoD::computeUnlimitedGradients ( const MeshData mesh,
SurfaceStateData state 
)

Compute unlimited gradients for all triangles via Green-Gauss theorem.

For each triangle, the gradient is the area-weighted average of edge contributions: ∇h_i = (1/A_i) Σ_j h_edge_j * n_j * ξ_j

Parameters
meshMesh geometry.
stateSurface state (reads head[], writes grad_hx[], grad_hy[]).
Here is the call graph for this function:

◆ load2DMeshExternalFile()

std::string openswmm::twoD::load2DMeshExternalFile ( MeshData mesh,
SolverOptions2D opts,
std::vector< SurfaceRouter2D::PendingBoundaryRow > &  pending_bc_rows,
const std::string &  mesh_file,
const std::string &  inp_base_dir 
)

Load 2D mesh sections from an external file.

Opens the file referenced by mesh_file (resolved relative to inp_base_dir if it is a relative path) and parses any [2D_OPTIONS], [2D_VERTICES], [2D_TRIANGLES], [2D_VERTEX_NODE_MAP], and [2D_TRIANGLE_NODE_MAP] sections found in it.

Parameters
meshMesh data to populate.
optsSolver options to populate.
mesh_filePath from the [2D_MESH_FILE] FILE token.
inp_base_dirDirectory of the parent .inp file (may be empty).
Returns
Empty string on success, or an error description on failure.
Here is the call graph for this function:

◆ parse2DBoundaryConditionsLine()

std::string openswmm::twoD::parse2DBoundaryConditionsLine ( const std::vector< std::string > &  tokens,
std::vector< SurfaceRouter2D::PendingBoundaryRow > &  pending_rows 
)

V-E3 — parse a single line from the [2D_BOUNDARY_CONDITIONS] section into a SurfaceRouter2D::PendingBoundaryRow appended to pending_rows.

Format: TRI EDGE TYPE [PARAM_1 [PARAM_2 [GROUP]]] TYPE ∈ WALL / NORMAL_FLOW / SPECIFIED_STAGE / TS_STAGE / SPECIFIED_FLOW / TS_FLOW / RATING_CURVE PARAM_1 = slope / head / TS name / flow / TS name / curve name (by type) PARAM_2 reserved, always "*" GROUP optional named group ("*" = none)

Rows are drained into BoundaryData inside SurfaceRouter2D::initialize() after boundary_.resize() has sized the per-edge slots.

Here is the caller graph for this function:

◆ parse2DOptionsLine()

std::string openswmm::twoD::parse2DOptionsLine ( const std::vector< std::string > &  tokens,
SolverOptions2D opts 
)

Parse a single line from the [2D_OPTIONS] section.

Parameters
tokensWhitespace-split tokens from the line.
optsOutput solver options to populate.
Returns
Empty string on success, or error description.
Here is the caller graph for this function:

◆ parse2DTriangleLine()

std::string openswmm::twoD::parse2DTriangleLine ( const std::vector< std::string > &  tokens,
MeshData mesh 
)

Parse a single line from the [2D_TRIANGLES] section.

Format: V1 V2 V3 MANNINGS_N [TAG]

Parameters
tokensWhitespace-split tokens from the line.
meshMesh data to append triangle to.
Returns
Empty string on success, or error description.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse2DTriangleNodeMapLine()

std::string openswmm::twoD::parse2DTriangleNodeMapLine ( const std::vector< std::string > &  tokens,
MeshData mesh 
)

Parse a single line from the [2D_TRIANGLE_NODE_MAP] section.

Format: TRIANGLE_INDEX_OR_TAG SWMM_NODE_NAME [CD] [AREA]

Parameters
tokensWhitespace-split tokens from the line.
meshMesh data to update coupling map.
Returns
Empty string on success, or error description.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse2DVertexLine()

std::string openswmm::twoD::parse2DVertexLine ( const std::vector< std::string > &  tokens,
MeshData mesh 
)

Parse a single line from the [2D_VERTICES] section.

Format: X Y Z [TAG]

Parameters
tokensWhitespace-split tokens from the line.
meshMesh data to append vertex to.
Returns
Empty string on success, or error description.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse2DVertexNodeMapLine()

std::string openswmm::twoD::parse2DVertexNodeMapLine ( const std::vector< std::string > &  tokens,
MeshData mesh 
)

Parse a single line from the [2D_VERTEX_NODE_MAP] section.

Format: VERTEX_INDEX_OR_TAG SWMM_NODE_NAME [CD] [AREA]

Parameters
tokensWhitespace-split tokens from the line.
meshMesh data to update coupling map.
Returns
Empty string on success, or error description.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ recomputeVertexZDependents()

void openswmm::twoD::recomputeVertexZDependents ( MeshData mesh,
int  vidx 
)

Recompute Z-derived per-triangle / per-edge geometry for triangles incident to a vertex whose Z just changed.

Updates tri_cz (centroid Z = mean of vertex Zs) and edge_mz (per-edge midpoint Z) for every triangle that references vertex vidx. XY-derived fields (tri_area, tri_cx, tri_cy, edge_length, edge_nx, edge_ny, edge_mx, edge_my) are not affected.

Used by swmm_2d_set_vertex_z and exposed here so tests can verify the recompute logic without spinning up a full engine.

Parameters
meshThe mesh; mesh.vz[vidx] is assumed to already hold the new Z.
vidxIndex of the vertex whose Z just changed.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconstructVertexHeads()

void openswmm::twoD::reconstructVertexHeads ( const MeshData mesh,
SurfaceStateData state 
)

Reconstruct head values at vertices from cell-centred heads.

Evaluates: h_vertex[b] = Σ_i ω_i * h_cell[stencil_idx[i]] Uses the CSR stencil built by buildVertexStencils().

Parameters
meshThe mesh (with stencils built).
stateSurface state (reads head[], writes vert_head[]).
Here is the call graph for this function:

◆ register2DSections()

void openswmm::twoD::register2DSections ( MeshData mesh,
SolverOptions2D options,
std::vector< SurfaceRouter2D::PendingBoundaryRow > &  pending_bc_rows,
input::SectionRegistry registry 
)

Register all 2D input section handlers with the section registry.

Call during input reader setup (conditional on OPENSWMM_HAS_2D). The handlers will populate the mesh and options data in SimulationContext.

Parameters
meshMesh data to populate.
optionsSolver options to populate.
registrySection registry to register handlers into.
Here is the call graph for this function:

◆ transferOutfallDischarges()

void openswmm::twoD::transferOutfallDischarges ( const std::vector< CouplingPoint > &  cps,
const MeshData mesh,
SurfaceStateData state,
const SimulationContext ctx,
double  dt 
)

Transfer outfall discharges into 2D coupling cells.

After 1D routing, the outfall discharge is a source for the 2D cell at the outfall coupling point.

Parameters
cpsCoupling points.
meshMesh data.
state2D surface state.
ctxSimulation context.
dtRouting timestep (s).
Here is the caller graph for this function:

◆ updateOutfallBoundaries()

void openswmm::twoD::updateOutfallBoundaries ( const std::vector< CouplingPoint > &  cps,
const MeshData mesh,
const SurfaceStateData state,
SimulationContext ctx 
)

Update outfall boundary depths from 2D surface heads.

For each outfall coupled to the 2D domain, sets the outfall depth to max(h_standard, h_2d) to account for dynamic tailwater from 2D flooding. Must be called before 1D routing step.

Parameters
cpsCoupling points.
meshMesh data.
state2D surface state.
ctxSimulation context.
Here is the caller graph for this function:

◆ validateMesh()

std::string openswmm::twoD::validateMesh ( const MeshData mesh)

Validate mesh data for consistency.

Checks: vertex indices in bounds, positive areas, no degenerate triangles.

Parameters
meshThe mesh to validate.
Returns
Empty string if valid, or a description of the first error found.
Here is the call graph for this function:
Here is the caller graph for this function: