Exercise 15.4
Gas Well Deliverability - Backpressure & Forchheimer AOF
A gas well was tested at four rates. Fit both the backpressure equation and the Forchheimer equation. Calculate AOF using both methods and compare. Which method is more conservative?
Use the following test data:
| Rate (Mscf/d) | Pwf (psia) |
|---|---|
| 0 | 3,200 |
| 1,500 | 3,050 |
| 3,000 | 2,810 |
| 4,500 | 2,480 |
| 6,000 | 2,050 |
---
A gas well on OML 58 was flow-after-flow tested at four stabilized rates, plus a shut-in reading. You will analyze the deliverability two ways: the simplified backpressure equation and the full Forchheimer (quadratic) equation, and report the Absolute Open Flow potential (AOF) from each.
The chapter's ch15-gas-ipr block does this analysis; here you package it into a single reusable function. No chapter function is pre-embedded; you re-code the two correlations directly from the chapter physics.
Write deliverability(q_test, Pwf_test, Pe) that returns a dict. Steps:
- Convert inputs to numpy arrays and drop any zero-rate point (the shut-in
(0, Pe) row must not enter the log fit (log10(0) is undefined).
- Backpressure equation
q = C * (Pe² - Pwf²)^n:
dP2 = Pe2 - Pwf2- Fit
log10(q) = log10(C) + n * log10(dP2)with
np.polyfit(np.log10(dP2), np.log10(q), 1).
n = slope,C = 10**intercept.AOF_bp = C (Pe2 - 14.72)*n.
- Forchheimer equation
Pe² - Pwf² = A*q + B*q², i.e.dP2/q = A + B*q:
ratio = dP2 / q- Fit
np.polyfit(q, ratio, 1)→B = slope,A = intercept. - Solve the quadratic at
Pwf = 14.7psia:
AOF_forch = (-A + sqrt(A2 + 4*B*(Pe2 - 14.7**2))) / (2*B).
- Return
dictwith keys'C','n','A','B','AOF_bp','AOF_forch'.
Embedded test data (from the book table):
Q = [0.0, 1500.0, 3000.0, 4500.0, 6000.0] # Mscf/d (first row is shut-in)
PWF = [3200.0, 3050.0, 2810.0, 2480.0, 2050.0] # psia
PE = 3200.0 # shut-in reservoir pressure, psiaThen call it once and pull out the values the tests read:
dd = deliverability(Q, PWF, PE)
aof_bp = dd['AOF_bp']
aof_forch = dd['AOF_forch']
n_exp = dd['n']> Think about it: the exponent n should land between 0.5 and 1.0; below 1.0 > means turbulence (non-Darcy flow) is robbing the well of deliverability. That is > exactly why the Forchheimer AOF comes out lower than the backpressure AOF: > the quadratic term B*q² charges the well for that turbulent loss. Which number > would you trust when sizing surface facilities?
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
# ── OML-58 backpressure (flow-after-flow) test data (do not edit) ─────────
# From the book table: a shut-in reading plus four stabilized flow rates.
Q = [0.0, 1500.0, 3000.0, 4500.0, 6000.0] # Mscf/d (first row is shut-in)
PWF = [3200.0, 3050.0, 2810.0, 2480.0, 2050.0] # flowing BHP, psia
PE = 3200.0 # shut-in reservoir pressure, psia
def deliverability(q_test, Pwf_test, Pe):
"""Analyze a gas-well backpressure test two ways.
Returns a dict with keys:
'C', 'n' -- backpressure: q = C*(Pe^2 - Pwf^2)^n
'A', 'B' -- Forchheimer: Pe^2 - Pwf^2 = A*q + B*q^2
'AOF_bp', 'AOF_forch'-- Absolute Open Flow (Mscf/d) at Pwf = 14.7 psia
Drop any zero-rate (shut-in) point before the log fit.
"""
q = np.asarray(q_test, float)
Pwf = np.asarray(Pwf_test, float)
# drop the shut-in (zero-rate) point -- log10(0) is undefined
mask = q > 0
q = q[mask]
Pwf = Pwf[mask]
dP2 = Pe**2 - Pwf**2
# Method 1: simplified backpressure equation
# log10(q) = log10(C) + n * log10(Pe^2 - Pwf^2)
coeffs = np.polyfit(np.log10(dP2), np.log10(q), 1)
n = coeffs[0]
C = 10**coeffs[1]
AOF_bp = C * (Pe**2 - 14.7**2)**n
# Method 2: Forchheimer (quadratic)
# (Pe^2 - Pwf^2)/q = A + B*q
ratio = dP2 / q
coeffs_q = np.polyfit(q, ratio, 1)
B = coeffs_q[0]
A = coeffs_q[1]
# AOF is the positive root of B*q^2 + A*q - (Pe^2 - 14.7^2) = 0
AOF_forch = (-A + np.sqrt(A**2 + 4*B*(Pe**2 - 14.7**2))) / (2*B)
return dict(C=C, n=n, A=A, B=B, AOF_bp=AOF_bp, AOF_forch=AOF_forch)
dd = deliverability(Q, PWF, PE)
aof_bp = dd['AOF_bp']
aof_forch = dd['AOF_forch']
n_exp = dd['n']
print("deliverability exponent n:", n_exp)
print("AOF (backpressure) Mscf/d:", aof_bp)
print("AOF (Forchheimer) Mscf/d:", aof_forch)
lockCopying code is a Full Access feature.