Exercise 8.8
Bubble Point vs. Temperature
A bubble-point number is never a single number; it lives at a reservoir temperature. When you push an OML 58 fluid through the lab at one temperature and then complete the well into a hotter (or cooler) interval, the pressure at which the first gas bubble breaks out moves. Get that wrong and you either flow the well two-phase when you thought it was undersaturated, or you choke it back for no reason.
The fluid here is a representative OML 58 medium crude: API = 30°, gamma_g = 0.78, solution GOR Rs = 500 scf/STB. You'll sweep reservoir temperature from 100°F to 300°F in 20°F steps and watch what Standing's correlation does to the bubble point.
Standing's bubble point is
Pb = 18.2 * ((Rs/gamma_g)**0.83 * 10**(0.00091*T_F - 0.0125*API) - 1.4)standing_bubble_point is provided. Write:
pb_vs_temperature(temps_f, Rs, gamma_g, API): return a dict mapping each
temperature T (a plain Python number, iterate temps_f) to its bubble point Pb in psia. Keys come straight from temps_f; values are floats.
temps_f is already built for you as temps_f = list(range(100, 301, 20)). Call your function once and store the result in pb_by_temp; that's the dict you'll be graded on.
Optional plot (not graded, but good practice): plot Pb vs. T with axis labels and a title.
The physics you must reproduce: the exponent 0.00091*T_F grows with temperature, so Pb rises monotonically with T: every step up in temperature lifts the bubble point. Physically, a hotter oil holds less gas in solution at a given pressure, so it takes a higher pressure to keep the same 500 scf/STB dissolved. Your dict must be strictly increasing in T, and Pb(300°F) must exceed Pb(100°F).
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 representative medium crude ───────────────────────────────────
API = 30.0 # oil gravity, degrees API
GAMMA_G = 0.78 # gas specific gravity (air = 1)
RS_SCF_STB = 500.0 # solution gas-oil ratio, scf/STB
# Reservoir temperatures to sweep: 100, 120, ... 300 degF
temps_f = list(range(100, 301, 20))
def standing_bubble_point(Rs, gamma_g, T_F, API):
"""Standing (1947) bubble-point pressure, psia."""
exponent = 0.00091 * T_F - 0.0125 * API
return 18.2 * ((Rs / gamma_g) ** 0.83 * 10 ** exponent - 1.4)
def pb_vs_temperature(temps_f, Rs, gamma_g, API):
"""Map each reservoir temperature (degF) to its bubble point (psia)."""
return {T: float(standing_bubble_point(Rs, gamma_g, T, API))
for T in temps_f}
pb_by_temp = pb_vs_temperature(temps_f, RS_SCF_STB, GAMMA_G, API)
# Optional (not graded): plot Pb vs T with axis labels and a title.
import matplotlib.pyplot as plt
_t = list(pb_by_temp.keys())
_pb = [pb_by_temp[t] for t in _t]
plt.figure()
plt.plot(_t, _pb, marker="o")
plt.xlabel("Reservoir temperature (degF)")
plt.ylabel("Bubble point Pb (psia)")
plt.title("Standing bubble point vs. temperature - OML 58 crude")
print("temperatures (degF):", temps_f)
print("bubble point by temperature (psia):", pb_by_temp)
lockCopying code is a Full Access feature.