MICP
PetroScript models microbial induced calcite precipitation as a semantic physics package. Users describe permeability reduction, biological parameters, aqueous species diffusion, and optional initial state fields; lowerers own the Flow/ECL keyword names and row layout.
Reservoir meaning
Section titled “Reservoir meaning”MICP couples microbes, oxygen, urea, biofilm, calcite, and permeability reduction inside the water phase. The public API keeps those concepts grouped as reservoir physics instead of asking authors to memorize table-card spellings.
PetroScript API
Section titled “PetroScript API”MicpPackage
Section titled “MicpPackage”MICP physics intent is a ps.micp.Package(...) in the model’s physics=:
import petroscript as ps
micp = ps.micp.Package( permeability=ps.micp.PermeabilityFactor( rows=[(0.0, 0.005), (0.4, 0.005), (0.6, 0.01), (0.9, 0.1), (1.0, 1.0)] ), biology=ps.micp.Biology(rows=[ { "biofilm_density": 35.0, "death_rate": 0.0275, "growth_rate": 3.6, "half_velocity": 2.0e-5, "yield_growth": 0.5, "yield_oxygen": 0.5, "attachment_rate": 0.0735, "detachment_rate": 2.6e-13, "detachment_exponent": 0.58, "urea_saturation": 1391.0, "oxygen_half_saturation": 21.3, "calcite_density": 2710.0, "yield_urea_to_calcite": 1.67, } ]), diffusion=ps.micp.Diffusion(microbes=2e-4, oxygen=2e-4, urea=1e-4), initial_state=ps.micp.InitialState( microbes=0.0, oxygen=0.0, urea=0.0, biofilm=0.0, calcite=0.0, ),)# ps.Model(..., physics=[micp])PermeabilityFactor
Section titled “PermeabilityFactor”ps.micp.PermeabilityFactor(rows=...) is a physical reduction curve with
(porosity_factor, permeability_factor) points. It is not a public constructor
for a PERMFACT card.
One curve is shared by every saturation-function region. PERMFACT is
dimensioned by NTSFUN like BIOFPARA beside it, so a run with more than one
region states the table once and then an empty body per further region — the
spelling that says “the same as the region before”. Importing one reads the
shared table back, and rendering states it that way again; a run with a single
region states the table alone.
Biology
Section titled “Biology”ps.micp.Biology(rows=...) states each row as a mapping of named biological
fields. This is verbose by design: each name documents reservoir meaning and
avoids positional keyword rows in user code.
A package states one biological-parameter row per saturation-function region,
and the rows may differ. BIOFPARA is dimensioned by NTSFUN, so those rows
are what a run’s saturation regions select; a single-phase MICP run may state
no saturation function at all and still declare two of them, which is what
opm-tests/micp/MICP.DATA does. Each region is written as its own terminated
record, and importing one reads it back the same way.
InitialState
Section titled “InitialState”ps.micp.InitialState(...) accepts scalar values or (nx, ny, nz) tensors for:
- microbes;
- oxygen;
- urea;
- biofilm;
- calcite.
MICP controls
Section titled “MICP controls”A dated ps.wells.InjectedStream names the injected concentrations; users
should not author WMICP rows directly. Here each injection lasts two report
steps, 0.001 and 0.049 days, so the next change is dated 0.05 days (01:12)
later:
schedule = ps.Schedule( report=[ps.Every(0.001, 0.049, 0.001, 0.049)], events=[ ps.Event("2020-01-01", ps.wells.InjectedStream( well="INJ1", microbe_concentration=0.01, oxygen_concentration=0.0, urea_concentration=0.0)), ps.Event("2020-01-01T01:12", ps.wells.InjectedStream( well="INJ1", microbe_concentration=0.0, oxygen_concentration=0.04, urea_concentration=0.0)), ps.Event("2020-01-01T02:24", ps.wells.InjectedStream( well="INJ1", microbe_concentration=0.0, oxygen_concentration=0.0, urea_concentration=0.0)), ],)Every concentration at zero stops the injection. Model validation checks that MICP controls name wells the model declares and that a MICP physics package is attached.
MICP summaries
Section titled “MICP summaries”MICP summary requests name each component’s quantity in ps.Summary’s scopes
rather than raw summary-vector strings: microbes_in_place and
microbes_injection_rate, for example.
Supported components are microbes, oxygen, urea, biofilm, and
calcite. Rate/total requests are supported for the mobile components used by
the target corpus. The compiler owns vector spellings such as FMMIP, CMMIR,
and CMMIRL.
Units and shapes
Section titled “Units and shapes”- MICP requires the water phase to be active.
- MICP controls require declared wells and non-negative concentrations.
- Table values and diffusion coefficients must be finite and non-negative.
- Initial state values may be scalars or full cell tensors matching the model grid shape.
- If a target deck also needs molecular diffusion or dispersion, state
ps.pvt.Diffusionon the fluid anddispersivity=onps.Rockbeside theps.micp.Package(...); MICP does not create a generic transport framework.
Validation and common mistakes
Section titled “Validation and common mistakes”- Do not pass raw keyword strings such as
"PERMFACT","BIOFPARA", or"SMICR"to public constructors. - Use named fields when authoring biology rows; positional 13-tuples are accepted for compact fixtures but should not be the default user experience.
- Initial state tensors are checked against grid dimensions at model validation
time and report stable issue codes such as
micp.initial_state.microbes.shape. - MICP controls naming a well the model does not declare report
schedule.well.unknown; controls without a MICP package reportmicp.controls.package_missing. - Summary requests name a component’s quantity in ps.Summary’s scopes, as
ps.Summary(field=["microbes_in_place"]), never the raw vector (FMMIP).
Lowers to
Section titled “Lowers to”For the OPM Flow target path, current lowerers emit:
MICPinRUNSPECwhen a MICP package is attached;PERMFACT,BIOFPARA, andDIFFMICPinPROPS;SMICR,SOXYG,SUREA,SBIOF, andSCALCinSOLUTIONwhen initial state fields are supplied;WMICPinSCHEDULEfor MICP well controls;- MICP summary vectors in
SUMMARY, including field, region, block, well, completion, and local-completion forms.
The MICP examples under tests/fixtures/examples/g9/micp.py and
tests/fixtures/examples/g9/micp_ad_micp_mrst_comparison.py are backed by native fixture Flow
evidence and generated PetroScript Flow evidence.
PetroScript is licensed under the Apache License 2.0. © 2026 Blauweiss EDV LLC. PetroScript by Blauweiss AI.For AI agents: llms.txt