ps.groups
ps.groups.Branch
Section titled “ps.groups.Branch”ps.groups.Branch() -> None
A pipeline of the extended production network, from one node to the next (BRANPROP).
ps.groups.Branch(name="b1", from_node=inlet, to_node=sink, uses_no_pressure_loss=True)
carries the production of the node inlet to sink with no pressure drop.
The pressure drop along it is read from lift_table (a ps.lift.ProductionTable),
or is none (uses_no_pressure_loss), or the branch is out of the network
(is_disabled). A branch is held in ps.groups.Network(branches=[...]), its address
network/branches/<n>, counted from 1.
ps.groups.Economics
Section titled “ps.groups.Economics”ps.groups.Economics(*, group: Group, minimum_oil_rate: Optional[ScalarPropertyInput] = None, minimum_gas_rate: Optional[ScalarPropertyInput] = None, maximum_water_cut: Optional[ScalarPropertyInput] = None, maximum_gas_oil_ratio: Optional[ScalarPropertyInput] = None, maximum_water_gas_ratio: Optional[ScalarPropertyInput] = None) -> None
A group’s economic limits (GECON): the rates and ratios its production is tested against.
ps.groups.Economics(group=north, minimum_oil_rate=50.0, maximum_water_cut=0.95) tests
north against an oil rate of 50 and a water cut of 0.95.
Each stated limit is a threshold the group’s production is tested against;
an unstated one is left to the simulator. At least one is stated, each positive. In
Flow, an oil or gas rate below its minimum closes every well under the group; a ratio
past its maximum calls for a workover, which the card states as none, so Flow takes no
action on it. It is stated in ps.Event(date, ...), at
schedule/<date>/<group>/economics. The rates are surface rates and the gas-oil and
water-gas ratios surface ratios, in the model’s units; the water cut is a fraction.
ps.groups.Efficiency
Section titled “ps.groups.Efficiency”ps.groups.Efficiency(*, group: Group, factor: ScalarPropertyInput, network_propagation: Optional[Literal['apply_factor', 'ignore_factor']] = None) -> None
A group’s efficiency (up-time) factor (GEFAC): the fraction of the time it flows.
ps.groups.Efficiency(group=north, factor=0.95) counts the rates of north, a group down
5% of the time, at 95% where they are summed into its parent and its cumulatives.
It is stated in ps.Event(date, ...), at schedule/<date>/<group>/efficiency, and
holds from that date; factor is positive and dimensionless.
ps.groups.FuelGas
Section titled “ps.groups.FuelGas”ps.groups.FuelGas(*, group: Group, intent: Literal['rate', 'fraction_of_produced'], consumption_rate: Optional[ScalarPropertyInput] = None, produced_gas_fraction: Optional[ScalarPropertyInput] = None) -> None
A group’s fuel gas (GCONSUMP): the gas it consumes, taken from what it produces.
ps.groups.FuelGas(group=north, intent="rate", consumption_rate=5000.0) burns 5000 of
the gas north produces as fuel, a surface gas rate in the model’s units.
intent="fraction_of_produced" states a fraction instead
(produced_gas_fraction=0.05), written as GCONSUMP item 2’s negative value (-0.05).
Flow 2026.04 reads item 2 as a gas rate only (opm-common’s GConSump), so it takes that
value as a consumption rate of -0.05, not as 5% of the group’s gas. It is stated in
ps.Event(date, ...), at schedule/<date>/<group>/fuel_gas.
ps.groups.GasLift
Section titled “ps.groups.GasLift”ps.groups.GasLift(*, well, enabled: bool = True, maximum_lift_gas_rate: Optional[ScalarPropertyInput] = None, weight_factor: Optional[ScalarPropertyInput] = None, minimum_lift_gas_rate: Optional[ScalarPropertyInput] = None, gas_factor: Optional[ScalarPropertyInput] = None, enforce_gas_limit: bool | None = None) -> None
A well’s part in gas-lift optimization (WLIFTOPT): whether and how much lift gas it gets.
ps.groups.GasLift(well="P1", maximum_lift_gas_rate=50000.0) lets the lift optimizer give P1
up to 50000 of lift gas.
enabled=False holds the well’s lift gas fixed at maximum_lift_gas_rate instead, or,
with no maximum_lift_gas_rate, where it stands. Enabled with no
maximum_lift_gas_rate, the most the optimizer gives the well is the largest lift-gas
value of the well’s ps.lift.ProductionTable. It holds the well by its name
(well="P1"; a ps.Well given is read by its name). It is stated in
ps.Event(date, ...), at schedule/<date>/<well>/gas_lift; the lift-gas rates are gas
rates in the model’s units.
ps.groups.GasLiftOptimization
Section titled “ps.groups.GasLiftOptimization”ps.groups.GasLiftOptimization(*, scope: Literal['field', 'group', 'well'], group: Group | None = None, well=None, maximum_lift_gas_rate: Optional[ScalarPropertyInput] = None, maximum_total_gas_rate: Optional[ScalarPropertyInput] = None, incremental_gas_rate: Optional[ScalarPropertyInput] = None, minimum_economic_gradient: Optional[ScalarPropertyInput] = None, optimization_interval: Optional[ScalarPropertyInput] = None, use_newton: bool | None = None) -> None
Gas-lift optimization: how the field’s lift gas is shared out, and a group’s or well’s cap.
ps.groups.GasLiftOptimization(scope="field", incremental_gas_rate=10000.0, minimum_economic_gradient=0.001) shares the field’s lift gas out in steps of 10000 while each
step still gains 0.001 of oil per unit of gas.
scope says what is stated: "field" the optimization itself (LIFTOPT); "group" a
group’s limits on lift gas (GLIFTOPT), which Flow refuses unless a LIFTOPT stands before
it, so the field’s scope is stated at or before the group’s date; "well" a well’s
largest lift gas (WLIFTOPT), as ps.groups.GasLift states it. A well’s scope holds the
well by its name (well="P1"; a ps.Well given is read by its name). It is stated in
ps.Event(date, ...), at schedule/<date>/gas_lift_optimization for the field and
schedule/<date>/<group or well>/gas_lift_optimization otherwise. The rates are gas
rates in the model’s units.
ps.groups.GasSales
Section titled “ps.groups.GasSales”ps.groups.GasSales(*, group: Group, sales_rate: ScalarPropertyInput, maximum_rate: Optional[ScalarPropertyInput] = None, minimum_rate: Optional[ScalarPropertyInput] = None, action: Literal['none', 'reduce_group_gas_rate'] = 'none') -> None
A group’s gas sales target (GCONSALE): the gas it sells, the surplus re-injected.
ps.groups.GasSales(group=north, sales_rate=500000.0, maximum_rate=600000.0, action="reduce_group_gas_rate") sells the gas of north at 500000 and re-injects the
surplus; past 600000 its gas production is cut.
It is stated in ps.Event(date, ...), at schedule/<date>/<group>/gas_sales; the
rates are surface gas rates in the model’s units.
ps.groups.GuideRates
Section titled “ps.groups.GuideRates”ps.groups.GuideRates(*, phase: Literal['total_rate', 'oil', 'water', 'gas', 'liquid', 'formula'], minimum_interval: ScalarPropertyInput = 0, potential_exponent: ScalarPropertyInput, denominator_constant: ScalarPropertyInput, ratio1_coefficient: ScalarPropertyInput, ratio1_exponent: ScalarPropertyInput, ratio2_coefficient: ScalarPropertyInput, ratio2_exponent: ScalarPropertyInput, incremental: bool = True, damping_factor: Optional[ScalarPropertyInput] = None, use_free_gas_only: bool | None = None, minimum_guide_rate: Optional[ScalarPropertyInput] = None) -> None
The guide-rate formula (GUIDERAT): how a group’s target is shared among its producers.
ps.groups.GuideRates(phase="oil", potential_exponent=1.0, denominator_constant=1.0, ratio1_coefficient=0.5, ratio1_exponent=1.0, ratio2_coefficient=0.0, ratio2_exponent=0.0)
weighs each well’s oil potential down as its water-oil ratio rises.
A guide rate is pA / (B + C*wD + E*g**F), p the potential of phase and w and g the
water and gas ratios read against it (for "gas", w is the water-gas ratio and g the
oil-gas ratio); A to F are potential_exponent, denominator_constant,
ratio1_coefficient, ratio1_exponent, ratio2_coefficient and
ratio2_exponent, each dimensionless. Flow gives every producer with no guide rate of
its own (ps.wells.GuideRate) its guide rate by the formula, and every group whose
ps.groups.ProductionTarget(guide_phase=) is "formula"; injectors take none from it.
It is stated in ps.Event(date, ...), at schedule/<date>/guide_rates, and
minimum_interval is in days in every unit system.
Flow runs the formula of "oil" or "gas" only. "water" and "total_rate"
write GUIDERAT’s WAT and RAT, which m.check() passes and Flow refuses when it loads the
deck; "liquid" and "formula" have no GUIDERAT word, m.check() passes them too,
and ps.compile refuses them with a plain ValueError whose message starts
[target.choice.unknown]: not a ps.PetroScriptError, with no .code.
The six coefficients A to F are stated, never assumed: Flow’s own default for each is 0, which leaves the denominator at zero, where Flow sets every guide rate to zero with a warning (GuideRateModel::eval), so no default stands for “the formula the author meant”; a loaded GUIDERAT states all six, as a deck must.
ps.groups.InjectionTarget
Section titled “ps.groups.InjectionTarget”ps.groups.InjectionTarget(*, group: Group, phase: Literal['oil', 'water', 'gas'], rate: Union[ScalarPropertyInput, Expression, NoneType] = None, reservoir_volume: Union[ScalarPropertyInput, Expression, NoneType] = None, reinjection_fraction: Union[ScalarPropertyInput, Expression, NoneType] = None, voidage_replacement: Union[ScalarPropertyInput, Expression, NoneType] = None, control: Optional[Literal['parent']] = None, rate_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, reservoir_volume_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, reinjection_fraction_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, voidage_replacement_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, available_to_parent: bool | None = None, guide_rate: Optional[ScalarPropertyInput] = None, guide_basis: Optional[Literal['net_voidage', 'rate', 'reservoir_volume', 'voidage']] = None, reinjection_source_group: Group | None = None, voidage_source_group: Group | None = None, phase_word: str | None = None) -> None
A group’s injection control of phase (GCONINJE), a well’s ps.Inject rule.
The one quantity given bare is the group’s target: rate (the phase’s surface rate),
reservoir_volume, reinjection_fraction (of the gas or water the group produces) or
voidage_replacement (of the voidage it produces); a reinjection or voidage target takes
the others below it as limits (rate_limit, …)::
ps.groups.InjectionTarget(group=field, phase="water", voidage_replacement=1.0)control="parent" puts the group under its parent’s control, its quantities limits; a
group that states no target and no control holds its limits alone. available_to_parent
says whether a parent group may set the group’s rate from its guide rate.
It is stated in ps.Event(date, ...), at schedule/<date>/<group>/injection_target,
and holds from that date. In the model’s units, rate is a surface rate of phase
and reservoir_volume a reservoir rate; reinjection_fraction and
voidage_replacement are dimensionless. A target may be a ps.actions.UserQuantity
the run evaluates.
ps.groups.Network
Section titled “ps.groups.Network”ps.groups.Network() -> None
The production network: its nodes and the pipelines between them, to a terminal pressure.
ps.groups.Network(name="n1", nodes=[inlet, sink], branches=[branch]) is an extended network
of two nodes and the branch between them; ps.Model(network=) holds it from the start.
An extended network (kind="extended") states its own nodes and branches (NETWORK in
RUNSPEC, BRANPROP, NODEPROP, NEFAC); a standard one (kind="standard") is the group
tree’s pipelines, one node per group (GRUPNET). Its address is network
(network/nodes/<n>, network/branches/<n>). A model with a network flows oil, water
and gas, or it is refused (schedule.networks.requires_three_phases).
ps.groups.Node
Section titled “ps.groups.Node”ps.groups.Node() -> None
A node of the production network, where pipelines meet; a terminal one holds a pressure.
ps.groups.Node(name="N1", terminal_pressure=20.0) is a terminal node held at a pressure of
20; a ps.groups.Branch joins two nodes.
An extended network writes its nodes in NODEPROP (and their efficiencies in NEFAC); a
standard one writes one node per group in GRUPNET. A node is held in
ps.groups.Network(nodes=[...]), its address network/nodes/<n>, counted from 1.
terminal_pressure is in the model’s pressure unit.
ps.groups.PressureMaintenance
Section titled “ps.groups.PressureMaintenance”ps.groups.PressureMaintenance(*, group: Group, intent: Literal['gas_injection', 'oil_injection', 'water_injection', 'production', 'disabled'], region: int, fluid_in_place_set: str | None = None, basis: Optional[Literal['gas_reservoir_injection', 'gas_surface_injection', 'oil_reservoir_injection', 'oil_surface_injection', 'production_reservoir_volume', 'water_reservoir_injection', 'water_surface_injection']] = None, pressure: Optional[ScalarPropertyInput] = None, alpha: Optional[ScalarPropertyInput] = None, beta: Optional[ScalarPropertyInput] = None) -> None
A group maintaining a fluid-in-place region’s average pressure (GPMAINT).
region is held at pressure by adjusting the group’s flow basis names, with the
controller’s constants alpha and beta. A region is named by its number: in the
model’s fluid-in-place map (ps.Regions(fluid_in_place=)), or in the set
fluid_in_place_set names (a key of ps.Regions(fluid_in_place_sets=)); 0 is the whole
field::
ps.groups.PressureMaintenance( group=field, intent="water_injection", basis="water_surface_injection", region=2, fluid_in_place_set="ABC", pressure=250.0, alpha=70.0, beta=90.0,)In the model’s units, pressure is the target pressure, alpha the controller’s
proportional constant (a reservoir-volume rate per unit pressure, the rate per day, or per
hour in a lab model) and beta its integral time constant, in days, or in hours in a lab
model, as GPMAINT reads them. All three are stated, each positive, unless intent is
"disabled", which stops the maintenance and takes no basis. It is stated in
ps.Event(date, ...), at schedule/<date>/<group>/pressure_maintenance.
ps.groups.ProductionTarget
Section titled “ps.groups.ProductionTarget”ps.groups.ProductionTarget(*, group: Group, oil_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, water_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, gas_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, liquid_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, reservoir_volume: Union[ScalarPropertyInput, Expression, NoneType] = None, control: Optional[Literal['parent']] = None, oil_rate_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, water_rate_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, gas_rate_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, liquid_rate_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, reservoir_volume_limit: Union[ScalarPropertyInput, Expression, NoneType] = None, on_violation: Optional[Literal['none', 'shut_worst_well', 'rate']] = None, on_water_violation: Optional[Literal['none', 'rate']] = None, on_gas_violation: Optional[Literal['none', 'rate']] = None, on_liquid_violation: Optional[Literal['none', 'rate']] = None, available_to_parent: bool | None = None, guide_rate: Optional[ScalarPropertyInput] = None, guide_phase: Optional[Literal['oil', 'water', 'gas', 'liquid', 'formula']] = None) -> None
A group’s production control (GCONPROD), the control rule of a well’s ps.Produce.
The one quantity given bare is the group’s target, and every other quantity is a limit
(water_rate_limit, …)::
ps.groups.ProductionTarget(group=north, oil_rate=5000.0, water_rate_limit=2000.0)control="parent" puts the group under its parent’s control: the parent sets the target,
so every stated quantity is a limit. A group that states no target and no control holds its
limits alone. available_to_parent says whether a parent group may set the group’s rate
from its guide rate.
It is stated in ps.Event(date, ...), at schedule/<date>/<group>/production_target,
and holds from that date. In the model’s units, oil_rate, water_rate,
gas_rate and liquid_rate and their limits are surface rates and
reservoir_volume a reservoir rate; a target may be a ps.actions.UserQuantity the
run evaluates.
ps.groups.Satellite
Section titled “ps.groups.Satellite”ps.groups.Satellite(*, group: Group, oil_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, water_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, gas_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, reservoir_volume: Union[ScalarPropertyInput, Expression, NoneType] = None, lift_gas_rate: Union[ScalarPropertyInput, Expression, NoneType] = None, phase: Optional[Literal['oil', 'water', 'gas']] = None, rate: Union[ScalarPropertyInput, Expression, NoneType] = None) -> None
A satellite group’s production or injection from this date (GSATPROD, GSATINJE).
Its rates are stated, not simulated.
ps.groups.Satellite(group=sat, oil_rate=500.0) states the group’s production rates
(oil_rate, water_rate, gas_rate, reservoir_volume, lift_gas_rate);
ps.groups.Satellite(group=sat, phase="gas", rate=2e6) its injection of one phase.
A statement holds a production or an injection, never both. It is stated in
ps.Event(date, ...), at schedule/<date>/<group>/satellite. The rates are surface
rates in the model’s units (reservoir_volume a reservoir rate), each positive.
PetroScript is licensed under the Apache License 2.0. © 2026 Blauweiss EDV LLC. PetroScript by Blauweiss AI.For AI agents: llms.txt