Add a rule that fires during the run
A rule (Flow’s ACTIONX) watches the run and changes the schedule when its condition holds: shut
a well whose water cut passes 50 %, open a standby producer when the field rate drops. In
PetroScript it is ps.actions.When(condition, then=[changes], name=...), dated like any other
change with m.at(date, rule) or in a ps.Event. A rule dated at the start is in force from
the first day.
A condition compares a quantity the run computes with a number:
| Reads | Spelled | Example |
|---|---|---|
| A field quantity | ps.actions.field().<name> | ps.actions.field().water_cut > 0.9 |
| A well’s quantity | ps.actions.well(<the ps.Well>).<name> | ps.actions.well(producer).gas_oil_ratio > 2.0 |
| A group’s quantity | ps.actions.group(<the ps.Group>).<name> | ps.actions.group(north).oil_production_rate < 100.0 |
| The date | ps.actions.date() | ps.actions.date() >= "2027-01-01" |
The names are the summary’s (water_cut, gas_oil_ratio, oil_production_rate,
bottom_hole_pressure; summary names). The threshold is a bare
number in the model’s units, as the summary reports the quantity: a water cut is a fraction,
a FIELD gas-oil ratio Mscf/stb (shut above 2,000 scf/stb is > 2.0), a METRIC one sm3/sm3
(units).
import petroscript as ps
m = ps.load("opm-tests/spe1/SPE1CASE2.DATA") # FIELD: GOR in Mscf/stbproducer = m.get("wells/PROD") # a rule reads the well itselfhigh_gor = ps.actions.When( ps.actions.well(producer).gas_oil_ratio > 2.0, # 2,000 scf/stb then=[ps.Adjust(well="PROD", oil_rate=5000.0)], # cut the oil target name="CUT_GOR",)late = ps.actions.When( ps.actions.field().oil_production_rate < 1000.0, ps.actions.date() >= "2020-01-01", # every condition must hold then=[ps.Shut(well="PROD")], name="LATE_SHUT",)m = m.at(m.start, high_gor, late)deck = ps.compile(m).files["SPE1CASE2.DATA"]assert "WGOR 'PROD' > 2" in deck and "ENDACTIO" in deckprint(m.find("schedule/*/actions/*")) # the rules, by addressWhat goes wrong:
- A well given by name:
TypeError: ps.actions.well() takes a well handle, not the name 'PROD'; look it up first: m.get("wells/PROD"). - A threshold with a unit:
[units.wrong_kind] an expression's number takes a bare number in the model's units. State the number in the model’s units. - A rule fires once unless it says otherwise:
runs=is how many times it may fire, andminimum_wait=the days between firings. A rule over every well that acts onwell="?"(the wells whose condition fired) must stateruns=, or only the first well to cross changes. - A threshold typed in the wrong unit runs without complaint: a FIELD GOR of
2000means 2,000 Mscf/stb and never fires. Check the threshold against the summary’s unit (run.wells("gas_oil_ratio")["unit"]).
examples/water_cut_rule.py runs a water-cut rule in Flow and checks the date it fired against Flow’s own log. User quantities (UDQ) and lookup tables (UDT), which a rule’s condition can read, are in the user-defined reference.
PetroScript is licensed under the Apache License 2.0. © 2026 Blauweiss EDV LLC. PetroScript by Blauweiss AI.For AI agents: llms.txt