SWMM5 Forcemain.c Summary
Below is an explanation of what each function in forcemain.c does, why it’s there, and how it fits into SWMM’s hydraulic calculations for pressurized force mains. This file handles Hazen-Williams and Darcy-Weisbach friction equations under force main conditions—i.e., when pipes are pressurized and do not follow standard Manning’s equation.
1. Background: Force Mains in SWMM
-
In typical open-channel flow, SWMM uses Manning’s equation to model headloss.
-
However, a force main is a pressurized conduit (often from a pump), where flow is not necessarily open-channel. In that scenario, many engineers use:
- Hazen-Williams equation (common in North America for water distribution), or
- Darcy-Weisbach equation (a more universal approach, used in many hydraulic contexts).
-
SWMM’s user can choose either Hazen-Williams (H_W) or Darcy-Weisbach (D_W) for force mains. The code in
forcemain.cprovides the specialized calculations for friction losses, Reynolds number, friction factors, etc.
2. The Main Functions
2.1 forcemain_getEquivN(...)
double forcemain_getEquivN(int j, int k)
Purpose: Computes an “equivalent Manning’s n” for a force main flowing full under fully turbulent conditions, using the user’s chosen equation (Hazen-Williams or Darcy-Weisbach).
- Inputs:
j= link index in SWMM’s data structuresk= conduit index- The conduit’s geometry is accessed via
Link[j].xsectandConduit[k].
- Logic:
- If Hazen-Williams:
return 1.067 / xsect.rBot * pow(d/Conduit[k].slope, 0.04);disyFull(full diameter or full depth).xsect.rBothere is repurposed to store the Hazen-Williams “C” factor.- The constant
1.067and exponent0.04come from deriving an approximate equivalence between Hazen-Williams and Manning’s formula when the pipe is completely full.
- If Darcy-Weisbach:
f = forcemain_getFricFactor(xsect.rBot, d/4.0, 1.0e12); return sqrt(f/185.0) * pow(d, (1./6.));xsect.rBotis used here to store the roughness height (e) for Darcy-Weisbach.- It calls
forcemain_getFricFactor(...)withre = 1.0e12—effectively a giant Reynolds number—to ensure fully turbulent regime. - Then it converts that friction factor into an “equivalent Manning’s n.”
- If neither (i.e., normal Manning’s is used), it just returns the conduit’s normal
roughness.
- If Hazen-Williams:
- Why do this?
- Internally, SWMM might do normal flow checks or partial flow logic that sometimes calls on Manning’s equation. This function helps “fake” a Manning’s n that yields the same full-flow result as Hazen-Williams or Darcy-Weisbach.
2.2 forcemain_getRoughFactor(...)
double forcemain_getRoughFactor(int j, double lengthFactor)
Purpose: Computes an adjustment factor for the pipe’s roughness that compensates for any artificial lengthening the user or the model might impose. Sometimes, a pipe is artificially lengthened to maintain stability in the SWMM solver (i.e., if a pipe is too short, you might virtually lengthen it but keep the slope the same).
- Inputs:
j= link indexlengthFactor= factor by which a pipe is “artificially lengthened.” (If the pipe length is doubled artificially, lengthFactor might be 2.0.)
- Logic:
- If Hazen-Williams (
H_W):r = 1.318*xsect.rBot*pow(lengthFactor, 0.54); return GRAVITY / pow(r, 1.852);xsect.rBotis the Hazen-Williams C-factor again.- The 1.318 and exponents 0.54, 1.852 come from the Hazen-Williams formula.
- If Darcy-Weisbach (
D_W):return 1.0/8.0/lengthFactor;- This modifies the friction factor for the artificial length.
- If Hazen-Williams (
- Why do this?
- If you artificially lengthen a pipe, you need to adjust the friction or roughness so that the final headloss is physically consistent with the original “real” pipe.
2.3 forcemain_getFricSlope(...)
double forcemain_getFricSlope(int j, double v, double hrad)
Purpose: Computes the headloss per unit length (i.e., friction slope ) in the dynamic wave flow routing for a pressurized force main. It uses either Hazen-Williams or Darcy-Weisbach, depending on ForceMainEqn.
- Inputs:
j= link indexv= flow velocity (ft/s)hrad= hydraulic radius (ft) (for a full pipe,hrad = diameter/4, but if partially pressurized, might differ).
- Logic:
- If Hazen-Williams:
return xsect.sBot * pow(v, 0.852) / pow(hrad, 1.1667);- The code previously stored a “roughness factor” in
xsect.sBot(during conduit validation), so that it can just multiply byv^0.852 / hrad^1.1667.
- The code previously stored a “roughness factor” in
- If Darcy-Weisbach:
re = forcemain_getReynolds(v, hrad); f = forcemain_getFricFactor(xsect.rBot, hrad, re); return f * xsect.sBot * v / hrad;- First calculates Reynolds number.
- Then obtains the friction factor
f. - Then friction slope =
f * sBot * (v / hrad).
- If Hazen-Williams:
- Why do this?
- SWMM’s dynamic wave solver needs friction slope (or friction headloss per length) at each time step. This is the crux of how SWMM calculates energy losses in pressure flow.
2.4 forcemain_getReynolds(...)
double forcemain_getReynolds(double v, double hrad)
Purpose: Computes the flow’s Reynolds number:
Here, is the kinematic viscosity of water at 20°C.
- Formula:
return 4.0 * hrad * v / VISCOS; - Why: Reynolds number tells us if the flow is laminar, transitional, or turbulent, which the code then uses to pick the right friction factor formula.
2.5 forcemain_getFricFactor(...)
double forcemain_getFricFactor(double e, double hrad, double re)
Purpose: Computes the Darcy-Weisbach friction factor for a force main using the Swamee-Jain approximation to the Colebrook-White equation.
- Inputs:
e: the roughness height (ft). In SWMM, this might be set by the user or derived from the “rBot” for Darcy-Weisbach.hrad: hydraulic radius.re: Reynolds number.
- Logic:
- Check for extremely low Re: if
re < 10.0, setre = 10.0artificially. - Laminar regime (Re <= 2000):
f = 64.0 / re; - Transitional (2000 < Re < 4000):
Actually, the code calls itself for Re=4000, gets that friction factor, and does a linear interpolation.// recursively calls forcemain_getFricFactor with re=4000, then // linearly blend from f=0.032 up to that friction factor - Turbulent (Re >= 4000):
f = e/3.7/(4.0*hrad); if (re < 1.0e10) f += 5.74/pow(re, 0.9); f = log10(f); f = 0.25 / (f*f);- This is the Swamee-Jain formula:
but here
Dis approximated as4 * hradif it’s a circular pipe.
- This is the Swamee-Jain formula:
but here
- Check for extremely low Re: if
- Why:
- The friction factor is crucial for Darcy-Weisbach calculations. The Swamee-Jain approximation is a direct (non-iterative) way to estimate friction factor from Colebrook-White.
3. Putting It All Together
-
Selecting Equation:
- SWMM’s global setting
ForceMainEqnis eitherH_W(Hazen-Williams) orD_W(Darcy-Weisbach). - Each force main (pressurized conduit) is flagged to use one or the other.
- SWMM’s global setting
-
During Simulation:
- Initialization:
- SWMM calls
forcemain_getEquivN()at validation time to store a stand-in Manning’s n for certain normal-flow checks. - It also calls
forcemain_getRoughFactor(...)to store the pipe’s friction coefficient inxsect.sBot.
- SWMM calls
- Every Time Step (Dynamic Wave):
- SWMM calculates velocity
v, hydraulic radiushrad, etc. - Then calls
forcemain_getFricSlope(...)to get friction slope, which goes into the momentum equation. - Inside that function, if Darcy-Weisbach is chosen, the code calls:
forcemain_getReynolds(...)to get Re,forcemain_getFricFactor(...)for Darcy-Weisbach’s friction factor.
- This friction slope is used in the St. Venant equations for unsteady flow.
- SWMM calculates velocity
- Initialization:
-
Result:
- The code ensures force main headloss is modeled with either H-W or D-W.
- The user sees more accurate pressurized-flow behavior than if SWMM were just forcing a Manning’s formula.
4. Key Takeaways
-
Hazen-Williams (H_W) vs. Darcy-Weisbach (D_W)
- H_W: simpler, widely used in water distribution, but less general for different fluids/temperatures.
- D_W: more universal, uses friction factor derived from roughness and Reynolds number (Colebrook-White/Swamee-Jain).
-
Equivalent Manning’s n
- Because SWMM’s internal logic often uses Manning-based checks, the code calculates a “fake n” that yields the same full-flow rate as the chosen force main formula under ideal conditions.
-
Friction Factor
- The code includes transitional laminar/turbulent handling.
- Swamee-Jain is a closed-form approximation to Colebrook-White, avoiding iterative solutions for friction factor.
-
Artificial Pipe Lengthening
- The user can artificially lengthen a short pipe for numerical stability. The code corrects friction to preserve real-world headloss.
Overall, forcemain.c is the specialized module that overrides normal Manning’s friction for pressurized pipes in SWMM, using either Hazen-Williams or Darcy-Weisbach—complete with Reynolds-number-based friction factors—so that force mains in your model behave more realistically than if they used open-channel Manning’s equations.