Exercise 15.5
Pipeline Pressure Profile - P² is Linear, Pressure is Not
For a 100-mile, 24-inch pipeline operating at 1,200 psia inlet and 800 psia outlet, calculate and plot the pressure at every mile along the pipeline. Is the pressure drop linear?
---
We'll trace the pressure foot-by-foot along a 100-mile, 24-inch OML trunk line running at 1,200 psia inlet and 800 psia outlet. Here's the physics that makes a gas line different from a water line: in steady horizontal flow with a constant mass rate q, the General Flow Equation says it is P², not P, that drops linearly along the pipe. Rearranging q ∝ sqrt((P1² − P2²)/L) for a constant q over any partial length x gives the exact local pressure:
P(x) = sqrt( P1**2 - (P1**2 - P2**2) * x / L )That square-root makes the profile convex: pressure falls slowly near the high-pressure inlet and steeply near the outlet, so the midpoint pressure sits above the naive linear average (P1 + P2)/2. A water engineer who interpolates linearly will under-predict the line-pack and mis-size compression.
The verified pipeline_capacity_general function is embedded for you so you can confirm the line carries a single constant capacity end to end; do not modify it or re-derive the physics.
Your tasks:
- Write
pressure_profile(P1, P2, L_miles, n_points):
- Build
x = np.linspace(0, L_miles, n_points): distances along the line. - For each
x[i], computeP[i] = sqrt(P12 - (P12 - P2*2) x[i] / L_miles).
(A vectorized numpy expression over the whole x array is fine.)
- Return the tuple
(x_array, P_array)in that order, both lengthn_points.
- Using the embedded constants
P1 = 1200.0,P2 = 800.0,L_MILES = 100.0,
N_POINTS = 101 (a node every mile, 0..100), call the function and unpack: ``python x_mi, p_psia = pressure_profile(P1, P2, L_MILES, N_POINTS) p_mid = float(p_psia[50]) # pressure at mile 50 p_at_25 = float(p_psia[25]) # pressure at mile 25 ``
> Think about it: p_mid comes out near 1019.8 psia, comfortably above > the linear-average 1000; that gap is the whole point. The endpoints must > land exactly on 1200 and 800. If you ever code P(x) as a straight line, the > P²-linearity and convexity checks will catch you. Why is the pressure drop per > mile steeper at the outlet than at the inlet, even though the same gas flows > through every cross-section?
Stuck? Reveal hints one at a time — they progress from nudge to near-solution.
visibilityReveal reference solutionexpand_more
Try solving it yourself first — the hints walk you through it. The solution below is one valid approach; yours may differ and still be correct.
import numpy as np
# ── Verified General Flow Equation for gas pipeline capacity (do not edit) ──
def pipeline_capacity_general(P1, P2, D_in, L_miles, gamma_g, T_avg_F,
Z_avg, efficiency=0.92):
"""
General Flow Equation for gas pipeline capacity.
Parameters
----------
P1 : float
Inlet pressure (psia).
P2 : float
Outlet pressure (psia).
D_in : float
Pipe internal diameter (inches).
L_miles : float
Pipeline length (miles).
gamma_g : float
Gas specific gravity.
T_avg_F : float
Average gas temperature (deg F).
Z_avg : float
Average compressibility factor.
efficiency : float
Pipeline efficiency factor (0 to 1).
Returns
-------
float
Flow rate (MMscf/day).
"""
Tb = 520 # base temperature, deg R (60 deg F)
Pb = 14.73 # base pressure, psia
T_avg_R = T_avg_F + 459.67
# Assume fully turbulent friction factor (Weymouth approximation)
f = 0.032 / (D_in**(1/3))
q_scfd = 77.54 * (Tb/Pb) * (
(P1**2 - P2**2) * D_in**5 /
(f * gamma_g * T_avg_R * Z_avg * L_miles)
)**0.5
return q_scfd * efficiency / 1e6 # convert to MMscf/day
# ── Pipeline constants (do not edit) ─────────────────────────────────────
P1 = 1200.0 # inlet pressure, psia
P2 = 800.0 # outlet pressure, psia
L_MILES = 100.0 # pipeline length, miles
N_POINTS = 101 # a node every mile, 0..100
D_IN = 24.0 # pipe internal diameter, inches (for the capacity check)
GAMMA_G = 0.65 # gas specific gravity
T_AVG_F = 80.0 # average gas temperature, deg F
Z_AVG = 0.92 # average compressibility factor
def pressure_profile(P1, P2, L_miles, n_points):
"""Pressure at every node along a horizontal gas pipeline.
In steady flow with constant rate, P**2 is LINEAR in distance, so
P(x) = sqrt(P1**2 - (P1**2 - P2**2) * x / L_miles).
Returns (x_array, P_array), both length n_points:
x_array = numpy.linspace(0, L_miles, n_points) -- miles from the inlet
P_array = local pressure at each node (psia)
"""
x = np.linspace(0, L_miles, n_points)
P = np.sqrt(P1**2 - (P1**2 - P2**2) * x / L_miles)
return x, P
x_mi, p_psia = pressure_profile(P1, P2, L_MILES, N_POINTS)
p_mid = float(p_psia[50]) # pressure at mile 50
p_at_25 = float(p_psia[25]) # pressure at mile 25
# The whole line carries one constant capacity end to end (sanity context).
q_line = pipeline_capacity_general(P1, P2, D_IN, L_MILES, GAMMA_G, T_AVG_F, Z_AVG)
print("nodes:", len(x_mi))
print("P at inlet / outlet (psia):", (float(p_psia[0]), float(p_psia[-1])))
print("P at mile 50 (psia):", p_mid, " linear-average would be:", (P1 + P2) / 2)
print("P at mile 25 (psia):", p_at_25)
print("constant line capacity (MMscf/day):", round(q_line, 2))
lockCopying code is a Full Access feature.