Map region arrays onto the leaf grid for LGR (EQLNUM, PVTNUM, SWATINIT, FIP) - #7244
Open
hnil wants to merge 4 commits into
Open
Map region arrays onto the leaf grid for LGR (EQLNUM, PVTNUM, SWATINIT, FIP)#7244hnil wants to merge 4 commits into
hnil wants to merge 4 commits into
Conversation
Equilibration read EQLNUM, PVTNUM and SWATINIT straight from the input-grid
field properties and indexed them by leaf cell. Without LGRs the leaf coincides
with the input grid, so this is correct. With an LGR the leaf has more cells and
a different ordering, so:
- EQLNUM: equilnum() copied the input-grid array into a leaf-sized vector with
std::ranges::transform, misaligning coarse cells and leaving every refined
cell in equil region 1. Refined cells then used the wrong OWC, raising the
water-oil contact (the reported symptom: LGR initialized far too wet, mobile
water mean ~0.675 vs ~0.567 in the reference; non-LGR matched).
- PVTNUM: setRegionPvtIdx() indexed the input-grid PVTNUM by a leaf cell index
(out of bounds for refined cells -> garbage PVT region -> 'table has 0
sampling points' once a region's first cell was refined).
- SWATINIT: copied input-grid values into a leaf-indexed vector.
Map each through LookUpData::assignFieldProps{Int,Double}OnLeaf, so a refined
cell inherits its parent cell's value. This is the identity for unrefined grids,
so non-LGR cases are byte-identical; equilnum now takes the GridView (LookUpData
needs it).
Verified: model2_lgr TEST_LGR_INJ1_NOTHPRES initial SWAT now matches the
reference within ~2% per cell - the same OPM-vs-reference spread as the non-LGR
case (was a gross WOC error before). No regression: non-LGR, single-level LGR
(SPE1CASE1_CARFIN1) and nested LGR (serial + np=2) still equilibrate and run.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tc.) createLocalRegion_ built each FIP region array (FIPNUM, ...) from the input-grid field property and then only resize()d it to the leaf cell count. std::vector resize keeps the existing (input-grid) values and zero-pads the appended entries, so with an LGR every refined leaf cell got region 0 and was dropped from the FIP/field region sums. The field pressure FPR (and FPRP, region FIP) are computed as the FIPNUM-region sum, so excluding the ~10k refined cells (near the well, different pressure) made FPR wrong by ~4% while per-cell maps stayed correct. Map the region array onto the leaf with LookUpData::assignFieldPropsIntOnLeaf so a refined cell inherits its parent cell's region (identity without LGRs, so non-LGR runs are unchanged), then keep the existing non-interior -> region 0 masking. Verified on model2_lgr: FPR vs the reference improves from abs 9.06 to 0.055 (matching the non-LGR baseline ~0.12), serial and at np=2; nolgr FPR unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The PPO/PPG/PPW and RPP* datum-pressure summary keywords build a RegionPhasePoreVolAverage from PVTNUM/FIP region arrays read on the input grid, then index them by leaf cell. With LGRs the leaf is larger, so refined cells read past the end of the input-grid arrays (out of bounds / wrong region). Map each region array onto the leaf via LookUpData (refined cell inherits its parent's region; identity without LGRs) and capture the mapped arrays by value in the lookup lambda so they outlive in the stored callable. Verified: an LGR deck with RPPO now runs; black-oil non-LGR output unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…il only) These extension initial conditions (SSOL, SPOLY, SPOLYMW, SMICR, SBIOF, SOXYG, SUREA, SCALC) are read from the input-grid field properties and indexed by leaf cell without mapping refined cells to their parent, so they would be wrong/out of bounds under LGR. LGR is supported for black-oil only; fail early with a clear message when an LGR/CARFIN deck also enables one of these extensions, instead of producing silently wrong results. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Region arrays (EQLNUM, PVTNUM, SWATINIT, FIPNUM and the datum-pressure regions) are read from the input grid field properties but then indexed by leaf cell. Without LGRs the leaf coincides with the input grid, so this is correct. With a CARFIN the leaf has more cells and a different ordering, and the arrays are silently misused.
Each case is mapped onto the leaf with
LookUpData::assignFieldProps{Int,Double}OnLeaf, so a refined cell inherits its parent cell's value. That is the identity on an unrefined grid, so non-LGR runs are byte-identical.Why it matters
These are wrong-answer bugs on decks upstream already supports, not new-feature enablers:
equilnum()copied the input-grid array into a leaf-sized vector withstd::ranges::transform, misaligning coarse cells and leaving every refined cell in equil region 1. Refined cells then equilibrate against the wrong OWC, so the refined region initialises at the wrong water saturation.setRegionPvtIdx()indexed the input-grid array by a leaf cell index. Out of bounds for refined cells; once a region's first cell was refined this surfaced as "table has 0 sampling points".createLocalRegion_built the array from the input grid and then onlyresize()d it to the leaf cell count.std::vector::resizekeeps the existing values and zero-pads the appended entries, so every refined leaf cell got region 0 and was dropped from the FIP/field sums.FPRis the FIPNUM-region pressure sum, so excluding the refined cells — which sit near the well, at a different pressure — biases the reported field pressure while the per-cell maps stay correct.PPO/PPG/PPWandRPP*keywords build aRegionPhasePoreVolAveragefrom PVTNUM/FIP arrays and index it by leaf cell, reading past the end of the input-grid arrays.The last commit is a guard rather than a fix: the solvent/polymer/biofilm/MICP initial conditions (
SSOL,SPOLY,SPOLYMW,SMICR,SBIOF,SOXYG,SUREA,SCALC) are read the same way and would need the same treatment. LGR is black-oil only today, so this fails early with a clear message instead of producing silently wrong results.How to reproduce
Compare
FPRand the initialSWATin the refined region against the equivalent unrefined run. This PR changes simulation output on LGR decks — that is the point; the previous values were wrong. Non-LGR output is unchanged.The quantified effect was measured on an internal two-phase LGR model (not in opm-tests):
FPRabsolute error against the reference dropped from 9.06 to 0.055, matching the non-LGR baseline of ~0.12, serially and atnp=2; initialSWATmoved from a gross WOC error to the same ~2% per-cell spread as the non-LGR case.Implementation notes
LookUpData/assignFieldPropsIntOnLeaf(opm/grid/LookUpData.hh). No grid-side change is needed.equilnum()now takes theGridView, whichLookUpDatarequires.OutputBlackoilModule, the mapped arrays are captured by value in the lookup lambda so they outlive the constructor;decltype(auto)is kept for the required reference-to-vector semantics.needsTranslation=falsethroughout, preserving the previous rawget_intvalues.Testing
Built and run against opm-common and opm-grid master. Non-LGR regression cases unchanged.