Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ restartcheck_params["atol"] = 1.0E-6
restartcheck_params["rtol"] = 1.0E-5

decks = [
TestDeck(
name="resvol_constraint",
description=
"Compositional multiphase well test (1D displacement, 2-phase 4-component, 2 wells, reservoir volume well constraint)",
partitions=[(1, 1, 1), (2, 1, 1)],
restart_step=5,
check_step=10,
restartcheck_params=RestartcheckParameters(**restartcheck_params)),
TestDeck(
name="compositional_multiphase_wells_1d",
description=
Expand Down
249 changes: 249 additions & 0 deletions inputFiles/compositionalMultiphaseWell/resvol_constraint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<?xml version="1.0" ?>

<Problem>
<Solvers>
<CompositionalMultiphaseReservoir
name="reservoirSystem"
flowSolverName="compositionalMultiphaseFlow"
wellSolverName="compositionalMultiphaseWell"
logLevel="1"
targetRegions="{ Region1, wellRegion1, wellRegion2 }">
<NonlinearSolverParameters
newtonTol="1.0e-8"
lineSearchAction="None"
newtonMaxIter="40"/>
<LinearSolverParameters
directParallel="0"/>
</CompositionalMultiphaseReservoir>

<CompositionalMultiphaseFVM
name="compositionalMultiphaseFlow"
logLevel="1"
discretization="fluidTPFA"
targetRegions="{ Region1 }"
temperature="297.15"/>

<CompositionalMultiphaseWell
name="compositionalMultiphaseWell"
logLevel="1"
writeCSV="1"
targetRegions="{ wellRegion1, wellRegion2 }">
<WellControls
name="wellControls1"
type="producer"
control="BHP"
referenceElevation="2"
targetBHP="4e6"
targetPhaseRate="1e-7"
referenceReservoirRegion="Region1"
targetPhaseName="oil"/>
<WellControls
name="wellControls2"
type="injector"
control="totalVolRate"
referenceReservoirRegion="Region1"
referenceElevation="2"
targetBHP="1e8"
targetTotalRate="1e-7"
injectionTemperature="297.15"
injectionStream="{ 0.1, 0.1, 0.1, 0.7 }"/>
</CompositionalMultiphaseWell>
</Solvers>

<Mesh>
<InternalMesh
name="mesh1"
elementTypes="{ C3D8 }"
xCoords="{ 0, 5 }"
yCoords="{ 0, 1 }"
zCoords="{ 0, 1 }"
nx="{ 5 }"
ny="{ 1 }"
nz="{ 1 }"
cellBlockNames="{ cb1 }">

<InternalWell
name="well_producer1"
wellRegionName="wellRegion1"
wellControlsName="wellControls1"
polylineNodeCoords="{ { 4.5, 0, 2 },
{ 4.5, 0, 0.5 } }"
polylineSegmentConn="{ { 0, 1 } }"
radius="0.1"
numElementsPerSegment="2">
<Perforation
name="producer1_perf1"
distanceFromHead="1.45"/>
</InternalWell>

<InternalWell
name="well_injector1"
wellRegionName="wellRegion2"
wellControlsName="wellControls2"
polylineNodeCoords="{ { 0.5, 0, 2 },
{ 0.5, 0, 0.5 } }"
polylineSegmentConn="{ { 0, 1 } }"
radius="0.1"
numElementsPerSegment="3">
<Perforation
name="injector1_perf1"
distanceFromHead="1.45"/>
</InternalWell>
</InternalMesh>
</Mesh>

<Events
maxTime="2.5e4">
<PeriodicEvent
name="compositionalMultipshaseFlowStatistics"
beginTime="0"
cycleFrequency="1"
target="/Tasks/compositionalMultiphaseFlowStatistics"/>
<PeriodicEvent
name="solverApplications"
forceDt="2.5e3"
target="/Solvers/reservoirSystem"/>

<PeriodicEvent
name="outputs"
timeFrequency="2.5e3"
target="/Outputs/vtkOutput"/>

<PeriodicEvent
name="restarts"
timeFrequency="1.25e4"
targetExactTimestep="0"
target="/Outputs/restartOutput"/>

</Events>

<Tasks>
<CompositionalMultiphaseStatistics
name="compositionalMultiphaseFlowStatistics"
flowSolverName="compositionalMultiphaseFlow"
computeRegionStatistics="1"
logLevel="1"
writeCSV="1"/>
</Tasks>
<NumericalMethods>
<FiniteVolume>
<TwoPointFluxApproximation
name="fluidTPFA"
/>
</FiniteVolume>
</NumericalMethods>

<ElementRegions>
<CellElementRegion
name="Region1"
cellBlocks="{ * }"
materialList="{ fluid1, rock, relperm }"/>

<WellElementRegion
name="wellRegion1"
materialList="{ fluid1 }"/>

<WellElementRegion
name="wellRegion2"
materialList="{ fluid1 }"/>
</ElementRegions>

<Constitutive>
<CompositionalMultiphaseFluid
name="fluid1"
phaseNames="{ oil, gas }"
equationsOfState="{ PR, PR }"
componentNames="{ N2, C10, C20, H2O }"
componentCriticalPressure="{ 34e5, 25.3e5, 14.6e5, 220.5e5 }"
componentCriticalTemperature="{ 126.2, 622.0, 782.0, 647.0 }"
componentAcentricFactor="{ 0.04, 0.443, 0.816, 0.344 }"
componentMolarWeight="{ 28e-3, 134e-3, 275e-3, 18e-3 }"
componentVolumeShift="{ 0, 0, 0, 0 }"
componentBinaryCoeff="{ { 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 } }"/>

<CompressibleSolidConstantPermeability
name="rock"
solidModelName="nullSolid"
porosityModelName="rockPorosity"
permeabilityModelName="rockPerm"/>

<NullModel
name="nullSolid"/>

<PressurePorosity
name="rockPorosity"
defaultReferencePorosity="0.05"
referencePressure="0.0"
compressibility="1.0e-9"/>

<BrooksCoreyRelativePermeability
name="relperm"
phaseNames="{ oil, gas }"
phaseMinVolumeFraction="{ 0.1, 0.15 }"
phaseRelPermExponent="{ 2.0, 2.0 }"
phaseRelPermMaxValue="{ 0.8, 0.9 }"/>

<ConstantPermeability
name="rockPerm"
permeabilityComponents="{ 2.0e-16, 2.0e-16, 2.0e-16 }"/>
</Constitutive>

<FieldSpecifications>
<!-- Initial pressure: ~5 bar -->
<FieldSpecification
name="initialPressure"
initialCondition="1"
setNames="{ all }"
objectPath="ElementRegions/Region1/cb1"
fieldName="pressure"
scale="5e6"/>

<!-- Initial composition: no water, only heavy hydrocarbon components and N2 -->
<FieldSpecification
name="initialComposition_N2"
initialCondition="1"
setNames="{ all }"
objectPath="ElementRegions/Region1/cb1"
fieldName="globalCompFraction"
component="0"
scale="0.099"/>

<FieldSpecification
name="initialComposition_C10"
initialCondition="1"
setNames="{ all }"
objectPath="ElementRegions/Region1/cb1"
fieldName="globalCompFraction"
component="1"
scale="0.3"/>

<FieldSpecification
name="initialComposition_C20"
initialCondition="1"
setNames="{ all }"
objectPath="ElementRegions/Region1/cb1"
fieldName="globalCompFraction"
component="2"
scale="0.6"/>

<FieldSpecification
name="initialComposition_H20"
initialCondition="1"
setNames="{ all }"
objectPath="ElementRegions/Region1/cb1"
fieldName="globalCompFraction"
component="3"
scale="0.001"/>
</FieldSpecifications>

<Outputs>
<VTK
name="vtkOutput"/>

<Restart
name="restartOutput"/>
</Outputs>
</Problem>
Original file line number Diff line number Diff line change
Expand Up @@ -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() )
Expand All @@ -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());
Expand Down Expand Up @@ -682,7 +671,7 @@ void CompositionalMultiphaseWell::updateBHPForConstraint( WellElementSubRegion &

}

void CompositionalMultiphaseWell::updateVolRatesForConstraint( WellElementSubRegion & subRegion )
void CompositionalMultiphaseWell::updateVolRatesForConstraint( ElementRegionManager const & elemManager, WellElementSubRegion const & subRegion )
{
GEOS_MARK_FUNCTION;

Expand Down Expand Up @@ -737,6 +726,21 @@ void CompositionalMultiphaseWell::updateVolRatesForConstraint( WellElementSubReg
}
else
{
if( !wellControls.referenceReservoirRegion().empty() )
{
ElementRegionBase const & region = elemManager.getRegion( wellControls.referenceReservoirRegion());
GEOS_ERROR_IF ( region.getWrapperPointer< CompositionalMultiphaseStatistics::RegionStatistics >( CompositionalMultiphaseStatistics::regionStatisticsName() ) == nullptr,
GEOS_FMT( "{}: WellControl {} referenceReservoirRegion field requires CompositionalMultiphaseStatistics to be configured for region {} ",
getDataContext(), wellControls.getName(), 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 )
Expand Down Expand Up @@ -1004,13 +1008,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 );
}
} );
Expand All @@ -1023,14 +1028,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

Expand Down Expand Up @@ -1148,7 +1153,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
Expand Down Expand Up @@ -1954,7 +1959,7 @@ void CompositionalMultiphaseWell::resetStateToBeginningOfStep( DomainPartition &

if( wellControls.isWellOpen( ) )
{
updateSubRegionState( subRegion );
updateSubRegionState( elemManager, subRegion );
}
} );
} );
Expand Down Expand Up @@ -2146,9 +2151,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 );
}
} )
;
Expand Down
Loading
Loading