#4665 Implement a Well Bore Stability Plot class

* Trigger updates when Ui fields are changed
  * Show only WBS parameter options that have available data
  * Clang-format WBS stuff
This commit is contained in:
Gaute Lindkvist
2019-09-05 12:24:45 +02:00
parent e550b435e4
commit 129df990ae
12 changed files with 1529 additions and 937 deletions

View File

@@ -18,25 +18,25 @@
#include "RicNewWellBoreStabilityPlotFeature.h"
#include "RicNewWellLogPlotFeatureImpl.h"
#include "RicNewWellLogFileCurveFeature.h"
#include "RicNewWellLogCurveExtractionFeature.h"
#include "RicNewWellLogFileCurveFeature.h"
#include "RicNewWellLogPlotFeatureImpl.h"
#include "RicWellLogTools.h"
#include "RigFemResultAddress.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigGeoMechCaseData.h"
#include "RigWellPath.h"
#include "RimGeoMechCase.h"
#include "RimGeoMechView.h"
#include "RimProject.h"
#include "RimWellLogPlot.h"
#include "RimWellLogPlotCollection.h"
#include "RimWellLogTrack.h"
#include "RimWellBoreStabilityPlot.h"
#include "RimWellLogExtractionCurve.h"
#include "RimWellLogFile.h"
#include "RimWellLogFileCurve.h"
#include "RimWellLogFileChannel.h"
#include "RimWellLogFileCurve.h"
#include "RimWellLogPlotCollection.h"
#include "RimWellLogTrack.h"
#include "RimWellPath.h"
#include "RicWellLogTools.h"
@@ -44,10 +44,10 @@
#include "RiaApplication.h"
#include "cvfAssert.h"
#include "cvfMath.h"
#include "cafProgressInfo.h"
#include "cafSelectionManager.h"
#include "cvfAssert.h"
#include "cvfMath.h"
#include <QAction>
#include <QDateTime>
@@ -74,7 +74,8 @@ bool RicNewWellBoreStabilityPlotFeature::isCommandEnabled()
void RicNewWellBoreStabilityPlotFeature::onActionTriggered( bool isChecked )
{
RimWellPath* wellPath = caf::SelectionManager::instance()->selectedItemAncestorOfType<RimWellPath>();
RimWellLogPlotCollection* plotCollection = caf::SelectionManager::instance()->selectedItemOfType<RimWellLogPlotCollection>();
RimWellLogPlotCollection* plotCollection = caf::SelectionManager::instance()
->selectedItemOfType<RimWellLogPlotCollection>();
if ( !wellPath )
{
if ( plotCollection )
@@ -104,7 +105,8 @@ void RicNewWellBoreStabilityPlotFeature::onActionTriggered(bool isChecked)
caf::ProgressInfo progInfo( 100, "Creating Well Bore Stability Plot" );
RimGeoMechCase* geoMechCase = geoMechView->geoMechCase();
RimWellLogPlot* plot = RicNewWellLogPlotFeatureImpl::createWellLogPlot(false, "Well Bore Stability");
RimWellBoreStabilityPlot* plot = RicNewWellLogPlotFeatureImpl::createWellBoreStabilityPlot( false,
"Well Bore Stability" );
{
auto task = progInfo.task( "Creating formation track", 2 );
@@ -157,7 +159,9 @@ void RicNewWellBoreStabilityPlotFeature::setupActionLook(QAction* actionToSetup)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewWellBoreStabilityPlotFeature::createFormationTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase)
void RicNewWellBoreStabilityPlotFeature::createFormationTrack( RimWellBoreStabilityPlot* plot,
RimWellPath* wellPath,
RimGeoMechCase* geoMechCase )
{
RimWellLogTrack* formationTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false, "Formations", plot );
formationTrack->setFormationWellPath( wellPath );
@@ -170,7 +174,9 @@ void RicNewWellBoreStabilityPlotFeature::createFormationTrack(RimWellLogPlot* pl
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewWellBoreStabilityPlotFeature::createCasingShoeTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase)
void RicNewWellBoreStabilityPlotFeature::createCasingShoeTrack( RimWellBoreStabilityPlot* plot,
RimWellPath* wellPath,
RimGeoMechCase* geoMechCase )
{
RimWellLogTrack* casingShoeTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false, "Well Design", plot );
casingShoeTrack->setWidthScaleFactor( RimWellLogTrack::NARROW_TRACK );
@@ -188,9 +194,13 @@ void RicNewWellBoreStabilityPlotFeature::createCasingShoeTrack(RimWellLogPlot* p
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView)
void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBoreStabilityPlot* plot,
RimWellPath* wellPath,
RimGeoMechView* geoMechView )
{
RimWellLogTrack* stabilityCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(false, "Stability Curves", plot);
RimWellLogTrack* stabilityCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false,
"Stability Curves",
plot );
stabilityCurvesTrack->setWidthScaleFactor( RimWellLogTrack::EXTRA_WIDE_TRACK );
stabilityCurvesTrack->setAutoScaleXEnabled( true );
stabilityCurvesTrack->setTickIntervals( 0.5, 0.05 );
@@ -202,14 +212,23 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack(RimWellLogPl
std::vector<QString> resultNames = RiaDefines::wellPathStabilityResultNames();
std::vector<cvf::Color3f> colors = { cvf::Color3f::RED, cvf::Color3f::PURPLE, cvf::Color3f::GREEN, cvf::Color3f::BLUE, cvf::Color3f::ORANGE };
std::vector<RiuQwtPlotCurve::LineStyleEnum> lineStyles = { RiuQwtPlotCurve::STYLE_SOLID, RiuQwtPlotCurve::STYLE_DASH, RiuQwtPlotCurve::STYLE_DASH_DOT, RiuQwtPlotCurve::STYLE_SOLID, RiuQwtPlotCurve::STYLE_DASH};
std::vector<cvf::Color3f> colors = {cvf::Color3f::RED,
cvf::Color3f::PURPLE,
cvf::Color3f::GREEN,
cvf::Color3f::BLUE,
cvf::Color3f::ORANGE};
std::vector<RiuQwtPlotCurve::LineStyleEnum> lineStyles = {RiuQwtPlotCurve::STYLE_SOLID,
RiuQwtPlotCurve::STYLE_DASH,
RiuQwtPlotCurve::STYLE_DASH_DOT,
RiuQwtPlotCurve::STYLE_SOLID,
RiuQwtPlotCurve::STYLE_DASH};
for ( size_t i = 0; i < resultNames.size(); ++i )
{
const QString& resultName = resultNames[i];
RigFemResultAddress resAddr( RIG_WELLPATH_DERIVED, resultName.toStdString(), "" );
RimWellLogExtractionCurve* curve = RicWellLogTools::addExtractionCurve(stabilityCurvesTrack, geoMechView, wellPath, nullptr, 0, false, false);
RimWellLogExtractionCurve* curve =
RicWellLogTools::addExtractionCurve( stabilityCurvesTrack, geoMechView, wellPath, nullptr, 0, false, false );
curve->setGeoMechResultAddress( resAddr );
curve->setCurrentTimeStep( geoMechView->currentTimeStep() );
curve->setCustomName( resultName );
@@ -224,9 +243,13 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack(RimWellLogPl
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewWellBoreStabilityPlotFeature::createAnglesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView)
void RicNewWellBoreStabilityPlotFeature::createAnglesTrack( RimWellBoreStabilityPlot* plot,
RimWellPath* wellPath,
RimGeoMechView* geoMechView )
{
RimWellLogTrack* wellPathAnglesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(false, "Well Path Angles", plot);
RimWellLogTrack* wellPathAnglesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false,
"Well Path Angles",
plot );
double minValue = 360.0, maxValue = 0.0;
const double angleIncrement = 90.0;
std::vector<QString> resultNames = RiaDefines::wellPathAngleResultNames();
@@ -239,7 +262,8 @@ void RicNewWellBoreStabilityPlotFeature::createAnglesTrack(RimWellLogPlot* plot,
{
const QString& resultName = resultNames[i];
RigFemResultAddress resAddr( RIG_WELLPATH_DERIVED, resultName.toStdString(), "" );
RimWellLogExtractionCurve* curve = RicWellLogTools::addExtractionCurve(wellPathAnglesTrack, geoMechView, wellPath, nullptr, 0, false, false);
RimWellLogExtractionCurve* curve =
RicWellLogTools::addExtractionCurve( wellPathAnglesTrack, geoMechView, wellPath, nullptr, 0, false, false );
curve->setGeoMechResultAddress( resAddr );
curve->setCurrentTimeStep( geoMechView->currentTimeStep() );
curve->setCustomName( resultName );

View File

@@ -22,7 +22,7 @@
class RimGeoMechCase;
class RimGeoMechView;
class RimWellLogPlot;
class RimWellBoreStabilityPlot;
class RimWellPath;
//==================================================================================================
@@ -39,8 +39,8 @@ protected:
void setupActionLook( QAction* actionToSetup ) override;
private:
void createFormationTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase);
void createCasingShoeTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase);
void createStabilityCurvesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechCase);
void createAnglesTrack(RimWellLogPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView);
void createFormationTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase );
void createCasingShoeTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase );
void createStabilityCurvesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechCase );
void createAnglesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView );
};

View File

@@ -21,6 +21,7 @@
#include "RimMainPlotCollection.h"
#include "RimProject.h"
#include "RimWellBoreStabilityPlot.h"
#include "RimWellLogPlot.h"
#include "RimWellLogPlotCollection.h"
#include "RimWellLogTrack.h"
@@ -31,6 +32,42 @@
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellBoreStabilityPlot*
RicNewWellLogPlotFeatureImpl::createWellBoreStabilityPlot( bool showAfterCreation /*= true*/,
const QString& plotDescription /*= QString("")*/ )
{
RimWellLogPlotCollection* wellLogPlotColl = wellLogPlotCollection();
CVF_ASSERT( wellLogPlotColl );
// Make sure the summary plot window is created
RiaGuiApplication::instance()->getOrCreateMainPlotWindow();
RimWellBoreStabilityPlot* plot = new RimWellBoreStabilityPlot();
plot->setAsPlotMdiWindow();
wellLogPlotColl->wellLogPlots().push_back( plot );
if ( !plotDescription.isEmpty() )
{
plot->setDescription( plotDescription );
}
else
{
plot->setDescription(
QString( "Well Bore Stability Plot %1" ).arg( wellLogPlotCollection()->wellLogPlots.size() ) );
}
if ( showAfterCreation )
{
RiaGuiApplication::instance()->getOrCreateAndShowMainPlotWindow();
}
return plot;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -67,7 +104,9 @@ RimWellLogPlot* RicNewWellLogPlotFeatureImpl::createWellLogPlot(bool showAfterCr
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack* RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack(bool updateAfter, const QString& trackDescription, RimWellLogPlot* existingPlot)
RimWellLogTrack* RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( bool updateAfter,
const QString& trackDescription,
RimWellLogPlot* existingPlot )
{
RimWellLogPlot* plot = existingPlot;
if ( plot == nullptr )

View File

@@ -21,6 +21,7 @@
#include <QString>
class RimWellBoreStabilityPlot;
class RimWellLogPlotCollection;
class RimWellLogPlot;
class RimWellLogTrack;
@@ -31,9 +32,15 @@ class RimWellLogTrack;
class RicNewWellLogPlotFeatureImpl
{
public:
static RimWellLogPlot* createWellLogPlot(bool showAfterCreation = true, const QString& plotDescription = QString(""));
static RimWellLogTrack* createWellLogPlotTrack(bool updateAfterCreation = true, const QString& trackDescription = QString(""), RimWellLogPlot* existingPlot = nullptr);
static RimWellBoreStabilityPlot* createWellBoreStabilityPlot( bool showAfterCreation = true,
const QString& plotDescription = QString( "" ) );
static RimWellLogPlot* createWellLogPlot( bool showAfterCreation = true,
const QString& plotDescription = QString( "" ) );
static RimWellLogTrack* createWellLogPlotTrack( bool updateAfterCreation = true,
const QString& trackDescription = QString( "" ),
RimWellLogPlot* existingPlot = nullptr );
static void updateAfterCreation( RimWellLogPlot* plot );
private:
static RimWellLogPlotCollection* wellLogPlotCollection();
};

View File

@@ -75,6 +75,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimPltPlotCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlot.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogTrack.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurve.h
${CMAKE_CURRENT_LIST_DIR}/RimWellBoreStabilityPlot.h
${CMAKE_CURRENT_LIST_DIR}/RimViewLinker.h
${CMAKE_CURRENT_LIST_DIR}/RimViewLinkerCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimWellLogExtractionCurve.h
@@ -210,6 +211,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimRftPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimPltPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellLogPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellBoreStabilityPlot.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellLogTrack.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellLogCurve.cpp
${CMAKE_CURRENT_LIST_DIR}/RimViewLinker.cpp

View File

@@ -24,6 +24,7 @@
#include "RimCase.h"
#include "RimEclipseCase.h"
#include "RimGeoMechCase.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimWellLogFile.h"
@@ -330,6 +331,31 @@ void RimTools::eclipseCaseOptionItems(QList<caf::PdmOptionItemInfo>* options)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimTools::geoMechCaseOptionItems(QList<caf::PdmOptionItemInfo>* options)
{
CVF_ASSERT(options);
if (!options) return;
RimProject* proj = RiaApplication::instance()->project();
if (proj)
{
std::vector<RimCase*> cases;
proj->allCases(cases);
for (RimCase* c : cases)
{
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>(c);
if (geoMechCase)
{
options->push_back(caf::PdmOptionItemInfo(c->caseUserDescription(), c, false, c->uiIconProvider()));
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -54,5 +54,6 @@ public:
static void wellPathWithFormations(std::vector<RimWellPath*>* wellPaths);
static void caseOptionItems(QList<caf::PdmOptionItemInfo>* options);
static void eclipseCaseOptionItems(QList<caf::PdmOptionItemInfo>* options);
static void geoMechCaseOptionItems(QList<caf::PdmOptionItemInfo>* options);
static RimWellPathCollection* wellPathCollection();
};

View File

@@ -0,0 +1,238 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimWellBoreStabilityPlot.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemResultAddress.h"
#include "RigGeoMechCaseData.h"
#include "RimGeoMechCase.h"
#include "RimTools.h"
#include "RimWellLogCurveCommonDataSource.h"
#include "RimWellLogFile.h"
#include "cafPdmBase.h"
#include "cafPdmObject.h"
#include "cafPdmUiGroup.h"
namespace caf
{
template<>
void RimWellBoreStabilityPlot::ParameterSourceEnum::setUp()
{
addItem(RigGeoMechWellLogExtractor::AUTO, "AUTO", "Automatic");
addItem(RigGeoMechWellLogExtractor::GRID, "GRID", "Grid");
addItem(RigGeoMechWellLogExtractor::LAS_FILE, "LAS_FILE", "LAS File");
addItem(RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE, "ELEMENT_PROPERTY_TABLE", "Element Property Table");
addItem(RigGeoMechWellLogExtractor::USER_DEFINED, "USER_DEFINED", "User Defined");
addItem(RigGeoMechWellLogExtractor::HYDROSTATIC_PP, "HYDROSTATIC_PP", "Hydrostatic");
setDefault(RigGeoMechWellLogExtractor::AUTO);
}
} // End namespace caf
CAF_PDM_SOURCE_INIT(RimWellBoreStabilityPlot, "WellBoreStabilityPlot");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellBoreStabilityPlot::RimWellBoreStabilityPlot()
{
CAF_PDM_InitObject("Well Bore Stability Plot", ":/WellLogPlot16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(
&m_porePressureSource, "PorePressureSource", "Pore Pressure", "", "Data source for Pore Pressure", "");
CAF_PDM_InitFieldNoDefault(
&m_poissonRatioSource, "PoissionRatioSource", "Poisson Ratio", "", "Data source for Poisson Ratio", "");
CAF_PDM_InitFieldNoDefault(&m_ucsSource, "UcsSource", "Uniaxial Compressive Strength", "", "Data source for UCS", "");
CAF_PDM_InitField(&m_userDefinedPoissionRatio, "UserPoissionRatio", 0.25, "", "", "User defined Poisson Ratio", "");
m_userDefinedPoissionRatio.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
// Typical UCS: http://ceae.colorado.edu/~amadei/CVEN5768/PDF/NOTES8.pdf
// Typical UCS for Shale is 5 - 100 MPa -> 50 - 1000 bar.
CAF_PDM_InitField(&m_userDefinedUcs, "UserUcs", 100.0, "", "", "User defined UCS [bar]", "");
m_userDefinedUcs.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGeoMechWellLogExtractor::WbsParameterSource RimWellBoreStabilityPlot::porePressureSource() const
{
return m_porePressureSource();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGeoMechWellLogExtractor::WbsParameterSource RimWellBoreStabilityPlot::poissonRatioSource() const
{
return m_poissonRatioSource();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGeoMechWellLogExtractor::WbsParameterSource RimWellBoreStabilityPlot::ucsSource() const
{
return m_ucsSource();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellBoreStabilityPlot::userDefinedPoissonRatio() const
{
return m_userDefinedPoissionRatio();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellBoreStabilityPlot::userDefinedUcs() const
{
return m_userDefinedUcs();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellBoreStabilityPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
caf::PdmUiGroup* parameterSources = uiOrdering.addNewGroup("Parameter Sources");
parameterSources->add(&m_porePressureSource);
parameterSources->add(&m_poissonRatioSource);
parameterSources->add(&m_userDefinedPoissionRatio, {false, 1, 1});
parameterSources->add(&m_ucsSource);
parameterSources->add(&m_userDefinedUcs, {false, 1, 1});
m_userDefinedPoissionRatio.uiCapability()->setUiReadOnly(m_poissonRatioSource() != RigGeoMechWellLogExtractor::USER_DEFINED);
m_userDefinedUcs.uiCapability()->setUiReadOnly(m_ucsSource() != RigGeoMechWellLogExtractor::USER_DEFINED);
RimWellLogPlot::defineUiOrdering(uiConfigName, uiOrdering);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimWellBoreStabilityPlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> options = RimWellLogPlot::calculateValueOptions(fieldNeedingOptions, useOptionsOnly);
RimWellPath* wellPath = m_commonDataSource->wellPathToApply();
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>(m_commonDataSource->caseToApply());
int timeStep = m_commonDataSource->timeStepToApply();
RigFemPartResultsCollection* femPartResults = nullptr;
if (geoMechCase)
{
femPartResults = geoMechCase->geoMechData()->femPartResults();
}
if (fieldNeedingOptions == &m_porePressureSource)
{
for (auto source : RigGeoMechWellLogExtractor::supportedSourcesForPorePressure())
{
if (source == RigGeoMechWellLogExtractor::LAS_FILE)
{
if (wellPath && !RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "PP").empty())
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
else if (source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE)
{
RigFemResultAddress resAddr(RIG_ELEMENT, "POR", "");
if (timeStep > 0 && femPartResults && !femPartResults->resultValues(resAddr, 0, timeStep).empty())
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
else
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
}
else if (fieldNeedingOptions == &m_poissonRatioSource)
{
for (auto source : RigGeoMechWellLogExtractor::supportedSourcesForPoissonRatio())
{
if (source == RigGeoMechWellLogExtractor::LAS_FILE)
{
if (wellPath && !RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "POISSON_RATIO").empty())
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
else if (source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE)
{
RigFemResultAddress resAddr(RIG_ELEMENT, "RATIO", "");
if (timeStep > 0 && femPartResults && !femPartResults->resultValues(resAddr, 0, timeStep).empty())
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
else
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
}
else if (fieldNeedingOptions == &m_ucsSource)
{
for (auto source : RigGeoMechWellLogExtractor::supportedSourcesForUcs())
{
if (source == RigGeoMechWellLogExtractor::LAS_FILE)
{
if (wellPath && !RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "UCS").empty())
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
else if (source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE)
{
RigFemResultAddress resAddr(RIG_ELEMENT, "UCS", "");
if (timeStep > 0 && femPartResults && !femPartResults->resultValues(resAddr, 0, timeStep).empty())
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
else
{
options.push_back(caf::PdmOptionItemInfo(ParameterSourceEnum::uiText(source), source));
}
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellBoreStabilityPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue)
{
RimWellLogPlot::fieldChangedByUi(changedField, oldValue, newValue);
if (changedField == &m_porePressureSource || changedField == &m_poissonRatioSource || changedField == &m_ucsSource ||
changedField == &m_userDefinedPoissionRatio || changedField == &m_userDefinedUcs)
{
this->loadDataAndUpdate();
}
}

View File

@@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2019- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimWellLogPlot.h"
#include "RigGeoMechWellLogExtractor.h"
#include "cafAppEnum.h"
#include "cafPdmField.h"
#include "cafPdmPtrField.h"
#include <set>
class RimGeoMechCase;
class RimWellPath;
class RimWellBoreStabilityPlot : public RimWellLogPlot
{
CAF_PDM_HEADER_INIT;
public:
typedef caf::AppEnum<RigGeoMechWellLogExtractor::WbsParameterSource> ParameterSourceEnum;
public:
RimWellBoreStabilityPlot();
RigGeoMechWellLogExtractor::WbsParameterSource porePressureSource() const;
RigGeoMechWellLogExtractor::WbsParameterSource poissonRatioSource() const;
RigGeoMechWellLogExtractor::WbsParameterSource ucsSource() const;
double userDefinedPoissonRatio() const;
double userDefinedUcs() const;
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
private:
caf::PdmField<ParameterSourceEnum> m_porePressureSource;
caf::PdmField<ParameterSourceEnum> m_poissonRatioSource;
caf::PdmField<ParameterSourceEnum> m_ucsSource;
caf::PdmField<double> m_userDefinedPoissionRatio;
caf::PdmField<double> m_userDefinedUcs;
};

View File

@@ -29,9 +29,9 @@
#include "RigGeoMechCaseData.h"
#include "RigGeoMechWellLogExtractor.h"
#include "RigResultAccessorFactory.h"
#include "RigSimWellData.h"
#include "RigSimulationWellCenterLineCalculator.h"
#include "RigSimulationWellCoordsAndMD.h"
#include "RigSimWellData.h"
#include "RigWellLogCurveData.h"
#include "RigWellPath.h"
@@ -46,6 +46,7 @@
#include "RimOilField.h"
#include "RimProject.h"
#include "RimTools.h"
#include "RimWellBoreStabilityPlot.h"
#include "RimWellLogCurve.h"
#include "RimWellLogFile.h"
#include "RimWellLogFileChannel.h"
@@ -72,7 +73,6 @@
CAF_PDM_SOURCE_INIT( RimWellLogExtractionCurve, "RimWellLogExtractionCurve" );
namespace caf
{
template <>
@@ -82,8 +82,7 @@ void AppEnum< RimWellLogExtractionCurve::TrajectoryType >::setUp()
addItem( RimWellLogExtractionCurve::SIMULATION_WELL, "SIMULATION_WELL", "Simulation Well" );
setDefault( RimWellLogExtractionCurve::WELL_PATH );
}
}
} // namespace caf
//--------------------------------------------------------------------------------------------------
///
@@ -98,8 +97,13 @@ RimWellLogExtractionCurve::RimWellLogExtractionCurve()
m_wellPath.uiCapability()->setUiTreeChildrenHidden( true );
CAF_PDM_InitField( &m_simWellName, "SimulationWellName", QString( "None" ), "Well Name", "", "", "" );
CAF_PDM_InitField(&m_branchDetection, "BranchDetection", true, "Branch Detection", "",
"Compute branches based on how simulation well cells are organized", "");
CAF_PDM_InitField( &m_branchDetection,
"BranchDetection",
true,
"Branch Detection",
"",
"Compute branches based on how simulation well cells are organized",
"" );
CAF_PDM_InitField( &m_branchIndex, "Branch", 0, "Branch Index", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_case, "CurveCase", "Case", "", "", "" );
@@ -138,7 +142,6 @@ RimWellLogExtractionCurve::~RimWellLogExtractionCurve()
delete m_eclipseResultDefinition;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -158,7 +161,9 @@ RimWellPath* RimWellLogExtractionCurve::wellPath() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::setFromSimulationWellName(const QString& simWellName, int branchIndex, bool branchDetection)
void RimWellLogExtractionCurve::setFromSimulationWellName( const QString& simWellName,
int branchIndex,
bool branchDetection )
{
m_trajectoryType = SIMULATION_WELL;
m_simWellName = simWellName;
@@ -242,11 +247,14 @@ void RimWellLogExtractionCurve::clampTimestep()
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::clampBranchIndex()
{
int branchCount = static_cast<int>(RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection).size());
int branchCount = static_cast<int>(
RiaSimWellBranchTools::simulationWellBranches( m_simWellName, m_branchDetection ).size() );
if ( branchCount > 0 )
{
if ( m_branchIndex >= branchCount ) m_branchIndex = branchCount - 1;
else if ( m_branchIndex < 0 ) m_branchIndex = 0;
if ( m_branchIndex >= branchCount )
m_branchIndex = branchCount - 1;
else if ( m_branchIndex < 0 )
m_branchIndex = 0;
}
else
{
@@ -257,7 +265,9 @@ void RimWellLogExtractionCurve::clampBranchIndex()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
void RimWellLogExtractionCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimWellLogCurve::fieldChangedByUi( changedField, oldValue, newValue );
@@ -286,8 +296,7 @@ void RimWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* chan
{
this->loadDataAndUpdate( true );
}
else if (changedField == &m_branchDetection ||
changedField == &m_branchIndex)
else if ( changedField == &m_branchDetection || changedField == &m_branchIndex )
{
clearGeneratedSimWellPaths();
@@ -298,10 +307,8 @@ void RimWellLogExtractionCurve::fieldChangedByUi(const caf::PdmFieldHandle* chan
this->loadDataAndUpdate( true );
}
if (changedField == &m_addCaseNameToCurveName ||
changedField == &m_addPropertyToCurveName ||
changedField == &m_addWellNameToCurveName ||
changedField == &m_addTimestepToCurveName ||
if ( changedField == &m_addCaseNameToCurveName || changedField == &m_addPropertyToCurveName ||
changedField == &m_addWellNameToCurveName || changedField == &m_addTimestepToCurveName ||
changedField == &m_addDateToCurveName )
{
this->uiCapability()->updateConnectedEditors();
@@ -343,7 +350,8 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot)
}
else
{
std::vector<const RigWellPath*> simWellBranches = RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection);
std::vector<const RigWellPath*> simWellBranches =
RiaSimWellBranchTools::simulationWellBranches( m_simWellName, m_branchDetection );
if ( m_branchIndex >= 0 && m_branchIndex < static_cast<int>( simWellBranches.size() ) )
{
auto wellBranch = simWellBranches[m_branchIndex];
@@ -360,7 +368,8 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot)
}
}
}
cvf::ref<RigGeoMechWellLogExtractor> geomExtractor = wellLogCollection->findOrCreateExtractor(m_wellPath, geomCase);
cvf::ref<RigGeoMechWellLogExtractor> geomExtractor = wellLogCollection->findOrCreateExtractor( m_wellPath,
geomCase );
std::vector<double> values;
std::vector<double> measuredDepthValues;
@@ -375,7 +384,8 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot)
m_eclipseResultDefinition->loadResult();
cvf::ref<RigResultAccessor> resAcc = RigResultAccessorFactory::createFromResultDefinition(eclipseCase->eclipseCaseData(),
cvf::ref<RigResultAccessor> resAcc =
RigResultAccessorFactory::createFromResultDefinition( eclipseCase->eclipseCaseData(),
0,
m_timeStep,
m_eclipseResultDefinition );
@@ -395,11 +405,20 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot)
}
else if ( geomExtractor.notNull() ) // geomExtractor
{
measuredDepthValues = geomExtractor->cellIntersectionMDs();
tvDepthValues = geomExtractor->cellIntersectionTVDs();
findAndLoadWbsParametersFromLasFiles( m_wellPath(), geomExtractor.p() );
RimWellBoreStabilityPlot* wbsPlot;
this->firstAncestorOrThisOfType( wbsPlot );
if ( wbsPlot )
{
geomExtractor->setWbsParameters( wbsPlot->porePressureSource(),
wbsPlot->poissonRatioSource(),
wbsPlot->ucsSource(),
wbsPlot->userDefinedPoissonRatio(),
wbsPlot->userDefinedUcs() );
}
geomExtractor->setRkbDiff( rkbDiff() );
@@ -431,12 +450,16 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot)
if ( wellLogPlot->depthType() == RimWellLogPlot::TRUE_VERTICAL_DEPTH )
{
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(), m_curveData->trueDepthPlotValues(displayUnit).data(), static_cast<int>(m_curveData->xPlotValues().size()));
m_qwtPlotCurve->setSamples( m_curveData->xPlotValues().data(),
m_curveData->trueDepthPlotValues( displayUnit ).data(),
static_cast<int>( m_curveData->xPlotValues().size() ) );
isUsingPseudoLength = false;
}
else if ( wellLogPlot->depthType() == RimWellLogPlot::MEASURED_DEPTH )
{
m_qwtPlotCurve->setSamples(m_curveData->xPlotValues().data(), m_curveData->measuredDepthPlotValues(displayUnit).data(), static_cast<int>(m_curveData->xPlotValues().size()));
m_qwtPlotCurve->setSamples( m_curveData->xPlotValues().data(),
m_curveData->measuredDepthPlotValues( displayUnit ).data(),
static_cast<int>( m_curveData->xPlotValues().size() ) );
}
m_qwtPlotCurve->setLineSegmentStartStopIndices( m_curveData->polylineStartStopIndices() );
@@ -471,9 +494,11 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate(bool updateParentPlot)
//--------------------------------------------------------------------------------------------------
/// Search well path for LAS-files containing Well Bore Stability data and set them in the extractor.
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles(const RimWellPath* wellPath, RigGeoMechWellLogExtractor* geomExtractor)
void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles( const RimWellPath* wellPath,
RigGeoMechWellLogExtractor* geomExtractor )
{
std::vector<std::pair<double, double>> logFileMudWeights = RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "PP");
std::vector<std::pair<double, double>> logFileMudWeights =
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "PP" );
if ( !logFileMudWeights.empty() )
{
// Log file pressures come in SG units (g / cm^3).
@@ -485,7 +510,8 @@ void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles(const RimWe
geomExtractor->setWellLogMdAndMudWeightKgPerM3( logFileMudWeights );
}
std::vector<std::pair<double, double>> logFileUcs = RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "UCS");
std::vector<std::pair<double, double>> logFileUcs = RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath,
"UCS" );
if ( !logFileUcs.empty() )
{
// TODO: UCS is typically in MPa, but not necessarily.
@@ -498,7 +524,8 @@ void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles(const RimWe
geomExtractor->setWellLogMdAndUcsBar( logFileUcs );
}
std::vector<std::pair<double, double>> logFilePoissonRatio = RimWellLogFile::findMdAndChannelValuesForWellPath(wellPath, "POISSON_RATIO");
std::vector<std::pair<double, double>> logFilePoissonRatio =
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "POISSON_RATIO" );
if ( !logFilePoissonRatio.empty() )
{
geomExtractor->setWellLogMdAndPoissonRatio( logFilePoissonRatio );
@@ -545,7 +572,9 @@ void RimWellLogExtractionCurve::clearGeneratedSimWellPaths()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimWellLogExtractionCurve::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
QList<caf::PdmOptionItemInfo>
RimWellLogExtractionCurve::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
@@ -634,17 +663,14 @@ void RimWellLogExtractionCurve::defineUiOrdering(QString uiConfigName, caf::PdmU
m_branchIndex );
}
m_eclipseResultDefinition->uiOrdering( uiConfigName, *curveDataGroup );
}
else if ( geomCase )
{
curveDataGroup->add( &m_wellPath );
m_geomResultDefinition->uiOrdering( uiConfigName, *curveDataGroup );
}
if ( (eclipseCase && m_eclipseResultDefinition->hasDynamicResult())
|| geomCase)
if ( ( eclipseCase && m_eclipseResultDefinition->hasDynamicResult() ) || geomCase )
{
curveDataGroup->add( &m_timeStep );
}
@@ -666,7 +692,6 @@ void RimWellLogExtractionCurve::defineUiOrdering(QString uiConfigName, caf::PdmU
nameGroup->add( &m_addTimestepToCurveName );
}
uiOrdering.skipRemainingFields( true );
}
@@ -687,7 +712,8 @@ void RimWellLogExtractionCurve::initAfterRead()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/)
void RimWellLogExtractionCurve::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering,
QString uiConfigName /*= ""*/ )
{
uiTreeOrdering.skipRemainingChildren( true );
}
@@ -728,7 +754,8 @@ QString RimWellLogExtractionCurve::createCurveAutoName()
if ( !wellName().isEmpty() )
{
generatedCurveName += wellName();
if (m_trajectoryType == SIMULATION_WELL && RiaSimWellBranchTools::simulationWellBranches(m_simWellName, m_branchDetection).size() > 1)
if ( m_trajectoryType == SIMULATION_WELL &&
RiaSimWellBranchTools::simulationWellBranches( m_simWellName, m_branchDetection ).size() > 1 )
{
generatedCurveName.push_back( " Br" + QString::number( m_branchIndex + 1 ) );
}
@@ -753,7 +780,9 @@ QString RimWellLogExtractionCurve::createCurveAutoName()
{
if ( eclipseCase->eclipseCaseData() )
{
maxTimeStep = eclipseCase->eclipseCaseData()->results(m_eclipseResultDefinition->porosityModel())->maxTimeStepCount();
maxTimeStep = eclipseCase->eclipseCaseData()
->results( m_eclipseResultDefinition->porosityModel() )
->maxTimeStepCount();
}
}
else if ( geomCase )

View File

@@ -24,12 +24,12 @@
#include "RiaDefines.h"
#include "RiaWeightedMeanCalculator.h"
#include "RigFemTypes.h"
#include "RigGeoMechBoreHoleStressCalculator.h"
#include "RigFemPart.h"
#include "RigFemPartCollection.h"
#include "RigGeoMechCaseData.h"
#include "RigFemPartResultsCollection.h"
#include "RigFemTypes.h"
#include "RigGeoMechBoreHoleStressCalculator.h"
#include "RigGeoMechCaseData.h"
#include "RigWellLogExtractionTools.h"
#include "RigWellPath.h"
@@ -64,7 +64,8 @@ void RigGeoMechWellLogExtractor::curveData(const RigFemResultAddress& resAddr, i
if ( resAddr.resultPosType == RIG_WELLPATH_DERIVED )
{
if (resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() || resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString())
if ( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() )
{
wellBoreWallCurveData( resAddr, frameIndex, values );
return;
@@ -79,7 +80,6 @@ void RigGeoMechWellLogExtractor::curveData(const RigFemResultAddress& resAddr, i
wellPathAngles( resAddr, values );
return;
}
}
if ( !resAddr.isValid() ) return;
@@ -101,25 +101,36 @@ void RigGeoMechWellLogExtractor::curveData(const RigFemResultAddress& resAddr, i
for ( size_t intersectionIdx = 0; intersectionIdx < m_intersections.size(); ++intersectionIdx )
{
(*values)[intersectionIdx] = static_cast<double>(interpolateGridResultValue<float>(convResAddr.resultPosType, resultValues, intersectionIdx, false));
( *values )[intersectionIdx] = static_cast<double>(
interpolateGridResultValue<float>( convResAddr.resultPosType, resultValues, intersectionIdx, false ) );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RigGeoMechWellLogExtractor::calculatePorePressureInSegment(int64_t intersectionIdx, float averageSegmentPorePressureBar, double hydroStaticPorePressureBar, double effectiveDepthMeters, const std::vector<float>& poreElementPressuresPascal) const
float RigGeoMechWellLogExtractor::calculatePorePressureInSegment( int64_t intersectionIdx,
float averageSegmentPorePressureBar,
double hydroStaticPorePressureBar,
double effectiveDepthMeters,
const std::vector<float>& poreElementPressuresPascal ) const
{
// Priority 4: Assign a default of hydrostatic pore pressure
double porePressure = hydroStaticPorePressureBar;
// 1: Try pore pressure from the grid
if (porePressure == hydroStaticPorePressureBar && averageSegmentPorePressureBar != std::numeric_limits<double>::infinity() && averageSegmentPorePressureBar > 0.0)
// Priority 3: Try element property tables
if ( m_porePressureSource == AUTO || m_porePressureSource == ELEMENT_PROPERTY_TABLE )
{
porePressure = averageSegmentPorePressureBar;
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
if ( elmIdx < poreElementPressuresPascal.size() )
{
// Pore pressure from element property tables are in pascal.
porePressure = pascalToBar( poreElementPressuresPascal[elmIdx] );
}
}
// 2: Try mud weight from LAS-file to generate pore pressure
if (porePressure == hydroStaticPorePressureBar && !m_wellLogMdAndMudWeightKgPerM3.empty())
// Priority 2: Try LAS-file
if ( m_porePressureSource == AUTO || m_porePressureSource == LAS_FILE )
{
double lasMudWeightKgPerM3 = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndMudWeightKgPerM3 );
if ( lasMudWeightKgPerM3 != std::numeric_limits<double>::infinity() )
@@ -129,14 +140,16 @@ float RigGeoMechWellLogExtractor::calculatePorePressureInSegment(int64_t interse
porePressure = pascalToBar( porePressurePascal );
}
}
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
// 3: Try pore pressure from element property tables
if (porePressure == hydroStaticPorePressureBar && elmIdx < poreElementPressuresPascal.size())
// Priority 1: Try pore pressure from the grid
if ( m_porePressureSource == AUTO || m_porePressureSource == GRID )
{
// Pore pressure from element property tables are in pascal.
porePressure = pascalToBar(poreElementPressuresPascal[elmIdx]);
if ( averageSegmentPorePressureBar != std::numeric_limits<double>::infinity() &&
averageSegmentPorePressureBar > 0.0 )
{
porePressure = averageSegmentPorePressureBar;
}
}
// 4: If no pore-pressure was found, the default value of hydrostatic pore pressure is used.
CVF_ASSERT( porePressure >= 0.0 );
return porePressure;
@@ -145,12 +158,25 @@ float RigGeoMechWellLogExtractor::calculatePorePressureInSegment(int64_t interse
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RigGeoMechWellLogExtractor::calculatePoissonRatio(int64_t intersectionIdx, const std::vector<float>& poissonRatios) const
float RigGeoMechWellLogExtractor::calculatePoissonRatio( int64_t intersectionIdx,
const std::vector<float>& poissonRatios ) const
{
const double defaultPoissonRatio = 0.25;
// Priority 3: User defined poisson ratio
double poissonRatio = m_userDefinedPoissonRatio;
double poissonRatio = defaultPoissonRatio;
// Priority 2: Element property table ratio
if ( m_poissonRatioSource == AUTO || m_poissonRatioSource == ELEMENT_PROPERTY_TABLE )
{
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
if ( elmIdx < poissonRatios.size() )
{
poissonRatio = poissonRatios[elmIdx];
}
}
// Priority 1: Las-file poisson ratio
if ( m_poissonRatioSource == AUTO || m_poissonRatioSource == LAS_FILE )
{
if ( !m_wellLogMdAndPoissonRatios.empty() )
{
double lasPoissionRatio = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndPoissonRatios );
@@ -159,26 +185,32 @@ float RigGeoMechWellLogExtractor::calculatePoissonRatio(int64_t intersectionIdx,
poissonRatio = lasPoissionRatio;
}
}
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
if (poissonRatio == defaultPoissonRatio && elmIdx < poissonRatios.size())
{
poissonRatio = poissonRatios[elmIdx];
}
return poissonRatio;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RigGeoMechWellLogExtractor::calculateUcs( int64_t intersectionIdx, const std::vector<float>& ucsValuesPascal ) const
{
// Typical UCS: http://ceae.colorado.edu/~amadei/CVEN5768/PDF/NOTES8.pdf
// Typical UCS for Shale is 5 - 100 MPa -> 50 - 1000 bar.
const double defaultUniaxialStrengthInBar = 100.0;
// Priority 3: User defined UCS
double uniaxialStrengthInBar = m_userDefinedUcs;
double uniaxialStrengthInBar = defaultUniaxialStrengthInBar;
// Priority 2: From element property table
if ( m_ucsSource == AUTO || m_ucsSource == ELEMENT_PROPERTY_TABLE )
{
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
if ( elmIdx < ucsValuesPascal.size() )
{
// Read UCS from element table in Pascal
uniaxialStrengthInBar = pascalToBar( ucsValuesPascal[elmIdx] );
}
}
if ( m_ucsSource == AUTO || m_ucsSource == LAS_FILE )
{
if ( !m_wellLogMdAndUcsBar.empty() )
{
double lasUniaxialStrengthInBar = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndUcsBar );
@@ -187,17 +219,11 @@ float RigGeoMechWellLogExtractor::calculateUcs(int64_t intersectionIdx, const st
uniaxialStrengthInBar = lasUniaxialStrengthInBar;
}
}
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
if (uniaxialStrengthInBar == defaultUniaxialStrengthInBar && elmIdx < ucsValuesPascal.size())
{
// Read UCS from element table in Pascal
uniaxialStrengthInBar = pascalToBar(ucsValuesPascal[elmIdx]);
}
return uniaxialStrengthInBar;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -214,7 +240,8 @@ void RigGeoMechWellLogExtractor::wellPathAngles(const RigFemResultAddress& resAd
cvf::Vec3d wellPathTangent = calculateWellPathTangent( intersectionIdx, TangentFollowWellPathSegments );
// Deviation from vertical. Since well path is tending downwards we compare with negative z.
double inclination = cvf::Math::toDegrees(std::acos(cvf::Vec3d(0.0, 0.0, -1.0) * wellPathTangent.getNormalized()));
double inclination = cvf::Math::toDegrees(
std::acos( cvf::Vec3d( 0.0, 0.0, -1.0 ) * wellPathTangent.getNormalized() ) );
if ( resAddr.fieldName == "Azimuth" )
{
@@ -252,7 +279,9 @@ void RigGeoMechWellLogExtractor::wellPathAngles(const RigFemResultAddress& resAd
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigGeoMechWellLogExtractor::wellPathScaledCurveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values)
void RigGeoMechWellLogExtractor::wellPathScaledCurveData( const RigFemResultAddress& resAddr,
int frameIndex,
std::vector<double>* values )
{
CVF_ASSERT( values );
@@ -292,7 +321,10 @@ void RigGeoMechWellLogExtractor::wellPathScaledCurveData(const RigFemResultAddre
RigElementType elmType = femPart->elementType( elmIdx );
if ( !( elmType == HEX8 || elmType == HEX8P ) ) continue;
interpolatedInterfaceValues[intersectionIdx] = interpolateGridResultValue<float>(nativeAddr.resultPosType, unscaledResultValues, intersectionIdx, false);
interpolatedInterfaceValues[intersectionIdx] = interpolateGridResultValue<float>( nativeAddr.resultPosType,
unscaledResultValues,
intersectionIdx,
false );
}
values->resize( m_intersections.size(), 0.0f );
@@ -316,13 +348,19 @@ void RigGeoMechWellLogExtractor::wellPathScaledCurveData(const RigFemResultAddre
double hydroStaticPorePressureBar = pascalToBar( effectiveDepthMeters * UNIT_WEIGHT_OF_WATER );
float averageUnscaledValue = std::numeric_limits<float>::infinity();
bool validAverage = averageIntersectionValuesToSegmentValue(intersectionIdx, interpolatedInterfaceValues, std::numeric_limits<float>::infinity(), &averageUnscaledValue);
bool validAverage = averageIntersectionValuesToSegmentValue( intersectionIdx,
interpolatedInterfaceValues,
std::numeric_limits<float>::infinity(),
&averageUnscaledValue );
if ( resAddr.fieldName == "PP" && validAverage )
{
double segmentPorePressureFromGrid = averageUnscaledValue;
averageUnscaledValue = calculatePorePressureInSegment(intersectionIdx, segmentPorePressureFromGrid, hydroStaticPorePressureBar, effectiveDepthMeters, poreElementPressuresPascal);
averageUnscaledValue = calculatePorePressureInSegment( intersectionIdx,
segmentPorePressureFromGrid,
hydroStaticPorePressureBar,
effectiveDepthMeters,
poreElementPressuresPascal );
}
( *values )[intersectionIdx] = static_cast<double>( averageUnscaledValue ) / hydroStaticPorePressureBar;
@@ -332,10 +370,13 @@ void RigGeoMechWellLogExtractor::wellPathScaledCurveData(const RigFemResultAddre
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigGeoMechWellLogExtractor::wellBoreWallCurveData(const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values)
void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddress& resAddr,
int frameIndex,
std::vector<double>* values )
{
CVF_ASSERT( values );
CVF_ASSERT(resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() || resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString());
CVF_ASSERT( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() ||
resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() );
// The result addresses needed
RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, "ST", "" );
@@ -352,7 +393,8 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData(const RigFemResultAddress
std::vector<caf::Ten3f> vertexStressesFloat = resultCollection->tensors( stressResAddr, 0, frameIndex );
if ( !vertexStressesFloat.size() ) return;
std::vector<caf::Ten3d> vertexStresses; vertexStresses.reserve(vertexStressesFloat.size());
std::vector<caf::Ten3d> vertexStresses;
vertexStresses.reserve( vertexStressesFloat.size() );
for ( const caf::Ten3f& floatTensor : vertexStressesFloat )
{
vertexStresses.push_back( caf::Ten3d( floatTensor ) );
@@ -374,8 +416,14 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData(const RigFemResultAddress
RigElementType elmType = femPart->elementType( elmIdx );
if ( !( elmType == HEX8 || elmType == HEX8P ) ) continue;
interpolatedInterfacePorePressureBar[intersectionIdx] = interpolateGridResultValue(porBarResAddr.resultPosType, porePressures, intersectionIdx, false);
interpolatedInterfaceStressBar[intersectionIdx] = interpolateGridResultValue(stressResAddr.resultPosType, vertexStresses, intersectionIdx, false);
interpolatedInterfacePorePressureBar[intersectionIdx] = interpolateGridResultValue( porBarResAddr.resultPosType,
porePressures,
intersectionIdx,
false );
interpolatedInterfaceStressBar[intersectionIdx] = interpolateGridResultValue( stressResAddr.resultPosType,
vertexStresses,
intersectionIdx,
false );
}
values->resize( m_intersections.size(), 0.0f );
@@ -395,15 +443,25 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData(const RigFemResultAddress
double hydroStaticPorePressureBar = pascalToBar( effectiveDepthMeters * UNIT_WEIGHT_OF_WATER );
float averagePorePressureBar = std::numeric_limits<float>::infinity();
bool validGridPorePressure = averageIntersectionValuesToSegmentValue(intersectionIdx, interpolatedInterfacePorePressureBar, std::numeric_limits<float>::infinity(), &averagePorePressureBar);
bool validGridPorePressure = averageIntersectionValuesToSegmentValue( intersectionIdx,
interpolatedInterfacePorePressureBar,
std::numeric_limits<float>::infinity(),
&averagePorePressureBar );
bool isFGregion = validGridPorePressure; // FG is for sands, SFG for shale. Sands has PP, shale does not.
double porePressureBar = calculatePorePressureInSegment(intersectionIdx, averagePorePressureBar, hydroStaticPorePressureBar, effectiveDepthMeters, poreElementPressuresPascal);
double porePressureBar = calculatePorePressureInSegment( intersectionIdx,
averagePorePressureBar,
hydroStaticPorePressureBar,
effectiveDepthMeters,
poreElementPressuresPascal );
double poissonRatio = calculatePoissonRatio( intersectionIdx, poissonRatios );
double ucsBar = calculateUcs( intersectionIdx, ucsValuesPascal );
caf::Ten3d segmentStress;
bool validSegmentStress = averageIntersectionValuesToSegmentValue(intersectionIdx, interpolatedInterfaceStressBar, caf::Ten3d::invalid(), &segmentStress);
bool validSegmentStress = averageIntersectionValuesToSegmentValue( intersectionIdx,
interpolatedInterfaceStressBar,
caf::Ten3d::invalid(),
&segmentStress );
cvf::Vec3d wellPathTangent = calculateWellPathTangent( intersectionIdx, TangentConstantWithinCell );
caf::Ten3d wellPathStressFloat = transformTensorToWellPathOrientation( wellPathTangent, segmentStress );
@@ -477,6 +535,46 @@ void RigGeoMechWellLogExtractor::setWellLogMdAndPoissonRatio(const std::vector<s
m_wellLogMdAndPoissonRatios = poissonRatios;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RigGeoMechWellLogExtractor::supportedSourcesForPorePressure()
{
return {AUTO, GRID, LAS_FILE, ELEMENT_PROPERTY_TABLE, HYDROSTATIC_PP};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RigGeoMechWellLogExtractor::supportedSourcesForPoissonRatio()
{
return {AUTO, LAS_FILE, ELEMENT_PROPERTY_TABLE, USER_DEFINED};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RigGeoMechWellLogExtractor::supportedSourcesForUcs()
{
return {AUTO, LAS_FILE, ELEMENT_PROPERTY_TABLE, USER_DEFINED};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigGeoMechWellLogExtractor::setWbsParameters( WbsParameterSource porePressureSource,
WbsParameterSource poissonRatioSource,
WbsParameterSource ucsSource,
double userDefinedPoissonRatio,
double userDefinedUcs )
{
m_porePressureSource = porePressureSource;
m_poissonRatioSource = poissonRatioSource;
m_ucsSource = ucsSource;
m_userDefinedPoissonRatio = userDefinedPoissonRatio;
m_userDefinedUcs = userDefinedUcs;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -514,7 +612,9 @@ T RigGeoMechWellLogExtractor::interpolateGridResultValue(RigFemResultPosEnum r
}
// TODO: Should interpolate within the whole hexahedron. This requires converting to locals coordinates.
// For now just pick the average value for the cell.
size_t gridResultValueIdx = femPart->resultValueIdxFromResultPosType(resultPosType, static_cast<int>(elmIdx), 0);
size_t gridResultValueIdx = femPart->resultValueIdxFromResultPosType( resultPosType,
static_cast<int>( elmIdx ),
0 );
T sumOfVertexValues = gridResultValues[gridResultValueIdx];
for ( int i = 1; i < 8; ++i )
{
@@ -543,7 +643,9 @@ T RigGeoMechWellLogExtractor::interpolateGridResultValue(RigFemResultPosEnum r
}
else
{
nodeResIdx[i] = femPart->resultValueIdxFromResultPosType(resultPosType, static_cast<int>(elmIdx), elementLocalIndicesForFace[i]);
nodeResIdx[i] = femPart->resultValueIdxFromResultPosType( resultPosType,
static_cast<int>( elmIdx ),
elementLocalIndicesForFace[i] );
}
}
@@ -557,31 +659,39 @@ T RigGeoMechWellLogExtractor::interpolateGridResultValue(RigFemResultPosEnum r
int nodeIndex = femPart->nodeIdxFromElementNodeResultIdx( nodeResIdx[i] );
const std::vector<int>& elements = femPart->elementsUsingNode( nodeIndex );
const std::vector<unsigned char>& localIndices = femPart->elementLocalIndicesForNode( nodeIndex );
size_t otherGridResultValueIdx = femPart->resultValueIdxFromResultPosType(resultPosType, elements[0], static_cast<int>(localIndices[0]));
size_t otherGridResultValueIdx = femPart->resultValueIdxFromResultPosType( resultPosType,
elements[0],
static_cast<int>(
localIndices[0] ) );
T nodeResultValue = gridResultValues[otherGridResultValueIdx];
for ( size_t j = 1; j < elements.size(); ++j )
{
otherGridResultValueIdx = femPart->resultValueIdxFromResultPosType(resultPosType, elements[j], static_cast<int>(localIndices[j]));
otherGridResultValueIdx = femPart->resultValueIdxFromResultPosType( resultPosType,
elements[j],
static_cast<int>( localIndices[j] ) );
nodeResultValue = nodeResultValue + gridResultValues[otherGridResultValueIdx];
}
nodeResultValue = nodeResultValue * ( 1.0 / elements.size() );
nodeResultValues.push_back( nodeResultValue );
}
}
else {
else
{
for ( size_t i = 0; i < nodeResIdx.size(); ++i )
{
nodeResultValues.push_back( gridResultValues[nodeResIdx[i]] );
}
}
T interpolatedValue = cvf::GeometryTools::interpolateQuad<T>(
v0, nodeResultValues[0],
v1, nodeResultValues[1],
v2, nodeResultValues[2],
v3, nodeResultValues[3],
m_intersections[intersectionIdx]
);
T interpolatedValue = cvf::GeometryTools::interpolateQuad<T>( v0,
nodeResultValues[0],
v1,
nodeResultValues[1],
v2,
nodeResultValues[2],
v3,
nodeResultValues[3],
m_intersections[intersectionIdx] );
return interpolatedValue;
}
@@ -589,7 +699,9 @@ T RigGeoMechWellLogExtractor::interpolateGridResultValue(RigFemResultPosEnum r
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RigGeoMechWellLogExtractor::gridResultIndexFace(size_t elementIdx, cvf::StructGridInterface::FaceType cellFace, int faceLocalNodeIdx) const
size_t RigGeoMechWellLogExtractor::gridResultIndexFace( size_t elementIdx,
cvf::StructGridInterface::FaceType cellFace,
int faceLocalNodeIdx ) const
{
CVF_ASSERT( cellFace != cvf::StructGridInterface::NO_FACE && faceLocalNodeIdx < 4 );
return elementIdx * 24 + static_cast<int>( cellFace ) * 4 + faceLocalNodeIdx;
@@ -650,9 +762,7 @@ void RigGeoMechWellLogExtractor::calculateIntersection()
double md1 = m_wellPath->m_measuredDepths[wpp];
double md2 = m_wellPath->m_measuredDepths[wpp + 1];
insertIntersectionsInMap(intersections,
p1, md1, p2, md2,
&uniqueIntersections);
insertIntersectionsInMap( intersections, p1, md1, p2, md2, &uniqueIntersections );
}
this->populateReturnArrays( uniqueIntersections );
@@ -675,7 +785,9 @@ std::vector<size_t> RigGeoMechWellLogExtractor::findCloseCells(const cvf::Boundi
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec3d RigGeoMechWellLogExtractor::calculateLengthInCell(size_t cellIndex, const cvf::Vec3d& startPoint, const cvf::Vec3d& endPoint) const
cvf::Vec3d RigGeoMechWellLogExtractor::calculateLengthInCell( size_t cellIndex,
const cvf::Vec3d& startPoint,
const cvf::Vec3d& endPoint ) const
{
std::array<cvf::Vec3d, 8> hexCorners;
@@ -764,7 +876,10 @@ cvf::Vec3f RigGeoMechWellLogExtractor::cellCentroid(size_t intersectionIdx) cons
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigGeoMechWellLogExtractor::getWellLogSegmentValue(size_t intersectionIdx, const std::vector<std::pair<double, double>>& wellLogValues) const
double RigGeoMechWellLogExtractor::getWellLogSegmentValue( size_t intersectionIdx,
const std::vector<std::pair<double, double>>& wellLogValues ) const
{
if ( !wellLogValues.empty() )
{
double startMD, endMD;
if ( intersectionIdx % 2 == 0 )
@@ -798,7 +913,7 @@ double RigGeoMechWellLogExtractor::getWellLogSegmentValue(size_t intersectionIdx
{
return averageCalc.weightedMean();
}
}
return std::numeric_limits<double>::infinity();
}
@@ -814,7 +929,10 @@ double RigGeoMechWellLogExtractor::pascalToBar(double pascalValue)
///
//--------------------------------------------------------------------------------------------------
template <typename T>
bool RigGeoMechWellLogExtractor::averageIntersectionValuesToSegmentValue(size_t intersectionIdx, const std::vector<T>& values, const T& invalidValue, T* averagedCellValue) const
bool RigGeoMechWellLogExtractor::averageIntersectionValuesToSegmentValue( size_t intersectionIdx,
const std::vector<T>& values,
const T& invalidValue,
T* averagedCellValue ) const
{
CVF_ASSERT( values.size() >= 2 );
@@ -831,7 +949,8 @@ bool RigGeoMechWellLogExtractor::averageIntersectionValuesToSegmentValue(size_t
dist1 = ( centroid - m_intersections[intersectionIdx] ).length();
dist2 = ( centroid - m_intersections[intersectionIdx + 1] ).length();
}
else {
else
{
value1 = values[intersectionIdx - 1];
value2 = values[intersectionIdx];

View File

@@ -26,8 +26,8 @@
#include "cafTensor3.h"
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfMath.h"
#include "cvfObject.h"
#include "cvfStructGrid.h"
#include "cvfVector3.h"
@@ -38,7 +38,8 @@ class RigFemResultAddress;
class RigGeoMechCaseData;
class RigWellPath;
namespace cvf {
namespace cvf
{
class BoundingBox;
}
@@ -48,7 +49,20 @@ namespace cvf {
class RigGeoMechWellLogExtractor : public RigWellLogExtractor
{
public:
RigGeoMechWellLogExtractor(RigGeoMechCaseData* aCase, const RigWellPath* wellpath, const std::string& wellCaseErrorMsgName);
enum WbsParameterSource
{
AUTO,
GRID, // Only relevant for Pore Pressure
LAS_FILE,
ELEMENT_PROPERTY_TABLE,
USER_DEFINED, // Not relevant for Pore Pressure
HYDROSTATIC_PP // Only relevant for Pore Pressure
};
public:
RigGeoMechWellLogExtractor( RigGeoMechCaseData* aCase,
const RigWellPath* wellpath,
const std::string& wellCaseErrorMsgName );
void curveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
const RigGeoMechCaseData* caseData();
@@ -58,6 +72,15 @@ public:
void setWellLogMdAndUcsBar( const std::vector<std::pair<double, double>>& ucsValues );
void setWellLogMdAndPoissonRatio( const std::vector<std::pair<double, double>>& poissonRatio );
static std::set<WbsParameterSource> supportedSourcesForPorePressure();
static std::set<WbsParameterSource> supportedSourcesForPoissonRatio();
static std::set<WbsParameterSource> supportedSourcesForUcs();
void setWbsParameters( WbsParameterSource porePressureSource,
WbsParameterSource poissonRatioSource,
WbsParameterSource ucsSource,
double userDefinedPoissonRatio,
double userDefinedUcs );
private:
enum WellPathTangentCalculation
@@ -66,18 +89,25 @@ private:
TangentConstantWithinCell
};
float calculatePorePressureInSegment(int64_t intersectionIdx, float averageSegmentPorePressureBar, double hydroStaticPorePressureBar, double effectiveDepthMeters, const std::vector<float>& poreElementPressuresPascal) const;
float calculatePorePressureInSegment( int64_t intersectionIdx,
float averageSegmentPorePressureBar,
double hydroStaticPorePressureBar,
double effectiveDepthMeters,
const std::vector<float>& poreElementPressuresPascal ) const;
float calculatePoissonRatio( int64_t intersectionIdx, const std::vector<float>& poissonRatios ) const;
float calculateUcs( int64_t intersectionIdx, const std::vector<float>& ucsValuesPascal ) const;
void wellPathAngles( const RigFemResultAddress& resAddr, std::vector<double>* values );
void wellPathScaledCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
void wellBoreWallCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
template <typename T>
T interpolateGridResultValue(RigFemResultPosEnum resultPosType, const std::vector<T>& gridResultValues, int64_t intersectionIdx, bool averageNodeElementResults) const;
T interpolateGridResultValue( RigFemResultPosEnum resultPosType,
const std::vector<T>& gridResultValues,
int64_t intersectionIdx,
bool averageNodeElementResults ) const;
size_t gridResultIndexFace( size_t elementIdx, cvf::StructGridInterface::FaceType cellFace, int faceLocalNodeIdx ) const;
void calculateIntersection();
std::vector<size_t> findCloseCells( const cvf::BoundingBox& bb );
@@ -89,11 +119,16 @@ private:
const caf::Ten3d& wellPathTensor );
cvf::Vec3f cellCentroid( size_t intersectionIdx ) const;
double getWellLogSegmentValue(size_t intersectionIdx, const std::vector<std::pair<double, double>>& wellLogValues) const;
double getWellLogSegmentValue( size_t intersectionIdx,
const std::vector<std::pair<double, double>>& wellLogValues ) const;
template <typename T>
bool averageIntersectionValuesToSegmentValue(size_t intersectionIdx, const std::vector<T>& intersectionValues, const T& invalidValue, T* averagedSegmentValue) const;
bool averageIntersectionValuesToSegmentValue( size_t intersectionIdx,
const std::vector<T>& intersectionValues,
const T& invalidValue,
T* averagedSegmentValue ) const;
static double pascalToBar( double pascalValue );
private:
cvf::ref<RigGeoMechCaseData> m_caseData;
double m_rkbDiff;
@@ -101,6 +136,11 @@ private:
std::vector<std::pair<double, double>> m_wellLogMdAndUcsBar;
std::vector<std::pair<double, double>> m_wellLogMdAndPoissonRatios;
WbsParameterSource m_porePressureSource;
WbsParameterSource m_poissonRatioSource;
WbsParameterSource m_ucsSource;
double m_userDefinedPoissonRatio;
double m_userDefinedUcs;
static const double UNIT_WEIGHT_OF_WATER;
};