mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-03 04:00:57 -06:00
#7158 Fix water depth calculation for WBS plot.
The first intersection between the well path and the GeoMech model is the correct water depth only when well path starts outside the model. Top of the bounding box is used as an estimated water depth when there is no intersection. WBS curves are now disabled for this case.
This commit is contained in:
parent
ee29349d5e
commit
d73bd60825
@ -498,23 +498,6 @@ QString RimDepthTrackPlot::createAutoName() const
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_nameConfig->addWaterDepth() )
|
||||
{
|
||||
if ( commonWellPath )
|
||||
{
|
||||
RigWellPath* wellPathGeometry = commonWellPath->wellPathGeometry();
|
||||
if ( wellPathGeometry )
|
||||
{
|
||||
const std::vector<cvf::Vec3d>& wellPathPoints = wellPathGeometry->wellPathPoints();
|
||||
if ( !wellPathPoints.empty() )
|
||||
{
|
||||
double tvdmsl = std::abs( wellPathPoints.front()[2] );
|
||||
generatedAutoTags.push_back( QString( "Water Depth = %1 m" ).arg( tvdmsl ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !generatedAutoTags.empty() )
|
||||
{
|
||||
generatedCurveName.push_back( generatedAutoTags.join( ", " ) );
|
||||
|
@ -64,6 +64,8 @@ RimWellBoreStabilityPlot::RimWellBoreStabilityPlot()
|
||||
m_nameConfig->enableAllAutoNameTags( true );
|
||||
|
||||
m_commonDataSource->setCaseType( RiaDefines::CaseType::GEOMECH_ODB_CASE );
|
||||
|
||||
m_waterDepth = std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -71,6 +73,10 @@ RimWellBoreStabilityPlot::RimWellBoreStabilityPlot()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellBoreStabilityPlot::applyWbsParametersToExtractor( RigGeoMechWellLogExtractor* extractor )
|
||||
{
|
||||
m_waterDepth = extractor->waterDepth();
|
||||
|
||||
if ( m_waterDepth == std::numeric_limits<double>::infinity() ) m_waterDepth = extractor->estimateWaterDepth();
|
||||
|
||||
m_wbsParameters->applyWbsParametersToExtractor( extractor );
|
||||
}
|
||||
|
||||
@ -171,3 +177,20 @@ void RimWellBoreStabilityPlot::applyDataSource()
|
||||
m_wbsParameters->setTimeStep( m_commonDataSource->timeStepToApply() );
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimWellBoreStabilityPlot::createAutoName() const
|
||||
{
|
||||
QString name = RimWellLogPlot::createAutoName();
|
||||
|
||||
if ( m_nameConfig->addWaterDepth() && m_waterDepth != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
double tvdmsl = m_waterDepth;
|
||||
QString waterDepthString = QString( ", Water Depth = %1 m" ).arg( tvdmsl );
|
||||
name += waterDepthString;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ public:
|
||||
void copyWbsParameters( const RimWbsParameters* wbsParameters );
|
||||
void setCaseWellPathAndTimeStep( RimGeoMechCase* geoMechCase, RimWellPath* wellPath, int timeStep );
|
||||
|
||||
QString createAutoName() const override;
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
@ -53,4 +55,5 @@ private:
|
||||
|
||||
private:
|
||||
caf::PdmChildField<RimWbsParameters*> m_wbsParameters;
|
||||
double m_waterDepth;
|
||||
};
|
||||
|
@ -1982,9 +1982,15 @@ void RimWellLogTrack::handleWheelEvent( QWheelEvent* event )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::pair<double, double>> RimWellLogTrack::waterAndRockRegions( RiaDefines::DepthTypeEnum depthType,
|
||||
const RigWellLogExtractor* extractor ) const
|
||||
std::vector<std::pair<double, double>> RimWellLogTrack::waterAndRockRegions( RiaDefines::DepthTypeEnum depthType,
|
||||
const RigGeoMechWellLogExtractor* extractor ) const
|
||||
{
|
||||
double waterEndTVD = extractor->waterDepth();
|
||||
if ( waterEndTVD == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
waterEndTVD = extractor->estimateWaterDepth();
|
||||
}
|
||||
|
||||
if ( depthType == RiaDefines::DepthTypeEnum::MEASURED_DEPTH )
|
||||
{
|
||||
double waterStartMD = 0.0;
|
||||
@ -1999,14 +2005,13 @@ std::vector<std::pair<double, double>> RimWellLogTrack::waterAndRockRegions( Ria
|
||||
else if ( depthType == RiaDefines::DepthTypeEnum::TRUE_VERTICAL_DEPTH )
|
||||
{
|
||||
double waterStartTVD = 0.0;
|
||||
double waterEndTVD = extractor->cellIntersectionTVDs().front();
|
||||
double rockEndTVD = extractor->cellIntersectionTVDs().back();
|
||||
return { { waterStartTVD, waterEndTVD }, { waterEndTVD, rockEndTVD } };
|
||||
}
|
||||
else if ( depthType == RiaDefines::DepthTypeEnum::TRUE_VERTICAL_DEPTH_RKB )
|
||||
{
|
||||
double waterStartTVDRKB = extractor->wellPathGeometry()->rkbDiff();
|
||||
double waterEndTVDRKB = extractor->cellIntersectionTVDs().front() + extractor->wellPathGeometry()->rkbDiff();
|
||||
double waterEndTVDRKB = waterEndTVD + extractor->wellPathGeometry()->rkbDiff();
|
||||
double rockEndTVDRKB = extractor->cellIntersectionTVDs().back() + extractor->wellPathGeometry()->rkbDiff();
|
||||
return { { waterStartTVDRKB, waterEndTVDRKB }, { waterEndTVDRKB, rockEndTVDRKB } };
|
||||
}
|
||||
@ -2532,7 +2537,6 @@ void RimWellLogTrack::updateFormationNamesOnPlot()
|
||||
|
||||
RigEclipseWellLogExtractor* eclWellLogExtractor = nullptr;
|
||||
RigGeoMechWellLogExtractor* geoMechWellLogExtractor = nullptr;
|
||||
RigWellLogExtractor* extractor = nullptr;
|
||||
|
||||
if ( m_formationTrajectoryType == SIMULATION_WELL )
|
||||
{
|
||||
@ -2561,7 +2565,6 @@ void RimWellLogTrack::updateFormationNamesOnPlot()
|
||||
RiaDefines::activeFormationNamesResultName() ) );
|
||||
|
||||
curveData = RimWellLogTrack::curveSamplingPointData( eclWellLogExtractor, resultAccessor.p() );
|
||||
extractor = eclWellLogExtractor;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2575,7 +2578,6 @@ void RimWellLogTrack::updateFormationNamesOnPlot()
|
||||
RigFemResultAddress( RIG_FORMATION_NAMES,
|
||||
activeFormationNamesResultName,
|
||||
"" ) );
|
||||
extractor = geoMechWellLogExtractor;
|
||||
}
|
||||
|
||||
if ( geoMechWellLogExtractor )
|
||||
@ -2585,7 +2587,7 @@ void RimWellLogTrack::updateFormationNamesOnPlot()
|
||||
|
||||
const caf::ColorTable waterAndRockColors = RiaColorTables::waterAndRockPaletteColors();
|
||||
const std::vector<std::pair<double, double>> waterAndRockIntervals =
|
||||
waterAndRockRegions( plot->depthType(), extractor );
|
||||
waterAndRockRegions( plot->depthType(), geoMechWellLogExtractor );
|
||||
|
||||
const std::vector<std::pair<double, double>> convertedYValues =
|
||||
RiaWellLogUnitTools<double>::convertDepths( waterAndRockIntervals, fromDepthUnit, toDepthUnit );
|
||||
|
@ -293,8 +293,8 @@ private:
|
||||
void handleWheelEvent( QWheelEvent* event ) override;
|
||||
void doUpdateLayout() override;
|
||||
|
||||
std::vector<std::pair<double, double>> waterAndRockRegions( RiaDefines::DepthTypeEnum depthType,
|
||||
const RigWellLogExtractor* extractor ) const;
|
||||
std::vector<std::pair<double, double>> waterAndRockRegions( RiaDefines::DepthTypeEnum depthType,
|
||||
const RigGeoMechWellLogExtractor* extractor ) const;
|
||||
|
||||
void connectCurveSignals( RimWellLogCurve* curve );
|
||||
|
||||
|
@ -61,6 +61,8 @@ RigGeoMechWellLogExtractor::RigGeoMechWellLogExtractor( gsl::not_null<RigGeoMech
|
||||
{
|
||||
calculateIntersection();
|
||||
|
||||
m_waterDepth = calculateWaterDepth();
|
||||
|
||||
for ( RigWbsParameter parameter : RigWbsParameter::allParameters() )
|
||||
{
|
||||
m_parameterSources[parameter] = parameter.sources().front();
|
||||
@ -125,6 +127,13 @@ QString RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAdd
|
||||
return "";
|
||||
}
|
||||
|
||||
if ( !isValid( m_waterDepth ) )
|
||||
{
|
||||
RiaLogging::error( "Well path does not intersect with sea floor. No well bore "
|
||||
"stability curves created." );
|
||||
return "";
|
||||
}
|
||||
|
||||
if ( resAddr.fieldName == RiaDefines::wbsFGResult().toStdString() )
|
||||
{
|
||||
wellBoreWallCurveData( resAddr, frameIndex, values );
|
||||
@ -1405,7 +1414,6 @@ double RigGeoMechWellLogExtractor::hydroStaticPorePressureAtDepth( double effect
|
||||
double RigGeoMechWellLogExtractor::wbsCurveValuesAtMsl() const
|
||||
{
|
||||
double waterDensityGCM3 = m_userDefinedValues.at( RigWbsParameter::waterDensity() );
|
||||
double waterDepth = std::abs( m_wellPathGeometry->wellPathPoints().front().z() );
|
||||
|
||||
double rkbDiff = m_wellPathGeometry->rkbDiff();
|
||||
if ( rkbDiff == std::numeric_limits<double>::infinity() )
|
||||
@ -1413,12 +1421,12 @@ double RigGeoMechWellLogExtractor::wbsCurveValuesAtMsl() const
|
||||
rkbDiff = 0.0;
|
||||
}
|
||||
|
||||
if ( waterDepth + rkbDiff < 1.0e-8 )
|
||||
if ( m_waterDepth + rkbDiff < 1.0e-8 )
|
||||
{
|
||||
return waterDensityGCM3;
|
||||
}
|
||||
|
||||
return waterDensityGCM3 * waterDepth / ( waterDepth + rkbDiff );
|
||||
return waterDensityGCM3 * m_waterDepth / ( m_waterDepth + rkbDiff );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1436,3 +1444,45 @@ bool RigGeoMechWellLogExtractor::isValid( float value )
|
||||
{
|
||||
return value != std::numeric_limits<float>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGeoMechWellLogExtractor::calculateWaterDepth() const
|
||||
{
|
||||
// Need a well path with intersections to generate a precise water depth
|
||||
if ( m_intersectionTVDs.empty() || m_wellPathGeometry->wellPathPoints().empty() )
|
||||
{
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
// Only calculate water depth if the well path starts outside the model.
|
||||
cvf::BoundingBox boundingBox = m_caseData->femParts()->boundingBox();
|
||||
if ( boundingBox.contains( m_wellPathGeometry->wellPathPoints().front() ) )
|
||||
{
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
// Water depth is always the first intersection with model for geo mech models.
|
||||
double waterDepth = m_intersectionTVDs.front();
|
||||
return waterDepth;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGeoMechWellLogExtractor::estimateWaterDepth() const
|
||||
{
|
||||
// Estimate water depth using bounding box. This will be imprecise
|
||||
// for models with a slanting top layer.
|
||||
cvf::BoundingBox boundingBox = m_caseData->femParts()->boundingBox();
|
||||
return std::abs( boundingBox.max().z() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGeoMechWellLogExtractor::waterDepth() const
|
||||
{
|
||||
return m_waterDepth;
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public:
|
||||
public:
|
||||
RigGeoMechWellLogExtractor( gsl::not_null<RigGeoMechCaseData*> aCase,
|
||||
gsl::not_null<const RigWellPath*> wellpath,
|
||||
const std::string& wellCaseErrorMsgName );
|
||||
const std::string& wellCaseErrorMsgName );
|
||||
|
||||
void performCurveDataSmoothing( int frameIndex,
|
||||
std::vector<double>* mds,
|
||||
@ -87,6 +87,9 @@ public:
|
||||
static double hydroStaticPorePressureAtDepth( double effectiveDepthMeters,
|
||||
double waterDensityGCM3 = PURE_WATER_DENSITY_GCM3 );
|
||||
|
||||
double waterDepth() const;
|
||||
double estimateWaterDepth() const;
|
||||
|
||||
private:
|
||||
enum WellPathTangentCalculation
|
||||
{
|
||||
@ -167,6 +170,8 @@ private:
|
||||
static bool isValid( double value );
|
||||
static bool isValid( float value );
|
||||
|
||||
double calculateWaterDepth() const;
|
||||
|
||||
private:
|
||||
cvf::ref<RigGeoMechCaseData> m_caseData;
|
||||
|
||||
@ -174,4 +179,6 @@ private:
|
||||
std::map<RigWbsParameter, QString> m_lasFileInputUnits;
|
||||
std::map<RigWbsParameter, WbsParameterSource> m_parameterSources;
|
||||
std::map<RigWbsParameter, double> m_userDefinedValues;
|
||||
|
||||
double m_waterDepth;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user