Below is a step‐by‐step explanation of what this culvert.c file does, how the code is organized, and how it applies FHWA HEC‐5 culvert equations within SWMM5 to adjust flows under inlet‐control conditions. The goal is to show you how each part of the code works together to compute reduced flow due to culvert inlet control.
1. Purpose of the File
culvert.c
is part of EPA SWMM5 (Storm Water Management Model), specifically focusing on culvert inlet control.- It implements FHWA HEC‐5 equations to reduce flow (relative to normal conduit flow) when a pipe or box conduit is operating under inlet control (i.e., the entrance shape and headwater conditions dominate how much water can flow through it).
Key point: under certain flow conditions (especially at high heads or shallow flows at the inlet), the effective capacity of a culvert can be reduced compared to its full conveyance capacity.
2. High-Level Flow of the Code
- When SWMM’s routing engine calculates flow through a conduit, it calls
culvert_getInflow(...)
if that conduit is flagged as a culvert. culvert_getInflow(...)
checks if inlet control conditions exist by comparing the raw hydraulic flow (q0
) to a flow derived from the FHWA culvert equations.- If the FHWA culvert flow is less than the normal flow (
q0
), the code sets the flow to the lower inlet‐controlled flow, thereby “reducing” the flow to reflect inlet constraints.
3. Data Structures & Parameters
3.1 The Params
Array
static const double Params[58][5] = {
// FORM K M C Y
// ----------------------------------
{0.0, 0.0, 0.0, 0.0, 0.00},
...
{2.0, 0.500, 0.667, 0.0378, 0.71}
};
- Each row in
Params
corresponds to a culvert type (e.g., circular concrete, corrugated metal pipe, box culvert with beveled edges, etc.). - There are five columns (indexed by the enum
CulvertParam {FORM, K, M, C, Y}
):- FORM – A flag (1 or 2) that indicates which inlet equation form to use.
- K, M – Empirical coefficients for unsubmerged flow (FHWA: head‐discharge relationships).
- C, Y – Empirical coefficients for submerged flow.
When a user configures a conduit as a culvert in SWMM, a “culvert code” (1 to 57) is assigned. That code indexes into Params[]
and selects the correct (FORM, K, M, C, Y) for that culvert shape/entrance type.
3.2 The TCulvert
Struct
typedef struct
{
double yFull; // full depth
double scf; // slope correction factor
double dQdH; // derivative dQ/dH
double qc; // critical flow found in iterative solution
double kk;
double mm; // coefficients for unsubmerged flow
double ad;
double hPlus;
TXsect* xsect; // pointer to cross section geometry
} TCulvert;
yFull
is the full depth of the culvert.scf
is a slope correction factor used by some culvert equations.dQdH
is the derivative of flow wrt head (used in SWMM’s solver).qc
is an intermediate variable storing “critical flow” during an iterative solution.kk
,mm
are assigned from the table (the K, M parameters).ad
is typicallyaFull * sqrt(yFull)
, used in dimensionless transformations.hPlus
is an intermediate expression used by “Equation Form 1.”xsect
is a pointer to the SWMM cross‐section object, giving methods to find area vs. depth, etc.
4. Primary Function: culvert_getInflow(...)
double culvert_getInflow(int j, double q0, double h)
- Arguments:
j
: The link index in SWMM’s data structures.q0
: The originally computed flow for that link (conduit) before applying inlet control.h
: The “head” at the inlet (in feet above the inlet invert).
- Returns: The adjusted flow if inlet control is more restrictive than
q0
; otherwise returnsq0
.
4.1 Logic Flow in culvert_getInflow
-
Check if this link is actually a culvert:
code = culvert.xsect->culvertCode; if ( code <= 0 || code > MAX_CULVERT_CODE ) return q0;
If there’s no valid culvert code, we do nothing.
-
Initialize key variables:
culvert.yFull
,culvert.ad
, slope factorculvert.scf
, etc.- Retrieve
K
,M
,C
, andY
for this culvert fromParams[code]
.
-
Compute the water depth
y
above the culvert’s inlet invert:y = h - (Node[Link[j].node1].invertElev + Link[j].offset1);
This
y
can be bigger than the culvert’s full depth if the inlet is flooded. -
Check if flow is submerged or unsubmerged:
- The code checks a threshold
y2
for submerged flow:y2 = yFull * (16.0*C + Y - scf); if ( y >= y2 ) q = getSubmergedFlow(...);
- Else if
y
is well below full depth, do unsubmerged:y1 = 0.95 * yFull; if ( y <= y1 ) q = getUnsubmergedFlow(...); else q = getTransitionFlow(...); // if between y1 & y2
- The code checks a threshold
-
Compare the culvert-limited flow
q
with the unconstrained flowq0
:if ( q < q0 ) { Link[j].inletControl = TRUE; Link[j].dqdh = culvert.dQdH; return q; } else return q0;
- If the culvert’s inlet flow capacity
q
is smaller, SWMM sets the link to “inletControl = TRUE,” updates the derivativedqdh
, and usesq
. - Otherwise, we leave it at
q0
.
- If the culvert’s inlet flow capacity
5. Supporting Functions
5.1 getUnsubmergedFlow(...)
- Purpose: For shallow (unsubmerged) flow, compute flow using either Equation Form 1 or a simpler power law:
if (Params[code][FORM] == 1.0) q = getForm1Flow(h, culvert); else q = culvert->ad * pow( arg, 1.0/culvert->mm );
- Stores
dQdH
= derivative of Q with respect to the inlet headh
.
5.2 getSubmergedFlow(...)
- Purpose: For deeper (submerged) flow, uses the C,Y relationship:
arg = (h/yFull - Y + scf) / C; q = sqrt(arg) * culvert->ad; dQdH = 0.5 * q / arg / yFull / C;
- This is a direct application of the HEC‐5 form for submerged inlets.
5.3 getTransitionFlow(...)
- Purpose: If
h
is between an “unsubmerged” threshold (h1
) and a “submerged” threshold (h2
), it interpolates between the unsubmerged flowq1
and the submerged flowq2
:q = q1 + (q2 - q1) * (h - h1)/(h2 - h1); dQdH = (q2 - q1)/(h2 - h1);
- Provides a smooth transition between the two regimes.
5.4 getForm1Flow(...)
& form1Eqn(...)
- Form 1 is a specific FHWA equation that requires solving for a “critical depth”
yc
inside the culvert. getForm1Flow(...)
:- Sets
culvert->hPlus = h / yFull + scf
. - Calls
findroot_Ridder(...)
(a numerical root‐finding routine) to solve the Form 1 equation foryc
. - Uses the resulting “critical flow” to produce a final flow value for the unsubmerged condition.
- Sets
form1Eqn(...)
is the function that the root‐finder uses to compute the error term of the equation: where is the “hydraulic depth” at critical depth, is critical flow, etc.
6. Slope Correction Factor (scf
)
The code uses a slope correction factor, scf
, that depends on the culvert type:
switch (code)
{
case 5:
case 37:
case 46: culvert.scf = -7.0 * Conduit[k].slope; break;
default: culvert.scf = 0.5 * Conduit[k].slope;
}
- Usually it’s
0.5 * slope
. - For certain codes (e.g., “mitered inlets”), it uses
-7.0 * slope
.
This factor modifies the head parameter in the FHWA formula so that the topography slope is accounted for in the final flow estimate.
7. Putting It All Together
- Identify the culvert code from the link’s cross‐section data structure.
- Lookup (FORM, K, M, C, Y) from the
Params[]
table. - Compute if the inlet is unsubmerged or submerged, or in the transition region.
- Apply the appropriate flow equation (with possible iterative solution for Equation Form 1).
- Compare the result to the normal flow
q0
. If the culvert flow is lower, use it; otherwise remain withq0
.
Essentially, SWMM’s normal conduit calculations do not by themselves account for inlet geometry constraints. This code ensures that when the wet‐well or upstream node is at certain depths, the flow is limited by the culvert entrance shape—matching the real‐world phenomenon that many culvert inlets cannot pass full pipe flow at certain depths.
8. Key Takeaways
- HEC‐5 Inlet Control: The code implements standard FHWA formulas for different culvert shapes and entrance conditions.
- Parameter Table: Each entrance type has empirical coefficients that define how flow is reduced under inlet control (K, M, C, Y, plus a “FORM” flag for different equations).
- Flow Regimes: Unsubmerged, submerged, or transitional.
- Root Finding: For “Form 1,” an iterative solution is needed to find critical depth.
- Integration with SWMM: This code runs only if a user has assigned a “culvert code” to a conduit. If the inlet control flow is less than the normally‐computed flow, SWMM overrides with the inlet‐controlled flow and flags that link as
inletControl = TRUE
.
This ensures that SWMM accurately simulates culvert hydraulics where the inlet, rather than the downstream barrel capacity, is the limiting factor.
No comments:
Post a Comment