Skip to content

Run a thermal model

A thermal run solves an energy equation beside the flow, so cells have a temperature that changes as hot or cold fluid moves through them. In PetroScript the heat model is one package in the model’s physics= list, ps.thermal.Package: the rock’s conductivity and heat capacity, the fluids’ heat capacities, and the initial temperature.

Here SPE1 (FIELD units) becomes a thermal run, its gas injector injecting at 80 degF:

import petroscript as ps
m = ps.load("opm-tests/spe1/SPE1CASE2.DATA")
heat = ps.thermal.Package(
mode="thermal", # or "temperature_only": see below
rock=ps.thermal.RockProperties(conductivity=30.0, volumetric_heat_capacity=32.0),
oil_heat_capacity=0.5, water_heat_capacity=1.0, gas_heat_capacity=0.25,
initial_temperature=ps.initial.TemperatureVsDepth(depth=[8300.0, 8450.0], # ft
temperature=[150.0, 200.0]), # degF
)
hot = m.set("physics", [*m.physics, heat])
hot = hot.at(hot.start, ps.wells.InjectedStream(well="INJ", temperature=80.0)) # degF
deck = ps.compile(hot)
assert "THERMAL" in deck.files["SPE1CASE2.DATA"]

mode="thermal" writes THERMAL: Flow solves the energy equation together with the flow. mode="temperature_only" writes TEMP: Flow 2026.04 still solves an energy equation, but after each black-oil step rather than with it.

Every number is in the model’s units; ps.help(ps.thermal.Package) and ps.help(ps.thermal.RockProperties) name what each one is. A temperature is degF in FIELD and degC in METRIC (units).

What goes wrong:

  • A package without the rock’s heat capacity or a conductivity is refused as it is built: thermal.rock.heat_capacity_missing, thermal.conductivity.missing. OPM Flow needs both in either mode.
  • An injector with no injection temperature passes PetroScript’s checks, but OPM Flow stops in the pre-flight, and deck.run() raises ps.CompileError [preflight.refused] quoting it: Well INJ: Unable to obtain injection temperature - not specified in deck and no default defined. State ps.wells.InjectedStream(well=, temperature=) for every injector.

physics is a list: keep what a loaded deck already holds ([*m.physics, heat]) rather than replacing it. The fluids’ heat capacities can also be tables against temperature (ps.thermal.FluidHeatCapacity), and the densities and viscosities can vary with temperature (ps.thermal.DensityVsTemperature, ps.thermal.ViscosityVsTemperature).

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