Skip to content

Polymer EOR

PetroScript authors polymer EOR through the ps.polymer semantic values: a ps.polymer.Package in the model’s physics=. The compiler owns the exact deck cards and section placement; authors should not build raw card rows or keyword-shaped escape hatches.

import petroscript as ps
polymer = ps.polymer.Package(
viscosity=ps.polymer.Viscosity(rows=[(0.0, 1.0), (1.0, 2.0)]),
rock=ps.polymer.Rock(
inaccessible_pore_volume=0.15,
residual_resistance_factor=1.0,
rock_density=2500.0,
adsorption_index=1,
maximum_adsorption=0.05,
),
adsorption=ps.polymer.Adsorption(rows=[(0.0, 0.0), (1.0, 0.05)]),
maximum_concentration=1.0,
mixing_parameter=ps.polymer.Mixing(value=1.0),
)

The same package states salt, temperature, joint salt-temperature, degradation, shear and rock-density effects:

polymer = ps.polymer.Package(
viscosity=ps.polymer.Viscosity(rows=[(0.0, 1.0), (1.0, 2.0)]),
thermal_degradation=ps.polymer.ThermalDegradation(rows=[(40.0, 365.0), (80.0, 150.0)]),
)

Each row is a temperature and the polymer’s half-life at it, both bare numbers in the model’s units: the temperature in its temperature unit (degC on a METRIC model, degF on a FIELD model) and the half-life in days. A ps.Quantity in a row is refused ([units.wrong_kind]), since the rows are read in the model’s own units. Cross-object checks emit stable issue codes when required brine or thermal physics is missing.

Use exactly one shear style:

polymer = ps.polymer.Package(
viscosity=ps.polymer.Viscosity(rows=[(0.0, 1.0), (1.0, 2.0)]),
shear_response=ps.polymer.Shear(rows=[(0.0, 1.0), (1.0, 0.9)]),
)
log_based = ps.polymer.Package(
viscosity=ps.polymer.Viscosity(rows=[(0.0, 1.0), (1.0, 2.0)]),
shear_log=ps.polymer.ShearLog(
reference_polymer_concentration=1.0,
rows=[(0.0, 1.0), (1.0, 0.9)],
log_shear_rate=4.8,
),
)

PetroScript rejects mixed direct-shear and log-shear-rate styles through polymer.shear.style_conflict.

Group reinjection names its source group by its ps.Group, not a raw string:

group = ps.Group(name="POLY_SRC")
stream = ps.wells.InjectedStream(well="INJ1", polymer_from_group=group)

The source group must be present in the schedule group tree or validation emits polymer.controls.group_unresolved.

OPM Flow does not run these residual polymer families: measured identically on 2025.10 and 2026.04, their decks fail with eight load errors and one segmentation fault. PetroScript states them and writes their cards, but does not present them as runnable in Flow until a Flow version accepts the same decks.

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