Skip to content

compositional equilibration with COMPVD - #7373

Open
GitPaean wants to merge 3 commits into
OPM:masterfrom
GitPaean:compvd_equilibration
Open

GitPaean wants to merge 3 commits into
OPM:masterfrom
GitPaean:compvd_equilibration

Conversation

@GitPaean

@GitPaean GitPaean commented Aug 28, 2026

Copy link
Copy Markdown
Member

Adds COMPVD as a composition-versus-depth source for the compositional
equilibration, alongside the ZMFVD support merged in #7306.

What COMPVD adds

COMPVD carries the same depth and mole-fraction columns as ZMFVD, plus a phase
flag on every row and a saturation pressure. The phase flag lets a deck state
something ZMFVD cannot:

  • All rows naming one phase — the flag names the EOS root the hydrostatic
    column is integrated with. Without it, the root follows from which side of
    the gas-oil contact the datum lies on.
  • Rows naming both phases — the table describes a gas zone above the
    gas-oil contact and a liquid zone below it, each with its own composition and
    its own hydrostatic column. The zone holding the datum is anchored there and
    the other picks up its pressure at the contact, so the datum pressure is
    honoured whichever zone it falls in, and the contact may lie outside the
    cells of the region.

Under EQUIL item 10 = 3, a table naming both phases supplies the gas above the
contact from its vapour rows instead of from the equilibrium vapour of the
contact liquid.

The saturation-pressure column is parsed but never read. Under item 10 = 3 the
reference pressure at the gas-oil contact is the bubble point computed from the
contact liquid, not the tabulated value, and CompvdSinglePhaseMatchesZmfvd
pins a COMPVD deck to the matching ZMFVD one to keep the column out of the
result. Whether it should be used at all — as the reference pressure, or as a
check on the computed one — is left open, and may well change once test cases
that can tell the two apart turn up.

Choosing the source per region

A deck giving one composition keyword keeps the usual table behaviour: a region
with no record of its own inherits the nearest preceding one.

A deck giving both ZMFVD and COMPVD has to name the source of every region.
Neither keyword is inherited there, since nothing defines which one a region
stating nothing would follow.

Rejected input

  • EQUIL item 10 other than 1 or 3, a non-zero gas-oil contact capillary
    pressure (item 6), or item 9 other than 0
  • a COMPVD table stating a vapour composition under item 10 = 3
  • a two-zone COMPVD table whose vapour and liquid rows do not meet at the
    gas-oil contact, or which has no row for one of the phases
  • a region with both a ZMFVD and a COMPVD record

Testing

tests/test_compequil.cpp grows to 23 cases, covering the EOS root a stated
phase selects, the two zones with the datum on either side of the contact, a
contact falling outside the cells, and how a region picks its composition
record.

Checked against third-party reference runs of two six-component decks, a SPE5
case and a lumped CO2 case: both agree to 4.6e-05 bar in pressure, with
identical compositions.

regressionTests.cmake adds equil_1d_compvd_oil, using the deck from
OPM/opm-tests#1611. It needs reference data to be generated before it passes.

Not in this PR

  • Parallel runs. CompvdTable::phaseFlags_ is not serialized, so the
    EclipseState broadcast slices the table. The fix belongs in opm-common, and
    compositional parallel support is Fix parallel runs of flow_comp #7387.
  • A water zone. Equilibration still rejects a water-oil contact above the
    deepest cell; that is a separate branch.

@GitPaean GitPaean added the manual:irrelevant This PR is a minor fix and should not appear in the manual label Aug 28, 2026
@GitPaean
GitPaean force-pushed the compvd_equilibration branch 2 times, most recently from b1bee28 to ba75c0e Compare August 31, 2026 11:53
@GitPaean
GitPaean force-pushed the compvd_equilibration branch 4 times, most recently from 13c7640 to 736884c Compare September 17, 2026 12:28
@GitPaean

Copy link
Copy Markdown
Member Author

jenkins build this failure_report please

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Pressure anchoring and water saturation handling are incorrect for several valid configurations.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds COMPVD-based compositional equilibration, including phase-specific hydrostatic columns and water-zone handling.

Changes:

  • Supports single- and two-zone COMPVD initialization.
  • Adds hydrostatic water pressure and saturation initialization.
  • Adds unit and regression coverage.
File summaries
File Description
InitStateEquilComp.hpp Implements COMPVD and water-zone equilibration.
tests/test_compequil.cpp Tests COMPVD and water initialization.
regressionTests.cmake Registers the COMPVD regression case.
Review details

Suppressed comments (2)

opm/simulators/flow/equil/InitStateEquilComp.hpp:708

  • This always anchors the liquid-composition column at the EQUIL datum and only then creates the gas column. If a valid datum is above the GOC, that pressure belongs to the gas zone, but it is integrated using the liquid COMPVD rows before the gas column is anchored at the contact, producing the wrong pressure profile. For two-zone COMPVD, integrate the zone containing the datum first and anchor the other zone at the contact.
        if (reg.twoZone) {
            // The gas zone is its own hydrostatic column, continuous with the
            // liquid one at the contact.
            const ODE gasOde([&reg](const Scalar d) { return vaporComposition(reg, d); },
                             reg.tempVdTable, FluidSystem::gasPhaseIdx, eosType_, gravity);
            reg.gasPressure.emplace(gasOde,
                                    typename PressFunc::InitCond{reg.zgoc,
                                                                 reg.oilPressure->value(reg.zgoc)},
                                    numSamplePoints, span);

opm/simulators/flow/equil/InitStateEquilComp.hpp:844

  • A single-phase COMPVD table marked Vapor sets statedPhaseIdx to gas, but inGasZone is false for type 1 and this still labels every cell as oil. This contradicts the new phase-selection behavior and returns an internally inconsistent initial fluid state. Use statedPhaseIdx when present to select the nominal hydrocarbon saturation.
        fs.setSaturation(inGasZone ? FluidSystem::gasPhaseIdx : FluidSystem::oilPhaseIdx,
                         Scalar{1} - sWat);
  • Files reviewed: 3/3 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread opm/simulators/flow/equil/InitStateEquilComp.hpp Outdated
Comment thread opm/simulators/flow/equil/InitStateEquilComp.hpp Outdated
Comment thread opm/simulators/flow/equil/InitStateEquilComp.hpp Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Pressure anchoring and phase assignment are incorrect for several supported COMPVD configurations.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

opm/simulators/flow/equil/InitStateEquilComp.hpp:579

  • When the EQUIL datum lies above zgoc, its specified pressure belongs to the gas zone, but this always integrates the liquid column from that datum and then anchors the gas column to the resulting contact pressure. The datum-to-contact interval is therefore integrated with liquid density, shifting both pressure columns. Build the column containing the datum first, then anchor the other column at the contact.
            reg.gasPressure.emplace(gasOde,
                                    typename PressFunc::InitCond{reg.zgoc,
                                                                 reg.oilPressure->value(reg.zgoc)},
                                    numSamplePoints, span);

opm/simulators/flow/equil/InitStateEquilComp.hpp:549

  • For a vapor-only COMPVD table this selects the gas EOS root, but the resulting pressure function is still stored as oilPressure and assignCell() still marks oil saturation because the region is neither type 3 nor twoZone. Consequently the phase flag produces an internally inconsistent initial state. Track the nominal phase separately from pressure-function selection and apply it when assigning saturation.
        // COMPVD states the phase its composition belongs to; without that the
        // datum's side of the gas-oil contact decides the EOS root.
        const auto phaseIdx = reg.statedPhaseIdx.value_or(
            (datum < reg.zgoc) ? FluidSystem::gasPhaseIdx : FluidSystem::oilPhaseIdx);
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread opm/simulators/flow/equil/InitStateEquilComp.hpp Outdated
@GitPaean

Copy link
Copy Markdown
Member Author

jenkins build this opm-tests=1611 failure_report please

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Datum anchoring and vapor-only phase assignment can produce inconsistent initial states.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

opm/simulators/flow/equil/InitStateEquilComp.hpp:549

  • For a vapor-only COMPVD table, this selects the gas EOS root, but a type-1 region still reaches assignCell() with inGasZone == false and is assigned unit oil saturation. Initial primary variables are formed from phase molarity times saturation, so this uses oil molarity even though the pressure profile used gas density. Preserve the selected nominal phase and use it when assigning saturation.

This issue also appears on line 576 of the same file.

opm/simulators/flow/equil/InitStateEquilComp.hpp:579

  • When a type-1 two-zone COMPVD region has its datum above the GOC, oilPressure was integrated from that datum using the liquid-row composition before this gas column is anchored at the contact. The datum pressure therefore crosses the datum-to-contact interval with the wrong fluid density and shifts both pressure profiles. Initialize the column containing the datum first, then anchor the other column at the contact.
            reg.gasPressure.emplace(gasOde,
                                    typename PressFunc::InitCond{reg.zgoc,
                                                                 reg.oilPressure->value(reg.zgoc)},
                                    numSamplePoints, span);
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@GitPaean
GitPaean force-pushed the compvd_equilibration branch 2 times, most recently from b3a3c08 to b04baf6 Compare September 18, 2026 09:25
COMPVD gives a composition versus depth like ZMFVD, and adds a phase
flag per row.  A table agreeing on one phase names the EOS root the
column is integrated with; one naming both describes a gas zone above
the gas-oil contact and a liquid zone below it, each with its own
composition and its own hydrostatic column.

A region without a record of its own inherits the nearest preceding one.
A deck giving both keywords has to name the source of every region,
since nothing says which keyword a blank region would follow.
@GitPaean
GitPaean force-pushed the compvd_equilibration branch from 26fe39d to ecec608 Compare September 18, 2026 12:14
Cover the EOS root a stated phase selects, the two zones a table naming
both phases describes and the datum sitting in either of them, the
contact falling outside the cells, and how a region picks its
composition record.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The numerical phase-zone and hydrostatic integration changes require final human validation against simulator reference results.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@GitPaean

Copy link
Copy Markdown
Member Author

The results look generally correct for the two cases checked.

image image

Those are filed average with time, and checked individual cells, they are similar,

image image

@GitPaean

GitPaean commented Sep 18, 2026

Copy link
Copy Markdown
Member Author

jenkins build this update_data failure_report please

https://ci.opm-project.org/job/opm-simulators-PR-builder/10683/

@GitPaean

Copy link
Copy Markdown
Member Author

I am dong working with the PR and marking the PR as ready for review, and inviting reviewers.

@GitPaean
GitPaean marked this pull request as ready for review September 18, 2026 13:44
@GitPaean
GitPaean requested a review from bska September 18, 2026 13:45
Comment thread regressionTests.cmake
@GitPaean

Copy link
Copy Markdown
Member Author

Udq-1 regression is false alarm.

@GitPaean GitPaean closed this Sep 18, 2026
@GitPaean GitPaean reopened this Sep 18, 2026
@GitPaean

Copy link
Copy Markdown
Member Author

jenkins build this update_data failure_report please

jenkins4opm pushed a commit to jenkins4opm/opm-tests that referenced this pull request Sep 18, 2026
Reason: PR OPM/opm-simulators#7373

opm-common     = 75fb0bf85184dff06424bbff9a73e8bbeb700723
opm-grid       = ed27fd832c1da18f4e0177f2d88e5197c3da23f0
opm-simulators = bd769dfaedad3a1f94338939ffc392675159fd78

### Changed Tests ###

  * equil_1d_compvd_oil
@GitPaean

Copy link
Copy Markdown
Member Author

jenkins build this opm-tests=1614 please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

manual:irrelevant This PR is a minor fix and should not appear in the manual

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants