Skip to content

A group tree

examples/group_tree.py
"""A group tree: two platforms under the field, and one oil target the field shares out.
NORTH and SOUTH each hold two producers. The wells are on group control (``control="group"``),
so the field's target, ``ps.groups.ProductionTarget(group=field, oil_rate=...)``, is what they
produce to. Both platforms take their share from the field (``control="parent"``), and NORTH
holds its own limit, so SOUTH makes up the rest. Results are read per group by name.
Flow keywords it exercises: GRUPTREE, WELSPECS with groups, WCONPROD GRUP, GCONPROD, and the
group summaries.
Run it with ``python examples/group_tree.py``; it writes ``out/group_tree/``.
"""
import petroscript as ps
field = ps.Group(name="FIELD")
north = ps.Group(name="NORTH", parent=field)
south = ps.Group(name="SOUTH", parent=field)
wells = [
ps.Well(name="N1", i=2, j=8, group=north), ps.Well(name="N2", i=8, j=9, group=north),
ps.Well(name="S1", i=2, j=2, group=south), ps.Well(name="S2", i=9, j=3, group=south),
]
m = ps.Model(
name="GROUP_TREE",
units="metric",
start="2025-01-01",
grid=ps.grid.Cartesian(shape=(10, 10, 3), dx=100.0, dy=100.0, dz=30.0, top=2000.0),
rock=ps.Rock(porosity=0.2, permeability=200.0, vertical_ratio=0.1,
compressibility=5.0e-5, reference_pressure=200.0),
fluid=ps.fluid.OilWater(
oil=ps.pvt.DeadOil(pressure=[50.0, 200.0, 400.0], oil_fvf=[1.12, 1.10, 1.08],
oil_viscosity=[1.8, 2.0, 2.3]),
water=ps.pvt.Water(reference_pressure=200.0, fvf=1.01, compressibility=4.5e-5,
viscosity=0.4, viscosibility=0.0),
oil_surface_density=850.0,
water_surface_density=1020.0,
),
relperm=[ps.relperm.OilWater(sw=[0.2, 0.4, 0.6, 0.8], krw=[0.0, 0.05, 0.2, 0.5],
krow=[0.9, 0.4, 0.1, 0.0], pcow=[0.0, 0.0, 0.0, 0.0])],
initial=ps.initial.Equilibrium(datum_depth=2000.0, datum_pressure=200.0,
oil_water_contact=2100.0),
groups=[field, north, south],
wells=wells,
schedule=ps.Schedule(
end="2026-01-01",
report="monthly",
events=[ps.Event(
"2025-01-01",
*(ps.Perforate(well=well.name, k=(1, 2), diameter=0.2) for well in wells),
*(ps.Produce(well=well.name, control="group", oil_rate_limit=400.0, bhp_limit=80.0)
for well in wells),
ps.groups.ProductionTarget(group=field, oil_rate=600.0),
ps.groups.ProductionTarget(group=north, control="parent", oil_rate_limit=200.0,
on_violation="rate"),
ps.groups.ProductionTarget(group=south, control="parent"),
)],
),
summary=ps.Summary(field=["oil_production_rate"],
groups={"NORTH": ["oil_production_rate"], "SOUTH": ["oil_production_rate"]}),
)
for issue in m.check():
print(issue.severity, issue.address, issue)
deck = ps.compile(m)
deck.write("out/group_tree")
if ps.simulators():
run = deck.run(folder="out/group_tree/run")
groups = run.groups("oil_production_rate")
for name, rate in (*((name, groups.filter(group=name)) for name in ("NORTH", "SOUTH")),
("FIELD", run.field("oil_production_rate"))):
print(f"{name} oil rate at the end: {rate['value'][-1]:.0f} {rate['unit'][-1]}")
else:
print("no simulator found (set PETROSCRIPT_FLOW, or put flow on PATH); the deck is in "
"out/group_tree")

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