Skip to content

Install and engines

PetroScript is a Python library. It builds, checks, compiles and writes models on its own; to run a model it calls a simulator you install beside it. Every engine is a separate program, found through one environment variable, so PetroScript works the same whether the engine is on your machine or behind a container.

What you wantWhat you need
Build, check, compile and write decks; load decks; read finished runsPetroScript alone
Run a deck in OPM Flow (deck.run())OPM Flow: PETROSCRIPT_FLOW, or flow on PATH
Run a deck in JutulDarcy (ps.compile(m, "jutuldarcy"))A JutulDarcy runner: PETROSCRIPT_JUTULDARCY
Make a lift table with NeqSim (ps.lift.generate)A NeqSim runner: PETROSCRIPT_NEQSIM

Python 3.10 or newer. From a clone of the repository:

python -m venv .venv
. .venv/bin/activate
pip install . # numpy, polars and pydantic come with it
pip install ".[excel]" # optional: read spreadsheets (ps.bundle)

Check it:

import petroscript as ps
print(ps.simulators()) # the simulators found; [] before any is installed

OPM Flow is the default target: ps.compile(m) writes a deck for it. Install it from opm-project.org (Linux packages, or the OPM Docker image), then either put flow on PATH or name it:

export PETROSCRIPT_FLOW=/usr/bin/flow

deck.run() looks for PETROSCRIPT_FLOW first, then flow on PATH, and asks it for its version: a program whose first line is not OPM Flow’s banner (flow 2026.04) is left out. PetroScript is measured on OPM Flow 2026.04. ps.simulators() lists what it found; deck.run(simulator=...) names one for a single run. Without Flow, deck.run() raises ps.RunError: no opm-flow simulator found.

JutulDarcy runs as a separate program, the runner: any program that runs Julia with the Julia packages JutulDarcy and GeoEnergyIO loadable. With Julia installed:

julia -e 'using Pkg; Pkg.add(["JutulDarcy", "GeoEnergyIO"])'
printf '#!/bin/sh\nexec julia "$@"\n' > ~/bin/jutuldarcy && chmod +x ~/bin/jutuldarcy
export PETROSCRIPT_JUTULDARCY=~/bin/jutuldarcy

PetroScript writes its own driver beside the deck and calls <runner> driver.jl ... in the case folder; the runner must print jutuldarcy <version> for driver.jl --version, or it is refused. PetroScript is measured on JutulDarcy 0.4.0. When the variable is set, ps.simulators() lists it with the target jutuldarcy.

NeqSim makes lift tables (ps.lift.generate). Its runner is a Python that can import jpype, with NEQSIM_JAR naming NeqSim’s jar. You need a Java runtime, the jar from NeqSim’s releases, and:

pip install jpype1
export NEQSIM_JAR=/opt/neqsim/neqsim-3.25.0.jar
export PETROSCRIPT_NEQSIM=$(which python)

PetroScript writes its driver beside the request and calls <runner> driver.py ...; the runner must print neqsim <version> for driver.py --version. PetroScript is measured on NeqSim 3.25.0. NeqSim does not appear in ps.simulators(), which lists deck simulators; a generate call without a runner raises ps.RunError: no NeqSim runner: PETROSCRIPT_NEQSIM is not set.

The variable may name any executable, so a short script can relay the call into a container. It must pass its arguments through and run in the current folder, mounted at the same path:

#!/bin/sh
# flow-docker: OPM Flow from its image, in the current folder
exec docker run --rm -v "$PWD:$PWD" -w "$PWD" <an OPM Flow image> flow "$@"

export PETROSCRIPT_FLOW=/path/to/flow-docker then runs every deck through it.

PetroScript is licensed under the Apache License 2.0. © 2026 Blauweiss EDV LLC. PetroScript by Blauweiss AI.For AI agents: llms.txt