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