Skip to content

ps.foam

ps.foam.Adsorption(*, rows) -> None

Foam’s adsorption isotherm: the foam the rock holds against the foam concentration.

ps.foam.Adsorption(rows=[(0.0, 0.0), (1.0, 0.0005)]): the rock holds 0.0005 mass of foam per mass of rock where the concentration is 1.

Each row is a foam concentration (a mass per volume, in the model’s units) and the foam adsorbed there (foam mass per rock mass, a ratio without unit, the same number in every unit system), the concentrations strictly rising. Flow reckons the adsorbed foam from it with the rock density of ps.foam.Rock and the rock’s share of the bulk volume. It writes FOAMADS (PROPS), one table, which ps.load reads back. ps.foam.Package(adsorption=...) holds it, at physics/foam/adsorption.

Rows: (concentration, adsorbed_concentration). State each row as a sequence in this order, or as a mapping by column name.

ps.foam.MobilityReduction(*, rows) -> None

Foam’s mobility reduction: the factor on the carrier’s mobility against foam concentration.

ps.foam.MobilityReduction(rows=[(0.0, 1.0), (1.0, 0.1)]) cuts the carrier’s mobility (the gas’s by default) to a tenth at a foam concentration of 1.

Each row is a foam concentration in the model’s units and the factor there (a fraction), the concentrations strictly rising. Flow multiplies the mobility of the phase that carries the foam by it: the gas’s, or the water’s or the solvent’s for those carriers (ps.foam.Package(carrier_phase=...)). It writes FOAMMOB (PROPS), one table, which ps.load reads back. ps.foam.Package(mobility=...) holds it, at physics/foam/mobility.

Rows: (concentration, mobility_reduction). State each row as a sequence in this order, or as a mapping by column name.

ps.foam.Package(*, rock: Rock, mobility: MobilityReduction, adsorption: Adsorption, carrier_phase: Literal['gas', 'water', 'solvent'] = 'gas') -> None

A foam flood’s physics: the rock, the mobility reduction, the adsorption and the carrier.

ps.foam.Package(rock=foam_rock, mobility=mobility, adsorption=adsorption) puts foam in the gas; ps.Model(physics=[...]) holds it, at physics/foam.

It switches foam on (FOAM in RUNSPEC) and writes FOAMROCK, FOAMMOB and FOAMADS (PROPS), with FOAMOPTS for a carrier other than gas; ps.load reads each back. A well injects foam with ps.wells.InjectedStream(well=..., foam_concentration=...) (WFOAM). The model refuses a carrier phase it does not flow (physics.foam.carrier_phase_inactive), a solvent carrier without a ps.solvent.Package (foam.options.solvent_package_missing), and, for a water carrier, foam injected by a well that is not a water injector (foam.controls.water_injector_required).

ps.foam.Rock(*, allow_desorption: bool, rock_density: ScalarPropertyInput) -> None

The rock’s part in a foam flood: its density, and whether adsorbed foam desorbs.

ps.foam.Rock(allow_desorption=True, rock_density=2650.0) is a rock of density 2650 that gives adsorbed foam back as the concentration falls.

It writes FOAMROCK (PROPS), one record, which ps.load reads back. ps.foam.Package(rock=...) holds it, at physics/foam/rock. rock_density is a density in the model’s units. allow_desorption takes only True: OPM Flow stops a run whose foam may not desorb, so False is refused.

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