Skip to content

Run a model in JutulDarcy

One model compiles for more than one simulator. ps.compile(m) writes a deck for OPM Flow, the default; ps.compile(m, "jutuldarcy") writes the same model for JutulDarcy (an open-source simulator in Julia, measured on 0.4.0). The deck is read by PetroScript’s names either way, so the two runs compare by name.

import petroscript as ps
m = ps.load("opm-tests/spe1/SPE1CASE2.DATA")
jutul = ps.compile(m, "jutuldarcy")
assert (jutul.target, list(jutul.files)) == ("jutuldarcy", ["SPE1CASE2.DATA"])
jutul.write("spe1-jutul")

With a JutulDarcy runner named by PETROSCRIPT_JUTULDARCY (install), run = jutul.run(folder="spe1-jutul/run") runs it, and run.field("oil_production_rate"), run.wells("bottom_hole_pressure") read it as a Flow run is read, one row per report. Cell arrays, the grid and the log are not read from a JutulDarcy run yet. A first run starts Julia and checks the deck first (its pre-flight), so it takes longer than Flow’s; jutul.run(folder=..., preflight=False) skips the check.

The compile checks the model against what JutulDarcy honours exactly, and refuses the rest with ps.CompileError: [target.unsupported] for a keyword it cannot honour (a dissolution-rate limit, DRSDT; a well’s efficiency; a production network; an equation-of-state fluid; every keyword never measured on JutulDarcy), and [target.item_dropped] for an item of a keyword it would read past (a THP limit or lift table on a control, a group control, a stated D-factor). A group or region summary quantity only warns: JutulDarcy does not report it. The compile for OPM Flow is never affected.

SPE1CASE1 states DRSDT (gas may not re-dissolve), so it is refused; SPE1CASE2 states none and compiles. To run SPE1CASE1 anyway, remove the statement, knowing it changes the physics:

case1 = ps.load("opm-tests/spe1/SPE1CASE1.DATA")
try:
ps.compile(case1, "jutuldarcy")
except ps.CompileError as refused:
print(str(refused).splitlines()[0]) # [target.unsupported] jutuldarcy cannot honour DRSDT ...
print(case1.find("schedule/*/dissolution_limits")) # where the model holds it
without = case1.set("schedule/2015-01-01/dissolution_limits", None)
ps.compile(without, "jutuldarcy") # compiles: gas may now re-dissolve

examples/two_targets.py compiles SPE1CASE2 for both simulators, runs both and prints the largest difference in oil rate, cumulative oil and BHP. The How PetroScript works says how the results are read.

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