oil_viscosity
Calculate oil viscosity at reservoir conditions using the Beggs-Robinson correlation. Determines how oil flows through reservoirs based on API gravity, temperature, and pressure inputs for petroleum engineering analysis.
Instructions
Calculate oil viscosity (μo).
CRITICAL PVT PROPERTY - Computes oil viscosity at reservoir conditions. Viscosity affects flow rates, pressure drops, and recovery efficiency. Uses Beggs-Robinson (1975) correlation, industry standard for oil viscosity.
Parameters:
api (float, required): Oil API gravity in degrees. Valid: 0-100. Example: 35.0. Higher API = lighter oil = lower viscosity.
degf (float, required): Reservoir temperature in °F. Valid: -460 to 1000. Example: 180.0. Higher temperature = lower viscosity.
p (float or list, required): Pressure(s) in psia. Must be > 0. Can be scalar or array. Example: 3000.0 or [2000, 3000, 4000].
pb (float, optional, default=0.0): Bubble point pressure in psia. Required for accurate calculation. Example: 3500.0.
rs (float or list, optional, default=0.0): Solution GOR at pressure p in scf/stb. If 0, will be calculated. Must match p shape. Example: 600.0.
rsb (float, optional, default=0.0): Solution GOR at bubble point in scf/stb. Required if pb provided. Example: 800.0.
method (str, optional, default="BR"): Correlation method. Only "BR" available.
Viscosity Behavior:
p < pb: Viscosity decreases with pressure (more gas dissolves, oil thins)
p = pb: Viscosity reaches minimum (μob, typically 0.5-5 cP)
p > pb: Viscosity increases with pressure (oil compression)
Typical Ranges:
Light oils (API > 35): 0.5-2 cP at bubble point
Medium oils (API 25-35): 1-10 cP at bubble point
Heavy oils (API < 25): 10-1000+ cP at bubble point
Returns: Dictionary with:
value (float or list): Viscosity in cP (matches input p shape)
method (str): "BR" (Beggs-Robinson)
units (str): "cP"
inputs (dict): Echo of input parameters
Common Mistakes:
Not providing rs when p < pb (will calculate incorrectly)
Using dead oil viscosity instead of live oil viscosity
Temperature in Celsius instead of Fahrenheit
Pressure in barg/psig instead of psia
Example Usage:
Result: Viscosity decreases from ~1.2 cP at 2000 psia to ~0.8 cP at 3500 psia, then increases to ~0.85 cP at 4000 psia (above bubble point).
Note: Viscosity is highly sensitive to temperature and dissolved gas content. Always use reservoir temperature, not separator temperature.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| request | Yes |
Input Schema (JSON Schema)
Implementation Reference
- The @mcp.tool()-decorated handler function that executes the oil viscosity calculation using pyrestoolbox.oil.oil_viso() correlation.@mcp.tool() def oil_viscosity(request: OilViscosityRequest) -> dict: """Calculate oil viscosity (μo). **CRITICAL PVT PROPERTY** - Computes oil viscosity at reservoir conditions. Viscosity affects flow rates, pressure drops, and recovery efficiency. Uses Beggs-Robinson (1975) correlation, industry standard for oil viscosity. **Parameters:** - **api** (float, required): Oil API gravity in degrees. Valid: 0-100. Example: 35.0. Higher API = lighter oil = lower viscosity. - **degf** (float, required): Reservoir temperature in °F. Valid: -460 to 1000. Example: 180.0. Higher temperature = lower viscosity. - **p** (float or list, required): Pressure(s) in psia. Must be > 0. Can be scalar or array. Example: 3000.0 or [2000, 3000, 4000]. - **pb** (float, optional, default=0.0): Bubble point pressure in psia. Required for accurate calculation. Example: 3500.0. - **rs** (float or list, optional, default=0.0): Solution GOR at pressure p in scf/stb. If 0, will be calculated. Must match p shape. Example: 600.0. - **rsb** (float, optional, default=0.0): Solution GOR at bubble point in scf/stb. Required if pb provided. Example: 800.0. - **method** (str, optional, default="BR"): Correlation method. Only "BR" available. **Viscosity Behavior:** - **p < pb**: Viscosity decreases with pressure (more gas dissolves, oil thins) - **p = pb**: Viscosity reaches minimum (μob, typically 0.5-5 cP) - **p > pb**: Viscosity increases with pressure (oil compression) **Typical Ranges:** - Light oils (API > 35): 0.5-2 cP at bubble point - Medium oils (API 25-35): 1-10 cP at bubble point - Heavy oils (API < 25): 10-1000+ cP at bubble point **Returns:** Dictionary with: - **value** (float or list): Viscosity in cP (matches input p shape) - **method** (str): "BR" (Beggs-Robinson) - **units** (str): "cP" - **inputs** (dict): Echo of input parameters **Common Mistakes:** - Not providing rs when p < pb (will calculate incorrectly) - Using dead oil viscosity instead of live oil viscosity - Temperature in Celsius instead of Fahrenheit - Pressure in barg/psig instead of psia **Example Usage:** ```python { "api": 35.0, "degf": 180.0, "p": [2000, 3000, 4000], "pb": 3500.0, "rs": [400, 600, 800], "rsb": 800.0, "method": "BR" } ``` Result: Viscosity decreases from ~1.2 cP at 2000 psia to ~0.8 cP at 3500 psia, then increases to ~0.85 cP at 4000 psia (above bubble point). **Note:** Viscosity is highly sensitive to temperature and dissolved gas content. Always use reservoir temperature, not separator temperature. """ method_enum = getattr(uo_method, request.method) uo = oil.oil_viso( p=request.p, api=request.api, degf=request.degf, pb=request.pb, rs=request.rs, ) # Convert numpy array to list for JSON serialization if isinstance(uo, np.ndarray): value = uo.tolist() else: value = float(uo) return { "value": value, "method": request.method, "units": "cP", "inputs": request.model_dump(), }
- Pydantic BaseModel defining the input parameters, validation rules, and types for the oil_viscosity tool.class OilViscosityRequest(BaseModel): """Request model for oil viscosity calculation.""" api: float = Field(..., gt=0, le=100, description="Oil API gravity (degrees)") degf: float = Field( ..., gt=-460, lt=1000, description="Temperature (degrees Fahrenheit)" ) p: Union[float, List[float]] = Field( ..., description="Pressure (psia) - scalar or array" ) pb: float = Field(0.0, ge=0, description="Bubble point pressure (psia)") rs: Union[float, List[float]] = Field( 0.0, description="Solution GOR (scf/stb) - scalar or array" ) rsb: float = Field( 0.0, ge=0, description="Solution GOR at bubble point (scf/stb)" ) method: Literal["BR"] = Field("BR", description="Calculation method") @field_validator("p", "rs") @classmethod def validate_arrays(cls, v): """Validate array inputs.""" if isinstance(v, list): if not all(val >= 0 for val in v): raise ValueError("All values must be non-negative") else: if v < 0: raise ValueError("Value must be non-negative") return v
- src/pyrestoolbox_mcp/server.py:24-24 (registration)Call to register_oil_tools(mcp) which defines and registers the oil_viscosity tool (along with other oil tools) to the FastMCP server instance.register_oil_tools(mcp)