Manning's Equation for Open Channel Flow in QUAL2K
QUAL2K computes the velocity, depth, and cross-sectional area of each reach using either Manning's equation or power-law rating curves, as described in the EPA QUAL2K technical documentation. Manning's equation is the default and most commonly used method for natural streams with known geometry. The computed hydraulic parameters feed directly into the reaeration coefficient and flow routing calculations.
Manning's Equation
Manning's equation relates the flow discharge (m³/s) to the channel geometry and roughness:
Where:
- — Manning's roughness coefficient (dimensionless)
- — cross-sectional area of flow (m²)
- — hydraulic radius (m)
- — wetted perimeter (m)
- — channel bed slope (m/m)
Trapezoidal Cross-Section Geometry
QUAL2K models the channel as a trapezoidal cross-section with a flat bottom of width and two (potentially different) side slopes and :
For a given depth of flow :
where is the average side slope.
Newton-Raphson Depth Solver
Given a known discharge , the depth must be found iteratively. QUAL2K uses the Newton-Raphson method to solve:
The derivative is:
where is the top width and .
The iteration starts at m and converges in 5–10 iterations for typical channels. The update rule is:
Derived Quantities
Once the depth is known, the remaining hydraulic parameters follow directly:
where is the reach length in meters.
Rating Curve Alternative
When rating curve coefficients are provided, QUAL2K uses power-law relationships instead of Manning's equation:
The cross-sectional area is then and the width is . This method is used when field-measured rating curves are available.
Typical Manning's n Values
Manning's roughness coefficients for natural streams
| Channel Type | n (minimum) | n (typical) | n (maximum) |
|---|---|---|---|
| Clean, straight, full stage | 0.025 | 0.030 | 0.033 |
| Clean, winding, some pools | 0.033 | 0.040 | 0.045 |
| Sluggish, weedy, deep pools | 0.050 | 0.070 | 0.080 |
| Very weedy, heavy brush | 0.075 | 0.100 | 0.150 |
| Mountain streams, cobbles | 0.030 | 0.050 | 0.070 |
| Mountain streams, boulders | 0.040 | 0.070 | 0.100 |
| Floodplain, pasture | 0.025 | 0.035 | 0.050 |
| Floodplain, heavy timber | 0.100 | 0.120 | 0.160 |
Python Implementation
def calculate_hydraulics(reach, geo_method):
q_s = reach.get('q', 0) # Flow in m³/s
n = reach.get('nm', 0.03)
s = reach.get('s', 0.0001)
bb = reach.get('BB', 1.0)
ss1 = reach.get('SS1', 0.0)
ss2 = reach.get('SS2', 0.0)
ss_avg = (ss1 + ss2) / 2.0
# Newton-Raphson iteration for depth y
y = 0.5 # initial guess (meters)
for _ in range(30):
area = bb * y + ss_avg * (y ** 2)
perim = bb + y * (sqrt(1 + ss1**2) + sqrt(1 + ss2**2))
radius = area / perim
f = (1/n) * area * radius**(2/3) * s**0.5 - q_s
top_width = bb + (ss1 + ss2) * y
df_dy = (1/n) * s**0.5 * (
(5/3) * top_width * radius**(2/3) -
(2/3) * radius**(5/3) * (sqrt(1+ss1**2) + sqrt(1+ss2**2))
)
dy = f / df_dy
y = y - dy
if abs(dy) < 1e-7:
break