mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Merge pull request #6300 from OPM/mud-weight-window-improvements
Mud weight window improvements
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "RiaOffshoreSphericalCoords.h"
|
||||
|
||||
#include "RimMudWeightWindowParameters.h"
|
||||
#include "cafProgressInfo.h"
|
||||
|
||||
#include "cvfBoundingBox.h"
|
||||
@@ -73,9 +74,10 @@ 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() ), "" );
|
||||
caf::ProgressInfo frameCountProgress( m_resultCollection->frameCount() * ( 5 + parameterTypes.size() ), "" );
|
||||
frameCountProgress.setProgressDescription( "Calculating Mud Weight Window" );
|
||||
|
||||
std::map<RimMudWeightWindowParameters::ParameterType, RigFemScalarResultFrames*> parameterFrames;
|
||||
@@ -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 =
|
||||
@@ -106,6 +112,13 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
|
||||
m_resultCollection->findOrLoadScalarResult( partIndex, RigFemResultAddress( resVarAddr.resultPosType, "ST", "S3" ) );
|
||||
frameCountProgress.incrementProgress();
|
||||
|
||||
// Initial overburden gradient (ST.S33)
|
||||
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
|
||||
RigFemScalarResultFrames* obg0DataFrames =
|
||||
m_resultCollection->findOrLoadScalarResult( partIndex,
|
||||
RigFemResultAddress( resVarAddr.resultPosType, "ST", "S33" ) );
|
||||
frameCountProgress.incrementProgress();
|
||||
|
||||
frameCountProgress.setNextProgressIncrement( m_resultCollection->frameCount() );
|
||||
|
||||
RigFemScalarResultFrames* mudWeightWindowFrames =
|
||||
@@ -125,6 +138,25 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
|
||||
const RigFemPart* femPart = m_resultCollection->parts()->part( partIndex );
|
||||
const RigFemPartGrid* femPartGrid = femPart->getOrCreateStructGrid();
|
||||
|
||||
const bool OBG0FromGrid =
|
||||
m_resultCollection->getCalculationParameterAddress( RimMudWeightWindowParameters::ParameterType::OBG0 ).isEmpty();
|
||||
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType PP_NonReservoirType =
|
||||
m_resultCollection->nonReservoirPorePressureTypeMudWeightWindow();
|
||||
double hydrostaticMultiplier = m_resultCollection->hydrostaticMultiplierPPNonRes();
|
||||
const QString& nonReservoirAddress = m_resultCollection->nonReservoirPorePressureAddressMudWeightWindow();
|
||||
RigFemScalarResultFrames* nonReservoirResultFrames = nullptr;
|
||||
|
||||
if ( PP_NonReservoirType != RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC &&
|
||||
!nonReservoirAddress.isEmpty() )
|
||||
{
|
||||
nonReservoirResultFrames =
|
||||
m_resultCollection->findOrLoadScalarResult( partIndex,
|
||||
RigFemResultAddress( RIG_ELEMENT,
|
||||
nonReservoirAddress.toStdString(),
|
||||
"" ) );
|
||||
}
|
||||
|
||||
float inf = std::numeric_limits<float>::infinity();
|
||||
|
||||
frameCountProgress.setNextProgressIncrement( 1u );
|
||||
@@ -132,8 +164,11 @@ 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 );
|
||||
const std::vector<float>& obg0FrameData = obg0DataFrames->frameData( 0 );
|
||||
|
||||
std::vector<float>& mudWeightWindowFrameData = mudWeightWindowFrames->frameData( fIdx );
|
||||
std::vector<float>& mudWeightMiddleFrameData = mudWeightMiddleFrames->frameData( fIdx );
|
||||
@@ -154,6 +189,12 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
|
||||
parameterFrameData[parameterType] = loadDataForFrame( parameterType, parameterFrames, fIdx );
|
||||
}
|
||||
|
||||
std::vector<float> nonReservoirPP;
|
||||
if ( nonReservoirResultFrames )
|
||||
{
|
||||
nonReservoirPP = nonReservoirResultFrames->frameData( 0 );
|
||||
}
|
||||
|
||||
// Load stress
|
||||
RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, "ST", "" );
|
||||
std::vector<caf::Ten3f> vertexStressesFloat = m_resultCollection->tensors( stressResAddr, partIndex, fIdx );
|
||||
@@ -195,18 +236,27 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
|
||||
parameterValues,
|
||||
elmIdx );
|
||||
|
||||
double OBG0 = 0.0;
|
||||
if ( !OBG0FromGrid )
|
||||
{
|
||||
OBG0 = getValueForElement( RimMudWeightWindowParameters::ParameterType::OBG0,
|
||||
parameterFrameData,
|
||||
parameterValues,
|
||||
elmIdx );
|
||||
}
|
||||
|
||||
int elmNodeCount = RigFemTypes::elementNodeCount( femPart->elementType( elmIdx ) );
|
||||
|
||||
if ( elmType == HEX8P )
|
||||
if ( elmType == HEX8P || elmType == HEX8 )
|
||||
{
|
||||
for ( int elmNodIdx = 0; elmNodIdx < elmNodeCount; ++elmNodIdx )
|
||||
{
|
||||
// Use hydrostatic pressure from cell centroid.
|
||||
// Use centroid to avoid intra-element differences
|
||||
cvf::Vec3d cellCentroid = femPartGrid->cellCentroid( elmIdx );
|
||||
double cellCentroidTvdRKB = std::abs( cellCentroid.z() ) + airGap;
|
||||
double cellCentroidTvdRKB = -cellCentroid.z() + airGap;
|
||||
double cellCenterHydroStaticPressure =
|
||||
RiaWellLogUnitTools<double>::hydrostaticPorePressureBar( cellCentroidTvdRKB );
|
||||
RigGeoMechWellLogExtractor::hydroStaticPorePressureAtDepth( cellCentroidTvdRKB );
|
||||
|
||||
size_t elmNodResIdx = femPart->elementNodeResultIdx( elmIdx, elmNodIdx );
|
||||
if ( elmNodResIdx < stressFrameData.size() )
|
||||
@@ -214,11 +264,36 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
|
||||
int nodeIdx = femPart->nodeIdxFromElementNodeResultIdx( elmNodResIdx );
|
||||
|
||||
// Pore pressure (unit: Bar)
|
||||
double porePressureBar = porFrameData[nodeIdx];
|
||||
float porePressureBar = porFrameData[nodeIdx];
|
||||
float initialPorePressureBar = initialPorFrameData[nodeIdx];
|
||||
|
||||
// Initial overburden gradient
|
||||
if ( OBG0FromGrid )
|
||||
{
|
||||
OBG0 = obg0FrameData[nodeIdx];
|
||||
}
|
||||
|
||||
// FG is for sands, SFG for shale. Sands has valid PP, shale does not.
|
||||
bool isSand = ( porePressureBar != inf );
|
||||
|
||||
//
|
||||
if ( porePressureBar == inf )
|
||||
{
|
||||
//
|
||||
if ( PP_NonReservoirType ==
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC )
|
||||
{
|
||||
porePressureBar = cellCenterHydroStaticPressure * hydrostaticMultiplier;
|
||||
initialPorePressureBar = cellCenterHydroStaticPressure * hydrostaticMultiplier;
|
||||
}
|
||||
else if ( !nonReservoirPP.empty() )
|
||||
{
|
||||
// Get from element table
|
||||
porePressureBar = nonReservoirPP[elmIdx];
|
||||
initialPorePressureBar = nonReservoirPP[elmIdx];
|
||||
}
|
||||
}
|
||||
|
||||
caf::Ten3d segmentStress = caf::Ten3d( vertexStressesFloat[nodeIdx] );
|
||||
|
||||
cvf::Vec3d wellPathTangent = calculateWellPathTangent( wellPathAzimuth, wellPathDeviation );
|
||||
@@ -235,7 +310,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
|
||||
|
||||
// Calculate upper limit
|
||||
float upperLimit = inf;
|
||||
if ( upperLimitParameter == RimMudWeightWindowParameters::UpperLimitType::FG )
|
||||
if ( upperLimitParameter == RimMudWeightWindowParameters::UpperLimitType::FG && isSand )
|
||||
{
|
||||
upperLimit = sigmaCalculator.solveFractureGradient();
|
||||
}
|
||||
@@ -244,6 +319,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 )
|
||||
@@ -260,7 +349,7 @@ RigFemScalarResultFrames* RigFemPartResultCalculatorMudWeightWindow::calculate(
|
||||
else
|
||||
{
|
||||
double SFG = sigmaCalculator.solveStassiDalia();
|
||||
lowerLimit = std::max( porePressureBar, SFG );
|
||||
lowerLimit = std::max( porePressureBar, static_cast<float>( SFG ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "RifElementPropertyReader.h"
|
||||
#include "RifGeoMechReaderInterface.h"
|
||||
#include "RimMudWeightWindowParameters.h"
|
||||
|
||||
#ifdef USE_ODB_API
|
||||
#include "RifOdbReader.h"
|
||||
@@ -119,8 +120,11 @@ RigFemPartResultsCollection::RigFemPartResultsCollection( RifGeoMechReaderInterf
|
||||
m_initialPermeabilityResultAddress = "";
|
||||
m_permeabilityExponent = 1.0;
|
||||
|
||||
m_airGapMudWeightWindow = 0.0;
|
||||
m_referenceLayerMudWeightWindow = 0;
|
||||
m_airGapMudWeightWindow = 0.0;
|
||||
m_referenceLayerMudWeightWindow = 0;
|
||||
m_shMultiplierMudWeightWindow = 1.05;
|
||||
m_nonReservoirPorePressureAddressMudWeightWindow = "";
|
||||
m_hydrostaticMultiplierPPNonResMudWeightWindow = 1.0;
|
||||
|
||||
m_resultCalculators.push_back(
|
||||
std::unique_ptr<RigFemPartResultCalculator>( new RigFemPartResultCalculatorTimeLapse( *this ) ) );
|
||||
@@ -1698,9 +1702,34 @@ double RigFemPartResultsCollection::airGapMudWeightWindow() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimMudWeightWindowParameters::UpperLimitType RigFemPartResultsCollection::upperLimitParameterMudWeightWindow() const
|
||||
double RigFemPartResultsCollection::shMultiplierMudWeightWindow() const
|
||||
{
|
||||
return m_upperLimitParameterMudWeightWindow;
|
||||
return m_shMultiplierMudWeightWindow;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigFemPartResultsCollection::hydrostaticMultiplierPPNonRes() const
|
||||
{
|
||||
return m_hydrostaticMultiplierPPNonResMudWeightWindow;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType
|
||||
RigFemPartResultsCollection::nonReservoirPorePressureTypeMudWeightWindow() const
|
||||
{
|
||||
return m_nonReservoirPorePressureTypeMudWeightWindow;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QString& RigFemPartResultsCollection::nonReservoirPorePressureAddressMudWeightWindow() const
|
||||
{
|
||||
return m_nonReservoirPorePressureAddressMudWeightWindow;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1711,6 +1740,14 @@ RimMudWeightWindowParameters::LowerLimitType RigFemPartResultsCollection::lowerL
|
||||
return m_lowerLimitParameterMudWeightWindow;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimMudWeightWindowParameters::UpperLimitType RigFemPartResultsCollection::upperLimitParameterMudWeightWindow() const
|
||||
{
|
||||
return m_upperLimitParameterMudWeightWindow;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1722,15 +1759,26 @@ 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,
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType nonReservoirPorePressureType,
|
||||
double hydrostaticMultiplierPPNonRes,
|
||||
const QString& nonReservoirPorePressureAddress )
|
||||
{
|
||||
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;
|
||||
m_nonReservoirPorePressureTypeMudWeightWindow = nonReservoirPorePressureType;
|
||||
m_hydrostaticMultiplierPPNonResMudWeightWindow = hydrostaticMultiplierPPNonRes;
|
||||
m_nonReservoirPorePressureAddressMudWeightWindow = nonReservoirPorePressureAddress;
|
||||
|
||||
// Invalidate dependent results
|
||||
for ( auto result : mudWeightWindowResults() )
|
||||
@@ -1738,3 +1786,12 @@ void RigFemPartResultsCollection::setMudWeightWindowParameters( double
|
||||
this->deleteResult( result );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimMudWeightWindowParameters::FractureGradientCalculationType
|
||||
RigFemPartResultsCollection::fractureGradientCalculationTypeMudWeightWindow() const
|
||||
{
|
||||
return m_fractureGradientCalculationTypeMudWeightWindow;
|
||||
}
|
||||
|
||||
@@ -88,15 +88,29 @@ 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,
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType nonReservoirPorePressureType,
|
||||
double hydroStaticMultiplierPPNonRes,
|
||||
const QString& nonReservoirPorePressureAddress );
|
||||
|
||||
double airGapMudWeightWindow() const;
|
||||
double shMultiplierMudWeightWindow() const;
|
||||
|
||||
double hydrostaticMultiplierPPNonRes() const;
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType nonReservoirPorePressureTypeMudWeightWindow() const;
|
||||
const QString& nonReservoirPorePressureAddressMudWeightWindow() 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 +210,16 @@ 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;
|
||||
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType m_nonReservoirPorePressureTypeMudWeightWindow;
|
||||
double m_hydrostaticMultiplierPPNonResMudWeightWindow;
|
||||
QString m_nonReservoirPorePressureAddressMudWeightWindow;
|
||||
|
||||
std::map<RimMudWeightWindowParameters::ParameterType, QString> parameterAddresses;
|
||||
std::map<RimMudWeightWindowParameters::ParameterType, double> parameterValues;
|
||||
|
||||
@@ -43,6 +43,7 @@ void caf::AppEnum<RimMudWeightWindowParameters::SourceType>::setUp()
|
||||
{
|
||||
addItem( RimMudWeightWindowParameters::SourceType::FIXED, "FIXED", "Fixed" );
|
||||
addItem( RimMudWeightWindowParameters::SourceType::PER_ELEMENT, "PER_ELEMENT", "From element properties" );
|
||||
addItem( RimMudWeightWindowParameters::SourceType::GRID, "GRID", "Grid" );
|
||||
setDefault( RimMudWeightWindowParameters::SourceType::FIXED );
|
||||
}
|
||||
|
||||
@@ -54,6 +55,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 +77,28 @@ 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 );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimMudWeightWindowParameters::NonReservoirPorePressureType>::setUp()
|
||||
{
|
||||
addItem( RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC, "HYDROSTATIC", "Hydrostatic" );
|
||||
addItem( RimMudWeightWindowParameters::NonReservoirPorePressureType::PER_ELEMENT,
|
||||
"PER_ELEMENT",
|
||||
"From element properties" );
|
||||
setDefault( RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC );
|
||||
}
|
||||
|
||||
} // End namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -126,8 +150,18 @@ RimMudWeightWindowParameters::RimMudWeightWindowParameters( void )
|
||||
CAF_PDM_InitField( &m_K0_FGAddress, "K0_FGAddress", QString( "" ), "Value", "", "", "" );
|
||||
m_K0_FGAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
|
||||
caf::AppEnum<SourceType> defaultOBG0SourceType = RimMudWeightWindowParameters::SourceType::GRID;
|
||||
CAF_PDM_InitField( &m_obg0Type, "obg0SourceType", defaultOBG0SourceType, "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 +169,29 @@ 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::AppEnum<NonReservoirPorePressureType> defaultNonReservoirPorePressureType =
|
||||
RimMudWeightWindowParameters::NonReservoirPorePressureType::HYDROSTATIC;
|
||||
CAF_PDM_InitField( &m_porePressureNonReservoirSource,
|
||||
"PorePressureNonReservoirSource",
|
||||
defaultNonReservoirPorePressureType,
|
||||
"Non-Reservoir Pore Pressure",
|
||||
"",
|
||||
"Data source for Non-Reservoir Pore Pressure",
|
||||
"" );
|
||||
CAF_PDM_InitField( &m_userDefinedPPNonReservoir, "UserPPNonReservoir", 1.0, " Multiplier of hydrostatic PP", "", "", "" );
|
||||
CAF_PDM_InitField( &m_porePressureNonReservoirAddress, "PPNonReservoirAddress", QString( "" ), "Value", "", "", "" );
|
||||
m_porePressureNonReservoirAddress.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitField( &m_referenceLayer, "ReferenceLayer", -1, "Reference Layer", "", "", "" );
|
||||
}
|
||||
|
||||
@@ -300,12 +357,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 +371,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 +380,14 @@ 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 || changedField == &m_porePressureNonReservoirSource ||
|
||||
changedField == &m_userDefinedPPNonReservoir || changedField == &m_porePressureNonReservoirAddress )
|
||||
{
|
||||
RigGeoMechCaseData* rigCaseData = geoMechCase->geoMechData();
|
||||
if ( rigCaseData && rigCaseData->femPartResults() )
|
||||
@@ -335,7 +395,12 @@ 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,
|
||||
m_porePressureNonReservoirSource.value(),
|
||||
m_userDefinedPPNonReservoir,
|
||||
m_porePressureNonReservoirAddress );
|
||||
geoMechCase->updateConnectedViews();
|
||||
}
|
||||
}
|
||||
@@ -353,7 +418,8 @@ void RimMudWeightWindowParameters::handleFieldChanged( RimGeoMechCase*
|
||||
|
||||
if ( rigCaseData && rigCaseData->femPartResults() )
|
||||
{
|
||||
if ( typeField->value() == RimMudWeightWindowParameters::SourceType::FIXED )
|
||||
if ( typeField->value() == RimMudWeightWindowParameters::SourceType::FIXED ||
|
||||
typeField->value() == RimMudWeightWindowParameters::SourceType::GRID )
|
||||
{
|
||||
rigCaseData->femPartResults()->setCalculationParameters( parameterType, "", fixedField->value() );
|
||||
}
|
||||
@@ -373,7 +439,7 @@ void RimMudWeightWindowParameters::handleFieldChanged( RimGeoMechCase*
|
||||
.arg( title );
|
||||
RiaLogging::info( importMessage );
|
||||
// Set back to default value
|
||||
*typeField = RimMudWeightWindowParameters::SourceType::FIXED;
|
||||
*typeField = typeField->defaultValue();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -406,7 +472,6 @@ 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 );
|
||||
|
||||
RimGeoMechCase* geoMechCase = nullptr;
|
||||
firstAncestorOrThisOfType( geoMechCase );
|
||||
@@ -422,6 +487,31 @@ 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 );
|
||||
|
||||
bool isDerivedFromK0_FG = m_fractureGradientCalculationType == FractureGradientCalculationType::DERIVED_FROM_K0FG;
|
||||
m_K0_FGType.uiCapability()->setUiHidden( !isDerivedFromK0_FG );
|
||||
m_K0_FGFixed.uiCapability()->setUiHidden(
|
||||
!( isDerivedFromK0_FG && m_K0_FGType == RimMudWeightWindowParameters::SourceType::FIXED ) );
|
||||
m_K0_FGAddress.uiCapability()->setUiHidden(
|
||||
!( isDerivedFromK0_FG && m_K0_FGType == RimMudWeightWindowParameters::SourceType::PER_ELEMENT ) );
|
||||
|
||||
defineGroup( uiOrdering, "Initial Overburden Gradient", &m_obg0Type, &m_obg0Fixed, &m_obg0Address );
|
||||
m_obg0Type.uiCapability()->setUiHidden( !isDerivedFromK0_FG );
|
||||
m_obg0Fixed.uiCapability()->setUiHidden( true );
|
||||
m_obg0Address.uiCapability()->setUiHidden(
|
||||
!( isDerivedFromK0_FG && m_obg0Type == RimMudWeightWindowParameters::SourceType::PER_ELEMENT ) );
|
||||
|
||||
bool ppNonResPerElement =
|
||||
( m_porePressureNonReservoirSource == RimMudWeightWindowParameters::NonReservoirPorePressureType::PER_ELEMENT );
|
||||
m_userDefinedPPNonReservoir.uiCapability()->setUiHidden( ppNonResPerElement );
|
||||
m_porePressureNonReservoirAddress.uiCapability()->setUiHidden( !ppNonResPerElement );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -472,9 +562,28 @@ QList<caf::PdmOptionItemInfo>
|
||||
|
||||
if ( geoMechCase != nullptr )
|
||||
{
|
||||
if ( fieldNeedingOptions == &m_wellDeviationAddress || fieldNeedingOptions == &m_wellAzimuthAddress ||
|
||||
fieldNeedingOptions == &m_UCSAddress || fieldNeedingOptions == &m_poissonsRatioAddress ||
|
||||
fieldNeedingOptions == &m_K0_FGAddress )
|
||||
if ( fieldNeedingOptions == &m_obg0Type )
|
||||
{
|
||||
std::vector<SourceType> sourceTypes = {SourceType::GRID, SourceType::PER_ELEMENT};
|
||||
for ( auto sourceType : sourceTypes )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( caf::AppEnum<SourceType>::uiText( sourceType ), sourceType ) );
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_wellDeviationType || fieldNeedingOptions == &m_wellAzimuthType ||
|
||||
fieldNeedingOptions == &m_UCSType || fieldNeedingOptions == &m_poissonsRatioType ||
|
||||
fieldNeedingOptions == &m_K0_FGType )
|
||||
{
|
||||
std::vector<SourceType> sourceTypes = {SourceType::FIXED, SourceType::PER_ELEMENT};
|
||||
for ( auto sourceType : sourceTypes )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( caf::AppEnum<SourceType>::uiText( sourceType ), sourceType ) );
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_wellDeviationAddress || fieldNeedingOptions == &m_wellAzimuthAddress ||
|
||||
fieldNeedingOptions == &m_UCSAddress || fieldNeedingOptions == &m_poissonsRatioAddress ||
|
||||
fieldNeedingOptions == &m_K0_FGAddress || fieldNeedingOptions == &m_obg0Address ||
|
||||
fieldNeedingOptions == &m_porePressureNonReservoirAddress )
|
||||
{
|
||||
std::vector<std::string> elementProperties = geoMechCase->possibleElementPropertyFieldNames();
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ public:
|
||||
enum class SourceType
|
||||
{
|
||||
FIXED = 0,
|
||||
PER_ELEMENT
|
||||
PER_ELEMENT,
|
||||
GRID
|
||||
};
|
||||
|
||||
enum class ParameterType
|
||||
@@ -44,7 +45,8 @@ public:
|
||||
WELL_AZIMUTH,
|
||||
UCS,
|
||||
POISSONS_RATIO,
|
||||
K0_FG
|
||||
K0_FG,
|
||||
OBG0
|
||||
};
|
||||
|
||||
enum class UpperLimitType
|
||||
@@ -59,6 +61,18 @@ public:
|
||||
MAX_OF_PORE_PRESSURE_AND_SFG
|
||||
};
|
||||
|
||||
enum class FractureGradientCalculationType
|
||||
{
|
||||
DERIVED_FROM_K0FG,
|
||||
PROPORTIONAL_TO_SH
|
||||
};
|
||||
|
||||
enum class NonReservoirPorePressureType
|
||||
{
|
||||
HYDROSTATIC,
|
||||
PER_ELEMENT
|
||||
};
|
||||
|
||||
RimMudWeightWindowParameters( void );
|
||||
|
||||
SourceType wellDeviationType() const;
|
||||
@@ -127,10 +141,20 @@ 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<double> m_userDefinedPPNonReservoir;
|
||||
|
||||
caf::PdmField<caf::AppEnum<UpperLimitType>> m_upperLimitType;
|
||||
caf::PdmField<caf::AppEnum<LowerLimitType>> m_lowerLimitType;
|
||||
caf::PdmField<caf::AppEnum<FractureGradientCalculationType>> m_fractureGradientCalculationType;
|
||||
caf::PdmField<caf::AppEnum<NonReservoirPorePressureType>> m_porePressureNonReservoirSource;
|
||||
|
||||
caf::PdmField<QString> m_porePressureNonReservoirAddress;
|
||||
|
||||
caf::PdmField<int> m_referenceLayer;
|
||||
};
|
||||
|
||||
@@ -1383,11 +1383,9 @@ std::vector<unsigned char>
|
||||
double RigGeoMechWellLogExtractor::hydroStaticPorePressureForIntersection( size_t intersectionIdx,
|
||||
double waterDensityGCM3 ) const
|
||||
{
|
||||
double trueVerticalDepth = m_intersectionTVDs[intersectionIdx];
|
||||
double effectiveDepthMeters = trueVerticalDepth + wellPathData()->rkbDiff();
|
||||
double hydroStaticPorePressurePascal = effectiveDepthMeters * GRAVITY_ACCEL * waterDensityGCM3 * 1000;
|
||||
double hydroStaticPorePressureBar = pascalToBar( hydroStaticPorePressurePascal );
|
||||
return hydroStaticPorePressureBar;
|
||||
double trueVerticalDepth = m_intersectionTVDs[intersectionIdx];
|
||||
double effectiveDepthMeters = trueVerticalDepth + wellPathData()->rkbDiff();
|
||||
return hydroStaticPorePressureAtDepth( effectiveDepthMeters, waterDensityGCM3 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1395,11 +1393,19 @@ double RigGeoMechWellLogExtractor::hydroStaticPorePressureForIntersection( size_
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGeoMechWellLogExtractor::hydroStaticPorePressureForSegment( size_t intersectionIdx, double waterDensityGCM3 ) const
|
||||
{
|
||||
cvf::Vec3f centroid = cellCentroid( intersectionIdx );
|
||||
double trueVerticalDepth = -centroid.z();
|
||||
double effectiveDepthMeters = trueVerticalDepth + wellPathData()->rkbDiff();
|
||||
double hydroStaticPorePressurePascal = effectiveDepthMeters * GRAVITY_ACCEL * waterDensityGCM3 * 1000;
|
||||
double hydroStaticPorePressureBar = pascalToBar( hydroStaticPorePressurePascal );
|
||||
cvf::Vec3f centroid = cellCentroid( intersectionIdx );
|
||||
double trueVerticalDepth = -centroid.z();
|
||||
double effectiveDepthMeters = trueVerticalDepth + wellPathData()->rkbDiff();
|
||||
return hydroStaticPorePressureAtDepth( effectiveDepthMeters, waterDensityGCM3 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGeoMechWellLogExtractor::hydroStaticPorePressureAtDepth( double effectiveDepthMeters, double waterDensityGCM3 )
|
||||
{
|
||||
double hydroStaticPorePressurePascal = effectiveDepthMeters * GRAVITY_ACCEL * waterDensityGCM3 * 1000;
|
||||
double hydroStaticPorePressureBar = pascalToBar( hydroStaticPorePressurePascal );
|
||||
return hydroStaticPorePressureBar;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,9 @@ public:
|
||||
static caf::Ten3d transformTensorToWellPathOrientation( const cvf::Vec3d& wellPathTangent,
|
||||
const caf::Ten3d& wellPathTensor );
|
||||
|
||||
static double hydroStaticPorePressureAtDepth( double effectiveDepthMeters,
|
||||
double waterDensityGCM3 = PURE_WATER_DENSITY_GCM3 );
|
||||
|
||||
private:
|
||||
enum WellPathTangentCalculation
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user