Beggs and Brill Pressure Drop Calculation: Step by Step

Beggs and Brill multiphase flow pressure drop calculation in a vertical oil well tubing string

By Saad Iqbal

Picture a gas-lifted well teetering on the edge of liquid loading. The vendor nodal-analysis software is down, and the production engineer needs an answer this afternoon: add gas, swap the choke, or pull the string. The 1973 Beggs and Brill correlation is the tool that gets that answer by hand, in any pipe, at any angle, whether the flow is segregated, slugging, or fully mixed. It has survived fifty years of flashier multiphase models because it is simple enough to code in an afternoon and robust enough to trust in a horizontal gathering line or a near-vertical tubing string alike.

This tutorial walks the full calculation end to end — the flow-pattern map, the liquid holdup, the inclination correction, the friction term — with one fully worked numeric example you can check your own spreadsheet against, then turns it into a Python function you never have to run by hand again.

Beggs and Brill multiphase flow pressure drop calculation in a vertical oil well tubing string

What You Need Before You Start

The correlation works on one pipe segment at a time — a joint of tubing, a flowline run, one increment of a wellbore traverse. You need the segment geometry and the in-situ (flowing) fluid properties at that segment’s average pressure and temperature. Here is the worked example used throughout this tutorial:

InputSymbolValue
Pipe inside diameterd3.0 in (0.250 ft)
Inclination from horizontalθ90° (vertical, uphill)
Segment lengthΔZ1,000 ft
Superficial liquid velocityVsl3.0 ft/s
Superficial gas velocityVsg6.0 ft/s
Liquid densityρL50.0 lb/ft³
Gas density (at 1,500 psia, 140°F, z=0.85, γg=0.75)ρg5.96 lb/ft³
Gas–liquid surface tensionσ20 dyn/cm
Liquid viscosityμL5.0 cp
Gas viscosityμg0.02 cp

All of this needs to be in field units — ft, ft/s, lb/ft³, cp. The correlation’s coefficients were regressed in these units, and mixing in SI numbers partway through is the single most common way to get a nonsense answer.

Step 1: Convert Rates to Velocities and Find the No-Slip Holdup

Add the superficial velocities to get the mixture velocity, then take the liquid’s share of it — this is the no-slip liquid holdup, λL, the input liquid fraction before the correlation accounts for gas slipping past the liquid:

V_m = V_sl + V_sg 
 λ_L = V_sl / V_m 
 N_Fr = V_m² / (g × d), with g = 32.2 ft/s²

Plugging in the example: Vm = 3.0 + 6.0 = 9.0 ft/s; λL = 3.0 / 9.0 = 0.3333; NFr = 9.0² / (32.2 × 0.250) = 10.062. The Froude number NFr is the backbone of the next step — it measures how gravity-dominated versus inertia-dominated the flow is, which is exactly what separates a smoothly distributed flow from a lurching slug.

Gathering flow rate and fluid property inputs for a multiphase flow pressure drop calculation

Step 2: Determine the Flow Pattern

Beggs and Brill map the flow into four regimes — segregated, transition, intermittent, and distributed — using four boundary curves that depend only on λL:

  • L1 = 316 × λL0.302
  • L2 = 0.0009252 × λL−2.4684
  • L3 = 0.10 × λL−1.4516
  • L4 = 0.5 × λL−6.738

With λL = 0.3333: L1 = 226.78, L2 = 0.0139, L3 = 0.4927, L4 ≈ 820.0. The regime follows from where NFr falls relative to these lines: segregated flow sits below L1/L2, distributed flow sits above L1 (for λL < 0.4) or L4, intermittent flow sits in between, and a narrow transition band sits between L2 and L3. Here, NFr = 10.062 falls between L3 (0.4927) and L1 (226.78) with λL < 0.4, so this segment is intermittent (slug) flow — exactly the regime you’d expect from a moderate-rate gas-lifted well.

Beggs and Brill flow pattern map showing segregated intermittent and distributed multiphase flow regimes

Step 3: Calculate Liquid Holdup and Apply the Inclination Correction

First, the horizontal holdup: EL(0) = a × λLb / NFrc, never allowed to fall below λL itself.

Regimeabc
Segregated0.9800.48460.0868
Intermittent0.8450.53510.0173
Distributed1.0650.58240.0609

For intermittent flow: EL(0) = 0.845 × 0.33330.5351 / 10.0620.0173 = 0.4510. Next, the liquid velocity number NLv = 1.938 × Vsl × (ρL/σ)0.25 = 7.311, which feeds the inclination factor C for uphill intermittent flow (coefficients d=2.96, e=0.305, f=−0.4473, g=0.0978):

C = (1−λL) × ln(2.96 × λL0.305 × NLv−0.4473 × NFr0.0978) = 0.0574 (floored at 0 if negative — it isn’t here)

The angle correction is ψ = 1 + C × [sin(1.8θ) − ⅓sin³(1.8θ)]. At θ=90°, sin(162°)=0.309, so ψ = 1 + 0.0574 × (0.309−0.0098) = 1.0172. The true, slip-corrected holdup is then EL(θ) = ψ × EL(0) = 0.4588 — noticeably higher than the no-slip value of 0.3333, because gas slips upward past the slower liquid and leaves more liquid behind per foot of pipe. That gap between λL and EL(θ) is the entire reason this correlation exists.

Liquid holdup inclination correction for inclined and vertical multiphase pipe flow

Step 4: Compute the Hydrostatic (Elevation) Pressure Component

The slip-corrected mixture density carries the weight of the column: ρm = ρL × EL(θ) + ρg × (1−EL(θ)) = 50.0 × 0.4588 + 5.96 × 0.5412 = 26.16 lb/ft³. The hydrostatic pressure drop over the segment is ΔPel = ρm × ΔZ / 144 (for a deviated well, replace ΔZ with the true vertical rise, L × sinθ):

ΔPel = 26.16 × 1,000 / 144 = 181.7 psi over the 1,000 ft segment.

Hydrostatic elevation pressure component increasing with depth in a vertical well

Step 5: Compute the Frictional Pressure Component

Friction needs a two-phase friction factor, built by scaling a no-slip friction factor by a ratio that depends on y = λL / EL(θ)² = 0.3333/0.4588² = 1.584. Since y > 1.2:

S = ln(y) / [−0.0523 + 3.182·ln(y) − 0.8725·ln(y)² + 0.01853·ln(y)⁴] = 0.4598 / 1.2273 = 0.3747, so ftp/fns = eS = 1.4545.

The no-slip density and viscosity use λL, not EL(θ): ρns = 50.0×0.3333 + 5.96×0.6667 = 20.64 lb/ft³; μns = 5.0×0.3333 + 0.02×0.6667 = 1.68 cp. That gives a no-slip Reynolds number NRe,ns = 1,488 × ρns × Vm × d / μns = 41,133 — comfortably turbulent. Using the Drew–Koo–McAdams smooth-pipe correlation that the original Beggs and Brill paper used, fns = 0.0056 + 0.5/NRe,ns0.32 = 0.02229 (Fanning basis), so ftp = 0.02229 × 1.4545 = 0.03242.

The frictional pressure drop (Fanning form) is ΔPf = 2×ftp×ρns×Vm²×ΔZ / (gc×d×144) = 93.5 psi over the segment.

Two-phase friction factor and frictional pressure loss in multiphase pipe flow

Step 6: Sum the Total and Automate It in Python

Total pressure drop is simply the two components added together: ΔP = 181.7 + 93.5 = 275.2 psi over 1,000 ft, a gradient of 0.275 psi/ft. Chain enough of these segments up the tubing — recomputing PVT properties at each new average pressure — and you have a full pressure traverse, which is exactly the VLP curve half of the nodal analysis plot that tells you where a well will actually operate.

Here is the whole calculation as a single Python function, using only the standard library for one segment (swap in Python with pandas and NumPy to vectorize it across hundreds of depth steps and dozens of wells at once):

import math

def beggs_brill_dp(d_ft, theta_deg, dZ_ft, Vsl, Vsg, rhoL, rhog, sigma, muL, mug):
    g, gc = 32.2, 32.2
    Vm = Vsl + Vsg
    lamL = Vsl / Vm
    NFr = Vm**2 / (g * d_ft)

    L1 = 316 * lamL**0.302
    L2 = 0.0009252 * lamL**-2.4684
    L3 = 0.10 * lamL**-1.4516
    L4 = 0.5 * lamL**-6.738

    if (lamL < 0.01 and NFr < L1) or (lamL >= 0.01 and NFr < L2):
        pattern = "segregated"
    elif lamL >= 0.01 and L2 <= NFr <= L3:
        pattern = "transition"
    elif (lamL < 0.4 and L3 < NFr <= L1) or (lamL >= 0.4 and L3 < NFr <= L4):
        pattern = "intermittent"
    else:
        pattern = "distributed"

    coeff = {"segregated": (0.98, 0.4846, 0.0868),
             "intermittent": (0.845, 0.5351, 0.0173),
             "distributed": (1.065, 0.5824, 0.0609)}
    incl = {"segregated": (0.011, -3.768, 3.539, -1.614),
            "intermittent": (2.96, 0.305, -0.4473, 0.0978),
            "distributed": None}

    def EL0_of(p):
        a, b, c = coeff[p]
        return max(a * lamL**b / NFr**c, lamL)

    def C_of(p):
        if incl[p] is None:
            return 0.0
        dc, e, f, gg = incl[p]
        return max((1 - lamL) * math.log(dc * lamL**e * NFr**gg * NLv**f), 0.0)

    NLv = 1.938 * Vsl * (rhoL / sigma)**0.25

    if pattern == "transition":
        A = (L3 - NFr) / (L3 - L2)
        EL0 = A * EL0_of("segregated") + (1 - A) * EL0_of("intermittent")
        C = A * C_of("segregated") + (1 - A) * C_of("intermittent")
    else:
        EL0 = EL0_of(pattern)
        C = C_of(pattern)

    theta = math.radians(theta_deg)
    psi = 1 + C * (math.sin(1.8 * theta) - (1/3) * math.sin(1.8 * theta)**3)
    ELtheta = psi * EL0

    rho_s = rhoL * ELtheta + rhog * (1 - ELtheta)
    dP_elev = rho_s * dZ_ft / 144.0

    y = lamL / ELtheta**2
    if 1 < y < 1.2:
        S = math.log(2.2 * y - 1.2)
    else:
        lny = math.log(y)
        S = lny / (-0.0523 + 3.182*lny - 0.8725*lny**2 + 0.01853*lny**4)

    rho_ns = rhoL * lamL + rhog * (1 - lamL)
    mu_ns = muL * lamL + mug * (1 - lamL)
    NRe_ns = 1488 * rho_ns * Vm * d_ft / mu_ns
    f_ns = 0.0056 + 0.5 / NRe_ns**0.32
    f_tp = f_ns * math.exp(S)

    dP_fric = 2 * f_tp * rho_ns * Vm**2 * dZ_ft / (gc * d_ft * 144.0)

    return {"pattern": pattern, "EL_theta": ELtheta,
            "dP_elevation_psi": dP_elev, "dP_friction_psi": dP_fric,
            "dP_total_psi": dP_elev + dP_fric}

result = beggs_brill_dp(d_ft=0.250, theta_deg=90, dZ_ft=1000,
                         Vsl=3.0, Vsg=6.0, rhoL=50.0, rhog=5.96,
                         sigma=20.0, muL=5.0, mug=0.02)
print(result)
# {'pattern': 'intermittent', 'EL_theta': 0.4588, 'dP_elevation_psi': 181.7,
#  'dP_friction_psi': 93.5, 'dP_total_psi': 275.2}

Running it reproduces the hand calculation exactly. For a daily job across your whole well list, drop the per-well inputs into a pandas DataFrame, apply the function row by row (or vectorize the math with NumPy), and push the output pressure traverses straight into Power BI or Looker Studio. If you'd rather not run Python at all, n8n or Power Automate can call the same logic as a scripted step inside a scheduled workflow that pulls rates from your production database and writes the gradient back.

Automating Beggs and Brill pressure traverse calculations with Python

How to Verify the Result and Common Pitfalls

Expected result: 275.2 psi over the 1,000 ft segment, split 181.7 psi hydrostatic and 93.5 psi frictional. Sanity check it two ways: first, the no-slip-only hydrostatic gradient (using ρns = 20.64 lb/ft³ instead of the slip-corrected 26.16 lb/ft³) would give only 143.3 psi — since gas always slips past liquid in upward flow, the true holdup EL(θ) must come out above the no-slip λL, and it does (0.4588 > 0.3333). If your code ever returns EL(θ) below λL for uphill flow, you have a sign or floor-check bug. Second, where you have vendor software or a second correlation like Hagedorn–Brown available, cross-check: the two should typically agree within 10–15% in bubble or slug flow.

  • Unit mixing — the L1–L4 and EL(0) coefficients are fit to field units (ft, ft/s, lb/ft³); feeding in meters or kg/m³ partway through silently produces a wrong flow pattern.
  • Skipping the EL(0) ≥ λL floor — easy to miss right at the segregated/intermittent boundary, where the raw power-law formula can dip below the physically required minimum.
  • Using uphill coefficients on a downhill run — a return bend or undulating flowline needs the separate downhill coefficient set (d=4.70, e=−0.3692, f=0.1244, g=−0.5056), not just a negated angle.
  • Confusing λL and EL(θ) — the no-slip input fraction and the true, slip-corrected holdup are never interchangeable; the gap between them is the entire physical point of the correlation.

Once the wellbore traverse is solid, the natural next stop is checking what happens at the surface: see our walkthrough of choke size calculation with the Gilbert equation for how the flowing wellhead pressure computed here sets the choke's performance, or the Turner equation tutorial for checking whether this same well is at risk of liquid loading.

Saad Iqbal Avatar

About the author

Saad Iqbal

Petroleum Engineer · Well Intervention & Stimulation Specialist

Saad Iqbal is a petroleum engineer and well intervention and stimulation specialist with more than a decade of field experience in hydraulic fracturing, coiled tubing, CSG, tight sandstone and shale developments. He explores practical AI, automation and data-driven engineering for safer, smarter upstream operations.

Discover more from EnergyMindAI

Subscribe now to keep reading and get access to the full archive.

Continue reading