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.c
provides 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].xsect
andConduit[k]
.
- Logic:
- If Hazen-Williams:
return 1.067 / xsect.rBot * pow(d/Conduit[k].slope, 0.04);
d
isyFull
(full diameter or full depth).xsect.rBot
here is repurposed to store the Hazen-Williams “C” factor.- The constant
1.067
and exponent0.04
come 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.rBot
is 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.rBot
is 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.0
artificially. - 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
D
is approximated as4 * hrad
if 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
ForceMainEqn
is 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.
No comments:
Post a Comment