From 8bfa9e037122f1141d85e52f4b3b344505582c3f Mon Sep 17 00:00:00 2001 From: "Victor A. P. Magri" Date: Thu, 26 Mar 2026 21:39:04 -0400 Subject: [PATCH 1/2] Add MGR strategy for thermal single-phase flow with wells and poromechanics --- .../interfaces/hypre/HypreMGR.cpp | 6 + ...alSinglePhasePoromechanicsReservoirFVM.hpp | 124 ++++++++++++++++++ .../utilities/LinearSolverParameters.hpp | 54 ++++---- .../multiphysics/SinglePhasePoromechanics.cpp | 5 +- .../SinglePhaseReservoirAndWells.cpp | 5 +- 5 files changed, 166 insertions(+), 28 deletions(-) create mode 100644 src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ThermalSinglePhasePoromechanicsReservoirFVM.hpp diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp index fd0d22b9ded..84912abe16c 100644 --- a/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/HypreMGR.cpp @@ -43,6 +43,7 @@ #include "linearAlgebra/interfaces/hypre/mgrStrategies/ThermalCompositionalMultiphaseFVM.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/ThermalCompositionalMultiphaseReservoirFVM.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/ThermalSinglePhasePoromechanics.hpp" +#include "linearAlgebra/interfaces/hypre/mgrStrategies/ThermalSinglePhasePoromechanicsReservoirFVM.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/ThermalSinglePhaseReservoirFVM.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/ThermalMultiphasePoromechanics.hpp" #include "linearAlgebra/interfaces/hypre/mgrStrategies/SolidMechanicsEmbeddedFractures.hpp" @@ -192,6 +193,11 @@ void hypre::mgr::createMGR( LinearSolverParameters const & params, setStrategy< SinglePhasePoromechanicsReservoirFVM >( params.mgr, numComponentsPerField, precond, mgrData ); break; } + case LinearSolverParameters::MGR::StrategyType::thermalSinglePhasePoromechanicsReservoirFVM: + { + setStrategy< ThermalSinglePhasePoromechanicsReservoirFVM >( params.mgr, numComponentsPerField, precond, mgrData ); + break; + } case LinearSolverParameters::MGR::StrategyType::singlePhaseReservoirFVM: { setStrategy< SinglePhaseReservoirFVM >( params.mgr, numComponentsPerField, precond, mgrData ); diff --git a/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ThermalSinglePhasePoromechanicsReservoirFVM.hpp b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ThermalSinglePhasePoromechanicsReservoirFVM.hpp new file mode 100644 index 00000000000..de68c2bd046 --- /dev/null +++ b/src/coreComponents/linearAlgebra/interfaces/hypre/mgrStrategies/ThermalSinglePhasePoromechanicsReservoirFVM.hpp @@ -0,0 +1,124 @@ +/* + * ------------------------------------------------------------------------------------------------------------ + * SPDX-License-Identifier: LGPL-2.1-only + * + * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC + * Copyright (c) 2018-2024 TotalEnergies + * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University + * Copyright (c) 2023-2024 Chevron + * Copyright (c) 2019- GEOS/GEOSX Contributors + * All rights reserved + * + * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details. + * ------------------------------------------------------------------------------------------------------------ + */ + +/** + * @file ThermalSinglePhasePoromechanicsReservoirFVM.hpp + */ + +#ifndef GEOS_LINEARALGEBRA_INTERFACES_HYPREMGRTHERMALSINGLEPHASEPOROMECHANICSRESERVOIRFVM_HPP_ +#define GEOS_LINEARALGEBRA_INTERFACES_HYPREMGRTHERMALSINGLEPHASEPOROMECHANICSRESERVOIRFVM_HPP_ + +#include "linearAlgebra/interfaces/hypre/HypreMGR.hpp" + +namespace geos +{ + +namespace hypre +{ + +namespace mgr +{ + +/** + * @brief ThermalSinglePhasePoromechanicsReservoirFVM strategy. + * + * dofLabel: 0 = displacement, x-component + * dofLabel: 1 = displacement, y-component + * dofLabel: 2 = displacement, z-component + * dofLabel: 3 = pressure + * dofLabel: 4 = temperature + * dofLabel: 5 = well pressure + * dofLabel: 6 = well rate + * dofLabel: 7 = well temperature + * + * 2-level MGR reduction strategy + * - 1st level: eliminate displacements (0,1,2) + * - 2nd level: eliminate the thermal well block + * - The coarse grid (pressure and temperature) is solved with BoomerAMG. + * + */ +class ThermalSinglePhasePoromechanicsReservoirFVM : public MGRStrategyBase< 2 > +{ +public: + + /** + * @brief Constructor. + */ + explicit ThermalSinglePhasePoromechanicsReservoirFVM( arrayView1d< int const > const & ) + : MGRStrategyBase( 8 ) + { + // Level 0: eliminate displacements + m_labels[0].push_back( 3 ); + m_labels[0].push_back( 4 ); + m_labels[0].push_back( 5 ); + m_labels[0].push_back( 6 ); + m_labels[0].push_back( 7 ); + + // Level 1: eliminate the well block + m_labels[1].push_back( 3 ); + m_labels[1].push_back( 4 ); + + setupLabels(); + + // Level 0 + m_levelFRelaxType[0] = MGRFRelaxationType::amgVCycle; + m_levelFRelaxIters[0] = 1; + m_levelInterpType[0] = MGRInterpolationType::jacobi; + m_levelRestrictType[0] = MGRRestrictionType::injection; + m_levelCoarseGridMethod[0] = MGRCoarseGridMethod::nonGalerkin; + m_levelGlobalSmootherType[0] = MGRGlobalSmootherType::none; + + // Level 1 + m_levelFRelaxType[1] = MGRFRelaxationType::gsElimWInverse; + m_levelFRelaxIters[1] = 1; + m_levelInterpType[1] = MGRInterpolationType::blockJacobi; + m_levelRestrictType[1] = MGRRestrictionType::injection; + m_levelCoarseGridMethod[1] = MGRCoarseGridMethod::galerkin; + m_levelGlobalSmootherType[1] = MGRGlobalSmootherType::none; + } + + /** + * @brief Setup the MGR strategy. + * @param mgrParams MGR configuration parameters + * @param precond preconditioner wrapper + * @param mgrData auxiliary MGR data + */ + void setup( LinearSolverParameters::MGR const & mgrParams, + HyprePrecWrapper & precond, + HypreMGRData & mgrData ) + { + // If the wells are shut, Gaussian elimination on the well block is unnecessary. + if( mgrParams.areWellsShut ) + { + m_levelFRelaxType[1] = MGRFRelaxationType::jacobi; + } + + setReduction( precond, mgrData ); + + // Configure the BoomerAMG solver used as F-relaxation for the first level. + setMechanicsFSolver( precond, mgrData, mgrParams.separateComponents ); + + // Configure the BoomerAMG solver used as coarse solver for the pressure/temperature system. + setPressureTemperatureAMG( mgrData.coarseSolver ); + } +}; + +} // namespace mgr + +} // namespace hypre + +} // namespace geos + +#endif /*GEOS_LINEARALGEBRA_INTERFACES_HYPREMGRTHERMALSINGLEPHASEPOROMECHANICSRESERVOIRFVM_HPP_*/ diff --git a/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp b/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp index 502227c5400..5b195b94db0 100644 --- a/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp +++ b/src/coreComponents/linearAlgebra/utilities/LinearSolverParameters.hpp @@ -294,33 +294,34 @@ struct LinearSolverParameters */ enum class StrategyType : integer { - invalid, ///< default value, to ensure solver sets something - singlePhaseReservoirFVM, ///< finite volume single-phase flow with wells - thermalSinglePhaseReservoirFVM, ///< finite volume thermal single-phase flow with wells - singlePhaseHybridFVM, ///< hybrid finite volume single-phase flow - singlePhaseReservoirHybridFVM, ///< hybrid finite volume single-phase flow with wells - singlePhasePoromechanics, ///< single phase poromechanics with finite volume single phase flow - thermalSinglePhasePoromechanics, ///< thermal single phase poromechanics with finite volume single phase flow - hybridSinglePhasePoromechanics, ///< single phase poromechanics with hybrid finite volume single phase flow - singlePhasePoromechanicsEmbeddedFractures, ///< single phase poromechanics with FV embedded fractures + invalid, ///< default value, to ensure solver sets something + singlePhaseReservoirFVM, ///< finite volume single-phase flow with wells + thermalSinglePhaseReservoirFVM, ///< finite volume thermal single-phase flow with wells + singlePhaseHybridFVM, ///< hybrid finite volume single-phase flow + singlePhaseReservoirHybridFVM, ///< hybrid finite volume single-phase flow with wells + singlePhasePoromechanics, ///< single phase poromechanics with finite volume single phase flow + thermalSinglePhasePoromechanics, ///< thermal single phase poromechanics with finite volume single phase flow + hybridSinglePhasePoromechanics, ///< single phase poromechanics with hybrid finite volume single phase flow + singlePhasePoromechanicsEmbeddedFractures, ///< single phase poromechanics with FV embedded fractures singlePhasePoromechanicsConformingFractures, ///< single phase poromechanics with conforming fractures - singlePhasePoromechanicsReservoirFVM, ///< single phase poromechanics with finite volume single phase flow with wells - compositionalMultiphaseFVM, ///< finite volume compositional multiphase flow - compositionalMultiphaseHybridFVM, ///< hybrid finite volume compositional multiphase flow - compositionalMultiphaseReservoirFVM, ///< finite volume compositional multiphase flow with wells - compositionalMultiphaseReservoirHybridFVM, ///< hybrid finite volume compositional multiphase flow with wells - immiscibleMultiphaseFVM, ///< finite volume immiscible multiphase flow - reactiveCompositionalMultiphaseOBL, ///< finite volume reactive compositional flow with OBL - thermalCompositionalMultiphaseFVM, ///< finite volume thermal compositional multiphase flow - thermalCompositionalMultiphaseReservoirFVM,///< finite volume thermal compositional multiphase flow - multiphasePoromechanics, ///< multiphase poromechanics with finite volume compositional multiphase flow - multiphasePoromechanicsReservoirFVM, ///< multiphase poromechanics with finite volume compositional multiphase flow with wells - thermalMultiphasePoromechanics, ///< thermal multiphase poromechanics with finite volume compositional multiphase flow - hydrofracture, ///< hydrofracture - lagrangianContactMechanics, ///< Lagrangian contact mechanics - augmentedLagrangianContactMechanics, ///< Augmented Lagrangian contact mechanics - lagrangianContactMechanicsBubbleStab, ///< Lagrangian contact mechanics with bubble stabilization - solidMechanicsEmbeddedFractures ///< Embedded fractures mechanics + singlePhasePoromechanicsReservoirFVM, ///< single phase poromechanics with finite volume single phase flow with wells + thermalSinglePhasePoromechanicsReservoirFVM, ///< thermal single phase poromechanics with finite volume single phase flow with wells + compositionalMultiphaseFVM, ///< finite volume compositional multiphase flow + compositionalMultiphaseHybridFVM, ///< hybrid finite volume compositional multiphase flow + compositionalMultiphaseReservoirFVM, ///< finite volume compositional multiphase flow with wells + compositionalMultiphaseReservoirHybridFVM, ///< hybrid finite volume compositional multiphase flow with wells + immiscibleMultiphaseFVM, ///< finite volume immiscible multiphase flow + reactiveCompositionalMultiphaseOBL, ///< finite volume reactive compositional flow with OBL + thermalCompositionalMultiphaseFVM, ///< finite volume thermal compositional multiphase flow + thermalCompositionalMultiphaseReservoirFVM, ///< finite volume thermal compositional multiphase flow + multiphasePoromechanics, ///< multiphase poromechanics with finite volume compositional multiphase flow + multiphasePoromechanicsReservoirFVM, ///< multiphase poromechanics with finite volume compositional multiphase flow with wells + thermalMultiphasePoromechanics, ///< thermal multiphase poromechanics with finite volume compositional multiphase flow + hydrofracture, ///< hydrofracture + lagrangianContactMechanics, ///< Lagrangian contact mechanics + augmentedLagrangianContactMechanics, ///< Augmented Lagrangian contact mechanics + lagrangianContactMechanicsBubbleStab, ///< Lagrangian contact mechanics with bubble stabilization + solidMechanicsEmbeddedFractures ///< Embedded fractures mechanics }; StrategyType strategy = StrategyType::invalid; ///< Predefined MGR solution strategy (solver specific) @@ -581,6 +582,7 @@ ENUM_STRINGS( LinearSolverParameters::MGR::StrategyType, "singlePhasePoromechanicsEmbeddedFractures", "singlePhasePoromechanicsConformingFractures", "singlePhasePoromechanicsReservoirFVM", + "thermalSinglePhasePoromechanicsReservoirFVM", "compositionalMultiphaseFVM", "compositionalMultiphaseHybridFVM", "compositionalMultiphaseReservoirFVM", diff --git a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp index 7265e98d52e..468117b09dd 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp @@ -158,7 +158,10 @@ void SinglePhasePoromechanics< SinglePhaseReservoirAndWells<>, SolidMechanicsLag } else { - linearSolverParameters.mgr.strategy = LinearSolverParameters::MGR::StrategyType::singlePhasePoromechanicsReservoirFVM; + linearSolverParameters.mgr.strategy = + this->m_isThermal + ? LinearSolverParameters::MGR::StrategyType::thermalSinglePhasePoromechanicsReservoirFVM + : LinearSolverParameters::MGR::StrategyType::singlePhasePoromechanicsReservoirFVM; } GEOS_LOG_LEVEL_RANK_0( logInfo::LinearSolver, GEOS_FMT( "{}: MGR strategy set to {}", this->getName(), diff --git a/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp b/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp index 2e86a1fcf2c..ca582820992 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/SinglePhaseReservoirAndWells.cpp @@ -119,7 +119,10 @@ setMGRStrategy() } else { - linearSolverParameters.mgr.strategy = LinearSolverParameters::MGR::StrategyType::singlePhasePoromechanicsReservoirFVM; + linearSolverParameters.mgr.strategy = + wellSolver()->isThermal() + ? LinearSolverParameters::MGR::StrategyType::thermalSinglePhasePoromechanicsReservoirFVM + : LinearSolverParameters::MGR::StrategyType::singlePhasePoromechanicsReservoirFVM; } GEOS_LOG_LEVEL_RANK_0( logInfo::LinearSolver, GEOS_FMT( "{}: MGR strategy set to {}", this->getName(), From d0c7b0a4a9510443d5e4cfb1647255c1b3be1c02 Mon Sep 17 00:00:00 2001 From: frankfeifan Date: Sat, 28 Mar 2026 12:58:24 -0700 Subject: [PATCH 2/2] cleaned up and added a fim case for ReservoirThermoPoroElastic with new mgr recipe --- ...voirThermoPoroElastic_Circulation_base.xml | 4 +- ...rvoirThermoPoroElastic_Circulation_fim.xml | 208 ++++++++++++++++++ ...rmoPoroElastic_Circulation_sequential.xml} | 19 +- .../pressureTable/pres.geos | 0 .../pressureTable/xlin.geos | 0 .../pressureTable/ylin.geos | 0 .../pressureTable/zlin.geos | 0 .../tempTable/temp.geos | 0 .../tempTable/xlin.geos | 0 .../tempTable/ylin.geos | 0 .../tempTable/zlin.geos | 0 11 files changed, 216 insertions(+), 15 deletions(-) rename inputFiles/{poromechanics => thermoPoromechanics}/ReservoirThermoPoroElastic_Circulation_base.xml (97%) create mode 100644 inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_fim.xml rename inputFiles/{poromechanics/ReservoirThermoPoroElastic_Circulation_debug.xml => thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_sequential.xml} (94%) rename inputFiles/{poromechanics => thermoPoromechanics}/pressureTable/pres.geos (100%) rename inputFiles/{poromechanics => thermoPoromechanics}/pressureTable/xlin.geos (100%) rename inputFiles/{poromechanics => thermoPoromechanics}/pressureTable/ylin.geos (100%) rename inputFiles/{poromechanics => thermoPoromechanics}/pressureTable/zlin.geos (100%) rename inputFiles/{poromechanics => thermoPoromechanics}/tempTable/temp.geos (100%) rename inputFiles/{poromechanics => thermoPoromechanics}/tempTable/xlin.geos (100%) rename inputFiles/{poromechanics => thermoPoromechanics}/tempTable/ylin.geos (100%) rename inputFiles/{poromechanics => thermoPoromechanics}/tempTable/zlin.geos (100%) diff --git a/inputFiles/poromechanics/ReservoirThermoPoroElastic_Circulation_base.xml b/inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_base.xml similarity index 97% rename from inputFiles/poromechanics/ReservoirThermoPoroElastic_Circulation_base.xml rename to inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_base.xml index 32cd3bdf55d..bc120678ffa 100644 --- a/inputFiles/poromechanics/ReservoirThermoPoroElastic_Circulation_base.xml +++ b/inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_base.xml @@ -55,11 +55,11 @@ + permeabilityComponents="{ 1e-15, 1e-15, 1e-15 }"/> + defaultThermalConductivityComponents="{ 100.0, 100.0, 100.0 }"/> diff --git a/inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_fim.xml b/inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_fim.xml new file mode 100644 index 00000000000..eabbac771cf --- /dev/null +++ b/inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_fim.xml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inputFiles/poromechanics/ReservoirThermoPoroElastic_Circulation_debug.xml b/inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_sequential.xml similarity index 94% rename from inputFiles/poromechanics/ReservoirThermoPoroElastic_Circulation_debug.xml rename to inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_sequential.xml index b2a0d65d59d..f960fd78eca 100644 --- a/inputFiles/poromechanics/ReservoirThermoPoroElastic_Circulation_debug.xml +++ b/inputFiles/thermoPoromechanics/ReservoirThermoPoroElastic_Circulation_sequential.xml @@ -20,8 +20,8 @@ subcycling="1" newtonTol="1e-4" lineSearchAction="None" - newtonMaxIter="20" - maxAllowedResidualNorm="1e40"/> + maxTimeStepCuts="4" + newtonMaxIter="20"/> + numElementsPerSegment="2"> + numElementsPerSegment="2"> + maxTime="1e5"> - -