Exerciseschevron_rightChapter 8chevron_right8.3
fitness_center

Exercise 8.3

Viscosity Profile by API Gravity

Level 2
Chapter 8: PVT Correlations
descriptionProblem

Three appraisal wells on OML 58 each penetrated a different oil leg, and the lab gave you three crudes: a heavy 20° API, a medium 32° API, and a light 45° API. Same gas gravity (gamma_g = 0.75), same reservoir temperature (T_F = 180 °F), and the same solution gas-oil ratio at the bubble point (Rs = 500 scf/STB) for all three. The facilities team needs to know how much pumping horsepower each barrel will cost, and viscosity is what drives that.

You'll run the Beggs-Robinson viscosity correlation, which is a two-step chain:

  1. Dead-oil (gas-free) viscosity from API and temperature:

mu_od = beggs_robinson_dead_oil(T_F, API), in cp.

  1. Live-oil (gas-saturated) viscosity by correcting the dead-oil value for

the dissolved gas at the bubble point: mu_l = beggs_robinson_live_oil(mu_od, Rs), in cp.

Both functions are embedded for you. Write one function:

  • viscosity_by_api(api_list, T_F, Rs): for each API in api_list, compute

the dead-oil and live-oil viscosities and return a dict keyed by the API value:

``python { 20: {"mu_dead_cp": ..., "mu_live_cp": ..., "reduction_pct": ...}, 32: {...}, 45: {...}, } ``

where reduction_pct = (mu_dead_cp - mu_live_cp) / mu_dead_cp * 100, the percentage of the dead-oil viscosity that the dissolved gas knocks out.

Then build the profile and store it:

profile = viscosity_by_api([20, 32, 45], T_F=180.0, Rs=500.0)

Optional plot: make mu_live_cp vs API (one line, markers welcome). Label the x-axis "API gravity (°API)" and the y-axis "Live oil viscosity (cp)" so the heavy-to-light fall-off is obvious.

The physics you should see: the heaviest crude (20° API) is the most viscous, both dead and live; dissolved gas always cuts viscosity, so mu_live_cp < mu_dead_cp in every case; and the gap between the heavy barrel and the light barrel is large; that 20° API oil costs far more to move.

lightbulbHints (0/3)

Stuck? Reveal hints one at a time — they progress from nudge to near-solution.

codeYour solution
main.py
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
import matplotlib.pyplot as plt

# OML 58 appraisal crudes: same gas gravity, temperature, and Rs at Pb.
GAMMA_G = 0.75
T_F = 180.0          # reservoir temperature, °F
RS_AT_PB = 500.0     # solution GOR at the bubble point, scf/STB
API_LIST = [20, 32, 45]  # heavy, medium, light


def beggs_robinson_dead_oil(T_F, API):
    """Dead-oil (gas-free) viscosity, cp."""
    Y = 10 ** (3.0324 - 0.02023 * API)
    X = Y * T_F ** (-1.163)
    return 10 ** X - 1


def beggs_robinson_live_oil(mu_od, Rs):
    """Live-oil (gas-saturated) viscosity from dead-oil viscosity, cp."""
    A = 10.715 * (Rs + 100) ** (-0.515)
    B = 5.44 * (Rs + 150) ** (-0.338)
    return A * mu_od ** B


def viscosity_by_api(api_list, T_F, Rs):
    """For each API -> {mu_dead_cp, mu_live_cp, reduction_pct}."""
    out = {}
    for api in api_list:
        mu_dead_cp = float(beggs_robinson_dead_oil(T_F, api))
        mu_live_cp = float(beggs_robinson_live_oil(mu_dead_cp, Rs))
        reduction_pct = (mu_dead_cp - mu_live_cp) / mu_dead_cp * 100.0
        out[api] = {
            "mu_dead_cp": mu_dead_cp,
            "mu_live_cp": mu_live_cp,
            "reduction_pct": reduction_pct,
        }
    return out


profile = viscosity_by_api(API_LIST, T_F=T_F, Rs=RS_AT_PB)

apis = list(profile.keys())
mu_live = [profile[a]["mu_live_cp"] for a in apis]

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(apis, mu_live, marker="o", color="darkred",
        label="Live oil viscosity")
ax.set_xlabel("API gravity (°API)")
ax.set_ylabel("Live oil viscosity (cp)")
ax.set_title("OML 58 - live oil viscosity vs API gravity")
ax.grid(True, alpha=0.3)
ax.legend()
plt.tight_layout()
plt.show()

print("viscosity profile:", profile)

lockCopying code is a Full Access feature.