mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#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:
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
};
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
238
ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp
Normal file
238
ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.cpp
Normal 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();
|
||||
}
|
||||
}
|
||||
67
ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.h
Normal file
67
ApplicationCode/ProjectDataModel/RimWellBoreStabilityPlot.h
Normal 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;
|
||||
};
|
||||
@@ -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 )
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user