PVT API

From wiki.pengtools.com
Revision as of 11:01, 15 July 2026 by MishaT (talk | contribs) (Example)
Jump to: navigation, search

PVT API

The PVT calculator models reservoir fluid properties (oil, gas, water) over a pressure range using various correlations, and returns property curves (plots), single‑point reservoir‑condition values (solution), and a stepped property table (results) available in PVT calculator of the pengtools.

Endpoints

All endpoints require the Authorization: Bearer <api_key> header and are subject to rate limiting. The response envelope is always { "success": <bool>, "data": <payload> }

Method Path Purpose
POST /pvt-calculator/calc Synchronous — compute and return the result in the same request
POST /pvt-calculator/calc-async Asynchronous — enqueue a job, return a {token}
GET /pvt-calculator/{token}/status Job status and progress
GET /pvt-calculator/{token}/output-data Job result (same shape as the sync data)
GET /pvt-calculator/{token}/input-data The input the job was created with
POST /pvt-calculator/{token}/start Reset and re-run the job
POST /pvt-calculator/{token}/stop Stop a running job
DELETE /pvt-calculator/{token} Delete the job

Use /calc (synchronous) for normal interactive requests — a single PVT model computes in well under a second and the result comes back in the HTTP response.

Use /calc-async only for batch/heavy workloads where you would rather not hold an open HTTP connection. The async path enqueues an api_task row that is picked up by the CalcDaemon worker; you then poll status and fetch output-data. The async job runs the same calculatePvt() code as the sync endpoint, so the result is identical for identical input.

Synchronous request

POST /pvt-calculator/calc

The request body is a JSON object containing PVT calculator attributes plus two optional unit-control keys:

{
  "unit_system": "RU",
  "defaultFluidType": "OIL",
  "maximumPressure": 300,
  "reservoirPressure": 300,
  "temperature": 90,
  "pBubbleInitial": 200,
  "rsbInitial": 60,
  "isRsbUsedForPb": true,
  "sgOil": 0.85,
  "sgGas": 0.75,
  "sgWater": 1.0
}

On success the endpoint returns HTTP 200 with:

{ "success": true, "data": { "plots": {},"solution": {}, "results": {}  } }

Where data carries:

  • plots — property curves
  • solution — single-point reservoir-condition values
  • results — stepped property table

Units

Input field names (e.g., maximumPressure, temperature) carry no unit. The unit system determines how values are interpreted.

unit_system a shortcut that applies a whole preset of units. Accepted values (case‑insensitive):

  • METRIC - Metric system
  • FIELD - Field system

Example

{
  "unit_system": "METRIC",
  "maximumPressure": 300,
  "temperature": 90
}

Attribute units

Field METRIC FIELD
maximumPressure ATM PSIA
minimumPressure ATM PSIA
reservoirPressure ATM PSIA
pBubbleInitial ATM PSIA
temperature CELSIUS FAHRENHEIT
rsbInitial M3_PER_M3 SCF_PER_BBL
sgOil SPECIFIC_GRAVITY API
sgGas SPECIFIC_GRAVITY SPECIFIC_GRAVITY
sgWater SPECIFIC_GRAVITY SPECIFIC_GRAVITY

Input parameter specification

Ranges below are expressed in internal units (the units the validator sees), with common METRIC/FIELD equivalents for convenience.

Field Required Internal unit Range (internal) METRIC FIELD Notes
defaultFluidType yes OIL or GAS Selects the primary fluid path. WATER is only valid inside forFluid.
maximumPressure yes PSIA 25 … 10000 ≈ 1.7 … 680 ATM 25 … 10000 psi Upper bound of the pressure sweep.
minimumPressure no (default 14.6) PSIA 14.6 … 10000 ≈ 1.0 … 680 ATM 14.6 … 10000 psi Lower bound of the sweep; must be ≤ maximumPressure.
reservoirPressure yes PSIA 25 … 10000 ≈ 1.7 … 680 ATM 25 … 10000 psi Reservoir-condition pressure for solution.
temperature yes RANKIN 529.47 … 851.67 ≈ 21 … 200 °C ≈ 70 … 392 °F Reservoir-condition temperature for solution.
pBubbleInitial yes PSIA 0 … 20000 ≈ 0 … 1361 ATM 0 … 20000 psi Initial bubble point. See isRsbUsedForPb.
rsbInitial yes (when OIL) M3_PER_M3 > 0 m³·m⁻³ scf/bbl Solution GOR at bubble point.
sgOil yes SPECIFIC_GRAVITY 0.75 … 0.99 0.75 … 0.99 SG ≈ 11.4 … 57.2 °API Oil specific gravity. US system accepts API.
sgGas yes SPECIFIC_GRAVITY 0.55 … 1.8 0.55 … 1.8 SG 0.55 … 1.8 SG Gas specific gravity (air = 1).
sgWater yes SPECIFIC_GRAVITY 0.9 … 1.2 0.9 … 1.2 SG 0.9 … 1.2 SG Water specific gravity.
isRsbUsedForPb no (default false) bool true / false true: derive bubble point from rsbInitial. false: derive GOR from pBubbleInitial.
forFluid no (default all) subset of OIL,GAS,WATER Which fluids to compute.
needPlots no (default true) bool true / false Include the plots block.
needSolution no (default true) bool true / false Include the solution block.
needResults no (default true) bool true / false Include the results block.

Notes

For an oil model, both pBubbleInitial and rsbInitialare required; isRsbUsedForPb decides which one is the input and which is derived.

Response format

On success, data contains up to three blocks, gated by needPlots / needSolution / needResults. Each block is keyed by fluid (OIL, GAS, WATER) — only the fluids in forFluid (and, for oil curves, only when defaultFluidType is OIL) are present.

Plots - property curves

Each fluid maps curve names to an array of [pressure, value] pairs, one pair per pressure step (200 steps by default). The pressure axis is in the output pressure unit (see Units section).

Fluid Curves
OIL Rs, density, fvf, viscosity, tension, compressibility
GAS ZFactor, densitygas, fvfgas, viscositygas, compressibilitygas
WATER densitywater, fvfwater, viscositywater, compressibilitywater, tensionwater

Example

"plots": {
  "OIL": {
    "Rs":      [[14.6, 0.0], [36.4, 5.1], "…", [4351.13, 200.0]],
    "fvf":     [[14.6, 1.02], "…"],
    "density": [[14.6, 812.4], "…"]
  }
}

Solution - reservoir‑condition values

Single scalar values evaluated at reservoir conditions.

Fluid Keys
OIL solution_pBubble, solution_rsb, solution_Rs, solution_compressibility, solution_density, solution_fvf, solution_deadOilViscosity, solution_viscosity, solution_tension
GAS solution_ZFactor, solution_compressibilitygas, solution_densitygas, solution_fvfgas, solution_viscositygas
WATER solution_compressibilitywater, solution_densitywater, solution_fvfwater, solution_viscositywater, solution_tensionwater

Example

"solution": {
  "OIL": {
    "solution_pBubble": 115.0,
    "solution_rsb": 60.0,
    "solution_density": 756.0,
    "solution_fvf": 1.197
  }
}

Results - stepped table

Each fluid maps to a list of rows. The first row is standard conditions; the next nine rows are stepped pressures between the bubble point (oil) or p/2 (gas/water) and the maximum pressure. Each row is a positional array with these columns:

Fluid Columns (in order)
OIL pressure, Rs, density, fvf, viscosity, temperature, compressibility, tension
GAS pressure, ZFactor, densitygas, fvfgas, viscositygas, temperature, compressibilitygas
WATER pressure, compressibilitywater, densitywater, fvfwater, viscositywater, temperature, tensionwater
"results": {
  "OIL": [
    [1.0, 0.0, 845.0, 1.01, 2.1, 20.0, 0.00012, 30.5],
    [12.8, 22.0, 812.4, 1.08, 1.6, 90.0, 0.00018, 12.1],
    "… 8 more rows …"
  ]
}

HTTP status codes

Status Meaning Body (data)
200 Success { plots, solution, results }
401 Missing or invalid API key Yii error payload
404 Unknown async token Yii error payload
422 Validation / calculation error { "errors": … }
429 Rate limit exceeded error message

422 - validation and calculation errors

Field validation errors are keyed by attribute:

{ "success": false, "data": { "errors": { "temperature": ["Temperature must be no less than 529.47."] } } }

Errors raised while loading the body or running the calculation (e.g. an unknown defaultFluidType, or a physical guard inside calculatePvt()) come back as a flat list:

{ "success": false, "data": { "errors": ["Invalid input: Wrong default fluid type"] } } 

429 - rate limiting

Limits are per API key over a 60‑second window, and the cap depends on the license tier that grants access to the pvtCalculator module.

Asynchronous flow

POST /pvt-calculator/calc-async        →  { "token": "<token>" }
GET  /pvt-calculator/<token>/status    →  { "status": <code>, "progress": <number> }
GET  /pvt-calculator/<token>/output-data →  { plots, solution, results }

status is returned as a numeric code (the raw api_task.status value), not a string:

Code Meaning
1 CREATED
2 IN_PROGRESS
3 ERROR
4 STOPPED
5 SUCCESS

A job cycles 1 → 2 → 5 (or 3 / 4). Poll status until it reaches a terminal code (3, 4, 5), then fetch output-data when it is 5. The CalcDaemon worker must be running for jobs to progress.