Skip to content

Let the classic CPRW contract D for multisegment wells - #7282

Open
hnil wants to merge 1 commit into
OPM:masterfrom
hnil:pr/msw-cprw-contract-d
Open

Let the classic CPRW contract D for multisegment wells#7282
hnil wants to merge 1 commit into
OPM:masterfrom
hnil:pr/msw-cprw-contract-d

Conversation

@hnil

@hnil hnil commented Aug 5, 2026

Copy link
Copy Markdown
Member

Standard wells build their coarse CPRW diagonal by contracting D
(StandardWellEquations reads duneD_[0][0]). Multisegment wells instead use
minus the row sum of the contracted reservoir entries, which never reads D and so
drops every segment-to-segment coupling — most of the well once there is one
segment per connection.

preconditioner.well_coarse_diagonal = contract_d makes the multisegment path
contract D as well. Default auto is today's behaviour, so nothing changes unless
asked for. Contracting D is also the Galerkin diagonal for the prolongation the
coarse column already assumes: one coarse value spread over the well's segment
pressures.

The flag is threaded next to use_well_weights. The contraction is
mswellhelpers::contractCprWellDiagonal, unit tested in test_MswCprWellDiagonal;
it returns 1 on exact cancellation, since a zero would make the coarse pressure
system singular.

Full Norne with --convert-to-multisegment-well=per-connection, linear iterations:

linear iterations
cprw 2716
cprw, well_coarse_diagonal = contract_d 2646

Standard wells are byte-identical either way, as they must be.

🤖 Generated with Claude Code

preconditioner.well_coarse_diagonal = contract_d takes a well's coarse
diagonal from lambda' D(:,p) instead of minus the row sum of its contracted
reservoir entries. Default "auto" keeps today's behaviour.

Standard wells have always contracted D (StandardWellEquations reads
duneD_[0][0]); only the multisegment path used the row sum, which never reads
D and therefore throws away all segment-to-segment coupling. With one segment
per connection that is most of the well. Contracting D is also the Galerkin
diagonal for the prolongation the coarse column already assumes -- one coarse
value spread over all of the well's segment pressures.

The flag is threaded next to use_well_weights, from PressureBhpTransferPolicy
down to MultisegmentWellEquations::extractCPRPressureMatrix. The contraction
itself is mswellhelpers::contractCprWellDiagonal, unit tested in
test_MswCprWellDiagonal; it returns 1 on exact cancellation, since a zero
would make the coarse pressure system singular.

Norne with --convert-to-multisegment-well=per-connection: every coarse matrix
differs from the default, i.e. the flag reaches the assembly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 2e00bc30da70b3677c7184cc69418e0daaceb10e)
@hnil hnil added the manual:enhancement This is an enhancement/improvent that needs to be documented in the manual label Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

manual:enhancement This is an enhancement/improvent that needs to be documented in the manual

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant