mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#7452 Use pressure gradient from equilibrium region for stress gradient
This commit is contained in:
parent
915b16dd78
commit
8542643963
@ -56,6 +56,7 @@ void AppEnum<RiaDefines::CurveProperty>::setUp()
|
|||||||
addItem( RiaDefines::CurveProperty::NET_TO_GROSS, "NET_TO_GROSS", "Net-To-Gross" );
|
addItem( RiaDefines::CurveProperty::NET_TO_GROSS, "NET_TO_GROSS", "Net-To-Gross" );
|
||||||
addItem( RiaDefines::CurveProperty::POROSITY_UNSCALED, "POROSITY_UNSCALED", "Porosity (Unscaled)" );
|
addItem( RiaDefines::CurveProperty::POROSITY_UNSCALED, "POROSITY_UNSCALED", "Porosity (Unscaled)" );
|
||||||
addItem( RiaDefines::CurveProperty::EQLNUM, "EQLNUM", "Equilibration Number" );
|
addItem( RiaDefines::CurveProperty::EQLNUM, "EQLNUM", "Equilibration Number" );
|
||||||
|
addItem( RiaDefines::CurveProperty::PRESSURE_GRADIENT, "PRESSURE_GRADIENT", "Pressure Gradient" );
|
||||||
|
|
||||||
setDefault( RiaDefines::CurveProperty::UNDEFINED );
|
setDefault( RiaDefines::CurveProperty::UNDEFINED );
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ enum class CurveProperty
|
|||||||
NET_TO_GROSS,
|
NET_TO_GROSS,
|
||||||
POROSITY_UNSCALED,
|
POROSITY_UNSCALED,
|
||||||
EQLNUM,
|
EQLNUM,
|
||||||
|
PRESSURE_GRADIENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
double defaultPorosity();
|
double defaultPorosity();
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#include "RimStimPlanModelStressCalculator.h"
|
#include "RimStimPlanModelStressCalculator.h"
|
||||||
#include "RimStimPlanModelWellLogCalculator.h"
|
#include "RimStimPlanModelWellLogCalculator.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -377,9 +379,12 @@ bool RimStimPlanModelCalculator::calculateStressWithGradients( std::vector<doubl
|
|||||||
// Poissons ratio
|
// Poissons ratio
|
||||||
std::vector<double> poissonsRatioData = extractValues( RiaDefines::CurveProperty::POISSONS_RATIO, timeStep );
|
std::vector<double> poissonsRatioData = extractValues( RiaDefines::CurveProperty::POISSONS_RATIO, timeStep );
|
||||||
|
|
||||||
|
// Pressure difference
|
||||||
|
std::vector<double> pressureDiffData = extractValues( RiaDefines::CurveProperty::PRESSURE_GRADIENT, timeStep );
|
||||||
|
|
||||||
// Check that we have data from all curves
|
// Check that we have data from all curves
|
||||||
if ( biotData.empty() || k0Data.empty() || timeStepPressureData.empty() || initialPressureData.empty() ||
|
if ( biotData.empty() || k0Data.empty() || timeStepPressureData.empty() || initialPressureData.empty() ||
|
||||||
poissonsRatioData.empty() )
|
poissonsRatioData.empty() || pressureDiffData.empty() )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -387,15 +392,11 @@ bool RimStimPlanModelCalculator::calculateStressWithGradients( std::vector<doubl
|
|||||||
if ( biotData.size() < layerBoundaryIndexes.size() || k0Data.size() < layerBoundaryIndexes.size() ||
|
if ( biotData.size() < layerBoundaryIndexes.size() || k0Data.size() < layerBoundaryIndexes.size() ||
|
||||||
timeStepPressureData.size() < layerBoundaryIndexes.size() ||
|
timeStepPressureData.size() < layerBoundaryIndexes.size() ||
|
||||||
initialPressureData.size() < layerBoundaryIndexes.size() ||
|
initialPressureData.size() < layerBoundaryIndexes.size() ||
|
||||||
poissonsRatioData.size() < layerBoundaryIndexes.size() )
|
poissonsRatioData.size() < layerBoundaryIndexes.size() || pressureDiffData.size() < layerBoundaryIndexes.size() )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<double> stressForGradients;
|
|
||||||
std::vector<double> pressureForGradients;
|
|
||||||
std::vector<double> depthForGradients;
|
|
||||||
|
|
||||||
// Calculate the stress
|
// Calculate the stress
|
||||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||||
{
|
{
|
||||||
@ -427,36 +428,38 @@ bool RimStimPlanModelCalculator::calculateStressWithGradients( std::vector<doubl
|
|||||||
|
|
||||||
initialStress.push_back( RiaEclipseUnitTools::barToPsi( Sh_init ) );
|
initialStress.push_back( RiaEclipseUnitTools::barToPsi( Sh_init ) );
|
||||||
|
|
||||||
// Cache some results for the gradients calculation
|
// Use the bottom of the last layer to compute gradient for last layer
|
||||||
stressForGradients.push_back( Sv );
|
double bottomInitialPressure = findValueAtBottomOfLayer( initialPressureData, layerBoundaryIndexes, i );
|
||||||
pressureForGradients.push_back( initialPressure );
|
|
||||||
depthForGradients.push_back( depthTopOfZone );
|
|
||||||
|
|
||||||
if ( i == layerBoundaryDepths.size() - 1 )
|
double bottomDepthDiff = depthBottomOfZone - stressDepthRef;
|
||||||
|
double bottomSv = verticalStressRef + verticalStressGradientRef * bottomDepthDiff;
|
||||||
|
|
||||||
|
double lengthOfLayer = depthBottomOfZone - depthTopOfZone;
|
||||||
|
double diffStressLayer = bottomSv - Sv;
|
||||||
|
double diffPressureLayer = bottomInitialPressure - initialPressure;
|
||||||
|
|
||||||
|
// The pressure difference result is only defined where there was no pressure data.
|
||||||
|
// Diff pressure is interpolated in the equilibration region.
|
||||||
|
double diffPressureEQLTop = findValueAtTopOfLayer( pressureDiffData, layerBoundaryIndexes, i );
|
||||||
|
double diffPressureEQLBottom = findValueAtBottomOfLayer( pressureDiffData, layerBoundaryIndexes, i );
|
||||||
|
if ( !std::isinf( diffPressureEQLTop ) )
|
||||||
{
|
{
|
||||||
// Use the bottom of the last layer to compute gradient for last layer
|
lengthOfLayer = 2.0;
|
||||||
double bottomInitialPressure = findValueAtBottomOfLayer( initialPressureData, layerBoundaryIndexes, i );
|
diffPressureLayer = diffPressureEQLTop;
|
||||||
|
diffStressLayer =
|
||||||
double bottomDepthDiff = depthBottomOfZone - stressDepthRef;
|
calculateStressAtDepth( depthTopOfZone - 1, stressDepthRef, verticalStressRef, verticalStressGradientRef ) -
|
||||||
double bottomSv = verticalStressRef + verticalStressGradientRef * bottomDepthDiff;
|
calculateStressAtDepth( depthTopOfZone + 1, stressDepthRef, verticalStressRef, verticalStressGradientRef );
|
||||||
stressForGradients.push_back( bottomSv );
|
}
|
||||||
pressureForGradients.push_back( bottomInitialPressure );
|
else if ( !std::isinf( diffPressureEQLBottom ) )
|
||||||
depthForGradients.push_back( depthBottomOfZone );
|
{
|
||||||
|
lengthOfLayer = 2.0;
|
||||||
|
diffPressureLayer = diffPressureEQLBottom;
|
||||||
|
diffStressLayer =
|
||||||
|
calculateStressAtDepth( depthBottomOfZone - 1, stressDepthRef, verticalStressRef, verticalStressGradientRef ) -
|
||||||
|
calculateStressAtDepth( depthBottomOfZone + 1, stressDepthRef, verticalStressRef, verticalStressGradientRef );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
assert( stressForGradients.size() == layerBoundaryDepths.size() + 1 );
|
double stressGradient = ( diffStressLayer * k0 + diffPressureLayer * ( 1.0 - k0 ) ) / lengthOfLayer;
|
||||||
assert( pressureForGradients.size() == layerBoundaryDepths.size() + 1 );
|
|
||||||
assert( depthForGradients.size() == layerBoundaryDepths.size() + 1 );
|
|
||||||
|
|
||||||
// Second pass to calculate the stress gradients
|
|
||||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
|
||||||
{
|
|
||||||
double diffStress = stressForGradients[i + 1] - stressForGradients[i];
|
|
||||||
double diffPressure = pressureForGradients[i + 1] - pressureForGradients[i];
|
|
||||||
double diffDepth = depthForGradients[i + 1] - depthForGradients[i];
|
|
||||||
double k0 = findValueAtTopOfLayer( k0Data, layerBoundaryIndexes, i );
|
|
||||||
double stressGradient = ( diffStress * k0 + diffPressure * ( 1.0 - k0 ) ) / diffDepth;
|
|
||||||
stressGradients.push_back( RiaEclipseUnitTools::barPerMeterToPsiPerFeet( stressGradient ) );
|
stressGradients.push_back( RiaEclipseUnitTools::barPerMeterToPsiPerFeet( stressGradient ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,3 +624,16 @@ std::vector<double> RimStimPlanModelCalculator::calculateThermalExpansionCoeffic
|
|||||||
|
|
||||||
return coefficientFahrenheit;
|
return coefficientFahrenheit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RimStimPlanModelCalculator::calculateStressAtDepth( double depth,
|
||||||
|
double stressDepthRef,
|
||||||
|
double verticalStressRef,
|
||||||
|
double verticalStressGradientRef )
|
||||||
|
{
|
||||||
|
double depthDiff = depth - stressDepthRef;
|
||||||
|
double stress = verticalStressRef + verticalStressGradientRef * depthDiff;
|
||||||
|
return stress;
|
||||||
|
}
|
||||||
|
@ -93,6 +93,11 @@ protected:
|
|||||||
const std::vector<double>& inputVector,
|
const std::vector<double>& inputVector,
|
||||||
std::vector<double>& result );
|
std::vector<double>& result );
|
||||||
|
|
||||||
|
static double calculateStressAtDepth( double depth,
|
||||||
|
double stressDepthRef,
|
||||||
|
double verticalStressRef,
|
||||||
|
double verticalStressGradientRef );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RimStimPlanModel* m_stimPlanModel;
|
RimStimPlanModel* m_stimPlanModel;
|
||||||
std::vector<std::unique_ptr<RimStimPlanModelPropertyCalculator>> m_resultCalculators;
|
std::vector<std::unique_ptr<RimStimPlanModelPropertyCalculator>> m_resultCalculators;
|
||||||
|
@ -58,6 +58,7 @@ bool RimStimPlanModelPressureCalculator::isMatching( RiaDefines::CurveProperty c
|
|||||||
std::vector<RiaDefines::CurveProperty> matching = {
|
std::vector<RiaDefines::CurveProperty> matching = {
|
||||||
RiaDefines::CurveProperty::INITIAL_PRESSURE,
|
RiaDefines::CurveProperty::INITIAL_PRESSURE,
|
||||||
RiaDefines::CurveProperty::PRESSURE,
|
RiaDefines::CurveProperty::PRESSURE,
|
||||||
|
RiaDefines::CurveProperty::PRESSURE_GRADIENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end();
|
return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end();
|
||||||
@ -134,9 +135,16 @@ bool RimStimPlanModelPressureCalculator::extractValuesForProperty( RiaDefines::C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( stimPlanModel->stimPlanModelTemplate()->usePressureTableForProperty( curveProperty ) )
|
RiaDefines::CurveProperty pressureCurveProperty = curveProperty;
|
||||||
|
if ( curveProperty == RiaDefines::CurveProperty::PRESSURE_GRADIENT )
|
||||||
{
|
{
|
||||||
if ( !extractPressureDataFromTable( curveProperty, stimPlanModel, values, measuredDepthValues, tvDepthValues ) )
|
// Use initial pressure for pressure diff
|
||||||
|
pressureCurveProperty = RiaDefines::CurveProperty::INITIAL_PRESSURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stimPlanModel->stimPlanModelTemplate()->usePressureTableForProperty( pressureCurveProperty ) )
|
||||||
|
{
|
||||||
|
if ( !extractPressureDataFromTable( pressureCurveProperty, stimPlanModel, values, measuredDepthValues, tvDepthValues ) )
|
||||||
{
|
{
|
||||||
RiaLogging::error( "Unable to extract pressure data from table" );
|
RiaLogging::error( "Unable to extract pressure data from table" );
|
||||||
return false;
|
return false;
|
||||||
@ -145,7 +153,7 @@ bool RimStimPlanModelPressureCalculator::extractValuesForProperty( RiaDefines::C
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Extract the property we care about
|
// Extract the property we care about
|
||||||
RimStimPlanModelWellLogCalculator::extractValuesForProperty( curveProperty,
|
RimStimPlanModelWellLogCalculator::extractValuesForProperty( pressureCurveProperty,
|
||||||
stimPlanModel,
|
stimPlanModel,
|
||||||
timeStep,
|
timeStep,
|
||||||
values,
|
values,
|
||||||
@ -227,7 +235,8 @@ bool RimStimPlanModelPressureCalculator::extractValuesForProperty( RiaDefines::C
|
|||||||
values.end();
|
values.end();
|
||||||
if ( hasMissingValues )
|
if ( hasMissingValues )
|
||||||
{
|
{
|
||||||
if ( !interpolateInitialPressureByEquilibrationRegion( stimPlanModel,
|
if ( !interpolateInitialPressureByEquilibrationRegion( curveProperty,
|
||||||
|
stimPlanModel,
|
||||||
timeStep,
|
timeStep,
|
||||||
measuredDepthValues,
|
measuredDepthValues,
|
||||||
tvDepthValues,
|
tvDepthValues,
|
||||||
@ -237,6 +246,21 @@ bool RimStimPlanModelPressureCalculator::extractValuesForProperty( RiaDefines::C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( curveProperty == RiaDefines::CurveProperty::PRESSURE_GRADIENT )
|
||||||
|
{
|
||||||
|
std::vector<double> initialPressureValues = values;
|
||||||
|
values.clear();
|
||||||
|
if ( !interpolatePressureDifferenceByEquilibrationRegion( curveProperty,
|
||||||
|
stimPlanModel,
|
||||||
|
timeStep,
|
||||||
|
measuredDepthValues,
|
||||||
|
tvDepthValues,
|
||||||
|
initialPressureValues,
|
||||||
|
values ) )
|
||||||
|
{
|
||||||
|
RiaLogging::error( "Pressure interpolation by equilibration region failed." );
|
||||||
|
}
|
||||||
|
}
|
||||||
else if ( curveProperty == RiaDefines::CurveProperty::PRESSURE )
|
else if ( curveProperty == RiaDefines::CurveProperty::PRESSURE )
|
||||||
{
|
{
|
||||||
// Filter out the facies which does not have pressure depletion.
|
// Filter out the facies which does not have pressure depletion.
|
||||||
@ -532,6 +556,7 @@ double RimStimPlanModelPressureCalculator::interpolatePressure( const DepthValue
|
|||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
bool RimStimPlanModelPressureCalculator::interpolateInitialPressureByEquilibrationRegion(
|
bool RimStimPlanModelPressureCalculator::interpolateInitialPressureByEquilibrationRegion(
|
||||||
|
RiaDefines::CurveProperty curveProperty,
|
||||||
const RimStimPlanModel* stimPlanModel,
|
const RimStimPlanModel* stimPlanModel,
|
||||||
int timeStep,
|
int timeStep,
|
||||||
const std::vector<double>& measuredDepthValues,
|
const std::vector<double>& measuredDepthValues,
|
||||||
@ -581,3 +606,64 @@ bool RimStimPlanModelPressureCalculator::interpolateInitialPressureByEquilibrati
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RimStimPlanModelPressureCalculator::interpolatePressureDifferenceByEquilibrationRegion(
|
||||||
|
RiaDefines::CurveProperty curveProperty,
|
||||||
|
const RimStimPlanModel* stimPlanModel,
|
||||||
|
int timeStep,
|
||||||
|
const std::vector<double>& measuredDepthValues,
|
||||||
|
const std::vector<double>& tvDepthValues,
|
||||||
|
const std::vector<double>& initialPressureValues,
|
||||||
|
std::vector<double>& values ) const
|
||||||
|
{
|
||||||
|
std::vector<double> eqlNumValues;
|
||||||
|
std::vector<double> eqlNumMeasuredDepthsValues;
|
||||||
|
std::vector<double> eqlNumTvDepthValues;
|
||||||
|
double rkbDiff = -1.0;
|
||||||
|
if ( !stimPlanModel->calculator()->extractCurveData( RiaDefines::CurveProperty::EQLNUM,
|
||||||
|
timeStep,
|
||||||
|
eqlNumValues,
|
||||||
|
eqlNumMeasuredDepthsValues,
|
||||||
|
eqlNumTvDepthValues,
|
||||||
|
rkbDiff ) )
|
||||||
|
{
|
||||||
|
RiaLogging::error( "Failed to extract EQLNUM data in pressure calculation" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<int> presentEqlNums = findUniqueValues( eqlNumValues );
|
||||||
|
|
||||||
|
RiaLogging::info( QString( "Found %1 EQLNUM values." ).arg( presentEqlNums.size() ) );
|
||||||
|
|
||||||
|
EqlNumToDepthValuePairMap valuesPerEqlNum;
|
||||||
|
if ( !buildPressureTablesPerEqlNum( stimPlanModel, valuesPerEqlNum, presentEqlNums ) )
|
||||||
|
{
|
||||||
|
RiaLogging::error( "Failed to build EQLNUM pressure data in pressure calculation" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
values.clear();
|
||||||
|
values.resize( initialPressureValues.size(), std::numeric_limits<double>::infinity() );
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < values.size(); i++ )
|
||||||
|
{
|
||||||
|
if ( std::isinf( initialPressureValues[i] ) )
|
||||||
|
{
|
||||||
|
int eqlNum = static_cast<int>( eqlNumValues[i] );
|
||||||
|
DepthValuePairVector depthValuePairs = valuesPerEqlNum[eqlNum];
|
||||||
|
if ( !depthValuePairs.empty() )
|
||||||
|
{
|
||||||
|
double depth = tvDepthValues[i];
|
||||||
|
double p1 = interpolatePressure( depthValuePairs, depth - 1, eqlNum );
|
||||||
|
double p2 = interpolatePressure( depthValuePairs, depth + 1, eqlNum );
|
||||||
|
values[i] = p2 - p1;
|
||||||
|
RiaLogging::debug( QString( "INTERPOLATING PRESSURE DIFF: %1 %2 = %3" ).arg( p1 ).arg( p2 ).arg( p2 - p1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -58,11 +58,19 @@ protected:
|
|||||||
std::vector<double>& measuredDepthValues,
|
std::vector<double>& measuredDepthValues,
|
||||||
std::vector<double>& tvDepthValues ) const;
|
std::vector<double>& tvDepthValues ) const;
|
||||||
|
|
||||||
bool interpolateInitialPressureByEquilibrationRegion( const RimStimPlanModel* stimPlanModel,
|
bool interpolateInitialPressureByEquilibrationRegion( RiaDefines::CurveProperty curveProperty,
|
||||||
|
const RimStimPlanModel* stimPlanModel,
|
||||||
int timeStep,
|
int timeStep,
|
||||||
const std::vector<double>& measuredDepthValues,
|
const std::vector<double>& measuredDepthValues,
|
||||||
const std::vector<double>& tvDepthValues,
|
const std::vector<double>& tvDepthValues,
|
||||||
std::vector<double>& values ) const;
|
std::vector<double>& values ) const;
|
||||||
|
bool interpolatePressureDifferenceByEquilibrationRegion( RiaDefines::CurveProperty curveProperty,
|
||||||
|
const RimStimPlanModel* stimPlanModel,
|
||||||
|
int timeStep,
|
||||||
|
const std::vector<double>& measuredDepthValues,
|
||||||
|
const std::vector<double>& tvDepthValues,
|
||||||
|
const std::vector<double>& initialPressureValues,
|
||||||
|
std::vector<double>& values ) const;
|
||||||
|
|
||||||
typedef std::pair<double, double> DepthValuePair;
|
typedef std::pair<double, double> DepthValuePair;
|
||||||
typedef std::vector<DepthValuePair> DepthValuePairVector;
|
typedef std::vector<DepthValuePair> DepthValuePairVector;
|
||||||
|
Loading…
Reference in New Issue
Block a user