Skip to content

Add system_cprw for coupled reservoir-well solves with CPRW#7209

Open
ElyesAhmed wants to merge 2 commits into
OPM:masterfrom
ElyesAhmed:linear_solver_cprw
Open

Add system_cprw for coupled reservoir-well solves with CPRW#7209
ElyesAhmed wants to merge 2 commits into
OPM:masterfrom
ElyesAhmed:linear_solver_cprw

Conversation

@ElyesAhmed

Copy link
Copy Markdown
Contributor

Extend the system CPR solver path with a new system_cprw preconditioner for full coupled (reservoir + well) linear systems. The CPRW path builds an extended pressure system of size (nCells + nWells) so well BHP variables are coupled directly in the pressure solve.

Main changes:

  • add SystemMatrixWellOperator to expose A_wr, A_rw, and A_ww to well-model matrix adapters used by CPRW
  • add system_cprw setup/dispatch in linear-solver configuration handling
  • implement CPRW pressure-system assembly, including well-weight handling and robust diagonal fallback behavior
  • support both sequential and parallel paths via WellModelMatrixAdapter and WellModelGhostLastMatrixAdapter
  • register system_cprw preconditioner factories for seq/par variants
  • extend JSON validation for system_cpr/system_cprw reservoir-solver compatibility and add dedicated system_cprw validation tests/fixtures

This provides a well-coupled baseline for cases with strong reservoir-well interaction while preserving compatibility with existing system_cpr usage.

Extend the system CPR solver path with a new `system_cprw` preconditioner
for full coupled (reservoir + well) linear systems. The CPRW path builds an
extended pressure system of size (nCells + nWells) so well BHP variables are
coupled directly in the pressure solve.

Main changes:
- add `SystemMatrixWellOperator` to expose `A_wr`, `A_rw`, and `A_ww` to
  well-model matrix adapters used by CPRW
- add `system_cprw` setup/dispatch in linear-solver configuration handling
- implement CPRW pressure-system assembly, including well-weight handling and
  robust diagonal fallback behavior
- support both sequential and parallel paths via
  `WellModelMatrixAdapter` and `WellModelGhostLastMatrixAdapter`
- register `system_cprw` preconditioner factories for seq/par variants
- extend JSON validation for `system_cpr`/`system_cprw` reservoir-solver
  compatibility and add dedicated `system_cprw` validation tests/fixtures

This provides a well-coupled baseline for cases with strong
reservoir-well interaction while preserving compatibility with existing
`system_cpr` usage.
@ElyesAhmed ElyesAhmed marked this pull request as ready for review June 30, 2026 06:46
@bska bska requested a review from Copilot July 2, 2026 08:40

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.

Pull request overview

This PR extends the coupled reservoir–well linear-solver path by introducing a new system_cprw system preconditioner that enables CPRW-style pressure solves on a coupled pressure system of size (nCells + nWells), including new validation fixtures/tests and factory registrations for sequential/parallel variants.

Changes:

  • Add system_cprw preconditioner registrations (seq/par) and integrate it into runtime solver selection and property-tree setup/validation.
  • Implement SystemMatrixWellOperator and wire SystemPreconditioner to optionally use well-coupled CPRW pressure solves (WithWellCoupling=true).
  • Add JSON validation tests/fixtures for system_cprw structural requirements and reservoir-solver compatibility.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/test_setuppropertytree.cpp Adds unit tests covering system_cprw validation failures.
tests/options_system_cprw_res_precond_not_cprw.json Fixture ensuring system_cprw rejects non-cprw reservoir solver preconditioner.
tests/options_system_cprw_missing_well.json Fixture covering missing well_solver subtree.
tests/options_system_cprw_missing_smoother.json Fixture covering missing reservoir_smoother subtree.
tests/options_system_cprw_missing_ressolver.json Fixture covering missing reservoir_solver subtree.
opm/simulators/linalg/system/SystemPreconditionerFactory.hpp Registers system_cprw creators for seq/par factories.
opm/simulators/linalg/system/SystemPreconditioner.hpp Adds WithWellCoupling path and rebuild logic for coupled CPRW reservoir solve.
opm/simulators/linalg/system/SystemPreconditioner.cpp Extends explicit template instantiation for parallel WithWellCoupling=true.
opm/simulators/linalg/system/SystemMatrixWellOperator.hpp New adapter exposing A_wr/A_rw/A_ww to CPRW pressure assembly.
opm/simulators/linalg/system/ISTLSolverSystem.hpp Updates well-structure-change handling to support sequential CPRW preconditioner updates.
opm/simulators/linalg/setupPropertyTree.hpp Declares setupSystemCPRW() and broadens validateSystemCPRTree() contract.
opm/simulators/linalg/setupPropertyTree.cpp Adds system_cprw setup + CPR-family setup refactor + enhanced validation.
opm/simulators/linalg/ISTLSolverRuntimeOptionProxy.hpp Extends runtime selection logic to include system_cprw.
CMakeLists_files.cmake Registers new test fixtures and public header.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

using Vector = GetPropType<TypeTag, Properties::GlobalEqVector>;
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using Matrix = typename SparseMatrixAdapter::IstlMatrix;
using Matrix = SparseMatrixAdapter::IstlMatrix;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed

Comment on lines +645 to +647
OPM_THROW(std::invalid_argument,
"--matrix-add-well-contributions=true is incompatible with "
"--linear-solver=system_cpr because the system CPR implementation assumes that well contributions are not added to the matrix.");
"--linear-solver=system_cpr because the system CPR/CPRW implementation assumes that well contributions are not added to the matrix.");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed

Comment thread opm/simulators/linalg/system/SystemPreconditioner.hpp
Comment on lines +162 to +179
if (use_well_weights) {
// bwt = inv(D[w][w])^T * e_bhp → row bhp of inv(D[w][w])
auto invD = (*S_.D)[w][w]; // 4×4 copy
detail::invertMatrix(invD);
Scalar abs_max = 0;
for (int i = 0; i < numWellDofs; ++i) {
bwt[i] = invD[bhpIdx][i];
abs_max = std::max(abs_max, std::abs(bwt[i]));
}
if (abs_max > 0) {
for (int i = 0; i < numWellDofs; ++i) {
bwt[i] /= abs_max;
}
wellDiag[w] = Scalar(1) / abs_max;
} else {
wellDiag[w] = Scalar(1);
}
} else {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants