#5494 Add user changable water density and change model for where WBS-curves meet

This commit is contained in:
Gaute Lindkvist 2020-02-10 12:39:16 +01:00
parent 6dfd994403
commit ae112bab64
6 changed files with 86 additions and 36 deletions

View File

@ -78,6 +78,9 @@ RimWbsParameters::RimWbsParameters()
"FG in shale = K0_FG * (OBG0-PP0)\nK0_FG = (FG-PP)/(OBG-PP)",
"" );
RICF_InitFieldNoDefault( &m_waterDensitySource, "WaterDensitySource", "Water Density", "", "", "" );
m_waterDensitySource.uiCapability()->setUiHidden( true );
RICF_InitField( &m_userDefinedPoissionRatio,
"UserPoissonRatio",
0.35,
@ -100,6 +103,8 @@ RimWbsParameters::RimWbsParameters()
"FG in Shale = Multiplier * SH",
"" );
RICF_InitField( &m_userDefinedDensity, "WaterDensity", 1.03, "Density of Sea Water [g/cm^3]", "", "Units: g/cm^3", "" );
CAF_PDM_InitFieldNoDefault( &m_geoMechCase, "GeoMechCase", "GeoMechCase", "", "", "" );
m_geoMechCase.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_wellPath, "WellPath", "WellPath", "", "", "" );
@ -115,7 +120,8 @@ RimWbsParameters::RimWbsParameters()
{RigWbsParameter::DF(), &m_DFSource},
{RigWbsParameter::K0_FG(), &m_K0FGSource},
{RigWbsParameter::K0_SH(), &m_K0SHSource},
{RigWbsParameter::FG_Shale(), &m_FGShaleSource}};
{RigWbsParameter::FG_Shale(), &m_FGShaleSource},
{RigWbsParameter::waterDensity(), &m_waterDensitySource}};
m_userDefinedValueFields = {{RigWbsParameter::PP_NonReservoir(), &m_userDefinedPPShale},
{RigWbsParameter::poissonRatio(), &m_userDefinedPoissionRatio},
@ -123,7 +129,8 @@ RimWbsParameters::RimWbsParameters()
{RigWbsParameter::DF(), &m_userDefinedDF},
{RigWbsParameter::K0_FG(), &m_userDefinedK0FG},
{RigWbsParameter::K0_SH(), &m_userDefinedK0SH},
{RigWbsParameter::FG_Shale(), &m_FGShaleMultiplier}};
{RigWbsParameter::FG_Shale(), &m_FGShaleMultiplier},
{RigWbsParameter::waterDensity(), &m_userDefinedDensity}};
for ( auto parameterFieldPair : m_parameterSourceFields )
{
@ -341,6 +348,7 @@ void RimWbsParameters::loadDataAndUpdate()
//--------------------------------------------------------------------------------------------------
void RimWbsParameters::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_userDefinedDensity );
uiOrdering.add( &m_porePressureSource );
uiOrdering.add( &m_porePressureNonReservoirSource );
if ( m_porePressureNonReservoirSource == RigWbsParameter::USER_DEFINED )

View File

@ -85,6 +85,7 @@ private:
caf::PdmField<ParameterSourceEnum> m_K0FGSource;
caf::PdmField<ParameterSourceEnum> m_K0SHSource;
caf::PdmField<ParameterSourceEnum> m_FGShaleSource;
caf::PdmField<ParameterSourceEnum> m_waterDensitySource;
caf::PdmField<double> m_userDefinedPPShale;
caf::PdmField<double> m_userDefinedPoissionRatio;
@ -93,6 +94,7 @@ private:
caf::PdmField<double> m_userDefinedK0FG;
caf::PdmField<double> m_userDefinedK0SH;
caf::PdmField<double> m_FGShaleMultiplier;
caf::PdmField<double> m_userDefinedDensity;
caf::PdmPtrField<RimGeoMechCase*> m_geoMechCase;
caf::PdmPtrField<RimWellPath*> m_wellPath;

View File

@ -47,7 +47,8 @@
#include <type_traits>
const double RigGeoMechWellLogExtractor::UNIT_WEIGHT_OF_WATER = 9.81 * 1000.0; // N / m^3
const double RigGeoMechWellLogExtractor::PURE_WATER_DENSITY_GCM3 = 1.0; // g / cm^3
const double RigGeoMechWellLogExtractor::GRAVITY_ACCEL = 9.81; // m / s^2
//--------------------------------------------------------------------------------------------------
///
@ -96,12 +97,7 @@ void RigGeoMechWellLogExtractor::performCurveDataSmoothing( int
#pragma omp parallel for
for ( int64_t i = 0; i < int64_t( m_intersections.size() ); ++i )
{
cvf::Vec3f centroid = cellCentroid( i );
double trueVerticalDepth = -centroid.z();
double effectiveDepthMeters = trueVerticalDepth + wellPathData()->rkbDiff();
double hydroStaticPorePressureBar = pascalToBar( effectiveDepthMeters * UNIT_WEIGHT_OF_WATER );
double hydroStaticPorePressureBar = hydroStaticPorePressureForSegment( i );
interfaceShValuesDbl[i] = interfaceShValues[i] / hydroStaticPorePressureBar;
interfacePorePressuresDbl[i] = interfacePorePressures[i];
}
@ -139,7 +135,7 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd
wellBoreWallCurveData( resAddr, frameIndex, values );
// Try to replace invalid values with Shale-values
wellBoreFGShale( frameIndex, values );
values->front() = 1.0;
values->front() = wbsCurveValuesAtMsl();
}
else if ( resAddr.fieldName == RiaDefines::wbsSFGResult().toStdString() )
{
@ -150,7 +146,7 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd
resAddr.fieldName == RiaDefines::wbsSHResult().toStdString() )
{
wellPathScaledCurveData( resAddr, frameIndex, values );
values->front() = 1.0;
values->front() = wbsCurveValuesAtMsl();
}
else if ( resAddr.fieldName == RiaDefines::wbsAzimuthResult().toStdString() ||
resAddr.fieldName == RiaDefines::wbsInclinationResult().toStdString() )
@ -160,7 +156,7 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd
else if ( resAddr.fieldName == RiaDefines::wbsSHMkResult().toStdString() )
{
wellBoreSH_MatthewsKelly( frameIndex, values );
values->front() = 1.0;
values->front() = wbsCurveValuesAtMsl();
}
else
{
@ -274,6 +270,8 @@ std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
std::vector<double> unscaledValues( m_intersections.size(), std::numeric_limits<double>::infinity() );
double waterDensityGCM3 = m_userDefinedValues[RigWbsParameter::waterDensity()];
#pragma omp parallel for
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
{
@ -316,7 +314,8 @@ std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
}
else if ( *it == RigWbsParameter::HYDROSTATIC && isPPresult )
{
unscaledValues[intersectionIdx] = hydroStaticPorePressureForIntersection( intersectionIdx );
unscaledValues[intersectionIdx] = hydroStaticPorePressureForIntersection( intersectionIdx,
waterDensityGCM3 );
finalSourcesPerSegment[intersectionIdx] = RigWbsParameter::HYDROSTATIC;
break;
}
@ -482,6 +481,8 @@ std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
std::vector<WbsParameterSource> ppShaleSources =
calculateWbsParameterForAllSegments( RigWbsParameter::PP_NonReservoir(), 0, &ppShaleValues );
double waterDensityGCM3 = m_userDefinedValues[RigWbsParameter::waterDensity()];
#pragma omp parallel for
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
{
@ -499,7 +500,8 @@ std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
}
else
{
( *values )[intersectionIdx] = hydroStaticPorePressureForIntersection( intersectionIdx );
( *values )[intersectionIdx] = hydroStaticPorePressureForIntersection( intersectionIdx,
waterDensityGCM3 );
sources[intersectionIdx] = RigWbsParameter::HYDROSTATIC;
}
}
@ -1267,11 +1269,12 @@ std::vector<unsigned char>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigGeoMechWellLogExtractor::hydroStaticPorePressureForIntersection( size_t intersectionIdx ) const
double RigGeoMechWellLogExtractor::hydroStaticPorePressureForIntersection( size_t intersectionIdx,
double waterDensityGCM3 ) const
{
double trueVerticalDepth = m_intersectionTVDs[intersectionIdx];
double effectiveDepthMeters = trueVerticalDepth + wellPathData()->rkbDiff();
double hydroStaticPorePressurePascal = effectiveDepthMeters * UNIT_WEIGHT_OF_WATER;
double hydroStaticPorePressurePascal = effectiveDepthMeters * GRAVITY_ACCEL * waterDensityGCM3 * 1000;
double hydroStaticPorePressureBar = pascalToBar( hydroStaticPorePressurePascal );
return hydroStaticPorePressureBar;
}
@ -1279,16 +1282,38 @@ double RigGeoMechWellLogExtractor::hydroStaticPorePressureForIntersection( size_
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigGeoMechWellLogExtractor::hydroStaticPorePressureForSegment( size_t intersectionIdx ) const
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 * UNIT_WEIGHT_OF_WATER;
double hydroStaticPorePressurePascal = effectiveDepthMeters * GRAVITY_ACCEL * waterDensityGCM3 * 1000;
double hydroStaticPorePressureBar = pascalToBar( hydroStaticPorePressurePascal );
return hydroStaticPorePressureBar;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigGeoMechWellLogExtractor::wbsCurveValuesAtMsl() const
{
double waterDensityGCM3 = m_userDefinedValues.at( RigWbsParameter::waterDensity() );
double waterDepth = std::abs( wellPathData()->wellPathPoints().front().z() );
double rkbDiff = wellPathData()->rkbDiff();
if ( rkbDiff == std::numeric_limits<double>::infinity() )
{
rkbDiff = 0.0;
}
if ( waterDepth + rkbDiff < 1.0e-8 )
{
return waterDensityGCM3;
}
return waterDensityGCM3 * waterDepth / ( waterDepth + rkbDiff );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -51,6 +51,9 @@ class BoundingBox;
class RigGeoMechWellLogExtractor : public RigWellLogExtractor
{
public:
static const double PURE_WATER_DENSITY_GCM3;
static const double GRAVITY_ACCEL;
using WbsParameterSource = RigWbsParameter::Source;
using WbsParameterSourceEnum = RigWbsParameter::SourceEnum;
@ -132,14 +135,6 @@ private:
static void initializeResultValues( std::vector<float>& resultValues, size_t resultCount );
static void initializeResultValues( std::vector<caf::Ten3d>& resultValues, size_t resultCount );
void filterShortSegments( std::vector<double>* xValues,
std::vector<double>* yValues,
std::vector<unsigned char>* filterSegments,
std::vector<std::vector<double>*>& vectorOfDependentValues );
void filterColinearSegments( std::vector<double>* xValues,
std::vector<double>* yValues,
std::vector<unsigned char>* filterSegments,
std::vector<std::vector<double>*>& vectorOfDependentValues );
void smoothSegments( std::vector<double>* mds,
std::vector<double>* tvds,
std::vector<double>* values,
@ -149,8 +144,12 @@ private:
std::vector<unsigned char> determineFilteringOrSmoothing( const std::vector<double>& porePressures );
double hydroStaticPorePressureForIntersection( size_t intersectionIdx ) const;
double hydroStaticPorePressureForSegment( size_t intersectionIdx ) const;
double hydroStaticPorePressureForIntersection( size_t intersectionIdx,
double waterDensityGCM3 = PURE_WATER_DENSITY_GCM3 ) const;
double hydroStaticPorePressureForSegment( size_t intersectionIdx,
double waterDensityGCM3 = PURE_WATER_DENSITY_GCM3 ) const;
double wbsCurveValuesAtMsl() const;
static bool isValid( double value );
static bool isValid( float value );
@ -162,6 +161,4 @@ private:
std::map<RigWbsParameter, QString> m_lasFileInputUnits;
std::map<RigWbsParameter, WbsParameterSource> m_parameterSources;
std::map<RigWbsParameter, double> m_userDefinedValues;
static const double UNIT_WEIGHT_OF_WATER;
};

View File

@ -336,21 +336,38 @@ RigWbsParameter RigWbsParameter::FG_Shale()
{
RigWbsParameter param( "FG Shale",
false,
{
{DERIVED_FROM_K0FG, SourceAddress()},
{{DERIVED_FROM_K0FG, SourceAddress()},
{PROPORTIONAL_TO_SH, SourceAddress()},
{LAS_FILE, SourceAddress( "FG_SHALE_INP" )},
} );
{LAS_FILE, SourceAddress( "FG_SHALE_INP" )}} );
param.setOptionsExclusive( true );
return param;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigWbsParameter RigWbsParameter::waterDensity()
{
RigWbsParameter param( "Density of Sea Water", false, {{USER_DEFINED, SourceAddress()}} );
return param;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RigWbsParameter> RigWbsParameter::allParameters()
{
return {PP_Reservoir(), PP_NonReservoir(), poissonRatio(), UCS(), OBG(), OBG0(), SH(), DF(), K0_FG(), K0_SH(), FG_Shale()};
return {PP_Reservoir(),
PP_NonReservoir(),
poissonRatio(),
UCS(),
OBG(),
OBG0(),
SH(),
DF(),
K0_FG(),
K0_SH(),
FG_Shale(),
waterDensity()};
}
//--------------------------------------------------------------------------------------------------

View File

@ -83,6 +83,7 @@ public:
static RigWbsParameter K0_FG();
static RigWbsParameter K0_SH();
static RigWbsParameter FG_Shale();
static RigWbsParameter waterDensity();
static std::set<RigWbsParameter> allParameters();
static bool findParameter( QString parameterName, RigWbsParameter* foundParam = nullptr );