ps.solvent
ps.solvent.CO2LiveOilPVT
Section titled “ps.solvent.CO2LiveOilPVT”ps.solvent.CO2LiveOilPVT() -> None
Live oil that CO2 dissolves into: the oil’s and gas’s PVT by CO2 fraction and pressure.
One PVT region’s table, the oil a ps.fluid.BlackOil(oil=...) holds, at
fluid/<region>/oil. It writes PVTSOL (PROPS), which switches on Flow’s extended
black-oil model, and ps.load reads it back.
rows hold a CO2 mass fraction, a pressure and the oil’s and the gas’s properties there,
the fraction column first, as the card states it: each fraction’s rows together and the
fractions rising, the pressures rising within one fraction. Every number is in the model’s
units; the fractions are fractions. Flow’s model also needs a conventional live-oil
baseline and the injected gas’s surface density and PVT, written beside PVTSOL:
baseline_oil is the live-oil PVT the CO2 model starts from (a ps.pvt.LiveOil,
written as PVTO), injection_gas_density the injected gas’s surface density (SDENSITY),
and injection_gas_pvt its PVT (a ps.solvent.PVT, written as PVDS); the model’s
checks name each one missing (fluids.oil.pvtsol.baseline_oil_missing,
fluids.oil.pvtsol.injection_gas_density_missing,
fluids.oil.pvtsol.injection_gas_pvt_missing). The model refuses it beside a
ps.solvent.Package (fluids.oil.pvtsol.excludes_solvent). source says where the
numbers come from; nothing reads it.
Rows: (co2_mass_fraction, pressure, oil_fvf, gas_fvf, solution_gor, vaporized_oil_gas_ratio, oil_co2_volume_fraction, gas_co2_volume_fraction, oil_viscosity, gas_viscosity). State each row as a sequence in this order, or as a mapping by column name.
ps.solvent.HydrocarbonRelPerm
Section titled “ps.solvent.HydrocarbonRelPerm”ps.solvent.HydrocarbonRelPerm(*, data: NDArray[numpy.float64], stated: NDArray[numpy.bool] | None = None, source: str | None = None) -> None
The hydrocarbon relative permeability of a miscible solvent run (SOF2).
ps.solvent.HydrocarbonRelPerm(data=[(0.0, 0.0), (1.0, 1.0)]) is a straight oil curve of the
hydrocarbon saturation.
Each row is a hydrocarbon saturation and the relative permeability there, both fractions.
It writes SOF2 (PROPS), which ps.load reads back; ps.Model(relperm=[...]) holds it
beside the other curves, at relperm/<region>/hydrocarbon_rel_perm. In a miscible solvent
run (a ps.solvent.Package beside a ps.miscible.Package) Flow reads it against the
oil, gas and solvent saturation together, and needs it where oil flows; elsewhere SOF2 is
the oil’s curve against the oil saturation. The model refuses it where no oil flows
(relperm.solvent_oil.requires_resolved_phase_semantics), and beside ps.relperm.Oil
without a solvent package (relperm.solvent_oil.excludes_oil). data holds its rows;
stated is False in a cell the deck leaves to the simulator (1*) and None when every
cell is stated; source says where the numbers come from, and nothing reads it.
Rows: (hydrocarbon_saturation, oil_relperm). State each row as a sequence in this order, or as a mapping by column name.
ps.solvent.PVT
Section titled “ps.solvent.PVT”ps.solvent.PVT(*, rows) -> None
The solvent’s PVT: its formation volume factor and viscosity against pressure.
ps.solvent.PVT(rows=[(100.0, 0.01, 0.02), (300.0, 0.004, 0.03)]) gives the solvent’s
formation volume factor and viscosity at 100 and at 300.
Each row is a pressure, the formation volume factor (reservoir volume per surface volume)
and the viscosity, in the model’s units, the pressures strictly rising; Flow needs the
factor strictly falling and the viscosity never falling. It writes PVDS (PROPS), one table,
which ps.load reads back. ps.solvent.Package(pvt=...) holds it, at
physics/solvent/pvt, and so does ps.solvent.CO2LiveOilPVT(injection_gas_pvt=...).
Flow reads it for a “generic” solvent only: a “co2” or “h2” one takes its properties from
Flow’s own CO2 or hydrogen model.
Rows: (pressure, fvf, viscosity). State each row as a sequence in this order, or as a mapping by column name.
ps.solvent.Package
Section titled “ps.solvent.Package”ps.solvent.Package(*, variant: Literal['generic', 'co2', 'h2'] = 'generic', saturation: SaturationFunction | None = None, density: Optional[ScalarPropertyInput] = None, pvt: PVT | None = None, initial_saturation=None, gas_dissolves_in_water: bool = False, simulator_supplied_phases: tuple[typing.Literal['water'], ...] = ()) -> None
A solvent flood’s physics: a fourth, gas-like component and its properties.
ps.solvent.Package(saturation=saturation, density=1.8, pvt=solvent_pvt) turns the solvent
model on; ps.Model(physics=[...]) holds it, at physics/solvent.
It switches the solvent on (SOLVENT in RUNSPEC, with CO2SOL or H2SOL for the “co2” and “h2”
variants and DISGASW when gas_dissolves_in_water) and writes SSFN, SDENSITY and PVDS
(PROPS) and the initial saturation as SSOL (SOLUTION); ps.load reads each back. It states
one of saturation, density and pvt at least. density is the solvent’s surface
density in the model’s units. Flow reads the density and the PVT for a “generic” solvent
only; a “co2” or “h2” one takes its properties from Flow’s own CO2 or hydrogen model, and
dissolves in the water where gas_dissolves_in_water is set. A well injects the solvent
with ps.wells.InjectedStream(well=..., solvent_fraction=...) (WSOLVENT); its miscibility
with the oil is a ps.miscible.Package.
ps.solvent.SaturationFunction
Section titled “ps.solvent.SaturationFunction”ps.solvent.SaturationFunction(*, rows) -> None
The split of the gas relative permeability between the gas and the solvent.
ps.solvent.SaturationFunction(rows=[(0.0, 0.0, 0.0), (1.0, 1.0, 1.0)]) shares the gas’s
relative permeability between gas and solvent in proportion to their saturations: Flow reads
the gas multiplier at the gas’s fraction of gas and solvent and the solvent multiplier at the
solvent’s, and needs both multiplier columns strictly rising.
Each row is a fraction of the gas and solvent saturation, the gas’s relative permeability
multiplier and the solvent’s, all fractions, the first column strictly rising. Flow reads
the third column, krog_multiplier, as the solvent’s multiplier. It writes SSFN (PROPS),
the table once per saturation region, which ps.load reads back.
ps.solvent.Package(saturation=...) holds it, at physics/solvent/saturation.
Rows: (solvent_saturation, krg_multiplier, krog_multiplier). 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