From e4cf3cf72a8f612ef98372b8f701f53a709d7dce Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Mon, 28 Sep 2026 01:14:56 -0400 Subject: [PATCH 1/5] fix: include the control equation in the thermal single-phase well residual norm The thermal single-phase well residual norm computed a normalizer for the control rows but never added their contribution, so Newton could report convergence while the well rate or BHP target was not met. When a rate-controlled well opened after a shut-in period, a line search could leave it at a fraction of the scheduled rate for the rest of the run, and a restarted run, which rebuilds the well state, followed a different path. Count the control rows as the isothermal kernel does. Fixes #4036 --- .../wells/kernels/ThermalSinglePhaseWellKernels.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalSinglePhaseWellKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalSinglePhaseWellKernels.hpp index 317a0082b81..a623797dfcb 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalSinglePhaseWellKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalSinglePhaseWellKernels.hpp @@ -590,6 +590,13 @@ class ResidualNormKernel : public physicsSolverBaseKernels::ResidualNormKernelBa { normalizer = m_targetBHP; } + + // we have the normalizer now, we can compute a dimensionless Linfty norm contribution + real64 const val = LvArray::math::abs( m_localResidual[stack.localRow + idof] ) / normalizer; + if( val > stack.localValue[0] ) + { + stack.localValue[0] = val; + } } // Step 2: compute a normalizer for the mass balance equation else if( idof == WJ_ROFFSET::MASSBAL ) From 4c63f7de0eb6e08cd892455c9b2e6d90de42b28b Mon Sep 17 00:00:00 2001 From: Byer Date: Mon, 28 Sep 2026 13:59:30 -0700 Subject: [PATCH 2/5] wm_we branch merge fix, rate used for residual scaling never set for compositional+thermal+wells --- .../ThermalCompositionalMultiphaseWellKernels.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp index f3ec5b517a3..dd0daa80a45 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp @@ -190,6 +190,15 @@ class ResidualNormKernel : public physicsSolverBaseKernels::ResidualNormKernelBa { const WellConstraintBase * currentConstraint = wellControls.getCurrentConstraint(); ConstraintTypeId currentControl = wellControls.getControl(); + // Note this assumes that there is only one rate constraint + // This is a normalizer for the balance equations. The normalizaer should be the current rate not the constraint value!! + // This is one of the reasons for restricting constraint type for a production well + // Another pr will remove fix this (so the cause for difference results is isolated to one change) + auto const * rateConstraint = wellControls.getRateConstraints().front(); + if( rateConstraint != nullptr ) + { + m_constraintValue = rateConstraint->getConstraintValue( time ); + } if( currentControl == ConstraintTypeId::BHP ) { m_targetBHP = currentConstraint->getConstraintValue( time ); From 7c82f098b77fb1c555553c49e4890d02cbdb7c2e Mon Sep 17 00:00:00 2001 From: Byer Date: Wed, 7 Oct 2026 13:08:32 -0700 Subject: [PATCH 3/5] add compositional thermal well test case --- .../co2_thermal_injwell_2d.xml | 243 +++++++++++++++ .../co2_thermal_prdwell_2d.xml | 246 +++++++++++++++ .../co2_thermal_well_2d.xml | 280 ++++++++++++++++++ .../thermalMultiphaseFlow.ats | 24 ++ 4 files changed, 793 insertions(+) create mode 100644 inputFiles/thermalMultiphaseFlow/co2_thermal_injwell_2d.xml create mode 100644 inputFiles/thermalMultiphaseFlow/co2_thermal_prdwell_2d.xml create mode 100644 inputFiles/thermalMultiphaseFlow/co2_thermal_well_2d.xml diff --git a/inputFiles/thermalMultiphaseFlow/co2_thermal_injwell_2d.xml b/inputFiles/thermalMultiphaseFlow/co2_thermal_injwell_2d.xml new file mode 100644 index 00000000000..1671c2b7ae8 --- /dev/null +++ b/inputFiles/thermalMultiphaseFlow/co2_thermal_injwell_2d.xml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/thermalMultiphaseFlow/co2_thermal_prdwell_2d.xml b/inputFiles/thermalMultiphaseFlow/co2_thermal_prdwell_2d.xml new file mode 100644 index 00000000000..881e3ca8832 --- /dev/null +++ b/inputFiles/thermalMultiphaseFlow/co2_thermal_prdwell_2d.xml @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/thermalMultiphaseFlow/co2_thermal_well_2d.xml b/inputFiles/thermalMultiphaseFlow/co2_thermal_well_2d.xml new file mode 100644 index 00000000000..f192d8fb0de --- /dev/null +++ b/inputFiles/thermalMultiphaseFlow/co2_thermal_well_2d.xml @@ -0,0 +1,280 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/thermalMultiphaseFlow/thermalMultiphaseFlow.ats b/inputFiles/thermalMultiphaseFlow/thermalMultiphaseFlow.ats index 979a7951140..84a88b166d8 100644 --- a/inputFiles/thermalMultiphaseFlow/thermalMultiphaseFlow.ats +++ b/inputFiles/thermalMultiphaseFlow/thermalMultiphaseFlow.ats @@ -13,6 +13,30 @@ decks = [ restart_step=9, check_step=11, restartcheck_params=RestartcheckParameters(**restartcheck_params)), + TestDeck( + name="co2_thermal_well_2d", + description= + 'Thermal compositional co2-brine flow test (2D co2 injection/production, 2-phase co2-brine, Brooks-Corey relperm curves, thermal)', + partitions=((1, 1, 1), (2, 2, 1)), + restart_step=3, + check_step=11, + restartcheck_params=RestartcheckParameters(**restartcheck_params)), + TestDeck( + name="co2_thermal_prdwell_2d", + description= + 'Thermal compositional co2-brine flow test (2D co2 production, 2-phase co2-brine, Brooks-Corey relperm curves, thermal)', + partitions=((1, 1, 1), (2, 2, 1)), + restart_step=3, + check_step=11, + restartcheck_params=RestartcheckParameters(**restartcheck_params)), + TestDeck( + name="co2_thermal_injwell_2d", + description= + 'Thermal compositional co2-brine flow test (2D co2 injection, 2-phase co2-brine, Brooks-Corey relperm curves, thermal)', + partitions=((1, 1, 1), (2, 2, 1)), + restart_step=3, + check_step=11, + restartcheck_params=RestartcheckParameters(**restartcheck_params)), TestDeck( name="co2_thermal_2d_iterative", description= From 1a7e0d1b579b65398bfaa52ecbb31fab792b4376 Mon Sep 17 00:00:00 2001 From: Byer Date: Thu, 8 Oct 2026 08:32:06 -0700 Subject: [PATCH 4/5] missed setting phaseIndex in merge --- .../kernels/ThermalCompositionalMultiphaseWellKernels.hpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp index dd0daa80a45..97d64553639 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/kernels/ThermalCompositionalMultiphaseWellKernels.hpp @@ -176,12 +176,13 @@ class ResidualNormKernel : public physicsSolverBaseKernels::ResidualNormKernelBa ghostRank, minNormalizer ), m_numPhases( fluid.numFluidPhases()), + m_targetPhaseIndex( wellControls.isProducer() ? wellControls.getConstraintPhaseIndex() : -1 ), m_dt( dt ), m_isLocallyOwned( subRegion.isLocallyOwned() ), m_iwelemControl( subRegion.getTopWellElementIndex() ), m_isProducer( wellControls.isProducer() ), m_currentControl( wellControls.getControl() ), - m_targetBHP( std::numeric_limits< real64 >::max() ), + m_targetBHP( wellControls.getTargetBHP( time ) ), m_volume( subRegion.getElementVolume() ), m_phaseDens_n( fluid.phaseDensity_n() ), m_totalDens_n( fluid.totalDensity_n() ), @@ -206,10 +207,6 @@ class ResidualNormKernel : public physicsSolverBaseKernels::ResidualNormKernelBa else { m_constraintValue = currentConstraint->getConstraintValue( time ); - if( currentControl == ConstraintTypeId::PHASEVOLRATE ) - { - m_targetPhaseIndex = wellControls.getConstraintPhaseIndex(); - } } } From 9879feb6a9953d1cf5a4517decb250a74be09d4b Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Thu, 22 Oct 2026 01:48:24 -0400 Subject: [PATCH 5/5] Add thermal well test baselines --- .integrated_tests.yaml | 2 +- BASELINE_NOTES.md | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.integrated_tests.yaml b/.integrated_tests.yaml index 74cea56702e..d0fd9460472 100644 --- a/.integrated_tests.yaml +++ b/.integrated_tests.yaml @@ -1,6 +1,6 @@ baselines: bucket: geosx - baseline: integratedTests/baseline_integratedTests-pr3996-17639-718fc69 + baseline: integratedTests/baseline_integratedTests-pr4155-17777-be35229 allow_fail: all: '' diff --git a/BASELINE_NOTES.md b/BASELINE_NOTES.md index e700a96f185..40932cf470f 100644 --- a/BASELINE_NOTES.md +++ b/BASELINE_NOTES.md @@ -4,6 +4,16 @@ Notes This file is designed to track changes to the integrated test baselines. Any developer who updates the baseline ID in the .integrated_tests.yaml file is expected to create an entry in this file with the pull request number, date, and their justification for rebaselining. These notes should be in reverse-chronological order, and use the following time format: (YYYY-MM-DD). + +PR #4155 (2026-10-22) +===================== +Add the missing restart baselines for the injection, production, and combined +thermal compositional-well tests on one and four MPI ranks. In CI run 17777, +all six simulations completed successfully, but their baseline checks failed +because the reference files did not exist. The other 650 test groups passed. +The archive preserves all existing baseline payloads and adds only these six +test datasets. + PR #3996 (2026-09-20) ===================== Switch the single-phase reactive transport solver to a molality-based primary