diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp index 14537f0d999..1493279b08a 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.cpp @@ -427,8 +427,7 @@ void CompositionalMultiphaseWell::validateInjectionStreams( WellElementSubRegion void CompositionalMultiphaseWell::validateWellConstraints( real64 const & time_n, real64 const & GEOS_UNUSED_PARAM( dt ), - WellElementSubRegion const & subRegion, - ElementRegionManager const & elemManager ) + WellElementSubRegion const & subRegion ) { WellControls & wellControls = getWellControls( subRegion ); if( !wellControls.useSurfaceConditions() ) @@ -453,17 +452,7 @@ void CompositionalMultiphaseWell::validateWellConstraints( real64 const & time_n GEOS_FMT( "{}: Region {} is not a target of the reservoir solver and cannot be used for referenceReservoirRegion in WellControl {}.", getDataContext(), regionName, wellControls.getName() ) ); - ElementRegionBase const & region = elemManager.getRegion( wellControls.referenceReservoirRegion()); - - // Check if regions statistics are being computed - GEOS_ERROR_IF( !region.hasWrapper( CompositionalMultiphaseStatistics::catalogName()), - GEOS_FMT( "{}: No region average quantities computed. WellControl {} referenceReservoirRegion field requires CompositionalMultiphaseStatistics to be configured for region {} ", - getDataContext(), wellControls.getName(), regionName )); - CompositionalMultiphaseStatistics::RegionStatistics const & stats = region.getReference< CompositionalMultiphaseStatistics::RegionStatistics >( - CompositionalMultiphaseStatistics::regionStatisticsName() ); - wellControls.setRegionAveragePressure( stats.averagePressure ); - wellControls.setRegionAverageTemperature( stats.averageTemperature ); } } string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString()); @@ -682,7 +671,7 @@ void CompositionalMultiphaseWell::updateBHPForConstraint( WellElementSubRegion & } -void CompositionalMultiphaseWell::updateVolRatesForConstraint( WellElementSubRegion & subRegion ) +void CompositionalMultiphaseWell::updateVolRatesForConstraint( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ) { GEOS_MARK_FUNCTION; @@ -737,6 +726,17 @@ void CompositionalMultiphaseWell::updateVolRatesForConstraint( WellElementSubReg } else { + if( wellControls.referenceReservoirRegion() != "" ) + { + ElementRegionBase const & region = elemManager.getRegion( wellControls.referenceReservoirRegion()); + CompositionalMultiphaseStatistics::RegionStatistics const & stats = region.getReference< CompositionalMultiphaseStatistics::RegionStatistics >( + CompositionalMultiphaseStatistics::regionStatisticsName() ); + wellControls.setRegionAveragePressure( stats.averagePressure ); + wellControls.setRegionAverageTemperature( stats.averageTemperature ); + GEOS_ERROR_IF( stats.averagePressure <= 0.0, + GEOS_FMT( "{}: No region average quantities computed. WellControl {} referenceReservoirRegion field requires CompositionalMultiphaseStatistics to be configured for region {} ", + getDataContext(), wellControls.getName(), wellControls.referenceReservoirRegion() )); + } // If flashPressure is not set by region the value is defaulted to -1 and indicates to use top segment conditions flashPressure = wellControls.getRegionAveragePressure(); if( flashPressure < 0.0 ) @@ -1004,13 +1004,14 @@ void CompositionalMultiphaseWell::updateState( DomainPartition & domain ) MeshLevel & mesh, string_array const & regionNames ) { - mesh.getElemManager().forElementSubRegions< WellElementSubRegion >( regionNames, [&]( localIndex const, - WellElementSubRegion & subRegion ) + ElementRegionManager & elemManager = mesh.getElemManager(); + elemManager.forElementSubRegions< WellElementSubRegion >( regionNames, [&]( localIndex const, + WellElementSubRegion & subRegion ) { WellControls & wellControls = getWellControls( subRegion ); if( wellControls.getWellStatus() == WellControls::Status::OPEN ) { - real64 const maxRegionPhaseVolFrac = updateSubRegionState( subRegion ); + real64 const maxRegionPhaseVolFrac = updateSubRegionState( elemManager, subRegion ); maxPhaseVolFrac = LvArray::math::max( maxRegionPhaseVolFrac, maxPhaseVolFrac ); } } ); @@ -1023,14 +1024,14 @@ void CompositionalMultiphaseWell::updateState( DomainPartition & domain ) } -real64 CompositionalMultiphaseWell::updateSubRegionState( WellElementSubRegion & subRegion ) +real64 CompositionalMultiphaseWell::updateSubRegionState( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ) { // update properties updateGlobalComponentFraction( subRegion ); // update volumetric rates for the well constraints // note: this must be called before updateFluidModel - updateVolRatesForConstraint( subRegion ); + updateVolRatesForConstraint( elemManager, subRegion ); // update densities, phase fractions, phase volume fractions @@ -1148,7 +1149,7 @@ void CompositionalMultiphaseWell::initializeWells( DomainPartition & domain, rea wellElemCompDens ); // 5) Recompute the pressure-dependent properties - updateSubRegionState( subRegion ); + updateSubRegionState( elemManager, subRegion ); // 6) Estimate the well rates // TODO: initialize rates using perforation rates @@ -1954,7 +1955,7 @@ void CompositionalMultiphaseWell::resetStateToBeginningOfStep( DomainPartition & if( wellControls.isWellOpen( ) ) { - updateSubRegionState( subRegion ); + updateSubRegionState( elemManager, subRegion ); } } ); } ); @@ -2146,9 +2147,9 @@ void CompositionalMultiphaseWell::implicitStepSetup( real64 const & time_n, MultiFluidBase const & fluid = getConstitutiveModel< MultiFluidBase >( subRegion, fluidName ); fluid.saveConvergedState(); - validateWellConstraints( time_n, dt, subRegion, elemManager ); + validateWellConstraints( time_n, dt, subRegion ); - updateSubRegionState( subRegion ); + updateSubRegionState( elemManager, subRegion ); } } ) ; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.hpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.hpp index fd874ec5a0e..38311177552 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/CompositionalMultiphaseWell.hpp @@ -140,10 +140,10 @@ class CompositionalMultiphaseWell : public WellSolverBase /** * @brief Recompute the volumetric rates that are used in the well constraints + * @param elemManager the well region manager containing the well * @param subRegion the well subregion containing all the primary and dependent fields - * @param targetIndex the targetIndex of the subRegion */ - void updateVolRatesForConstraint( WellElementSubRegion & subRegion ); + void updateVolRatesForConstraint( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ); /** * @brief Recompute the current BHP pressure @@ -185,7 +185,7 @@ class CompositionalMultiphaseWell : public WellSolverBase */ virtual void updateState( DomainPartition & domain ) override; - virtual real64 updateSubRegionState( WellElementSubRegion & subRegion ) override; + virtual real64 updateSubRegionState( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ) override; virtual string wellElementDofName() const override { return viewKeyStruct::dofFieldString(); } @@ -345,8 +345,7 @@ class CompositionalMultiphaseWell : public WellSolverBase */ virtual void validateWellConstraints( real64 const & time_n, real64 const & dt, - WellElementSubRegion const & subRegion, - ElementRegionManager const & elemManager ) override; + WellElementSubRegion const & subRegion ) override; /** * @brief Create well separator diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.cpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.cpp index 4d49a5062e4..60f09a7f1a7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.cpp @@ -140,8 +140,7 @@ string SinglePhaseWell::resElementDofName() const void SinglePhaseWell::validateWellConstraints( real64 const & time_n, real64 const & GEOS_UNUSED_PARAM( dt ), - WellElementSubRegion const & subRegion, - ElementRegionManager const & elemManager ) + WellElementSubRegion const & subRegion ) { WellControls & wellControls = getWellControls( subRegion ); if( !wellControls.useSurfaceConditions() ) @@ -164,16 +163,6 @@ void SinglePhaseWell::validateWellConstraints( real64 const & time_n, GEOS_FMT( "{}: Region {} is not a target of the reservoir solver and cannot be used for referenceReservoirRegion in WellControl {}.", getDataContext(), regionName, wellControls.getName() ) ); - ElementRegionBase const & region = elemManager.getRegion( wellControls.referenceReservoirRegion() ); - - // Check if regions statistics are being computed - GEOS_ERROR_IF( !region.hasWrapper( SinglePhaseStatistics::catalogName()), - GEOS_FMT( "{}: No region average quantities computed. WellControl {} referenceReservoirRegion field requires SinglePhaseStatistics to be configured for region {} ", - getDataContext(), wellControls.getName(), regionName )); - - SinglePhaseStatistics::RegionStatistics const & stats = region.getReference< SinglePhaseStatistics::RegionStatistics >( SinglePhaseStatistics::regionStatisticsName() ); - wellControls.setRegionAveragePressure( stats.averagePressure ); - wellControls.setRegionAverageTemperature( stats.averageTemperature ); } } WellControls::Control currentControl = wellControls.getControl(); @@ -262,7 +251,7 @@ void SinglePhaseWell::updateBHPForConstraint( WellElementSubRegion & subRegion ) } -void SinglePhaseWell::updateVolRateForConstraint( WellElementSubRegion & subRegion ) +void SinglePhaseWell::updateVolRateForConstraint( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ) { GEOS_MARK_FUNCTION; @@ -303,6 +292,18 @@ void SinglePhaseWell::updateVolRateForConstraint( WellElementSubRegion & subRegi } else { + if( wellControls.referenceReservoirRegion() != "" ) + { + ElementRegionBase const & region = elemManager.getRegion( wellControls.referenceReservoirRegion() ); + + // Check if regions statistics are being computed + SinglePhaseStatistics::RegionStatistics const & stats = region.getReference< SinglePhaseStatistics::RegionStatistics >( SinglePhaseStatistics::regionStatisticsName() ); + GEOS_ERROR_IF( stats.averagePressure <= 0.0, + GEOS_FMT( "{}: No region average quantities computed. WellControl {} referenceReservoirRegion field requires SinglePhaseStatistics to be configured for region {} ", + getDataContext(), wellControls.getName(), wellControls.referenceReservoirRegion() )); + wellControls.setRegionAveragePressure( stats.averagePressure ); + wellControls.setRegionAverageTemperature( stats.averageTemperature ); + } // use region conditions flashPressure = wellControls.getRegionAveragePressure(); if( flashPressure < 0.0 ) @@ -401,11 +402,11 @@ void SinglePhaseWell::updateFluidModel( WellElementSubRegion & subRegion ) const } ); } -real64 SinglePhaseWell::updateSubRegionState( WellElementSubRegion & subRegion ) +real64 SinglePhaseWell::updateSubRegionState( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ) { // update volumetric rates for the well constraints // Warning! This must be called before updating the fluid model - updateVolRateForConstraint( subRegion ); + updateVolRateForConstraint( elemManager, subRegion ); // update density in the well elements updateFluidModel( subRegion ); @@ -491,7 +492,7 @@ void SinglePhaseWell::initializeWells( DomainPartition & domain, real64 const & // 4) Recompute the pressure-dependent properties // Note: I am leaving that here because I would like to use the perforationRates (computed in UpdateState) // to better initialize the rates - updateSubRegionState( subRegion ); + updateSubRegionState( elemManager, subRegion ); string const & fluidName = subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ); SingleFluidBase & fluid = subRegion.getConstitutiveModel< SingleFluidBase >( fluidName ); @@ -1152,7 +1153,7 @@ void SinglePhaseWell::resetStateToBeginningOfStep( DomainPartition & domain ) subRegion.getField< well::connectionRate_n >(); connRate.setValues< parallelDevicePolicy<> >( connRate_n ); - updateSubRegionState( subRegion ); + updateSubRegionState( elemManager, subRegion ); } ); } ); } @@ -1192,9 +1193,9 @@ void SinglePhaseWell::implicitStepSetup( real64 const & time, getConstitutiveModel< SingleFluidBase >( subRegion, subRegion.getReference< string >( viewKeyStruct::fluidNamesString() ) ); fluid.saveConvergedState(); - validateWellConstraints( time, dt, subRegion, elemManager ); + validateWellConstraints( time, dt, subRegion ); - updateSubRegionState( subRegion ); + updateSubRegionState( elemManager, subRegion ); } ); } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.hpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.hpp index 7bfeb996aa4..8c07e223fb7 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/SinglePhaseWell.hpp @@ -140,9 +140,10 @@ class SinglePhaseWell : public WellSolverBase /** * @brief Recompute the volumetric rate that are used in the well constraints + * @param elemManager the well region manager * @param subRegion the well subregion containing all the primary and dependent fields */ - virtual void updateVolRateForConstraint( WellElementSubRegion & subRegion ); + virtual void updateVolRateForConstraint( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ); /** * @brief Recompute the BHP pressure that is used in the well constraints @@ -164,10 +165,11 @@ class SinglePhaseWell : public WellSolverBase real64 const & dt, DomainPartition & domain ) override; /** - * @brief Recompute all dependent quantities from primary variables (including constitutive models) on the well + * @brief Recompute all dependent quantities from primary variables (including constitutive models) + * @param elemManager the elemManager containing the well * @param subRegion the well subRegion containing the well elements and their associated fields */ - virtual real64 updateSubRegionState( WellElementSubRegion & subRegion ) override; + virtual real64 updateSubRegionState( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ) override; /** * @brief function to assemble the linear system matrix and rhs @@ -290,12 +292,10 @@ class SinglePhaseWell : public WellSolverBase * @param time_n the time at the beginning of the time step * @param dt the time step dt * @param subRegion the well subRegion - * @param elemManager the element manager */ virtual void validateWellConstraints( real64 const & time_n, real64 const & dt, - WellElementSubRegion const & subRegion, - ElementRegionManager const & elemManager ) override; + WellElementSubRegion const & subRegion ) override; }; diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp index e470984d7cd..bba04073fbd 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.cpp @@ -159,7 +159,7 @@ void WellSolverBase::initializePostSubGroups() [&]( localIndex const, WellElementSubRegion & subRegion ) { - validateWellConstraints( 0, 0, subRegion, elemManager ); + validateWellConstraints( 0, 0, subRegion ); // validate perforation status table PerforationData & perforationData = *subRegion.getPerforationData(); @@ -305,9 +305,10 @@ void WellSolverBase::updateState( DomainPartition & domain ) MeshLevel & mesh, string_array const & regionNames ) { - mesh.getElemManager().forElementSubRegions< WellElementSubRegion >( regionNames, [&]( localIndex const, - WellElementSubRegion & subRegion ) - { updateSubRegionState( subRegion ); } ); + ElementRegionManager & elemManager = mesh.getElemManager(); + elemManager.forElementSubRegions< WellElementSubRegion >( regionNames, [&]( localIndex const, + WellElementSubRegion & subRegion ) + { updateSubRegionState( elemManager, subRegion ); } ); } ); } diff --git a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp index a8159378b50..04fe58112b4 100644 --- a/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp +++ b/src/coreComponents/physicsSolvers/fluidFlow/wells/WellSolverBase.hpp @@ -250,9 +250,10 @@ class WellSolverBase : public PhysicsSolverBase /** * @brief Recompute all dependent quantities from primary variables (including constitutive models) + * @param elemManager the elemManager containing the well * @param subRegion the well subRegion containing the well elements and their associated fields */ - virtual real64 updateSubRegionState( WellElementSubRegion & subRegion ) = 0; + virtual real64 updateSubRegionState( ElementRegionManager const & elemManager, WellElementSubRegion & subRegion ) = 0; /** * @brief Recompute the perforation rates for all the wells @@ -320,8 +321,7 @@ class WellSolverBase : public PhysicsSolverBase */ virtual void validateWellConstraints( real64 const & time_n, real64 const & dt, - WellElementSubRegion const & subRegion, - ElementRegionManager const & elemManager ) = 0; + WellElementSubRegion const & subRegion ) = 0; virtual void printRates( real64 const & time_n, real64 const & dt,