diff --git a/src/coreComponents/physicsSolvers/multiphysics/MultiphasePoromechanics.cpp b/src/coreComponents/physicsSolvers/multiphysics/MultiphasePoromechanics.cpp index 30cd3db9a6..6b01f872f5 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/MultiphasePoromechanics.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/MultiphasePoromechanics.cpp @@ -24,6 +24,7 @@ #include "dataRepository/LogLevelsInfo.hpp" #include "constitutive/fluid/multifluid/MultiFluidBase.hpp" #include "constitutive/solid/PorousSolid.hpp" +#include "physicsSolvers/fluidFlow/CompositionalMultiphaseHybridFVM.hpp" #include "physicsSolvers/fluidFlow/FlowSolverBaseFields.hpp" #include "physicsSolvers/fluidFlow/CompositionalMultiphaseHybridFVM.hpp" #include "physicsSolvers/multiphysics/poromechanicsKernels/MultiphasePoromechanics.hpp" @@ -54,13 +55,6 @@ void MultiphasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::postInputInitiali Base::postInputInitialization(); setMGRStrategy(); - - GEOS_ERROR_IF( this->flowSolver()->getCatalogName() == "CompositionalMultiphaseReservoir" && - this->getNonlinearSolverParameters().couplingType() != NonlinearSolverParameters::CouplingType::Sequential, - GEOS_FMT( "{}: {} solver is only designed to work for {} = {}", - this->getDataContext(), catalogName(), NonlinearSolverParameters::viewKeysStruct::couplingTypeString(), - EnumStrings< NonlinearSolverParameters::CouplingType >::toString( NonlinearSolverParameters::CouplingType::Sequential ) - )); } template< typename FLOW_SOLVER, typename MECHANICS_SOLVER > @@ -82,6 +76,7 @@ void MultiphasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::assembleSystem( r { GEOS_MARK_FUNCTION; + // Steps 1 and 2: compute element-based terms (mechanics and local flow terms) assembleElementBasedTerms( time, dt, domain, @@ -110,6 +105,50 @@ void MultiphasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::assembleSystem( r } } +template<> +void MultiphasePoromechanics< CompositionalMultiphaseReservoirAndWells<>, SolidMechanicsLagrangianFEM >::assembleSystem( real64 const time, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + // Steps 1 and 2: compute element-based terms (mechanics and local flow terms) + assembleElementBasedTerms( time, + dt, + domain, + dofManager, + localMatrix, + localRhs ); + + // step 3: compute the fluxes (face-based contributions) + + if( m_stabilizationType == StabilizationType::Global || + m_stabilizationType == StabilizationType::Local ) + { + this->flowSolver()->assembleStabilizedFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); + } + else + { + this->flowSolver()->assembleFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); + } + + // step 4: assemble well contributions + + this->flowSolver()->wellSolver()->assembleSystem( time, dt, domain, dofManager, localMatrix, localRhs ); + this->flowSolver()->assembleCouplingTerms( time, dt, domain, dofManager, localMatrix, localRhs ); +} + template< typename FLOW_SOLVER, typename MECHANICS_SOLVER > void MultiphasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::assembleElementBasedTerms( real64 const time_n, real64 const dt, @@ -275,6 +314,32 @@ void MultiphasePoromechanics<>::setMGRStrategy() EnumStrings< LinearSolverParameters::MGR::StrategyType >::toString( linearSolverParameters.mgr.strategy ))); } +template<> +void MultiphasePoromechanics< CompositionalMultiphaseReservoirAndWells<>, SolidMechanicsLagrangianFEM >::setMGRStrategy() +{ + // same as CompositionalMultiphaseReservoirAndWells< MultiphasePoromechanics<> >::setMGRStrategy + + LinearSolverParameters & linearSolverParameters = m_linearSolverParameters.get(); + + if( linearSolverParameters.preconditionerType != LinearSolverParameters::PreconditionerType::mgr ) + return; + + linearSolverParameters.mgr.separateComponents = true; + linearSolverParameters.dofsPerNode = 3; + + if( dynamic_cast< CompositionalMultiphaseHybridFVM * >( this->flowSolver() ) ) + { + GEOS_ERROR( GEOS_FMT( "{}: MGR strategy is not implemented for {}/{}", + this->getName(), this->getCatalogName(), this->flowSolver()->getCatalogName() ) ); + } + else + { + linearSolverParameters.mgr.strategy = LinearSolverParameters::MGR::StrategyType::multiphasePoromechanicsReservoirFVM; + } + GEOS_LOG_LEVEL_RANK_0( 1, GEOS_FMT( "{}: MGR strategy set to {}", getName(), + EnumStrings< LinearSolverParameters::MGR::StrategyType >::toString( linearSolverParameters.mgr.strategy ))); +} + template< typename FLOW_SOLVER, typename MECHANICS_SOLVER > void MultiphasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::updateBulkDensity( ElementSubRegionBase & subRegion ) { diff --git a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp index 4c3d3fc6e9..0bfa9146a2 100644 --- a/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp +++ b/src/coreComponents/physicsSolvers/multiphysics/SinglePhasePoromechanics.cpp @@ -54,13 +54,6 @@ void SinglePhasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::postInputInitial Base::postInputInitialization(); setMGRStrategy(); - - GEOS_ERROR_IF( this->flowSolver()->getCatalogName() == "SinglePhaseReservoir" && - this->getNonlinearSolverParameters().couplingType() != NonlinearSolverParameters::CouplingType::Sequential, - GEOS_FMT( "{}: {} solver is only designed to work for {} = {}", - this->getName(), catalogName(), NonlinearSolverParameters::viewKeysStruct::couplingTypeString(), - EnumStrings< NonlinearSolverParameters::CouplingType >::toString( NonlinearSolverParameters::CouplingType::Sequential ) - )); } template< typename FLOW_SOLVER, typename MECHANICS_SOLVER > @@ -151,6 +144,32 @@ void SinglePhasePoromechanics<>::setMGRStrategy() EnumStrings< LinearSolverParameters::MGR::StrategyType >::toString( linearSolverParameters.mgr.strategy ))); } +template<> +void SinglePhasePoromechanics< SinglePhaseReservoirAndWells<>, SolidMechanicsLagrangianFEM >::setMGRStrategy() +{ + // same as SinglePhaseReservoirAndWells< SinglePhasePoromechanics<> >::setMGRStrategy + + LinearSolverParameters & linearSolverParameters = m_linearSolverParameters.get(); + + if( linearSolverParameters.preconditionerType != LinearSolverParameters::PreconditionerType::mgr ) + return; + + linearSolverParameters.mgr.separateComponents = true; + linearSolverParameters.dofsPerNode = 3; + + if( dynamic_cast< SinglePhaseHybridFVM * >( this->flowSolver() ) ) + { + GEOS_ERROR( GEOS_FMT( "{}: MGR strategy is not implemented for poromechanics {}/{}", + this->getName(), this->getCatalogName(), this->flowSolver()->getCatalogName())); + } + else + { + linearSolverParameters.mgr.strategy = LinearSolverParameters::MGR::StrategyType::singlePhasePoromechanicsReservoirFVM; + } + GEOS_LOG_LEVEL_RANK_0( 1, GEOS_FMT( "{}: MGR strategy set to {}", this->getName(), + EnumStrings< LinearSolverParameters::MGR::StrategyType >::toString( linearSolverParameters.mgr.strategy ))); +} + template< typename FLOW_SOLVER, typename MECHANICS_SOLVER > void SinglePhasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::assembleSystem( real64 const time_n, real64 const dt, @@ -186,7 +205,48 @@ void SinglePhasePoromechanics< FLOW_SOLVER, MECHANICS_SOLVER >::assembleSystem( localMatrix, localRhs ); } +} + +template<> +void SinglePhasePoromechanics< SinglePhaseReservoirAndWells<>, SolidMechanicsLagrangianFEM >::assembleSystem( real64 const time_n, + real64 const dt, + DomainPartition & domain, + DofManager const & dofManager, + CRSMatrixView< real64, globalIndex const > const & localMatrix, + arrayView1d< real64 > const & localRhs ) +{ + GEOS_MARK_FUNCTION; + + // Steps 1 and 2: compute element-based terms (mechanics and local flow terms) + assembleElementBasedTerms( time_n, + dt, + domain, + dofManager, + localMatrix, + localRhs ); + + // Step 3: compute the fluxes (face-based contributions) + if( m_stabilizationType == StabilizationType::Global || m_stabilizationType == StabilizationType::Local ) + { + this->flowSolver()->assembleStabilizedFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); + } + else + { + this->flowSolver()->assembleFluxTerms( dt, + domain, + dofManager, + localMatrix, + localRhs ); + } + + // step 4: assemble well contributions + this->flowSolver()->wellSolver()->assembleSystem( time_n, dt, domain, dofManager, localMatrix, localRhs ); + this->flowSolver()->assembleCouplingTerms( time_n, dt, domain, dofManager, localMatrix, localRhs ); } template< typename FLOW_SOLVER, typename MECHANICS_SOLVER >