gas_density
Calculate gas density at reservoir conditions using specific gravity, temperature, pressure, and gas composition for gradient calculations and pressure analysis in petroleum engineering.
Instructions
Calculate gas density (ρg) at reservoir conditions.
CRITICAL GAS PVT PROPERTY - Computes gas density from real gas equation of state. Essential for gradient calculations, well pressure analysis, and material balance. Gas density increases significantly with pressure due to compressibility.
Parameters:
sg (float, required): Gas specific gravity (air=1.0). Valid: 0.55-3.0. Typical: 0.6-1.2. Example: 0.7.
degf (float, required): Reservoir temperature in °F. Valid: -460 to 1000. Typical: 100-400°F. Example: 180.0.
p (float or list, required): Pressure(s) in psia. Must be > 0. Can be scalar or array. Example: 3500.0 or [1000, 2000, 3000, 4000].
h2s (float, optional, default=0.0): H2S mole fraction (0-1). Typical: 0-0.05. Example: 0.02.
co2 (float, optional, default=0.0): CO2 mole fraction (0-1). Typical: 0-0.20. Example: 0.05.
n2 (float, optional, default=0.0): N2 mole fraction (0-1). Typical: 0-0.10. Example: 0.01.
zmethod (str, optional, default="DAK"): Z-factor method for density calculation. Options: "DAK", "HY", "WYW", "BUR". DAK recommended.
Density Formula: ρg = (P × MW) / (Z × R × T)
Where:
P = pressure (psia)
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)
Density Behavior:
Increases with pressure (gas compresses)
Decreases with temperature (gas expands)
Typical range: 5-20 lb/cuft at reservoir conditions
At standard conditions: ~0.05-0.1 lb/cuft
Returns: Dictionary with:
value (float or list): Density in lb/cuft (matches input p shape)
method (str): Z-factor method used
units (str): "lb/cuft"
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
Using ideal gas law (Z=1) instead of real gas (Z<1)
Temperature in Celsius instead of Fahrenheit
Example Usage:
Result: Density increases from ~8 lb/cuft at 1000 psia to ~18 lb/cuft at 4000 psia.
Note: Gas density is much lower than oil density (typically 5-20 lb/cuft vs 40-60 lb/cuft). Always use reservoir conditions. Account for all non-hydrocarbon components - they significantly affect molecular weight and density.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Input Schema (JSON Schema)
Implementation Reference
- The gas_density tool handler function decorated with @mcp.tool(). Computes gas density using pyrestoolbox.gas.gas_den based on input parameters and Z-factor method.@mcp.tool() def gas_density(request: GasDensityRequest) -> dict: """Calculate gas density (ρg) at reservoir conditions. **CRITICAL GAS PVT PROPERTY** - Computes gas density from real gas equation of state. Essential for gradient calculations, well pressure analysis, and material balance. Gas density increases significantly with pressure due to compressibility. **Parameters:** - **sg** (float, required): Gas specific gravity (air=1.0). Valid: 0.55-3.0. Typical: 0.6-1.2. Example: 0.7. - **degf** (float, required): Reservoir temperature in °F. Valid: -460 to 1000. Typical: 100-400°F. Example: 180.0. - **p** (float or list, required): Pressure(s) in psia. Must be > 0. Can be scalar or array. Example: 3500.0 or [1000, 2000, 3000, 4000]. - **h2s** (float, optional, default=0.0): H2S mole fraction (0-1). Typical: 0-0.05. Example: 0.02. - **co2** (float, optional, default=0.0): CO2 mole fraction (0-1). Typical: 0-0.20. Example: 0.05. - **n2** (float, optional, default=0.0): N2 mole fraction (0-1). Typical: 0-0.10. Example: 0.01. - **zmethod** (str, optional, default="DAK"): Z-factor method for density calculation. Options: "DAK", "HY", "WYW", "BUR". DAK recommended. **Density Formula:** ρg = (P × MW) / (Z × R × T) Where: - P = pressure (psia) - 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) **Density Behavior:** - Increases with pressure (gas compresses) - Decreases with temperature (gas expands) - Typical range: 5-20 lb/cuft at reservoir conditions - At standard conditions: ~0.05-0.1 lb/cuft **Returns:** Dictionary with: - **value** (float or list): Density in lb/cuft (matches input p shape) - **method** (str): Z-factor method used - **units** (str): "lb/cuft" - **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 - Using ideal gas law (Z=1) instead of real gas (Z<1) - Temperature in Celsius instead of Fahrenheit **Example Usage:** ```python { "sg": 0.7, "degf": 180.0, "p": [1000, 2000, 3000, 4000], "h2s": 0.0, "co2": 0.05, "n2": 0.01, "zmethod": "DAK" } ``` Result: Density increases from ~8 lb/cuft at 1000 psia to ~18 lb/cuft at 4000 psia. **Note:** Gas density is much lower than oil density (typically 5-20 lb/cuft vs 40-60 lb/cuft). Always use reservoir conditions. Account for all non-hydrocarbon components - they significantly affect molecular weight and density. """ method_enum = getattr(z_method, request.zmethod) den = gas.gas_den( sg=request.sg, degf=request.degf, p=request.p, h2s=request.h2s, co2=request.co2, n2=request.n2, zmethod=method_enum, ) # Convert numpy array to list for JSON serialization if isinstance(den, np.ndarray): value = den.tolist() else: value = float(den) return { "value": value, "method": request.zmethod, "units": "lb/cuft", "inputs": request.model_dump(), }
- Pydantic model GasDensityRequest defining input schema with validation for sg, degf, p (scalar or list), h2s, co2, n2, zmethod.class GasDensityRequest(BaseModel): """Request model for gas density calculation.""" sg: float = Field( ..., ge=0.5, le=2.0, description="Gas specific gravity (air=1, dimensionless)" ) degf: float = Field( ..., gt=-460, lt=1000, description="Temperature (degrees Fahrenheit)" ) p: Union[float, List[float]] = Field( ..., description="Pressure (psia) - scalar or array" ) h2s: float = Field( 0.0, ge=0.0, le=1.0, description="H2S mole fraction (dimensionless)" ) co2: float = Field( 0.0, ge=0.0, le=1.0, description="CO2 mole fraction (dimensionless)" ) n2: float = Field( 0.0, ge=0.0, le=1.0, description="N2 mole fraction (dimensionless)" ) zmethod: Literal["DAK", "HY", "WYW", "BUR"] = Field( "DAK", description="Z-factor calculation method" ) @field_validator("p") @classmethod def validate_pressure(cls, v): """Validate pressure values.""" if isinstance(v, list): if not all(p > 0 for p in v): raise ValueError("All pressure values must be positive") else: if v <= 0: raise ValueError("Pressure must be positive") return v
- src/pyrestoolbox_mcp/server.py:25-25 (registration)Invocation of register_gas_tools(mcp) in the main server setup, which defines and registers the gas_density tool via @mcp.tool() decorator.register_gas_tools(mcp)