Chapter 4 — Reading a finished run
A run leaves its files in a folder. ps.results.open(folder) reads them by PetroScript’s
names, the names a model asks for them by. Here case_dir is a finished run’s folder, the
one deck.run(folder=...) wrote its files into:
run = ps.results.open(case_dir) # one call, then everything off itoil = run.field("oil_production_rate") # polars: date, value, unitbhp = run.wells("bottom_hole_pressure") # polars: date, well, value, unitlong_form = run.frame() # date, scope, name, quantity, value, unitassert set(bhp["well"]) == {"INJ1", "PROD1"}There is one spelling: a Flow mnemonic is answered with its PetroScript name, so
run.field("FOPR") is refused with run.field("oil_production_rate"). run.groups(name)
and run.regions(name) read the other scopes the same way. A row is one time step the
simulator wrote to the summary, not a report date: Flow writes one at every time step it
takes unless the deck thins them (RPTONLY, SUMTHIN), so SPE1CASE1’s first rows sit at
days 1, 4 and 11.6, before its first report at day 31. run.times holds those times, in days since the start.
Cell arrays read by name too. run.initial["pressure"] is the state at the start,
run.restart(at="2011-06-01")["pressure"] the state at a restart report and
run.restarts every one of them by date, run.static["pore_volume"] the arrays that do
not change, and run.grid the grid the run wrote. Each array is a read-only (nx, ny, nz)
array with NaN in the cells the run did not simulate, so an unmasked average comes back NaN
instead of quietly low: weight by run.static["pore_volume"] (the simulator’s own, its
net-to-gross included) with np.nansum, which is 0 in those cells.
run.units is the run’s unit system ("metric", "field" or "lab"), read from the
restart file’s header, never inferred: a file in another unit system is refused with
results.unit_system, and one that marks what a run’s views do not read (a dual-porosity
run, a local grid, more than one reservoir) with results.dual_porosity or
results.grid_type, so a local grid’s arrays never stand in for the global ones.
run.phases is the phases it simulated, oil, water and gas in that order, and run.log what
the simulator said while it ran (run.log.warnings, run.log.errors). A reader that needs a file the run did not keep is refused, naming the
file: a summary-only folder answers summary reads and refuses the rest.
deck.run() returns the same Run for the folder it wrote, and ps.results.open reads a
folder at any time after.
PetroScript is licensed under the Apache License 2.0. © 2026 Blauweiss EDV LLC. PetroScript by Blauweiss AI.For AI agents: llms.txt