Skip to main content
Glama
gabrielserrao

pyResToolbox MCP Server

gas_sg_from_gradient

Calculate gas specific gravity from measured pressure gradient using Newton-Raphson solver for formation fluid identification and gas property verification when only gradient data is available.

Instructions

Calculate gas specific gravity from pressure gradient.

DIAGNOSTIC TOOL - Determines gas specific gravity from measured pressure gradient in a gas column. Uses standalone Newton-Raphson solver (fixed implementation) to solve the inverse problem. Essential for formation fluid identification and gas property verification when only gradient data is available.

Parameters:

  • gradient (float, required): Pressure gradient in psi/ft. Must be > 0. Typical: 0.05-0.15 psi/ft. Example: 0.1 psi/ft.

  • degf (float, required): Temperature in °F at measurement depth. Valid: -460 to 1000. Typical: 100-400°F. Example: 180.0.

  • p (float, required): Pressure in psia at measurement depth. Must be > 0. Example: 3500.0.

  • method (str, optional, default="DAK"): Z-factor method for calculation. Options: "DAK", "HY", "WYW", "BUR". DAK recommended.

Gradient Principle: Gas gradient = dP/dh = (ρg × g) / 144 = (P × MW) / (Z × R × T × 144)

Where:

  • ρg = gas density (lb/cuft)

  • MW = molecular weight = sg × 28.97 lb/lbmol

  • Z = gas compressibility factor

  • R = gas constant = 10.732 psia·ft³/(lbmol·°R)

  • T = temperature (°R = °F + 460)

Applications:

  • Formation Fluid ID: Identify gas vs oil vs water from gradient

  • Gas Density Verification: Check measured gas gravity against gradient

  • Completion Fluid Design: Design mud weight based on gas gradient

  • Wellbore Pressure Modeling: Calculate pressure profiles in gas columns

Typical Gradients:

  • Dry gas (sg=0.6): ~0.08 psi/ft

  • Associated gas (sg=0.8): ~0.11 psi/ft

  • Heavy gas (sg=1.0): ~0.14 psi/ft

Solution Method: Uses Newton-Raphson iterative solver to find sg that yields the specified gradient. This is a standalone fixed implementation that avoids upstream library bugs.

Returns: Dictionary with:

  • value (float): Gas specific gravity (dimensionless, air=1)

  • method (str): "Gradient correlation (Newton-Raphson)"

  • units (str): "dimensionless (air=1)"

  • inputs (dict): Echo of input parameters

Common Mistakes:

  • Using separator temperature instead of reservoir temperature

  • Pressure in barg/psig instead of psia (must be absolute)

  • Not accounting for non-hydrocarbon fractions (affects MW and Z)

  • Using wrong gradient units (must be psi/ft, not psi/100ft)

  • Temperature in Celsius instead of Fahrenheit

Example Usage:

{ "gradient": 0.1, "degf": 180.0, "p": 3500.0, "method": "DAK" }

Result: Gas SG ≈ 0.7-0.8 for typical natural gas gradient.

Note: This tool uses a standalone fixed implementation to avoid upstream bugs. Always use reservoir conditions (pressure and temperature at measurement depth). Gradient is sensitive to temperature - use correct temperature for accurate results.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
requestYes

Implementation Reference

  • The core handler function for the 'gas_sg_from_gradient' tool. Decorated with @mcp.tool() for automatic registration. Computes gas specific gravity using a fixed Newton-Raphson solver and returns formatted results.
    @mcp.tool() def gas_sg_from_gradient(request: GasSGFromGradientRequest) -> dict: """Calculate gas specific gravity from pressure gradient. **DIAGNOSTIC TOOL** - Determines gas specific gravity from measured pressure gradient in a gas column. Uses standalone Newton-Raphson solver (fixed implementation) to solve the inverse problem. Essential for formation fluid identification and gas property verification when only gradient data is available. **Parameters:** - **gradient** (float, required): Pressure gradient in psi/ft. Must be > 0. Typical: 0.05-0.15 psi/ft. Example: 0.1 psi/ft. - **degf** (float, required): Temperature in °F at measurement depth. Valid: -460 to 1000. Typical: 100-400°F. Example: 180.0. - **p** (float, required): Pressure in psia at measurement depth. Must be > 0. Example: 3500.0. - **method** (str, optional, default="DAK"): Z-factor method for calculation. Options: "DAK", "HY", "WYW", "BUR". DAK recommended. **Gradient Principle:** Gas gradient = dP/dh = (ρg × g) / 144 = (P × MW) / (Z × R × T × 144) Where: - ρg = gas density (lb/cuft) - MW = molecular weight = sg × 28.97 lb/lbmol - Z = gas compressibility factor - R = gas constant = 10.732 psia·ft³/(lbmol·°R) - T = temperature (°R = °F + 460) **Applications:** - **Formation Fluid ID:** Identify gas vs oil vs water from gradient - **Gas Density Verification:** Check measured gas gravity against gradient - **Completion Fluid Design:** Design mud weight based on gas gradient - **Wellbore Pressure Modeling:** Calculate pressure profiles in gas columns **Typical Gradients:** - Dry gas (sg=0.6): ~0.08 psi/ft - Associated gas (sg=0.8): ~0.11 psi/ft - Heavy gas (sg=1.0): ~0.14 psi/ft **Solution Method:** Uses Newton-Raphson iterative solver to find sg that yields the specified gradient. This is a standalone fixed implementation that avoids upstream library bugs. **Returns:** Dictionary with: - **value** (float): Gas specific gravity (dimensionless, air=1) - **method** (str): "Gradient correlation (Newton-Raphson)" - **units** (str): "dimensionless (air=1)" - **inputs** (dict): Echo of input parameters **Common Mistakes:** - Using separator temperature instead of reservoir temperature - Pressure in barg/psig instead of psia (must be absolute) - Not accounting for non-hydrocarbon fractions (affects MW and Z) - Using wrong gradient units (must be psi/ft, not psi/100ft) - Temperature in Celsius instead of Fahrenheit **Example Usage:** ```python { "gradient": 0.1, "degf": 180.0, "p": 3500.0, "method": "DAK" } ``` Result: Gas SG ≈ 0.7-0.8 for typical natural gas gradient. **Note:** This tool uses a standalone fixed implementation to avoid upstream bugs. Always use reservoir conditions (pressure and temperature at measurement depth). Gradient is sensitive to temperature - use correct temperature for accurate results. """ # Use fixed version that doesn't have the bisect_solve bug sg = gas_grad2sg_fixed( grad=request.grad, degf=request.degf, p=request.p, zmethod='DAK', cmethod='PMC', ) value = float(sg) return { "value": value, "method": "Gradient correlation (Newton-Raphson)", "units": "dimensionless (air=1)", "inputs": request.model_dump(), }
  • Pydantic model defining the input schema (parameters: gradient, degf, p) with validation for the tool.
    class GasSGFromGradientRequest(BaseModel): """Request model for gas SG from pressure gradient.""" grad: Union[float, List[float]] = Field( ..., description="Pressure gradient (psi/ft) - scalar or array" ) degf: float = Field( ..., gt=-460, lt=1000, description="Temperature (degrees Fahrenheit)" ) p: float = Field(..., gt=0, description="Pressure (psia)")
  • Call to register_gas_tools(mcp) which defines and registers the gas tools including gas_sg_from_gradient to the MCP server instance.
    register_gas_tools(mcp)
  • Helper function implementing the Newton-Raphson solver to compute gas SG from gradient, fixing bugs in the upstream pyrestoolbox library. Called by the main handler.
    def gas_grad2sg_fixed( grad: float, p: float, degf: float, zmethod: z_method = z_method.DAK, cmethod: c_method = c_method.PMC, co2: float = 0, h2s: float = 0, n2: float = 0, tc: float = 0, pc: float = 0, rtol: float = 1e-7, ) -> float: """Returns insitu gas specific gravity consistent with observed gas gradient. Fixed version of gas_grad2sg that doesn't rely on buggy bisect_solve. Uses Newton-Raphson iteration instead of bisection. Args: grad: Observed gas gradient (psi/ft) p: Pressure at observation (psia) degf: Reservoir Temperature (deg F) zmethod: Method for calculating Z-Factor cmethod: Method for calculating critical properties co2: Molar fraction of CO2 h2s: Molar fraction of H2S n2: Molar fraction of Nitrogen tc: Critical gas temperature (deg R) pc: Critical gas pressure (psia) rtol: Relative solution tolerance Returns: Gas specific gravity (air = 1.0) """ degR = degf + degF2R def calc_gradient(sg): """Calculate gradient for a given gas SG.""" m = sg * MW_AIR zee = gas.gas_z( p=p, degf=degf, sg=sg, zmethod=zmethod, cmethod=cmethod, co2=co2, h2s=h2s, n2=n2, tc=tc, pc=pc, ) grad_calc = p * m / (zee * R * degR) / 144 return grad_calc # Newton-Raphson iteration sg_guess = 0.7 # Initial guess max_iter = 50 for i in range(max_iter): grad_calc = calc_gradient(sg_guess) error = abs((grad - grad_calc) / grad) if error < rtol: return sg_guess # Numerical derivative delta = 0.001 grad_plus = calc_gradient(sg_guess + delta) derivative = (grad_plus - grad_calc) / delta # Newton-Raphson update if abs(derivative) > 1e-10: sg_new = sg_guess - (grad_calc - grad) / derivative # Keep within reasonable bounds sg_new = max(0.55, min(1.75, sg_new)) sg_guess = sg_new else: # If derivative is too small, use bisection fallback if grad_calc > grad: sg_guess *= 0.95 else: sg_guess *= 1.05 # Return best estimate even if not fully converged return sg_guess

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gabrielserrao/pyrestoolbox-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server