Skip to content

ps.miscible

ps.miscible.CriticalGas(*, rows) -> None

The miscible critical gas saturation against the water saturation.

ps.miscible.CriticalGas(rows=[(0.0, 0.0), (1.0, 0.03)]). The water saturations rise from 0 to 1 and the critical gas saturation never falls.

Both columns are saturations (fractions). Where water flows, Flow blends it with the immiscible critical gas saturation by the miscibility, and reads a model that states none as zero. It writes SGCWMIS (PROPS), once per miscible region; ps.load refuses a deck that states SGCWMIS. ps.miscible.Package(critical_gas=...) holds it, at physics/miscible/critical_gas.

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

ps.miscible.Mixing(*, regions) -> None

The Todd-Longstaff mixing parameters of each miscible region.

regions maps each miscible region’s number to its viscosity_parameter and density_parameter, each a fraction from 0 (no mixing) to 1 (full mixing): ps.miscible.Mixing(regions={1: {"viscosity_parameter": 0.6, "density_parameter": 0.6}}). They are held in region order. It writes TLMIXPAR (PROPS), one record per region, which ps.load reads back; the model refuses regions that are not 1 to the model’s miscible region count (miscible.todd_longstaff.regions_incomplete). ps.miscible.Package(todd_longstaff=...) holds it, at physics/miscible/todd_longstaff.

ps.miscible.Package(*, transform: Transform | None = None, pressure_miscibility: PressureCurve | None = None, normalized_relperm: RelPerm | None = None, residual_oil: ResidualOil | None = None, critical_gas: CriticalGas | None = None, todd_longstaff: Mixing | None = None) -> None

A solvent’s miscibility with the oil: Flow’s miscible solvent model and its tables.

ps.miscible.Package(transform=ps.miscible.Transform(rows=[(0.0, 0.0), (1.0, 1.0)]), todd_longstaff=ps.miscible.Mixing(regions={1: {"viscosity_parameter": 0.6, "density_parameter": 0.6}})) beside a ps.solvent.Package makes the solvent miscible with the oil; ps.Model(physics=[...]) holds it, at physics/miscible. Where the transform is stated, Flow stops the run unless the Todd-Longstaff parameters (todd_longstaff, TLMIXPAR) are stated too and, where oil is a phase, the model holds a ps.solvent.HydrocarbonRelPerm (SOF2) in ps.Model(relperm=[...]); ps.compile writes the deck without them all the same.

The package switches the miscible model on (MISCIBLE in RUNSPEC). MISC, PMISC, SORWMIS and SGCWMIS are written once per miscible region and MSFN once, and the regions are the model’s: the MISCNUM map (ps.Regions(miscible=)) and the Todd-Longstaff rows; the most rows a table may hold is ps.Capacity(rows_per_miscible_table=), counted from the tables when not stated. Flow takes no dispersion but NONE (MISCIBLE item 3), which the writer writes. ps.load reads MISCIBLE, MISC, PMISC and TLMIXPAR back and refuses a deck that states MSFN, SORWMIS or SGCWMIS. It states one table at least, and Flow’s miscible solvent model reads them only where the transform is stated.

ps.miscible.PressureCurve(*, rows) -> None

The miscibility against the oil pressure.

ps.miscible.PressureCurve(rows=[(100.0, 0.0), (200.0, 1.0)]): immiscible at a pressure of 100, fully miscible from 200.

Each row is a pressure in the model’s units and the miscibility there (a fraction), the pressures strictly rising and the miscibility never falling. Flow multiplies the transform (ps.miscible.Transform) by it, and reads a model that states none as fully miscible at every pressure. It writes PMISC (PROPS), once per miscible region, which ps.load reads back. ps.miscible.Package(pressure_miscibility=...) holds it, at physics/miscible/pressure_miscibility.

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

ps.miscible.RelPerm(*, rows) -> None

The miscible relative permeability multipliers of the gas and solvent and of the oil.

ps.miscible.RelPerm(rows=[(0.0, 0.0, 1.0), (1.0, 1.0, 0.0)]) makes both miscible relative permeabilities straight lines of the gas and solvent’s fraction: the gas and solvent’s rises from 0 to 1 and the oil’s falls from 1 to 0 (Flow needs the oil column never rising).

Each row is the gas and solvent’s fraction of the mobile hydrocarbon saturation (the column total_gas_saturation), then the gas and solvent’s multiplier and the oil’s, all fractions; the first column strictly rising from 0 to 1, the gas multiplier never falling. Flow multiplies the hydrocarbon curve (ps.solvent.HydrocarbonRelPerm, SOF2) by each, and reads a model that states none as these straight lines. It writes MSFN (PROPS), one table; ps.load refuses a deck that states MSFN. ps.miscible.Package(normalized_relperm=...) holds it, at physics/miscible/normalized_relperm.

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

ps.miscible.ResidualOil(*, rows) -> None

The miscible residual oil saturation against the water saturation.

ps.miscible.ResidualOil(rows=[(0.0, 0.05), (1.0, 0.30)]). The water saturations rise from 0 to 1 and the residual oil saturation never falls.

Both columns are saturations (fractions). Where water flows, Flow blends it with the immiscible residual by the miscibility, and reads a model that states none as zero. It writes SORWMIS (PROPS), once per miscible region; ps.load refuses a deck that states SORWMIS. ps.miscible.Package(residual_oil=...) holds it, at physics/miscible/residual_oil.

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

ps.miscible.Transform(*, rows) -> None

The miscibility of the solvent with the oil against the solvent’s fraction of the gas.

ps.miscible.Transform(rows=[(0.0, 0.0), (1.0, 1.0)]) makes the miscibility grow in proportion to the solvent fraction.

Each row is a solvent fraction (the solvent over the gas and solvent saturation) and the miscibility there, both fractions: the solvent fractions strictly rising from 0 to 1, the miscibility never falling, from 0 to 1. Flow multiplies it by the pressure curve (ps.miscible.PressureCurve) at the oil pressure. It writes MISC (PROPS), once per miscible region, which ps.load reads back, and Flow’s miscible solvent model runs only where it is stated, and then needs a ps.miscible.Mixing (TLMIXPAR) beside it (what else it needs: ps.miscible.Package); the model refuses it without a ps.solvent.Package (miscible.package.requires_solvent). ps.miscible.Package(transform=...) holds it, at physics/miscible/transform.

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

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