#6286 Mud Weight Window: Improve fracture gradient calculation for shale.

This commit is contained in:
Kristian Bendiksen 2020-08-10 14:21:46 +02:00
parent c3982a5782
commit 68ce7f590d
5 changed files with 155 additions and 32 deletions

View File

@ -29,6 +29,7 @@
#include "RiaOffshoreSphericalCoords.h"
#include "RimMudWeightWindowParameters.h"
#include "cafProgressInfo.h"
#include "cvfBoundingBox.h"
@ -73,7 +74,8 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
RimMudWeightWindowParameters::ParameterType::WELL_AZIMUTH,
RimMudWeightWindowParameters::ParameterType::UCS,
RimMudWeightWindowParameters::ParameterType::POISSONS_RATIO,
RimMudWeightWindowParameters::ParameterType::K0_FG};
RimMudWeightWindowParameters::ParameterType::K0_FG,
RimMudWeightWindowParameters::ParameterType::OBG0};
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * ( 4 + parameterTypes.size() ), "" );
frameCountProgress.setProgressDescription( "Calculating Mud Weight Window" );
@ -88,7 +90,11 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
frameCountProgress.incrementProgress();
}
double airGap = m_resultCollection->airGapMudWeightWindow();
double airGap = m_resultCollection->airGapMudWeightWindow();
double shMultiplier = m_resultCollection->shMultiplierMudWeightWindow();
RimMudWeightWindowParameters::FractureGradientCalculationType fractureGradientCalculationType =
m_resultCollection->fractureGradientCalculationTypeMudWeightWindow();
RimMudWeightWindowParameters::UpperLimitType upperLimitParameter =
m_resultCollection->upperLimitParameterMudWeightWindow();
RimMudWeightWindowParameters::LowerLimitType lowerLimitParameter =
@ -132,7 +138,9 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
int frameCount = stressDataFrames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& porFrameData = porePressureDataFrames->frameData( fIdx );
const std::vector<float>& porFrameData = porePressureDataFrames->frameData( fIdx );
const std::vector<float>& initialPorFrameData = porePressureDataFrames->frameData( 0 );
const std::vector<float>& stressFrameData = stressDataFrames->frameData( fIdx );
std::vector<float>& mudWeightWindowFrameData = mudWeightWindowFrames->frameData( fIdx );
@ -195,6 +203,11 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
parameterValues,
elmIdx );
double OBG0 = getValueForElement( RimMudWeightWindowParameters::ParameterType::OBG0,
parameterFrameData,
parameterValues,
elmIdx );
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
if ( elmType == HEX8P )
@ -214,7 +227,8 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodResIdx );
// Pore pressure (unit: Bar)
double porePressureBar = porFrameData[nodeIdx];
double porePressureBar = porFrameData[nodeIdx];
double initialPorePressureBar = initialPorFrameData[nodeIdx];
// FG is for sands, SFG for shale. Sands has valid PP, shale does not.
bool isSand = ( porePressureBar != inf );
@ -244,6 +258,20 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
upperLimit = stressFrameData[elmNodResIdx];
}
//
if ( upperLimit == inf )
{
if ( fractureGradientCalculationType ==
RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG )
{
upperLimit = K0_FG * ( OBG0 - initialPorePressureBar ) + initialPorePressureBar;
}
else
{
upperLimit = stressFrameData[elmNodResIdx] * shMultiplier;
}
}
// Calculate lower limit
float lowerLimit = inf;
if ( lowerLimitParameter == RimMudWeightWindowParameters::LowerLimitType::PORE_PRESSURE )

View File

@ -1695,6 +1695,14 @@ double RigFemPartResultsCollection::airGapMudWeightWindow() const
return m_airGapMudWeightWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigFemPartResultsCollection::shMultiplierMudWeightWindow() const
{
return m_shMultiplierMudWeightWindow;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1722,15 +1730,20 @@ size_t RigFemPartResultsCollection::referenceLayerMudWeightWindow() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFemPartResultsCollection::setMudWeightWindowParameters( double airGap,
RimMudWeightWindowParameters::UpperLimitType upperLimit,
RimMudWeightWindowParameters::LowerLimitType lowerLimit,
int referenceLayer )
void RigFemPartResultsCollection::setMudWeightWindowParameters(
double airGap,
RimMudWeightWindowParameters::UpperLimitType upperLimit,
RimMudWeightWindowParameters::LowerLimitType lowerLimit,
int referenceLayer,
RimMudWeightWindowParameters::FractureGradientCalculationType fgCalculationType,
double shMultiplier )
{
m_airGapMudWeightWindow = airGap;
m_upperLimitParameterMudWeightWindow = upperLimit;
m_lowerLimitParameterMudWeightWindow = lowerLimit;
m_referenceLayerMudWeightWindow = referenceLayer;
m_airGapMudWeightWindow = airGap;
m_upperLimitParameterMudWeightWindow = upperLimit;
m_lowerLimitParameterMudWeightWindow = lowerLimit;
m_referenceLayerMudWeightWindow = referenceLayer;
m_fractureGradientCalculationTypeMudWeightWindow = fgCalculationType;
m_shMultiplierMudWeightWindow = shMultiplier;
// Invalidate dependent results
for ( auto result : mudWeightWindowResults() )
@ -1738,3 +1751,12 @@ void RigFemPartResultsCollection::setMudWeightWindowParameters( double
this->deleteResult( result );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimMudWeightWindowParameters::FractureGradientCalculationType
RigFemPartResultsCollection::fractureGradientCalculationTypeMudWeightWindow() const
{
return m_fractureGradientCalculationTypeMudWeightWindow;
}

View File

@ -88,15 +88,21 @@ public:
double getCalculationParameterValue( RimMudWeightWindowParameters::ParameterType ) const;
QString getCalculationParameterAddress( RimMudWeightWindowParameters::ParameterType ) const;
void setMudWeightWindowParameters( double airGap,
RimMudWeightWindowParameters::UpperLimitType upperLimit,
RimMudWeightWindowParameters::LowerLimitType lowerLimit,
int referenceLayer );
double airGapMudWeightWindow() const;
void setMudWeightWindowParameters( double airGap,
RimMudWeightWindowParameters::UpperLimitType upperLimit,
RimMudWeightWindowParameters::LowerLimitType lowerLimit,
int referenceLayer,
RimMudWeightWindowParameters::FractureGradientCalculationType fgCalculationType,
double shMultiplier );
double airGapMudWeightWindow() const;
double shMultiplierMudWeightWindow() const;
RimMudWeightWindowParameters::UpperLimitType upperLimitParameterMudWeightWindow() const;
RimMudWeightWindowParameters::LowerLimitType lowerLimitParameterMudWeightWindow() const;
size_t referenceLayerMudWeightWindow() const;
RimMudWeightWindowParameters::FractureGradientCalculationType fractureGradientCalculationTypeMudWeightWindow() const;
std::map<std::string, std::vector<std::string>> scalarFieldAndComponentNames( RigFemResultPosEnum resPos );
std::vector<std::string> filteredStepNames() const;
bool assertResultsLoaded( const RigFemResultAddress& resVarAddr );
@ -196,10 +202,12 @@ private:
int m_referenceTimeStep;
double m_airGapMudWeightWindow;
int m_referenceLayerMudWeightWindow;
RimMudWeightWindowParameters::UpperLimitType m_upperLimitParameterMudWeightWindow;
RimMudWeightWindowParameters::LowerLimitType m_lowerLimitParameterMudWeightWindow;
double m_airGapMudWeightWindow;
double m_shMultiplierMudWeightWindow;
int m_referenceLayerMudWeightWindow;
RimMudWeightWindowParameters::UpperLimitType m_upperLimitParameterMudWeightWindow;
RimMudWeightWindowParameters::LowerLimitType m_lowerLimitParameterMudWeightWindow;
RimMudWeightWindowParameters::FractureGradientCalculationType m_fractureGradientCalculationTypeMudWeightWindow;
std::map<RimMudWeightWindowParameters::ParameterType, QString> parameterAddresses;
std::map<RimMudWeightWindowParameters::ParameterType, double> parameterValues;

View File

@ -54,6 +54,7 @@ void caf::AppEnum<RimMudWeightWindowParameters::ParameterType>::setUp()
addItem( RimMudWeightWindowParameters::ParameterType::UCS, "UCS", "UCS" );
addItem( RimMudWeightWindowParameters::ParameterType::POISSONS_RATIO, "POISSONS_RARIO", "Poisson's Ratio" );
addItem( RimMudWeightWindowParameters::ParameterType::K0_FG, "K0_FG", "K0 FG" );
addItem( RimMudWeightWindowParameters::ParameterType::OBG0, "OBG0", "Initial Overburden Gradient" );
setDefault( RimMudWeightWindowParameters::ParameterType::WELL_DEVIATION );
}
@ -75,6 +76,18 @@ void caf::AppEnum<RimMudWeightWindowParameters::LowerLimitType>::setUp()
setDefault( RimMudWeightWindowParameters::LowerLimitType::PORE_PRESSURE );
}
template <>
void caf::AppEnum<RimMudWeightWindowParameters::FractureGradientCalculationType>::setUp()
{
addItem( RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG,
"DERIVED_FROM_K0FG",
"FG derived from K0_FG" );
addItem( RimMudWeightWindowParameters::FractureGradientCalculationType::PROPORTIONAL_TO_SH,
"PROPORTIONAL_TO_SH",
"Proportional to SH" );
setDefault( RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG );
}
} // End namespace caf
//--------------------------------------------------------------------------------------------------
@ -126,8 +139,17 @@ RimMudWeightWindowParameters::RimMudWeightWindowParameters( void )
CAF_PDM_InitField( &m_K0_FGAddress, "K0_FGAddress", QString( "" ), "Value", "", "", "" );
m_K0_FGAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_obg0Type, "obg0SourceType", defaultSourceType, "Initial Overburden Gradient", "", "", "" );
CAF_PDM_InitField( &m_obg0Fixed, "obg0Fixed", 0.75, "Fixed Initial Overburden Gradient", "", "", "" );
m_obg0Fixed.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_obg0Address, "obg0Address", QString( "" ), "Value", "", "", "" );
m_obg0Address.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
CAF_PDM_InitField( &m_airGap, "AirGap", 0.0, "Air Gap", "", "", "" );
CAF_PDM_InitField( &m_shMultiplier, "SHMultiplier", 1.05, "SH Multplier for FG in Shale", "", "", "" );
caf::AppEnum<UpperLimitType> defaultUpperLimitType = RimMudWeightWindowParameters::UpperLimitType::FG;
CAF_PDM_InitField( &m_upperLimitType, "UpperLimitType", defaultUpperLimitType, "Upper Limit Type", "", "", "" );
@ -135,6 +157,16 @@ RimMudWeightWindowParameters::RimMudWeightWindowParameters( void )
RimMudWeightWindowParameters::LowerLimitType::MAX_OF_PORE_PRESSURE_AND_SFG;
CAF_PDM_InitField( &m_lowerLimitType, "LowerLimitType", defaultLowerLimitType, "Lower Limit Type", "", "", "" );
caf::AppEnum<FractureGradientCalculationType> defaultFractureGradientCalculationType =
RimMudWeightWindowParameters::FractureGradientCalculationType::DERIVED_FROM_K0FG;
CAF_PDM_InitField( &m_fractureGradientCalculationType,
"FractureGradientCalculationType",
defaultFractureGradientCalculationType,
"FG in Shale Calculation",
"",
"",
"" );
CAF_PDM_InitField( &m_referenceLayer, "ReferenceLayer", -1, "Reference Layer", "", "", "" );
}
@ -300,12 +332,10 @@ void RimMudWeightWindowParameters::fieldChangedByUi( const caf::PdmFieldHandle*
&m_wellAzimuthAddress,
changedField == &m_wellAzimuthType );
}
else if ( changedField == &m_UCSFixed || changedField == &m_UCSType || changedField == &m_UCSAddress )
{
handleFieldChanged( geoMechCase, ParameterType::UCS, &m_UCSType, &m_UCSFixed, &m_UCSAddress, changedField == &m_UCSType );
}
else if ( changedField == &m_poissonsRatioFixed || changedField == &m_poissonsRatioType ||
changedField == &m_poissonsRatioAddress )
{
@ -316,7 +346,6 @@ void RimMudWeightWindowParameters::fieldChangedByUi( const caf::PdmFieldHandle*
&m_poissonsRatioAddress,
changedField == &m_poissonsRatioType );
}
else if ( changedField == &m_K0_FGFixed || changedField == &m_K0_FGType || changedField == &m_K0_FGAddress )
{
handleFieldChanged( geoMechCase,
@ -326,8 +355,13 @@ void RimMudWeightWindowParameters::fieldChangedByUi( const caf::PdmFieldHandle*
&m_K0_FGAddress,
changedField == &m_K0_FGType );
}
else if ( changedField == &m_obg0Fixed || changedField == &m_obg0Type || changedField == &m_obg0Address )
{
handleFieldChanged( geoMechCase, ParameterType::OBG0, &m_obg0Type, &m_obg0Fixed, &m_obg0Address, changedField == &m_obg0Type );
}
else if ( changedField == &m_airGap || changedField == &m_upperLimitType || changedField == &m_lowerLimitType ||
changedField == &m_referenceLayer )
changedField == &m_referenceLayer || changedField == &m_fractureGradientCalculationType ||
changedField == &m_shMultiplier )
{
RigGeoMechCaseData* rigCaseData = geoMechCase->geoMechData();
if ( rigCaseData && rigCaseData->femPartResults() )
@ -335,7 +369,9 @@ void RimMudWeightWindowParameters::fieldChangedByUi( const caf::PdmFieldHandle*
rigCaseData->femPartResults()->setMudWeightWindowParameters( m_airGap,
m_upperLimitType.value(),
m_lowerLimitType.value(),
m_referenceLayer );
m_referenceLayer,
m_fractureGradientCalculationType.value(),
m_shMultiplier );
geoMechCase->updateConnectedViews();
}
}
@ -406,7 +442,7 @@ void RimMudWeightWindowParameters::defineUiOrdering( QString uiConfigName, caf::
defineGroup( uiOrdering, "Well Azimuth", &m_wellAzimuthType, &m_wellAzimuthFixed, &m_wellAzimuthAddress );
defineGroup( uiOrdering, "UCS", &m_UCSType, &m_UCSFixed, &m_UCSAddress );
defineGroup( uiOrdering, "Poisson's Ratio", &m_poissonsRatioType, &m_poissonsRatioFixed, &m_poissonsRatioAddress );
defineGroup( uiOrdering, "K0 for Fracture Gradient Factor for Shale", &m_K0_FGType, &m_K0_FGFixed, &m_K0_FGAddress );
defineGroup( uiOrdering, "Initial Overburden Gradient", &m_obg0Type, &m_obg0Fixed, &m_obg0Address );
RimGeoMechCase* geoMechCase = nullptr;
firstAncestorOrThisOfType( geoMechCase );
@ -422,6 +458,22 @@ void RimMudWeightWindowParameters::defineUiOrdering( QString uiConfigName, caf::
m_referenceLayer =
(int)rigCaseData->femParts()->part( 0 )->getOrCreateStructGrid()->reservoirIJKBoundingBox().first.z();
}
uiOrdering.add( &m_fractureGradientCalculationType );
uiOrdering.add( &m_shMultiplier );
defineGroup( uiOrdering, "K0 for Fracture Gradient Factor for Shale", &m_K0_FGType, &m_K0_FGFixed, &m_K0_FGAddress );
m_shMultiplier.uiCapability()->setUiHidden( m_fractureGradientCalculationType !=
FractureGradientCalculationType::PROPORTIONAL_TO_SH );
m_K0_FGType.uiCapability()->setUiHidden( m_fractureGradientCalculationType !=
FractureGradientCalculationType::DERIVED_FROM_K0FG );
m_K0_FGFixed.uiCapability()->setUiHidden(
!( m_fractureGradientCalculationType == FractureGradientCalculationType::DERIVED_FROM_K0FG &&
m_K0_FGType == RimMudWeightWindowParameters::SourceType::FIXED ) );
m_K0_FGAddress.uiCapability()->setUiHidden(
!( m_fractureGradientCalculationType == FractureGradientCalculationType::DERIVED_FROM_K0FG &&
m_K0_FGType == RimMudWeightWindowParameters::SourceType::PER_ELEMENT ) );
}
//--------------------------------------------------------------------------------------------------
@ -474,7 +526,7 @@ QList<caf::PdmOptionItemInfo>
{
if ( fieldNeedingOptions == &m_wellDeviationAddress || fieldNeedingOptions == &m_wellAzimuthAddress ||
fieldNeedingOptions == &m_UCSAddress || fieldNeedingOptions == &m_poissonsRatioAddress ||
fieldNeedingOptions == &m_K0_FGAddress )
fieldNeedingOptions == &m_K0_FGAddress || fieldNeedingOptions == &m_obg0Address )
{
std::vector<std::string> elementProperties = geoMechCase->possibleElementPropertyFieldNames();

View File

@ -44,7 +44,8 @@ public:
WELL_AZIMUTH,
UCS,
POISSONS_RATIO,
K0_FG
K0_FG,
OBG0
};
enum class UpperLimitType
@ -59,6 +60,12 @@ public:
MAX_OF_PORE_PRESSURE_AND_SFG
};
enum class FractureGradientCalculationType
{
DERIVED_FROM_K0FG,
PROPORTIONAL_TO_SH
};
RimMudWeightWindowParameters( void );
SourceType wellDeviationType() const;
@ -127,10 +134,16 @@ private:
caf::PdmField<double> m_K0_FGFixed;
caf::PdmField<QString> m_K0_FGAddress;
caf::PdmField<double> m_airGap;
caf::PdmField<caf::AppEnum<SourceType>> m_obg0Type;
caf::PdmField<double> m_obg0Fixed;
caf::PdmField<QString> m_obg0Address;
caf::PdmField<caf::AppEnum<UpperLimitType>> m_upperLimitType;
caf::PdmField<caf::AppEnum<LowerLimitType>> m_lowerLimitType;
caf::PdmField<double> m_airGap;
caf::PdmField<double> m_shMultiplier;
caf::PdmField<caf::AppEnum<UpperLimitType>> m_upperLimitType;
caf::PdmField<caf::AppEnum<LowerLimitType>> m_lowerLimitType;
caf::PdmField<caf::AppEnum<FractureGradientCalculationType>> m_fractureGradientCalculationType;
caf::PdmField<int> m_referenceLayer;
};