Skip to content

OOIP Calculation

Probabilistic oil originally in place using the volumetric equation with uncertain porosity, water saturation, and formation volume factor.

Deterministic baseline

import quantia as qu

Vp  = qu.Q(1_000_000.0, 'm3_res')        # pore volume
Sw  = 0.25                               # water saturation
Bo  = qu.Q(1.2, 'm3_res') / qu.Q(1.0, 'm3_sc')

ooip = Vp * (1 - Sw) / Bo
print(f"OOIP: {ooip.to('MMbbl'):.2f}")   # 3.93 MMbbl

Probabilistic — independent inputs

with qu.config(n_samples=5000, seed=42):
    phi = qu.ProbUnitFloat.triangular(0.12, 0.18, 0.25, '1')
    Sw  = qu.ProbUnitFloat.triangular(0.20, 0.28, 0.35, '1')
    Bo  = qu.ProbUnitFloat.normal(1.25, 0.05, 'm3_res/m3_sc')

A  = qu.Q(3_000_000.0, 'm2')     # 3 km²
h  = qu.Q(18.0, 'm')

Vp_r = A * h * phi
ooip = Vp_r * (1 - Sw) / Bo

lo, mid, hi = (ooip.percentile(p).to('MMbbl') for p in [10, 50, 90])
print(f"P10: {lo:.2f}  P50: {mid:.2f}  P90: {hi:.2f}")

Probabilistic — correlated inputs

Porosity and Bo are positively correlated (better rock holds lighter, more expandable oil):

with qu.config(n_samples=5000, seed=0):
    src = qu.CorrelatedSource(n_vars=2, rho=0.6)
    phi = src.draw(0, 'triangular', '1', low=0.12, mode=0.18, high=0.25)
    Bo  = src.draw(1, 'normal', 'm3_res/m3_sc', mean=1.25, std=0.05)

Sw   = 0.25
Vp_r = qu.Q(3_000_000.0 * 18.0, 'm3_res') * phi
ooip = Vp_r * (1 - Sw) / Bo

lo, mid, hi = (ooip.percentile(p).to('MMbbl') for p in [10, 50, 90])
print(f"P10: {lo:.2f}  P50: {mid:.2f}  P90: {hi:.2f}")