mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Add additional WBS curves and rewrite parameters
This commit is contained in:
parent
4f4c48635b
commit
431f0ff347
@ -410,7 +410,7 @@ QString RiaDefines::activeFormationNamesResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsAzimuthResultName()
|
||||
QString RiaDefines::wbsAzimuthResult()
|
||||
{
|
||||
return "Azimuth";
|
||||
}
|
||||
@ -418,7 +418,7 @@ QString RiaDefines::wbsAzimuthResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsInclinationResultName()
|
||||
QString RiaDefines::wbsInclinationResult()
|
||||
{
|
||||
return "Inclination";
|
||||
}
|
||||
@ -426,7 +426,7 @@ QString RiaDefines::wbsInclinationResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsPPResultName()
|
||||
QString RiaDefines::wbsPPResult()
|
||||
{
|
||||
return "PP";
|
||||
}
|
||||
@ -434,7 +434,7 @@ QString RiaDefines::wbsPPResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsSHResultName()
|
||||
QString RiaDefines::wbsSHResult()
|
||||
{
|
||||
return "SH";
|
||||
}
|
||||
@ -442,7 +442,15 @@ QString RiaDefines::wbsSHResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsOBGResultName()
|
||||
QString RiaDefines::wbsSHMkResult()
|
||||
{
|
||||
return "SH_MK";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsOBGResult()
|
||||
{
|
||||
return "OBG";
|
||||
}
|
||||
@ -450,7 +458,7 @@ QString RiaDefines::wbsOBGResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsFGResultName()
|
||||
QString RiaDefines::wbsFGResult()
|
||||
{
|
||||
return "FG";
|
||||
}
|
||||
@ -458,7 +466,7 @@ QString RiaDefines::wbsFGResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsSFGResultName()
|
||||
QString RiaDefines::wbsSFGResult()
|
||||
{
|
||||
return "SFG";
|
||||
}
|
||||
@ -466,41 +474,24 @@ QString RiaDefines::wbsSFGResultName()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsPoissonParameterName()
|
||||
std::vector<QString> RiaDefines::wbsAngleResultNames()
|
||||
{
|
||||
return "RATIO";
|
||||
return {wbsAzimuthResult(), wbsInclinationResult()};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RiaDefines::wbsUCSParameterName()
|
||||
std::vector<QString> RiaDefines::wbsDerivedResultNames()
|
||||
{
|
||||
return "UCS";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> RiaDefines::wellPathAngleResultNames()
|
||||
{
|
||||
return {wbsAzimuthResultName(), wbsInclinationResultName()};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> RiaDefines::wellPathStabilityResultNames()
|
||||
{
|
||||
return {wbsFGResultName(), wbsOBGResultName(), wbsPPResultName(), wbsSFGResultName(), wbsSHResultName()};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> RiaDefines::wellPathStabilityParameterNames()
|
||||
{
|
||||
return {wbsPoissonParameterName(), wbsUCSParameterName()};
|
||||
return {
|
||||
wbsFGResult(),
|
||||
wbsOBGResult(),
|
||||
wbsPPResult(),
|
||||
wbsSFGResult(),
|
||||
wbsSHResult(),
|
||||
wbsSHMkResult(),
|
||||
};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -114,20 +114,18 @@ QString mockModelBasicInputCase();
|
||||
QString activeFormationNamesResultName();
|
||||
|
||||
// Well path derived results
|
||||
QString wbsAzimuthResultName();
|
||||
QString wbsInclinationResultName();
|
||||
QString wbsPPResultName();
|
||||
QString wbsSHResultName();
|
||||
QString wbsOBGResultName();
|
||||
QString wbsFGResultName();
|
||||
QString wbsSFGResultName();
|
||||
QString wbsPoissonParameterName();
|
||||
QString wbsUCSParameterName();
|
||||
QString wbsAzimuthResult();
|
||||
QString wbsInclinationResult();
|
||||
QString wbsPPResult();
|
||||
QString wbsSHResult();
|
||||
QString wbsSHMkResult();
|
||||
QString wbsOBGResult();
|
||||
QString wbsFGResult();
|
||||
QString wbsSFGResult();
|
||||
|
||||
// List of well path derived results
|
||||
std::vector<QString> wellPathAngleResultNames();
|
||||
std::vector<QString> wellPathStabilityResultNames();
|
||||
std::vector<QString> wellPathStabilityParameterNames();
|
||||
std::vector<QString> wbsAngleResultNames();
|
||||
std::vector<QString> wbsDerivedResultNames();
|
||||
|
||||
// Units and conversions
|
||||
enum DepthUnitType
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include "RicNewWellBoreStabilityPlotFeature.h"
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
|
||||
#include "RicNewWellLogCurveExtractionFeature.h"
|
||||
#include "RicNewWellLogFileCurveFeature.h"
|
||||
#include "RicNewWellLogPlotFeatureImpl.h"
|
||||
@ -226,7 +228,8 @@ void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabi
|
||||
RimWellLogTrack* paramCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false,
|
||||
"WBS Parameters",
|
||||
plot );
|
||||
paramCurvesTrack->setColSpan( RimPlot::TWO );
|
||||
paramCurvesTrack->setColSpan( RimPlot::THREE );
|
||||
paramCurvesTrack->setVisibleXRange( 0.0, 1.0 );
|
||||
paramCurvesTrack->setAutoScaleXEnabled( true );
|
||||
paramCurvesTrack->setTickIntervals( 0.5, 0.05 );
|
||||
paramCurvesTrack->setXAxisGridVisibility( RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR );
|
||||
@ -235,13 +238,18 @@ void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabi
|
||||
paramCurvesTrack->setAnnotationType( RiuPlotAnnotationTool::CURVE_ANNOTATIONS );
|
||||
paramCurvesTrack->setShowRegionLabels( true );
|
||||
paramCurvesTrack->setShowWindow( false );
|
||||
std::vector<QString> resultNames = RiaDefines::wellPathStabilityParameterNames();
|
||||
std::set<RigWbsParameter> parameters = RigWbsParameter::allParameters();
|
||||
|
||||
std::vector<cvf::Color3f> colors = {cvf::Color3f::CRIMSON, cvf::Color3f::DARK_YELLOW};
|
||||
caf::ColorTable colors = RiaColorTables::contrastCategoryPaletteColors();
|
||||
std::vector<RiuQwtPlotCurve::LineStyleEnum> lineStyles = {RiuQwtPlotCurve::STYLE_SOLID,
|
||||
RiuQwtPlotCurve::STYLE_DASH,
|
||||
RiuQwtPlotCurve::STYLE_DASH_DOT};
|
||||
|
||||
for ( size_t i = 0; i < resultNames.size(); ++i )
|
||||
size_t i = 0;
|
||||
for ( const RigWbsParameter& param : parameters )
|
||||
{
|
||||
const QString& resultName = resultNames[i];
|
||||
const QString& resultName = param.addressString( RigWbsParameter::LAS_FILE );
|
||||
|
||||
RigFemResultAddress resAddr( RIG_WELLPATH_DERIVED, resultName.toStdString(), "" );
|
||||
RimWellLogExtractionCurve* curve = RicWellLogTools::addWellLogExtractionCurve( paramCurvesTrack,
|
||||
geoMechCase,
|
||||
@ -253,10 +261,12 @@ void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabi
|
||||
false );
|
||||
curve->setGeoMechResultAddress( resAddr );
|
||||
curve->setCurrentTimeStep( timeStep );
|
||||
curve->setColor( colors[i % colors.size()] );
|
||||
curve->setColor( colors.cycledColor3f( i ) );
|
||||
curve->setLineStyle( lineStyles[i % lineStyles.size()] );
|
||||
curve->setLineThickness( 2 );
|
||||
curve->loadDataAndUpdate( false );
|
||||
curve->setAutoNameComponents( false, true, false, false, false );
|
||||
curve->setCustomName( param.name() );
|
||||
i++;
|
||||
}
|
||||
paramCurvesTrack->setAutoScaleXEnabled( true );
|
||||
}
|
||||
@ -271,7 +281,9 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore
|
||||
{
|
||||
RimWellLogTrack* stabilityCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false,
|
||||
"Stability Curves",
|
||||
|
||||
plot );
|
||||
stabilityCurvesTrack->setVisibleXRange( 0.0, 2.5 );
|
||||
stabilityCurvesTrack->setColSpan( RimPlot::FIVE );
|
||||
stabilityCurvesTrack->setAutoScaleXEnabled( true );
|
||||
stabilityCurvesTrack->setTickIntervals( 0.5, 0.05 );
|
||||
@ -281,13 +293,17 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore
|
||||
stabilityCurvesTrack->setAnnotationType( RiuPlotAnnotationTool::NO_ANNOTATIONS );
|
||||
stabilityCurvesTrack->setShowRegionLabels( true );
|
||||
|
||||
std::vector<QString> resultNames = RiaDefines::wellPathStabilityResultNames();
|
||||
std::vector<QString> resultNames = RiaDefines::wbsDerivedResultNames();
|
||||
|
||||
std::vector<cvf::Color3f> colors = {cvf::Color3f::BLUE,
|
||||
cvf::Color3f::BROWN,
|
||||
cvf::Color3f::RED,
|
||||
cvf::Color3f::PURPLE,
|
||||
cvf::Color3f::DARK_GREEN};
|
||||
cvf::Color3f::DARK_GREEN,
|
||||
cvf::Color3f::OLIVE};
|
||||
|
||||
std::vector<RiuQwtPlotCurve::LineStyleEnum> lineStyles( resultNames.size(), RiuQwtPlotCurve::STYLE_SOLID );
|
||||
lineStyles.back() = RiuQwtPlotCurve::STYLE_DASH;
|
||||
|
||||
for ( size_t i = 0; i < resultNames.size(); ++i )
|
||||
{
|
||||
@ -299,6 +315,7 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore
|
||||
curve->setCurrentTimeStep( timeStep );
|
||||
curve->setAutoNameComponents( false, true, false, false, false );
|
||||
curve->setColor( colors[i % colors.size()] );
|
||||
curve->setLineStyle( lineStyles[i] );
|
||||
curve->setLineThickness( 2 );
|
||||
curve->loadDataAndUpdate( false );
|
||||
curve->setSmoothCurve( true );
|
||||
@ -320,7 +337,7 @@ void RicNewWellBoreStabilityPlotFeature::createAnglesTrack( RimWellBoreStability
|
||||
plot );
|
||||
double minValue = 360.0, maxValue = 0.0;
|
||||
const double angleIncrement = 90.0;
|
||||
std::vector<QString> resultNames = RiaDefines::wellPathAngleResultNames();
|
||||
std::vector<QString> resultNames = RiaDefines::wbsAngleResultNames();
|
||||
|
||||
std::vector<cvf::Color3f> colors = {cvf::Color3f::GREEN, cvf::Color3f::ORANGE};
|
||||
|
||||
|
@ -500,12 +500,12 @@ std::map<std::string, std::vector<std::string>>
|
||||
}
|
||||
else if ( resPos == RIG_WELLPATH_DERIVED )
|
||||
{
|
||||
std::vector<QString> angles = RiaDefines::wellPathAngleResultNames();
|
||||
std::vector<QString> angles = RiaDefines::wbsAngleResultNames();
|
||||
for ( QString angle : angles )
|
||||
{
|
||||
fieldCompNames[angle.toStdString()];
|
||||
}
|
||||
std::vector<QString> derivedResults = RiaDefines::wellPathStabilityResultNames();
|
||||
std::vector<QString> derivedResults = RiaDefines::wbsDerivedResultNames();
|
||||
for ( QString result : derivedResults )
|
||||
{
|
||||
fieldCompNames[result.toStdString()];
|
||||
|
@ -472,8 +472,8 @@ void RimGeoMechResultDefinition::loadResult()
|
||||
{
|
||||
if ( m_geomCase && m_geomCase->geoMechData() )
|
||||
{
|
||||
if ( this->resultAddress().fieldName == RiaDefines::wbsFGResultName().toStdString() ||
|
||||
this->resultAddress().fieldName == RiaDefines::wbsSFGResultName().toStdString() )
|
||||
if ( this->resultAddress().fieldName == RiaDefines::wbsFGResult().toStdString() ||
|
||||
this->resultAddress().fieldName == RiaDefines::wbsSFGResult().toStdString() )
|
||||
{
|
||||
RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, std::string( "ST" ), "" );
|
||||
RigFemResultAddress porBarResAddr( RIG_ELEMENT_NODAL, std::string( "POR-Bar" ), "" );
|
||||
|
@ -28,23 +28,9 @@
|
||||
|
||||
#include "cafPdmBase.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmUiComboBoxEditor.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" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -60,64 +46,147 @@ RimWellBoreStabilityPlot::RimWellBoreStabilityPlot()
|
||||
"",
|
||||
"Data source for Pore Pressure",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_porePressureShaleSource,
|
||||
"PorePressureShaleSource",
|
||||
"Shale Pore Pressure",
|
||||
"",
|
||||
"Data source for Pore Pressure in Shale",
|
||||
"" );
|
||||
|
||||
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_InitFieldNoDefault( &m_OBG0Source, "OBG0Source", "Initial Overburden Gradient", "", "Data source for OBG0", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_DFSource, "DFSource", "Depletion Factor (DF)", "", "Data source for Depletion Factor", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_K0SHSource,
|
||||
"K0SHSource",
|
||||
"K0_SH",
|
||||
"",
|
||||
"SH in Shale (Matthews & Kelly) = K0_SH * (OBG0-PP0) + PP0 + DF * (PP-PP0)\nK0_SH = "
|
||||
"(SH - PP)/(OBG-PP)",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_FGShaleSource, "FGShaleSource", "FG in Shale Calculation", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_K0FGSource,
|
||||
"K0FGSource",
|
||||
"K0_FG",
|
||||
"",
|
||||
"FG in shale = K0_FG * (OBG0-PP0)\nK0_FG = (FG-PP)/(OBG-PP)",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitField( &m_userDefinedPPShale, "UserPPShale", 200.0, "User Defined Pore Pressure, Shale [bar]", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_userDefinedPoissionRatio,
|
||||
"UserPoissionRatio",
|
||||
0.25,
|
||||
"User defined Poisson Ratio",
|
||||
0.35,
|
||||
"User Defined Poisson Ratio",
|
||||
"",
|
||||
"User defined Poisson Ratio",
|
||||
"User Defined Poisson Ratio",
|
||||
"" );
|
||||
// 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]", "", "User defined UCS [bar]", "" );
|
||||
CAF_PDM_InitField( &m_userDefinedUcs, "UserUcs", 100.0, "User Defined UCS [bar]", "", "User Defined UCS [bar]", "" );
|
||||
|
||||
// TODO: Get reasonable defaults from Lasse. For now all set to 1
|
||||
CAF_PDM_InitField( &m_userDefinedDF, "UserDF", 0.7, "User Defined DF", "", "User Defined Depletion Factor", "" );
|
||||
CAF_PDM_InitField( &m_userDefinedK0FG, "UserK0FG", 0.75, "User Defined K0_FG", "", "", "" );
|
||||
CAF_PDM_InitField( &m_userDefinedK0SH, "UserK0SH", 0.65, "User Defined K0_SH", "", "", "" );
|
||||
CAF_PDM_InitField( &m_FGShaleMultiplier,
|
||||
"FGMultiplier",
|
||||
1.05,
|
||||
"SH Multiplier for FG in Shale",
|
||||
"",
|
||||
"FG in Shale = Multiplier * SH",
|
||||
"" );
|
||||
|
||||
m_parameterSourceFields = {{RigWbsParameter::PP_Sand(), &m_porePressureSource},
|
||||
{RigWbsParameter::PP_Shale(), &m_porePressureShaleSource},
|
||||
{RigWbsParameter::poissonRatio(), &m_poissonRatioSource},
|
||||
{RigWbsParameter::UCS(), &m_ucsSource},
|
||||
{RigWbsParameter::OBG0(), &m_OBG0Source},
|
||||
{RigWbsParameter::DF(), &m_DFSource},
|
||||
{RigWbsParameter::K0_FG(), &m_K0FGSource},
|
||||
{RigWbsParameter::K0_SH(), &m_K0SHSource},
|
||||
{RigWbsParameter::FG_Shale(), &m_FGShaleSource}};
|
||||
|
||||
m_userDefinedValueFields = {{RigWbsParameter::PP_Shale(), &m_userDefinedPPShale},
|
||||
{RigWbsParameter::poissonRatio(), &m_userDefinedPoissionRatio},
|
||||
{RigWbsParameter::UCS(), &m_userDefinedUcs},
|
||||
{RigWbsParameter::DF(), &m_userDefinedDF},
|
||||
{RigWbsParameter::K0_FG(), &m_userDefinedK0FG},
|
||||
{RigWbsParameter::K0_SH(), &m_userDefinedK0SH},
|
||||
{RigWbsParameter::FG_Shale(), &m_FGShaleMultiplier}};
|
||||
|
||||
for ( auto parameterFieldPair : m_parameterSourceFields )
|
||||
{
|
||||
auto sources = parameterFieldPair.first.sources();
|
||||
if ( !sources.empty() )
|
||||
{
|
||||
setParameterSource( parameterFieldPair.first, sources.front() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigGeoMechWellLogExtractor::WbsParameterSource RimWellBoreStabilityPlot::porePressureSource() const
|
||||
void RimWellBoreStabilityPlot::applyWbsParametersToExtractor( RigGeoMechWellLogExtractor* extractor )
|
||||
{
|
||||
return m_porePressureSource();
|
||||
for ( auto parameterSourcePair : m_parameterSourceFields )
|
||||
{
|
||||
extractor->setWbsParametersSource( parameterSourcePair.first, ( *parameterSourcePair.second )() );
|
||||
}
|
||||
for ( auto parameterUserDefinedValuePair : m_userDefinedValueFields )
|
||||
{
|
||||
extractor->setWbsUserDefinedValue( parameterUserDefinedValuePair.first,
|
||||
( *parameterUserDefinedValuePair.second ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigGeoMechWellLogExtractor::WbsParameterSource RimWellBoreStabilityPlot::poissonRatioSource() const
|
||||
RimWellBoreStabilityPlot::ParameterSource RimWellBoreStabilityPlot::parameterSource( const RigWbsParameter& parameter ) const
|
||||
{
|
||||
return m_poissonRatioSource();
|
||||
auto field = sourceField( parameter );
|
||||
if ( field )
|
||||
{
|
||||
return ( *field )();
|
||||
}
|
||||
return RigWbsParameter::INVALID;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigGeoMechWellLogExtractor::WbsParameterSource RimWellBoreStabilityPlot::ucsSource() const
|
||||
double RimWellBoreStabilityPlot::userDefinedValue( const RigWbsParameter& parameter ) const
|
||||
{
|
||||
return m_ucsSource();
|
||||
auto it = m_userDefinedValueFields.find( parameter );
|
||||
if ( it != m_userDefinedValueFields.end() )
|
||||
{
|
||||
return *it->second;
|
||||
}
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellBoreStabilityPlot::userDefinedPoissonRatio() const
|
||||
void RimWellBoreStabilityPlot::setParameterSource( const RigWbsParameter& parameter, ParameterSource source )
|
||||
{
|
||||
return m_userDefinedPoissionRatio();
|
||||
auto field = sourceField( parameter );
|
||||
if ( field )
|
||||
{
|
||||
*field = source;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimWellBoreStabilityPlot::userDefinedUcs() const
|
||||
{
|
||||
return m_userDefinedUcs();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -129,10 +198,30 @@ void RimWellBoreStabilityPlot::defineUiOrdering( QString uiConfigName, caf::PdmU
|
||||
|
||||
caf::PdmUiGroup* parameterSources = uiOrdering.addNewGroup( "Parameter Sources" );
|
||||
parameterSources->add( &m_porePressureSource );
|
||||
parameterSources->add( &m_porePressureShaleSource );
|
||||
if ( m_porePressureShaleSource == RigWbsParameter::USER_DEFINED )
|
||||
{
|
||||
parameterSources->add( &m_userDefinedPPShale );
|
||||
}
|
||||
parameterSources->add( &m_poissonRatioSource );
|
||||
parameterSources->add( &m_userDefinedPoissionRatio );
|
||||
parameterSources->add( &m_ucsSource );
|
||||
parameterSources->add( &m_userDefinedUcs );
|
||||
parameterSources->add( &m_OBG0Source );
|
||||
parameterSources->add( &m_DFSource );
|
||||
parameterSources->add( &m_userDefinedDF );
|
||||
parameterSources->add( &m_K0SHSource );
|
||||
parameterSources->add( &m_userDefinedK0SH );
|
||||
parameterSources->add( &m_FGShaleSource );
|
||||
if ( m_FGShaleSource == RigWbsParameter::PROPORTIONAL_TO_SH )
|
||||
{
|
||||
parameterSources->add( &m_FGShaleMultiplier );
|
||||
}
|
||||
else
|
||||
{
|
||||
parameterSources->add( &m_K0FGSource );
|
||||
parameterSources->add( &m_userDefinedK0FG );
|
||||
}
|
||||
|
||||
caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup( "Title, Legend and Axis" );
|
||||
RimWellLogPlot::uiOrderingForLegendSettings( uiConfigName, *legendAndAxisGroup );
|
||||
@ -149,27 +238,36 @@ QList<caf::PdmOptionItemInfo>
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options = RimWellLogPlot::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
||||
|
||||
if ( fieldNeedingOptions == &m_porePressureSource )
|
||||
std::set<RigWbsParameter> allParameters = RigWbsParameter::allParameters();
|
||||
|
||||
for ( const RigWbsParameter& parameter : allParameters )
|
||||
{
|
||||
for ( auto source : supportedSourcesForPorePressure() )
|
||||
caf::PdmField<ParameterSourceEnum>* field = sourceField( parameter );
|
||||
if ( field == fieldNeedingOptions )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
std::vector<ParameterSource> sources = supportedSources( parameter );
|
||||
for ( int i = 0; i < (int)sources.size(); ++i )
|
||||
{
|
||||
if ( parameter.exclusiveOptions() || i == (int)sources.size() - 1 )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( sources[i] ), sources[i] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QStringList cumulativeSourceLabels;
|
||||
for ( int j = i; j < (int)sources.size(); ++j )
|
||||
{
|
||||
int index = 1 + ( j - i );
|
||||
cumulativeSourceLabels.push_back(
|
||||
QString( "%1. %2" ).arg( index ).arg( ParameterSourceEnum::uiText( sources[j] ) ) );
|
||||
}
|
||||
options.push_back( caf::PdmOptionItemInfo( cumulativeSourceLabels.join( ", " ), sources[i] ) );
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_poissonRatioSource )
|
||||
{
|
||||
for ( auto source : supportedSourcesForPoisson() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_ucsSource )
|
||||
{
|
||||
for ( auto source : supportedSourcesForUcs() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
@ -182,31 +280,49 @@ void RimWellBoreStabilityPlot::fieldChangedByUi( const caf::PdmFieldHandle* chan
|
||||
{
|
||||
RimWellLogPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
||||
|
||||
if ( changedField == &m_porePressureSource || changedField == &m_poissonRatioSource || changedField == &m_ucsSource ||
|
||||
changedField == &m_userDefinedPoissionRatio || changedField == &m_userDefinedUcs )
|
||||
if ( changedField == &m_porePressureSource || changedField == &m_porePressureShaleSource ||
|
||||
changedField == &m_poissonRatioSource || changedField == &m_ucsSource || changedField == &m_OBG0Source ||
|
||||
changedField == &m_DFSource || changedField == &m_K0FGSource || changedField == &m_K0SHSource ||
|
||||
changedField == &m_FGShaleSource )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
else if ( changedField == &m_userDefinedPPShale || changedField == &m_userDefinedPoissionRatio ||
|
||||
changedField == &m_userDefinedUcs || changedField == &m_userDefinedDF ||
|
||||
changedField == &m_userDefinedK0FG || changedField == &m_userDefinedK0SH ||
|
||||
changedField == &m_FGShaleMultiplier )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellBoreStabilityPlot::assignValidSource( caf::PdmField<ParameterSourceEnum>* parameterSourceField,
|
||||
const std::vector<ParameterSource>& validSources )
|
||||
{
|
||||
CAF_ASSERT( parameterSourceField );
|
||||
if ( std::find( validSources.begin(), validSources.end(), ( *parameterSourceField )() ) == validSources.end() )
|
||||
{
|
||||
*parameterSourceField = validSources.front();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellBoreStabilityPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
if ( !supportedSourcesForPorePressure().count( m_porePressureSource() ) )
|
||||
{
|
||||
m_porePressureSource = RigGeoMechWellLogExtractor::AUTO;
|
||||
}
|
||||
std::set<RigWbsParameter> allParameters = RigWbsParameter::allParameters();
|
||||
|
||||
if ( !supportedSourcesForPoisson().count( m_poissonRatioSource() ) )
|
||||
for ( const RigWbsParameter& parameter : allParameters )
|
||||
{
|
||||
m_poissonRatioSource = RigGeoMechWellLogExtractor::AUTO;
|
||||
caf::PdmField<ParameterSourceEnum>* field = sourceField( parameter );
|
||||
if ( field )
|
||||
{
|
||||
assignValidSource( field, supportedSources( parameter ) );
|
||||
}
|
||||
|
||||
if ( !supportedSourcesForUcs().count( m_ucsSource() ) )
|
||||
{
|
||||
m_ucsSource = RigGeoMechWellLogExtractor::AUTO;
|
||||
}
|
||||
|
||||
RimWellLogPlot::onLoadDataAndUpdate();
|
||||
@ -248,94 +364,45 @@ bool RimWellBoreStabilityPlot::hasElementPropertyEntry( const RigFemResultAddres
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RimWellBoreStabilityPlot::supportedSourcesForPorePressure() const
|
||||
caf::PdmField<RimWellBoreStabilityPlot::ParameterSourceEnum>*
|
||||
RimWellBoreStabilityPlot::sourceField( const RigWbsParameter& parameter ) const
|
||||
{
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> sources;
|
||||
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForPorePressure() )
|
||||
auto it = m_parameterSourceFields.find( parameter );
|
||||
if ( it != m_parameterSourceFields.end() )
|
||||
{
|
||||
if ( source == RigGeoMechWellLogExtractor::LAS_FILE )
|
||||
{
|
||||
if ( hasLasFileWithChannel( "PP" ) )
|
||||
{
|
||||
sources.insert( source );
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
RigFemResultAddress resAddr( RIG_ELEMENT, "POR", "" );
|
||||
if ( hasElementPropertyEntry( resAddr ) )
|
||||
{
|
||||
sources.insert( source );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sources.insert( source );
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RimWellBoreStabilityPlot::supportedSourcesForPoisson() const
|
||||
std::vector<RimWellBoreStabilityPlot::ParameterSource>
|
||||
RimWellBoreStabilityPlot::supportedSources( const RigWbsParameter& parameter ) const
|
||||
{
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> sources;
|
||||
std::vector<RigGeoMechWellLogExtractor::WbsParameterSource> sources;
|
||||
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForPoissonRatio() )
|
||||
for ( auto source : parameter.sources() )
|
||||
{
|
||||
if ( source == RigGeoMechWellLogExtractor::LAS_FILE )
|
||||
if ( source == RigWbsParameter::LAS_FILE )
|
||||
{
|
||||
if ( hasLasFileWithChannel( "POISSON_RATIO" ) )
|
||||
if ( hasLasFileWithChannel( parameter.addressString( RigWbsParameter::LAS_FILE ) ) )
|
||||
{
|
||||
sources.insert( source );
|
||||
sources.push_back( source );
|
||||
}
|
||||
}
|
||||
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
|
||||
else if ( source == RigWbsParameter::ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
RigFemResultAddress resAddr( RIG_ELEMENT, "RATIO", "" );
|
||||
RigFemResultAddress resAddr = parameter.femAddress( RigWbsParameter::ELEMENT_PROPERTY_TABLE );
|
||||
if ( hasElementPropertyEntry( resAddr ) )
|
||||
{
|
||||
sources.insert( source );
|
||||
sources.push_back( source );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sources.insert( source );
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RimWellBoreStabilityPlot::supportedSourcesForUcs() const
|
||||
{
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> sources;
|
||||
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForUcs() )
|
||||
{
|
||||
if ( source == RigGeoMechWellLogExtractor::LAS_FILE )
|
||||
{
|
||||
if ( hasLasFileWithChannel( "UCS" ) )
|
||||
{
|
||||
sources.insert( source );
|
||||
}
|
||||
}
|
||||
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
RigFemResultAddress resAddr( RIG_ELEMENT, "UCS", "" );
|
||||
if ( hasElementPropertyEntry( resAddr ) )
|
||||
{
|
||||
sources.insert( source );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sources.insert( source );
|
||||
sources.push_back( source );
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "RimWellLogPlot.h"
|
||||
|
||||
#include "RigGeoMechWellLogExtractor.h"
|
||||
#include "RigWbsParameter.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
@ -34,18 +35,18 @@ class RimWellBoreStabilityPlot : public RimWellLogPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
typedef caf::AppEnum<RigGeoMechWellLogExtractor::WbsParameterSource> ParameterSourceEnum;
|
||||
using ParameterSource = RigGeoMechWellLogExtractor::WbsParameterSource;
|
||||
using ParameterSourceEnum = RigGeoMechWellLogExtractor::WbsParameterSourceEnum;
|
||||
|
||||
public:
|
||||
RimWellBoreStabilityPlot();
|
||||
|
||||
RigGeoMechWellLogExtractor::WbsParameterSource porePressureSource() const;
|
||||
RigGeoMechWellLogExtractor::WbsParameterSource poissonRatioSource() const;
|
||||
RigGeoMechWellLogExtractor::WbsParameterSource ucsSource() const;
|
||||
void applyWbsParametersToExtractor( RigGeoMechWellLogExtractor* extractor );
|
||||
|
||||
double userDefinedPoissonRatio() const;
|
||||
double userDefinedUcs() const;
|
||||
RimWellBoreStabilityPlot::ParameterSource parameterSource( const RigWbsParameter& parameter ) const;
|
||||
double userDefinedValue( const RigWbsParameter& parameter ) const;
|
||||
|
||||
void setParameterSource( const RigWbsParameter& parameter, RimWellBoreStabilityPlot::ParameterSource );
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
@ -57,20 +58,36 @@ protected:
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue ) override;
|
||||
|
||||
void assignValidSource( caf::PdmField<ParameterSourceEnum>* parameterSourceField,
|
||||
const std::vector<ParameterSource>& validSources );
|
||||
void onLoadDataAndUpdate() override;
|
||||
|
||||
bool hasLasFileWithChannel( const QString& channel ) const;
|
||||
bool hasElementPropertyEntry( const RigFemResultAddress& resAddr ) const;
|
||||
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> supportedSourcesForPorePressure() const;
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> supportedSourcesForPoisson() const;
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> supportedSourcesForUcs() const;
|
||||
caf::PdmField<ParameterSourceEnum>* sourceField( const RigWbsParameter& parameter ) const;
|
||||
|
||||
std::vector<ParameterSource> supportedSources( const RigWbsParameter& parameter ) const;
|
||||
|
||||
private:
|
||||
caf::PdmField<ParameterSourceEnum> m_porePressureSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_porePressureShaleSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_poissonRatioSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_ucsSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_OBG0Source;
|
||||
caf::PdmField<ParameterSourceEnum> m_DFSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_K0FGSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_K0SHSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_FGShaleSource;
|
||||
|
||||
caf::PdmField<double> m_userDefinedPPShale;
|
||||
caf::PdmField<double> m_userDefinedPoissionRatio;
|
||||
caf::PdmField<double> m_userDefinedUcs;
|
||||
caf::PdmField<double> m_userDefinedDF;
|
||||
caf::PdmField<double> m_userDefinedK0FG;
|
||||
caf::PdmField<double> m_userDefinedK0SH;
|
||||
caf::PdmField<double> m_FGShaleMultiplier;
|
||||
|
||||
std::map<RigWbsParameter, caf::PdmField<ParameterSourceEnum>*> m_parameterSourceFields;
|
||||
std::map<RigWbsParameter, caf::PdmField<double>*> m_userDefinedValueFields;
|
||||
};
|
||||
|
@ -487,11 +487,7 @@ void RimWellLogExtractionCurve::extractData( bool* isUsingPseudoLength,
|
||||
this->firstAncestorOrThisOfType( wbsPlot );
|
||||
if ( wbsPlot )
|
||||
{
|
||||
geomExtractor->setWbsParameters( wbsPlot->porePressureSource(),
|
||||
wbsPlot->poissonRatioSource(),
|
||||
wbsPlot->ucsSource(),
|
||||
wbsPlot->userDefinedPoissonRatio(),
|
||||
wbsPlot->userDefinedUcs() );
|
||||
wbsPlot->applyWbsParametersToExtractor( geomExtractor.p() );
|
||||
}
|
||||
|
||||
geomExtractor->setRkbDiff( rkbDiff() );
|
||||
@ -508,9 +504,9 @@ void RimWellLogExtractionCurve::extractData( bool* isUsingPseudoLength,
|
||||
}
|
||||
}
|
||||
|
||||
if ( values.size() && measuredDepthValues.size() )
|
||||
if ( !values.empty() && !measuredDepthValues.empty() )
|
||||
{
|
||||
if ( !tvDepthValues.size() )
|
||||
if ( tvDepthValues.empty() )
|
||||
{
|
||||
this->setValuesAndDepths( values,
|
||||
measuredDepthValues,
|
||||
@ -531,21 +527,42 @@ void RimWellLogExtractionCurve::extractData( bool* isUsingPseudoLength,
|
||||
void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles( const RimWellPath* wellPath,
|
||||
RigGeoMechWellLogExtractor* geomExtractor )
|
||||
{
|
||||
std::vector<std::pair<double, double>> logFileMudWeights =
|
||||
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "PP" );
|
||||
if ( !logFileMudWeights.empty() )
|
||||
auto allParams = RigWbsParameter::allParameters();
|
||||
for ( const RigWbsParameter& parameter : allParams )
|
||||
{
|
||||
// Log file pressures come in SG units (g / cm^3).
|
||||
// We need SI as input (kg / m^3), so multiply by 1000:
|
||||
for ( auto& mudWeight : logFileMudWeights )
|
||||
if ( parameter == RigWbsParameter::PP_Sand() || parameter == RigWbsParameter::PP_Shale() )
|
||||
{
|
||||
mudWeight.second *= 1000.0;
|
||||
findAndLoadPorePressuresFromLasFiles( wellPath, parameter, geomExtractor );
|
||||
}
|
||||
else if ( parameter == RigWbsParameter::UCS() )
|
||||
{
|
||||
findAndLoadUcsFromLasFiles( wellPath, geomExtractor );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generic LAS
|
||||
QString lasAddress = parameter.addressString( RigWbsParameter::LAS_FILE );
|
||||
|
||||
std::vector<std::pair<double, double>> lasFileValues =
|
||||
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, lasAddress );
|
||||
if ( !lasFileValues.empty() )
|
||||
{
|
||||
geomExtractor->setWbsLasValues( parameter, lasFileValues );
|
||||
}
|
||||
}
|
||||
}
|
||||
geomExtractor->setWellLogMdAndMudWeightKgPerM3( logFileMudWeights );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogExtractionCurve::findAndLoadUcsFromLasFiles( const RimWellPath* wellPath,
|
||||
RigGeoMechWellLogExtractor* geomExtractor )
|
||||
{
|
||||
{
|
||||
QString lasAddress = RigWbsParameter::UCS().addressString( RigWbsParameter::LAS_FILE );
|
||||
std::vector<std::pair<double, double>> logFileUcs = RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath,
|
||||
"UCS" );
|
||||
lasAddress );
|
||||
if ( !logFileUcs.empty() )
|
||||
{
|
||||
// TODO: UCS is typically in MPa, but not necessarily.
|
||||
@ -555,14 +572,47 @@ void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles( const RimW
|
||||
{
|
||||
ucsValue.second *= 10.0; // MPa -> Bar
|
||||
}
|
||||
geomExtractor->setWellLogMdAndUcsBar( logFileUcs );
|
||||
geomExtractor->setWbsLasValues( RigWbsParameter::UCS(), logFileUcs );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<double, double>> logFilePoissonRatio =
|
||||
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "POISSON_RATIO" );
|
||||
if ( !logFilePoissonRatio.empty() )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogExtractionCurve::findAndLoadPorePressuresFromLasFiles( const RimWellPath* wellPath,
|
||||
const RigWbsParameter& parameter,
|
||||
RigGeoMechWellLogExtractor* geomExtractor )
|
||||
{
|
||||
geomExtractor->setWellLogMdAndPoissonRatio( logFilePoissonRatio );
|
||||
{
|
||||
std::vector<std::pair<double, double>> logFileMudWeights =
|
||||
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath,
|
||||
parameter.addressString( RigWbsParameter::LAS_FILE ) );
|
||||
if ( !logFileMudWeights.empty() )
|
||||
{
|
||||
std::vector<std::pair<double, double>> porePressuresBar;
|
||||
porePressuresBar.reserve( logFileMudWeights.size() );
|
||||
|
||||
for ( auto& mudWeight : logFileMudWeights )
|
||||
{
|
||||
// Log file mud weights come in SG units (g / cm^3).
|
||||
// We need SI as input (kg / m^3), so multiply by 1000:
|
||||
double mudWeightsSI = mudWeight.second * 1000.0;
|
||||
// To get specific mudWeight (N / m^3):
|
||||
double specificMudWeight = mudWeightsSI * 9.81;
|
||||
|
||||
double md = mudWeight.first;
|
||||
cvf::Vec3d point = wellPath->wellPathGeometry()->interpolatedPointAlongWellPath( md );
|
||||
double depth = -point.z() + wellPath->wellPathGeometry()->rkbDiff();
|
||||
|
||||
// Pore pressure in pascal
|
||||
double ppPascal = specificMudWeight * depth;
|
||||
|
||||
// Pore pressure in bar
|
||||
porePressuresBar.emplace_back( mudWeight.first, ppPascal * 1.0e-5 );
|
||||
}
|
||||
geomExtractor->setWbsLasValues( parameter, porePressuresBar );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RigWbsParameter.h"
|
||||
#include "RimWellLogCurve.h"
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
@ -86,6 +87,12 @@ public:
|
||||
static void findAndLoadWbsParametersFromLasFiles( const RimWellPath* wellPath,
|
||||
RigGeoMechWellLogExtractor* geomExtractor );
|
||||
|
||||
static void findAndLoadUcsFromLasFiles( const RimWellPath* wellPath, RigGeoMechWellLogExtractor* geomExtractor );
|
||||
|
||||
static void findAndLoadPorePressuresFromLasFiles( const RimWellPath* wellPath,
|
||||
const RigWbsParameter& parameter,
|
||||
RigGeoMechWellLogExtractor* geomExtractor );
|
||||
|
||||
void setAutoNameComponents( bool addCaseName, bool addProperty, bool addWellname, bool addTimeStep, bool addDate );
|
||||
|
||||
protected:
|
||||
|
@ -374,20 +374,11 @@ void RimWellLogTrack::calculateXZoomRange()
|
||||
|
||||
if ( minValue == HUGE_VAL )
|
||||
{
|
||||
if ( visibleCurves )
|
||||
{
|
||||
minValue = RI_LOGPLOTTRACK_MINX_DEFAULT;
|
||||
maxValue = RI_LOGPLOTTRACK_MAXX_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Empty axis when there are no curves
|
||||
// Empty axis when there are no sensible visible curves
|
||||
minValue = 0;
|
||||
maxValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_minorTickInterval() != 0.0 )
|
||||
else if ( m_minorTickInterval() != 0.0 )
|
||||
{
|
||||
std::tie( minValue, maxValue ) = adjustXRange( minValue, maxValue, m_minorTickInterval() );
|
||||
}
|
||||
@ -697,6 +688,18 @@ void RimWellLogTrack::updateXAxisAndGridTickIntervals()
|
||||
{
|
||||
if ( !m_plotWidget ) return;
|
||||
|
||||
bool emptyRange = std::abs( m_visibleXRangeMax() - m_visibleXRangeMin ) <
|
||||
1.0e-6 * std::max( 1.0, std::max( m_visibleXRangeMax(), m_visibleXRangeMin() ) );
|
||||
|
||||
if ( emptyRange )
|
||||
{
|
||||
m_plotWidget->enableGridLines( QwtPlot::xTop, false, false );
|
||||
m_plotWidget->setAxisRange( QwtPlot::xTop, 0.0, 0.0 );
|
||||
m_plotWidget->setAxisLabelsAndTicksEnabled( QwtPlot::xTop, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_plotWidget->setAxisLabelsAndTicksEnabled( QwtPlot::xTop, true );
|
||||
if ( m_explicitTickIntervals )
|
||||
{
|
||||
m_plotWidget->setMajorAndMinorTickIntervals( QwtPlot::xTop,
|
||||
@ -716,6 +719,7 @@ void RimWellLogTrack::updateXAxisAndGridTickIntervals()
|
||||
m_plotWidget->enableGridLines( QwtPlot::xTop,
|
||||
m_xAxisGridVisibility() & RimWellLogPlot::AXIS_GRID_MAJOR,
|
||||
m_xAxisGridVisibility() & RimWellLogPlot::AXIS_GRID_MINOR );
|
||||
}
|
||||
|
||||
RimWellLogPlot* wellLogPlot = nullptr;
|
||||
this->firstAncestorOrThisOfType( wellLogPlot );
|
||||
@ -2227,23 +2231,20 @@ void RimWellLogTrack::updateCurveDataRegionsOnPlot()
|
||||
this->firstAncestorOrThisOfType( wbsPlot );
|
||||
if ( wbsPlot )
|
||||
{
|
||||
geoMechWellLogExtractor->setWbsParameters( wbsPlot->porePressureSource(),
|
||||
wbsPlot->poissonRatioSource(),
|
||||
wbsPlot->ucsSource(),
|
||||
wbsPlot->userDefinedPoissonRatio(),
|
||||
wbsPlot->userDefinedUcs() );
|
||||
wbsPlot->applyWbsParametersToExtractor( geoMechWellLogExtractor );
|
||||
}
|
||||
|
||||
std::vector<double> ppValues = geoMechWellLogExtractor->porePressureIntervals( timeStep );
|
||||
std::vector<double> poissonValues = geoMechWellLogExtractor->poissonIntervals( timeStep );
|
||||
std::vector<double> ucsValues = geoMechWellLogExtractor->ucsIntervals( timeStep );
|
||||
std::vector<double> ppSourceRegions = geoMechWellLogExtractor->porePressureSourceRegions( timeStep );
|
||||
std::vector<double> poissonSourceRegions = geoMechWellLogExtractor->poissonSourceRegions( timeStep );
|
||||
std::vector<double> ucsSourceRegions = geoMechWellLogExtractor->ucsSourceRegions( timeStep );
|
||||
|
||||
{
|
||||
caf::ColorTable colorTable( RimRegularLegendConfig::colorArrayFromColorType( m_colorShadingPalette() ) );
|
||||
|
||||
std::vector<QString> sourceNames =
|
||||
{"", "PP=Grid", "PP=Las-File", "PP=Element Property Table", "", "PP=Hydrostatic"};
|
||||
curveData.data = ppValues;
|
||||
RigWbsParameter::PP_Sand().allSourceLabels( "\n",
|
||||
wbsPlot->userDefinedValue( RigWbsParameter::PP_Shale() ) );
|
||||
curveData.data = ppSourceRegions;
|
||||
|
||||
std::vector<QString> sourceNamesToPlot;
|
||||
std::vector<std::pair<double, double>> yValues;
|
||||
@ -2266,13 +2267,10 @@ void RimWellLogTrack::updateCurveDataRegionsOnPlot()
|
||||
caf::ColorTable colorTable( RimRegularLegendConfig::colorArrayFromColorType( m_colorShadingPalette() ) );
|
||||
|
||||
std::vector<QString> sourceNames =
|
||||
{"",
|
||||
"",
|
||||
"Poisson=Las-File",
|
||||
"Poisson=Element Property Table",
|
||||
QString( "Poisson=%1" ).arg( wellBoreStabilityPlot->userDefinedPoissonRatio() ),
|
||||
""};
|
||||
curveData.data = poissonValues;
|
||||
RigWbsParameter::poissonRatio().allSourceLabels( "\n",
|
||||
wbsPlot->userDefinedValue(
|
||||
RigWbsParameter::poissonRatio() ) );
|
||||
curveData.data = poissonSourceRegions;
|
||||
|
||||
std::vector<QString> sourceNamesToPlot;
|
||||
std::vector<std::pair<double, double>> yValues;
|
||||
@ -2294,14 +2292,10 @@ void RimWellLogTrack::updateCurveDataRegionsOnPlot()
|
||||
{
|
||||
caf::ColorTable colorTable( RimRegularLegendConfig::colorArrayFromColorType( m_colorShadingPalette() ) );
|
||||
|
||||
std::vector<QString> sourceNames = {"",
|
||||
"",
|
||||
"UCS=Las-File",
|
||||
"UCS=Element Property Table",
|
||||
QString( "UCS=%1" ).arg( wellBoreStabilityPlot->userDefinedUcs() ),
|
||||
""};
|
||||
std::vector<QString> sourceNames =
|
||||
RigWbsParameter::UCS().allSourceLabels( "\n", wbsPlot->userDefinedValue( RigWbsParameter::UCS() ) );
|
||||
|
||||
curveData.data = ucsValues;
|
||||
curveData.data = ucsSourceRegions;
|
||||
|
||||
std::vector<QString> sourceNamesToPlot;
|
||||
std::vector<std::pair<double, double>> yValues;
|
||||
|
@ -70,6 +70,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigGridCrossPlotCurveGrouping.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseCrossPlotDataExtractor.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEquil.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigWbsParameter.h
|
||||
)
|
||||
|
||||
|
||||
@ -137,6 +138,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RigPolyLinesData.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigCaseCellResultCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseCrossPlotDataExtractor.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEquil.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigWbsParameter.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "cvfGeometryTools.h"
|
||||
#include "cvfMath.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPolygonF>
|
||||
|
||||
#include <type_traits>
|
||||
@ -56,6 +57,13 @@ RigGeoMechWellLogExtractor::RigGeoMechWellLogExtractor( RigGeoMechCaseData* aCas
|
||||
, m_caseData( aCase )
|
||||
{
|
||||
calculateIntersection();
|
||||
|
||||
for ( RigWbsParameter parameter : RigWbsParameter::allParameters() )
|
||||
{
|
||||
m_parameterSources[parameter] = parameter.sources().front();
|
||||
m_lasFileValues[parameter] = std::vector<std::pair<double, double>>();
|
||||
m_userDefinedValues[parameter] = std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -77,8 +85,8 @@ void RigGeoMechWellLogExtractor::performCurveDataSmoothing( int
|
||||
const std::vector<float>& unscaledShValues = resultCollection->resultValues( shAddr, 0, frameIndex );
|
||||
const std::vector<float>& porePressures = resultCollection->resultValues( porBarResAddr, 0, frameIndex );
|
||||
|
||||
std::vector<float> interfaceShValues = interpolateInterfaceValues( shAddr, unscaledShValues );
|
||||
std::vector<float> interfacePorePressures = interpolateInterfaceValues( porBarResAddr, porePressures );
|
||||
std::vector<float> interfaceShValues = interpolateInterfaceValues( shAddr, frameIndex, unscaledShValues );
|
||||
std::vector<float> interfacePorePressures = interpolateInterfaceValues( porBarResAddr, frameIndex, porePressures );
|
||||
|
||||
std::vector<double> interfaceShValuesDbl( interfaceShValues.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> interfacePorePressuresDbl( interfacePorePressures.size(),
|
||||
@ -117,32 +125,49 @@ void RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAddr,
|
||||
|
||||
if ( resAddr.resultPosType == RIG_WELLPATH_DERIVED )
|
||||
{
|
||||
if ( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() )
|
||||
if ( resAddr.fieldName == RiaDefines::wbsFGResult().toStdString() )
|
||||
{
|
||||
wellBoreWallCurveData( resAddr, frameIndex, values );
|
||||
return;
|
||||
wellBoreFGShale( frameIndex, values );
|
||||
}
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsUCSParameterName().toStdString() )
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsSFGResult().toStdString() )
|
||||
{
|
||||
wellPathParameters( resAddr, frameIndex, values );
|
||||
wellBoreWallCurveData( resAddr, frameIndex, values );
|
||||
}
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsPPResultName().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsOBGResultName().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsSHResultName().toStdString() )
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsPPResult().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsOBGResult().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsSHResult().toStdString() )
|
||||
{
|
||||
wellPathScaledCurveData( resAddr, frameIndex, values );
|
||||
return;
|
||||
}
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsAzimuthResultName().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsInclinationResultName().toStdString() )
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsAzimuthResult().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsInclinationResult().toStdString() )
|
||||
{
|
||||
wellPathAngles( resAddr, values );
|
||||
return;
|
||||
}
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsSHMkResult().toStdString() )
|
||||
{
|
||||
wellBoreSHMk( frameIndex, values );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plotting parameters as curves
|
||||
RigWbsParameter param;
|
||||
if ( RigWbsParameter::findParameter( QString::fromStdString( resAddr.fieldName ), ¶m ) )
|
||||
{
|
||||
calculateWbsParameterForAllSegments( param, frameIndex, values );
|
||||
if ( param == RigWbsParameter::UCS() ) // UCS is reported as UCS/100
|
||||
{
|
||||
for ( double& value : *values )
|
||||
{
|
||||
if ( isValid( value ) ) value /= 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !resAddr.isValid() ) return;
|
||||
|
||||
RigFemResultAddress convResAddr = resAddr;
|
||||
@ -156,132 +181,164 @@ void RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAddr,
|
||||
|
||||
const std::vector<float>& resultValues = m_caseData->femPartResults()->resultValues( convResAddr, 0, frameIndex );
|
||||
|
||||
if ( !resultValues.size() ) return;
|
||||
if ( resultValues.empty() ) return;
|
||||
|
||||
values->resize( m_intersections.size() );
|
||||
std::vector<float> interfaceValues = interpolateInterfaceValues( convResAddr, frameIndex, resultValues );
|
||||
|
||||
for ( size_t intersectionIdx = 0; intersectionIdx < m_intersections.size(); ++intersectionIdx )
|
||||
values->resize( interfaceValues.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
( *values )[intersectionIdx] = static_cast<double>(
|
||||
interpolateGridResultValue<float>( convResAddr.resultPosType, resultValues, intersectionIdx ) );
|
||||
( *values )[intersectionIdx] = static_cast<double>( interfaceValues[intersectionIdx] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<float, RigGeoMechWellLogExtractor::WbsParameterSource> RigGeoMechWellLogExtractor::calculatePorePressureInSegment(
|
||||
int64_t intersectionIdx,
|
||||
double effectiveDepthMeters,
|
||||
const std::vector<float>& interpolatedInterfacePorePressuresBar,
|
||||
const std::vector<float>& poreElementPressuresPascal ) const
|
||||
std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::calculateWbsParameterForAllSegments( const RigWbsParameter& parameter,
|
||||
WbsParameterSource primarySource,
|
||||
int frameIndex,
|
||||
std::vector<double>* outputValues )
|
||||
{
|
||||
// Priority 1: Try pore pressure from the grid
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == GRID )
|
||||
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
|
||||
|
||||
std::vector<WbsParameterSource> finalSourcesPerSegment( m_intersections.size(), RigWbsParameter::INVALID );
|
||||
|
||||
outputValues->resize( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
if ( primarySource == RigWbsParameter::INVALID )
|
||||
{
|
||||
float averagePorePressureBar = std::numeric_limits<float>::infinity();
|
||||
bool validGridPorePressure = averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
interpolatedInterfacePorePressuresBar,
|
||||
return finalSourcesPerSegment;
|
||||
}
|
||||
|
||||
bool isPPresult = parameter == RigWbsParameter::PP_Sand() || parameter == RigWbsParameter::PP_Shale();
|
||||
|
||||
std::vector<WbsParameterSource> allSources = parameter.sources();
|
||||
auto primary_it = std::find( allSources.begin(), allSources.end(), primarySource );
|
||||
CVF_ASSERT( primary_it != allSources.end() );
|
||||
|
||||
std::vector<double> gridValues;
|
||||
if ( std::find( allSources.begin(), allSources.end(), RigWbsParameter::GRID ) != allSources.end() )
|
||||
{
|
||||
RigFemResultAddress nativeAddr = parameter.femAddress( RigWbsParameter::GRID );
|
||||
|
||||
const std::vector<float>& unscaledResultValues = resultCollection->resultValues( nativeAddr, 0, frameIndex );
|
||||
std::vector<float> interpolatedInterfaceValues = interpolateInterfaceValues( nativeAddr,
|
||||
frameIndex,
|
||||
unscaledResultValues );
|
||||
gridValues.resize( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
float averageUnscaledValue = std::numeric_limits<float>::infinity();
|
||||
averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
interpolatedInterfaceValues,
|
||||
std::numeric_limits<float>::infinity(),
|
||||
&averagePorePressureBar );
|
||||
if ( validGridPorePressure )
|
||||
{
|
||||
return std::make_pair( averagePorePressureBar, GRID );
|
||||
&averageUnscaledValue );
|
||||
gridValues[intersectionIdx] = static_cast<double>( averageUnscaledValue );
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 2: Try LAS-file
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == LAS_FILE )
|
||||
const std::vector<std::pair<double, double>>& lasFileValues = m_lasFileValues.at( parameter );
|
||||
const double& userDefinedValue = m_userDefinedValues.at( parameter );
|
||||
|
||||
const std::vector<float>* elementPropertyValues = nullptr;
|
||||
if ( std::find( allSources.begin(), allSources.end(), RigWbsParameter::ELEMENT_PROPERTY_TABLE ) != allSources.end() )
|
||||
{
|
||||
double lasMudWeightKgPerM3 = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndMudWeightKgPerM3 );
|
||||
if ( lasMudWeightKgPerM3 != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
double specificMudWeightNPerM3 = lasMudWeightKgPerM3 * 9.81;
|
||||
double porePressurePascal = specificMudWeightNPerM3 * effectiveDepthMeters;
|
||||
double porePressureBar = pascalToBar( porePressurePascal );
|
||||
return std::make_pair( (float)porePressureBar, LAS_FILE );
|
||||
}
|
||||
RigFemResultAddress elementPropertyAddr = parameter.femAddress( RigWbsParameter::ELEMENT_PROPERTY_TABLE );
|
||||
elementPropertyValues = &( resultCollection->resultValues( elementPropertyAddr, 0, frameIndex ) );
|
||||
}
|
||||
|
||||
// Priority 3: Try element property tables
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == ELEMENT_PROPERTY_TABLE )
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
// Loop from primary source and out for each value
|
||||
for ( auto it = primary_it; it != allSources.end(); ++it )
|
||||
{
|
||||
if ( *it == RigWbsParameter::GRID ) // Priority 0: Grid
|
||||
{
|
||||
if ( intersectionIdx < (int64_t)gridValues.size() &&
|
||||
gridValues[intersectionIdx] != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
( *outputValues )[intersectionIdx] = gridValues[intersectionIdx];
|
||||
finalSourcesPerSegment[intersectionIdx] = RigWbsParameter::GRID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( *it == RigWbsParameter::LAS_FILE ) // Priority 1: Las-file value
|
||||
{
|
||||
if ( !lasFileValues.empty() )
|
||||
{
|
||||
double lasValue = getWellLogSegmentValue( intersectionIdx, lasFileValues );
|
||||
if ( lasValue != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
( *outputValues )[intersectionIdx] = lasValue;
|
||||
finalSourcesPerSegment[intersectionIdx] = RigWbsParameter::LAS_FILE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( *it == RigWbsParameter::ELEMENT_PROPERTY_TABLE ) // Priority 2: Element property table value
|
||||
{
|
||||
CVF_ASSERT( elementPropertyValues );
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
if ( elmIdx < poreElementPressuresPascal.size() )
|
||||
if ( elmIdx < elementPropertyValues->size() )
|
||||
{
|
||||
float porePressureBar = pascalToBar( poreElementPressuresPascal[elmIdx] );
|
||||
return std::make_pair( porePressureBar, ELEMENT_PROPERTY_TABLE );
|
||||
( *outputValues )[intersectionIdx] = ( *elementPropertyValues )[elmIdx];
|
||||
finalSourcesPerSegment[intersectionIdx] = RigWbsParameter::ELEMENT_PROPERTY_TABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair( std::numeric_limits<float>::infinity(), INVALID );
|
||||
else if ( *it == RigWbsParameter::HYDROSTATIC && isPPresult )
|
||||
{
|
||||
( *outputValues )[intersectionIdx] = hydroStaticPorePressureForSegment( intersectionIdx );
|
||||
finalSourcesPerSegment[intersectionIdx] = RigWbsParameter::HYDROSTATIC;
|
||||
break;
|
||||
}
|
||||
else if ( *it == RigWbsParameter::USER_DEFINED )
|
||||
{
|
||||
( *outputValues )[intersectionIdx] = userDefinedValue;
|
||||
finalSourcesPerSegment[intersectionIdx] = RigWbsParameter::USER_DEFINED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return finalSourcesPerSegment;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<float, RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::calculatePoissonRatioInSegment( int64_t intersectionIdx,
|
||||
const std::vector<float>& poissonRatios ) const
|
||||
std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::calculateWbsParameterForAllSegments( const RigWbsParameter& parameter,
|
||||
int frameIndex,
|
||||
std::vector<double>* outputValues )
|
||||
{
|
||||
// Priority 1: Las-file poisson ratio
|
||||
if ( m_poissonRatioSource == AUTO || m_poissonRatioSource == LAS_FILE )
|
||||
{
|
||||
if ( !m_wellLogMdAndPoissonRatios.empty() )
|
||||
{
|
||||
double lasPoissionRatio = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndPoissonRatios );
|
||||
if ( lasPoissionRatio != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
return std::make_pair( (float)lasPoissionRatio, LAS_FILE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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() )
|
||||
{
|
||||
return std::make_pair( poissonRatios[elmIdx], ELEMENT_PROPERTY_TABLE );
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 3: User defined poisson ratio
|
||||
return std::make_pair( (float)m_userDefinedPoissonRatio, USER_DEFINED );
|
||||
return calculateWbsParameterForAllSegments( parameter, m_parameterSources.at( parameter ), frameIndex, outputValues );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<float, RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::calculateUcsInSegment( int64_t intersectionIdx,
|
||||
const std::vector<float>& ucsValuesPascal ) const
|
||||
std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::calculateWbsParametersForAllSegments( const RigFemResultAddress& resAddr,
|
||||
int frameIndex,
|
||||
std::vector<double>* values )
|
||||
{
|
||||
if ( m_ucsSource == AUTO || m_ucsSource == LAS_FILE )
|
||||
CVF_ASSERT( values );
|
||||
|
||||
RigWbsParameter param;
|
||||
if ( !RigWbsParameter::findParameter( QString::fromStdString( resAddr.fieldName ), ¶m ) )
|
||||
{
|
||||
if ( !m_wellLogMdAndUcsBar.empty() )
|
||||
{
|
||||
double lasUniaxialStrengthInBar = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndUcsBar );
|
||||
if ( lasUniaxialStrengthInBar != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
return std::make_pair( (float)lasUniaxialStrengthInBar, LAS_FILE );
|
||||
CVF_ASSERT( false && "wbsParameters() called on something that isn't a wbs parameter" );
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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
|
||||
double uniaxialStrengthInBar = pascalToBar( ucsValuesPascal[elmIdx] );
|
||||
return std::make_pair( (float)uniaxialStrengthInBar, ELEMENT_PROPERTY_TABLE );
|
||||
}
|
||||
}
|
||||
// Priority 3: User defined UCS (in bar)
|
||||
return std::make_pair( (float)m_userDefinedUcs, USER_DEFINED );
|
||||
|
||||
return calculateWbsParameterForAllSegments( param, m_userDefinedValues.at( param ), values );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -339,94 +396,68 @@ void RigGeoMechWellLogExtractor::wellPathAngles( const RigFemResultAddress& resA
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGeoMechWellLogExtractor::wellPathScaledCurveData( const RigFemResultAddress& resAddr,
|
||||
std::vector<RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::wellPathScaledCurveData( const RigFemResultAddress& resAddr,
|
||||
int frameIndex,
|
||||
std::vector<double>* values )
|
||||
{
|
||||
CVF_ASSERT( values );
|
||||
|
||||
const RigFemPart* femPart = m_caseData->femParts()->part( 0 );
|
||||
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
|
||||
values->resize( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<WbsParameterSource> sources( m_intersections.size(), RigWbsParameter::INVALID );
|
||||
|
||||
std::string nativeFieldName;
|
||||
std::string nativeCompName;
|
||||
if ( resAddr.fieldName == "PP" )
|
||||
if ( resAddr.fieldName == RiaDefines::wbsPPResult().toStdString() )
|
||||
{
|
||||
nativeFieldName = "POR-Bar"; // More likely to be in memory than POR
|
||||
}
|
||||
else if ( resAddr.fieldName == "OBG" )
|
||||
{
|
||||
nativeFieldName = "ST";
|
||||
nativeCompName = "S33";
|
||||
}
|
||||
else if ( resAddr.fieldName == "SH" )
|
||||
{
|
||||
nativeFieldName = "ST";
|
||||
nativeCompName = "S3";
|
||||
}
|
||||
// Las or element property table values
|
||||
std::vector<double> ppSandValues( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<double> ppShaleValues( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
RigFemResultAddress nativeAddr( RIG_ELEMENT_NODAL, nativeFieldName, nativeCompName );
|
||||
RigFemResultAddress porElementResAddr( RIG_ELEMENT, "POR", "" );
|
||||
|
||||
const std::vector<float>& unscaledResultValues = resultCollection->resultValues( nativeAddr, 0, frameIndex );
|
||||
const std::vector<float>& poreElementPressuresPascal = resultCollection->resultValues( porElementResAddr,
|
||||
std::vector<WbsParameterSource> ppSandSources = calculateWbsParameterForAllSegments( RigWbsParameter::PP_Sand(),
|
||||
frameIndex,
|
||||
&ppSandValues );
|
||||
std::vector<WbsParameterSource> ppShaleSources = calculateWbsParameterForAllSegments( RigWbsParameter::PP_Shale(),
|
||||
0,
|
||||
frameIndex );
|
||||
|
||||
std::vector<float> interpolatedInterfaceValues = interpolateInterfaceValues( nativeAddr, unscaledResultValues );
|
||||
|
||||
values->resize( m_intersections.size(), 0.0f );
|
||||
&ppShaleValues );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
// Set the value to invalid by default
|
||||
( *values )[intersectionIdx] = std::numeric_limits<double>::infinity();
|
||||
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
RigElementType elmType = femPart->elementType( elmIdx );
|
||||
|
||||
if ( !( elmType == HEX8 || elmType == HEX8P ) ) continue;
|
||||
|
||||
cvf::Vec3f centroid = cellCentroid( intersectionIdx );
|
||||
|
||||
double trueVerticalDepth = -centroid.z();
|
||||
|
||||
double effectiveDepthMeters = trueVerticalDepth + m_rkbDiff;
|
||||
double hydroStaticPorePressureBar = pascalToBar( effectiveDepthMeters * UNIT_WEIGHT_OF_WATER );
|
||||
|
||||
float averageUnscaledValue = std::numeric_limits<float>::infinity();
|
||||
|
||||
if ( resAddr.fieldName == "PP" )
|
||||
if ( ( *values )[intersectionIdx] == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
auto ppSourcePair = calculatePorePressureInSegment( intersectionIdx,
|
||||
effectiveDepthMeters,
|
||||
interpolatedInterfaceValues,
|
||||
poreElementPressuresPascal );
|
||||
if ( ppSourcePair.second == INVALID )
|
||||
if ( ppSandValues[intersectionIdx] != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
averageUnscaledValue = hydroStaticPorePressureBar;
|
||||
( *values )[intersectionIdx] = ppSandValues[intersectionIdx];
|
||||
sources[intersectionIdx] = ppSandSources[intersectionIdx];
|
||||
}
|
||||
else if ( ppShaleValues[intersectionIdx] != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
( *values )[intersectionIdx] = ppShaleValues[intersectionIdx];
|
||||
sources[intersectionIdx] = ppShaleSources[intersectionIdx];
|
||||
}
|
||||
else
|
||||
{
|
||||
averageUnscaledValue = ppSourcePair.first;
|
||||
( *values )[intersectionIdx] = hydroStaticPorePressureForSegment( intersectionIdx );
|
||||
sources[intersectionIdx] = RigWbsParameter::HYDROSTATIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( resAddr.fieldName == RiaDefines::wbsOBGResult().toStdString() )
|
||||
{
|
||||
sources = calculateWbsParameterForAllSegments( RigWbsParameter::OBG(), frameIndex, values );
|
||||
}
|
||||
else
|
||||
{
|
||||
averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
interpolatedInterfaceValues,
|
||||
std::numeric_limits<float>::infinity(),
|
||||
&averageUnscaledValue );
|
||||
sources = calculateWbsParameterForAllSegments( RigWbsParameter::SH(), frameIndex, values );
|
||||
}
|
||||
|
||||
( *values )[intersectionIdx] = static_cast<double>( averageUnscaledValue ) / hydroStaticPorePressureBar;
|
||||
}
|
||||
|
||||
#pragma omp parallel for
|
||||
// Scaling
|
||||
#pragma omp parallel for schedule( dynamic )
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
( *values )[intersectionIdx] /= hydroStaticPorePressureForSegment( intersectionIdx );
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -437,18 +468,21 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
std::vector<double>* values )
|
||||
{
|
||||
CVF_ASSERT( values );
|
||||
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() );
|
||||
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsFGResult().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsSFGResult().toStdString() );
|
||||
|
||||
// The result addresses needed
|
||||
RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, "ST", "" );
|
||||
RigFemResultAddress porBarResAddr( RIG_ELEMENT_NODAL, "POR-Bar", "" );
|
||||
// Allow POR as an element property value
|
||||
RigFemResultAddress porElementResAddr( RIG_ELEMENT, "POR", "" );
|
||||
RigFemResultAddress poissonResAddr( RIG_ELEMENT, "RATIO", "" );
|
||||
RigFemResultAddress ucsResAddr( RIG_ELEMENT, "UCS", "" );
|
||||
|
||||
const RigFemPart* femPart = m_caseData->femParts()->part( 0 );
|
||||
// Allow POR as an element property value
|
||||
RigFemResultAddress ppSandElementPropertyAddr = RigWbsParameter::PP_Sand().femAddress(
|
||||
RigWbsParameter::ELEMENT_PROPERTY_TABLE );
|
||||
|
||||
RigFemResultAddress poissonResAddr = RigWbsParameter::poissonRatio().femAddress(
|
||||
RigWbsParameter::ELEMENT_PROPERTY_TABLE );
|
||||
RigFemResultAddress ucsResAddr = RigWbsParameter::UCS().femAddress( RigWbsParameter::ELEMENT_PROPERTY_TABLE );
|
||||
|
||||
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
|
||||
|
||||
// Load results
|
||||
@ -461,49 +495,41 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
{
|
||||
vertexStresses.push_back( caf::Ten3d( floatTensor ) );
|
||||
}
|
||||
std::vector<float> porePressures = resultCollection->resultValues( porBarResAddr, 0, frameIndex );
|
||||
std::vector<float> poreElementPressuresPascal = resultCollection->resultValues( porElementResAddr, 0, frameIndex );
|
||||
std::vector<float> poissonRatios = resultCollection->resultValues( poissonResAddr, 0, frameIndex );
|
||||
std::vector<float> ucsValuesPascal = resultCollection->resultValues( ucsResAddr, 0, frameIndex );
|
||||
|
||||
std::vector<float> interpolatedInterfacePorePressuresBar = interpolateInterfaceValues<float>( porBarResAddr,
|
||||
porePressures );
|
||||
|
||||
std::vector<caf::Ten3d> interpolatedInterfaceStressBar = interpolateInterfaceValues<caf::Ten3d>( stressResAddr,
|
||||
std::vector<caf::Ten3d> interpolatedInterfaceStressBar = interpolateInterfaceValues( stressResAddr,
|
||||
frameIndex,
|
||||
vertexStresses );
|
||||
|
||||
values->resize( m_intersections.size(), 0.0f );
|
||||
|
||||
std::vector<double> ppSandAllSegments( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<WbsParameterSource> ppSources = calculateWbsParameterForAllSegments( RigWbsParameter::PP_Sand(),
|
||||
RigWbsParameter::GRID,
|
||||
frameIndex,
|
||||
&ppSandAllSegments );
|
||||
|
||||
std::vector<double> poissonAllSegments( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::poissonRatio(), frameIndex, &poissonAllSegments );
|
||||
|
||||
std::vector<double> ucsAllSegments( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::UCS(), frameIndex, &ucsAllSegments );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
RigElementType elmType = femPart->elementType( elmIdx );
|
||||
|
||||
if ( !( elmType == HEX8 || elmType == HEX8P ) ) continue;
|
||||
|
||||
cvf::Vec3f centroid = cellCentroid( intersectionIdx );
|
||||
|
||||
double trueVerticalDepth = -centroid.z();
|
||||
double effectiveDepthMeters = trueVerticalDepth + m_rkbDiff;
|
||||
double hydroStaticPorePressureBar = pascalToBar( effectiveDepthMeters * UNIT_WEIGHT_OF_WATER );
|
||||
|
||||
auto ppSourcePair = calculatePorePressureInSegment( intersectionIdx,
|
||||
effectiveDepthMeters,
|
||||
interpolatedInterfacePorePressuresBar,
|
||||
poreElementPressuresPascal );
|
||||
double porePressureBar = ppSourcePair.first;
|
||||
|
||||
// FG is for sands, SFG for shale. Sands has valid PP, shale does not.
|
||||
bool isFGregion = ppSourcePair.second != INVALID;
|
||||
bool isFGregion = ppSources[intersectionIdx] == RigWbsParameter::GRID;
|
||||
|
||||
if ( ppSourcePair.second == INVALID )
|
||||
double hydroStaticPorePressureBar = hydroStaticPorePressureForSegment( intersectionIdx );
|
||||
|
||||
double porePressureBar = ppSandAllSegments[intersectionIdx];
|
||||
if ( porePressureBar == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
porePressureBar = hydroStaticPorePressureBar;
|
||||
}
|
||||
|
||||
double poissonRatio = calculatePoissonRatioInSegment( intersectionIdx, poissonRatios ).first;
|
||||
double ucsBar = calculateUcsInSegment( intersectionIdx, ucsValuesPascal ).first;
|
||||
double poissonRatio = poissonAllSegments[intersectionIdx];
|
||||
double ucsBar = ucsAllSegments[intersectionIdx];
|
||||
|
||||
caf::Ten3d segmentStress;
|
||||
bool validSegmentStress = averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
@ -517,7 +543,7 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
|
||||
RigGeoMechBoreHoleStressCalculator sigmaCalculator( wellPathStressDouble, porePressureBar, poissonRatio, ucsBar, 32 );
|
||||
double resultValue = std::numeric_limits<double>::infinity();
|
||||
if ( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() )
|
||||
if ( resAddr.fieldName == RiaDefines::wbsFGResult().toStdString() )
|
||||
{
|
||||
if ( isFGregion && validSegmentStress )
|
||||
{
|
||||
@ -526,7 +552,7 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
}
|
||||
else
|
||||
{
|
||||
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() );
|
||||
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsSFGResult().toStdString() );
|
||||
if ( !isFGregion && validSegmentStress )
|
||||
{
|
||||
resultValue = sigmaCalculator.solveStassiDalia();
|
||||
@ -546,36 +572,86 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGeoMechWellLogExtractor::wellPathParameters( const RigFemResultAddress& resAddr,
|
||||
int frameIndex,
|
||||
std::vector<double>* values )
|
||||
void RigGeoMechWellLogExtractor::wellBoreFGShale( int frameIndex, std::vector<double>* values )
|
||||
{
|
||||
CVF_ASSERT( values );
|
||||
CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() ||
|
||||
resAddr.fieldName == RiaDefines::wbsUCSParameterName().toStdString() );
|
||||
|
||||
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
|
||||
|
||||
// Check for element property values
|
||||
RigFemResultAddress elmResAddr( RIG_ELEMENT, resAddr.fieldName, "" );
|
||||
std::vector<float> elmPropertyValues = resultCollection->resultValues( elmResAddr, 0, frameIndex );
|
||||
|
||||
values->resize( m_intersections.size(), 0.0f );
|
||||
|
||||
if ( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() )
|
||||
WbsParameterSource source = m_parameterSources.at( RigWbsParameter::FG_Shale() );
|
||||
if ( source == RigWbsParameter::MATTHEWS_KELLY )
|
||||
{
|
||||
std::vector<double> PP0; // results
|
||||
std::vector<double> K0_FG, OBG0; // parameters
|
||||
|
||||
RigFemResultAddress ppAddr( RIG_WELLPATH_DERIVED, RiaDefines::wbsPPResult().toStdString(), "" );
|
||||
|
||||
curveData( ppAddr, 0, &PP0 );
|
||||
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::K0_FG(), frameIndex, &K0_FG );
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::OBG0(), 0, &OBG0 );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
( *values )[intersectionIdx] = calculatePoissonRatioInSegment( intersectionIdx, elmPropertyValues ).first;
|
||||
if ( !isValid( ( *values )[intersectionIdx] ) )
|
||||
{
|
||||
if ( isValid( PP0[intersectionIdx] ) && isValid( OBG0[intersectionIdx] ) &&
|
||||
isValid( K0_FG[intersectionIdx] ) )
|
||||
{
|
||||
( *values )[intersectionIdx] = ( K0_FG[intersectionIdx] *
|
||||
( OBG0[intersectionIdx] - PP0[intersectionIdx] ) +
|
||||
PP0[intersectionIdx] ) /
|
||||
hydroStaticPorePressureForSegment( intersectionIdx );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<double> SH;
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::SH(), frameIndex, &SH );
|
||||
double multiplier = m_userDefinedValues.at( RigWbsParameter::FG_Shale() );
|
||||
CVF_ASSERT( multiplier != std::numeric_limits<double>::infinity() );
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
( *values )[intersectionIdx] = calculateUcsInSegment( intersectionIdx, elmPropertyValues ).first / 100.0;
|
||||
if ( !isValid( ( *values )[intersectionIdx] ) )
|
||||
{
|
||||
if ( isValid( SH[intersectionIdx] ) )
|
||||
{
|
||||
( *values )[intersectionIdx] = SH[intersectionIdx] * multiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGeoMechWellLogExtractor::wellBoreSHMk( int frameIndex, std::vector<double>* values )
|
||||
{
|
||||
std::vector<double> PP, PP0; // results
|
||||
std::vector<double> K0_SH, OBG0, DF; // parameters
|
||||
|
||||
RigFemResultAddress ppAddr( RIG_WELLPATH_DERIVED, RiaDefines::wbsPPResult().toStdString(), "" );
|
||||
|
||||
curveData( ppAddr, frameIndex, &PP );
|
||||
curveData( ppAddr, 0, &PP0 );
|
||||
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::K0_SH(), 0, &K0_SH );
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::OBG0(), 0, &OBG0 );
|
||||
calculateWbsParameterForAllSegments( RigWbsParameter::DF(), 0, &DF );
|
||||
|
||||
values->resize( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
if ( isValid( PP[intersectionIdx] ) && isValid( PP0[intersectionIdx] ) && isValid( OBG0[intersectionIdx] ) &&
|
||||
isValid( K0_SH[intersectionIdx] ) && isValid( DF[intersectionIdx] ) )
|
||||
{
|
||||
( *values )[intersectionIdx] = ( K0_SH[intersectionIdx] * ( OBG0[intersectionIdx] - PP0[intersectionIdx] ) +
|
||||
PP0[intersectionIdx] +
|
||||
DF[intersectionIdx] * ( PP[intersectionIdx] - PP0[intersectionIdx] ) ) /
|
||||
hydroStaticPorePressureForSegment( intersectionIdx );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -599,160 +675,82 @@ void RigGeoMechWellLogExtractor::setRkbDiff( double rkbDiff )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGeoMechWellLogExtractor::setWellLogMdAndMudWeightKgPerM3( const std::vector<std::pair<double, double>>& porePressures )
|
||||
void RigGeoMechWellLogExtractor::setWbsLasValues( const RigWbsParameter& parameter,
|
||||
const std::vector<std::pair<double, double>>& values )
|
||||
{
|
||||
m_wellLogMdAndMudWeightKgPerM3 = porePressures;
|
||||
m_lasFileValues[parameter] = values;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGeoMechWellLogExtractor::setWellLogMdAndUcsBar( const std::vector<std::pair<double, double>>& ucsValues )
|
||||
void RigGeoMechWellLogExtractor::setWbsParametersSource( RigWbsParameter parameter, WbsParameterSource source )
|
||||
{
|
||||
m_wellLogMdAndUcsBar = ucsValues;
|
||||
m_parameterSources[parameter] = source;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigGeoMechWellLogExtractor::setWellLogMdAndPoissonRatio( const std::vector<std::pair<double, double>>& poissonRatios )
|
||||
void RigGeoMechWellLogExtractor::setWbsUserDefinedValue( RigWbsParameter parameter, double userDefinedValue )
|
||||
{
|
||||
m_wellLogMdAndPoissonRatios = poissonRatios;
|
||||
m_userDefinedValues[parameter] = userDefinedValue;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RigGeoMechWellLogExtractor::supportedSourcesForPorePressure()
|
||||
std::vector<double> RigGeoMechWellLogExtractor::porePressureSourceRegions( int frameIndex )
|
||||
{
|
||||
return {AUTO, GRID, LAS_FILE, ELEMENT_PROPERTY_TABLE, HYDROSTATIC_PP};
|
||||
}
|
||||
RigFemResultAddress ppResAddr( RIG_ELEMENT_NODAL, RiaDefines::wbsPPResult().toStdString(), "" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RigGeoMechWellLogExtractor::porePressureIntervals( int frameIndex )
|
||||
{
|
||||
std::vector<double> ppValues( m_intersections.size(), 0.0 );
|
||||
|
||||
RigFemResultAddress porBarResAddr( RIG_ELEMENT_NODAL, "POR-Bar", "" );
|
||||
RigFemResultAddress porElementResAddr( RIG_ELEMENT, "POR", "" );
|
||||
|
||||
const RigFemPart* femPart = m_caseData->femParts()->part( 0 );
|
||||
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
|
||||
|
||||
const std::vector<float>& porePressures = resultCollection->resultValues( porBarResAddr, 0, frameIndex );
|
||||
const std::vector<float>& poreElementPressuresPascal = resultCollection->resultValues( porElementResAddr,
|
||||
0,
|
||||
frameIndex );
|
||||
|
||||
std::vector<float> interpolatedInterfacePorePressureBar;
|
||||
interpolatedInterfacePorePressureBar.resize( m_intersections.size(), std::numeric_limits<float>::infinity() );
|
||||
std::vector<double> values;
|
||||
std::vector<WbsParameterSource> sources = wellPathScaledCurveData( ppResAddr, frameIndex, &values );
|
||||
|
||||
std::vector<double> doubleSources( sources.size(), 0.0 );
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
RigElementType elmType = femPart->elementType( elmIdx );
|
||||
if ( !( elmType == HEX8 || elmType == HEX8P ) ) continue;
|
||||
|
||||
interpolatedInterfacePorePressureBar[intersectionIdx] = interpolateGridResultValue( porBarResAddr.resultPosType,
|
||||
porePressures,
|
||||
intersectionIdx );
|
||||
doubleSources[intersectionIdx] = static_cast<double>( sources[intersectionIdx] );
|
||||
}
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
auto ppSourcePair = calculatePorePressureInSegment( intersectionIdx,
|
||||
0.0,
|
||||
interpolatedInterfacePorePressureBar,
|
||||
poreElementPressuresPascal );
|
||||
if ( ppSourcePair.second == INVALID )
|
||||
{
|
||||
ppValues[intersectionIdx] = static_cast<double>( HYDROSTATIC_PP );
|
||||
}
|
||||
else
|
||||
{
|
||||
ppValues[intersectionIdx] = static_cast<double>( ppSourcePair.second );
|
||||
}
|
||||
}
|
||||
return ppValues;
|
||||
return doubleSources;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RigGeoMechWellLogExtractor::poissonIntervals( int frameIndex )
|
||||
std::vector<double> RigGeoMechWellLogExtractor::poissonSourceRegions( int frameIndex )
|
||||
{
|
||||
std::vector<double> poissonValues( m_intersections.size(), 0.0 );
|
||||
|
||||
RigFemResultAddress poissonResAddr( RIG_ELEMENT, "RATIO", "" );
|
||||
|
||||
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
|
||||
|
||||
std::vector<float> poissonRatios = resultCollection->resultValues( poissonResAddr, 0, frameIndex );
|
||||
std::vector<double> outputValues;
|
||||
std::vector<WbsParameterSource> sources = calculateWbsParameterForAllSegments( RigWbsParameter::poissonRatio(),
|
||||
frameIndex,
|
||||
&outputValues );
|
||||
|
||||
std::vector<double> doubleSources( sources.size(), 0.0 );
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
auto poissonSourcePair = calculatePoissonRatioInSegment( intersectionIdx, poissonRatios );
|
||||
poissonValues[intersectionIdx] = static_cast<double>( poissonSourcePair.second );
|
||||
doubleSources[intersectionIdx] = static_cast<double>( sources[intersectionIdx] );
|
||||
}
|
||||
return poissonValues;
|
||||
return doubleSources;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RigGeoMechWellLogExtractor::ucsIntervals( int frameIndex )
|
||||
std::vector<double> RigGeoMechWellLogExtractor::ucsSourceRegions( int frameIndex )
|
||||
{
|
||||
std::vector<double> ucsValues( m_intersections.size(), 0.0 );
|
||||
|
||||
RigFemResultAddress ucsResAddr( RIG_ELEMENT, "UCS", "" );
|
||||
|
||||
RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults();
|
||||
|
||||
std::vector<float> ucsValuesPascal = resultCollection->resultValues( ucsResAddr, 0, frameIndex );
|
||||
std::vector<double> outputValues;
|
||||
std::vector<WbsParameterSource> sources = calculateWbsParameterForAllSegments( RigWbsParameter::UCS(),
|
||||
frameIndex,
|
||||
&outputValues );
|
||||
|
||||
std::vector<double> doubleSources( sources.size(), 0.0 );
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
auto ucsSourcePair = calculateUcsInSegment( intersectionIdx, ucsValuesPascal );
|
||||
ucsValues[intersectionIdx] = static_cast<double>( ucsSourcePair.second );
|
||||
doubleSources[intersectionIdx] = static_cast<double>( sources[intersectionIdx] );
|
||||
}
|
||||
return ucsValues;
|
||||
return doubleSources;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1130,7 +1128,8 @@ bool RigGeoMechWellLogExtractor::averageIntersectionValuesToSegmentValue( size_t
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
std::vector<T> RigGeoMechWellLogExtractor::interpolateInterfaceValues( RigFemResultAddress nativeAddr,
|
||||
const std::vector<T>& unscaledResultValues ) const
|
||||
int frameIndex,
|
||||
const std::vector<T>& unscaledResultValues )
|
||||
{
|
||||
std::vector<T> interpolatedInterfaceValues;
|
||||
initializeResultValues( interpolatedInterfaceValues, m_intersections.size() );
|
||||
@ -1234,15 +1233,18 @@ void RigGeoMechWellLogExtractor::filterColinearSegments( std::vector<double>*
|
||||
std::vector<unsigned char> simpledFilterSegments;
|
||||
std::vector<std::vector<double>> simplerDependentValues( vectorOfDependentValues.size() );
|
||||
|
||||
simplerXValues.push_back( xValues->front() );
|
||||
simplerYValues.push_back( yValues->front() );
|
||||
simpledFilterSegments.push_back( filterSegments->front() );
|
||||
for ( size_t i = 0; i < 2; ++i )
|
||||
{
|
||||
simplerXValues.push_back( ( *xValues )[i] );
|
||||
simplerYValues.push_back( ( *yValues )[i] );
|
||||
simpledFilterSegments.push_back( ( *filterSegments )[i] );
|
||||
|
||||
for ( size_t n = 0; n < vectorOfDependentValues.size(); ++n )
|
||||
{
|
||||
simplerDependentValues[n].push_back( vectorOfDependentValues[n]->front() );
|
||||
simplerDependentValues[n].push_back( ( *vectorOfDependentValues[n] )[i] );
|
||||
}
|
||||
for ( int64_t i = 1; i < int64_t( xValues->size() - 1 ); ++i )
|
||||
}
|
||||
for ( int64_t i = 2; i < int64_t( xValues->size() - 1 ); ++i )
|
||||
{
|
||||
cvf::Vec2d vecIn( ( ( *xValues )[i] - simplerXValues.back() ) / std::max( 1.0, simplerXValues.back() ),
|
||||
( ( *yValues )[i] - simplerYValues.back() ) / std::max( 1.0, simplerYValues.back() ) );
|
||||
@ -1312,13 +1314,23 @@ void RigGeoMechWellLogExtractor::smoothSegments( std::vector<double>*
|
||||
if ( leapSh )
|
||||
{
|
||||
// Update depth of current
|
||||
if ( i == 1 )
|
||||
{
|
||||
( *mds )[i] = maxOriginalMd;
|
||||
if ( !tvds->empty() )
|
||||
{
|
||||
( *tvds )[i] = maxOriginalTvd;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
( *mds )[i] = 0.5 * ( ( *mds )[i] + maxOriginalMd );
|
||||
|
||||
if ( !tvds->empty() )
|
||||
{
|
||||
( *tvds )[i] = 0.5 * ( ( *tvds )[i] + maxOriginalTvd );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update depth of current
|
||||
@ -1341,7 +1353,6 @@ void RigGeoMechWellLogExtractor::smoothSegments( std::vector<double>*
|
||||
maxOriginalTvd = std::max( maxOriginalTvd, originalTVD );
|
||||
}
|
||||
}
|
||||
( *values )[0] = std::numeric_limits<float>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1362,3 +1373,32 @@ std::vector<unsigned char>
|
||||
}
|
||||
return smoothOrFilterSegments;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigGeoMechWellLogExtractor::hydroStaticPorePressureForSegment( size_t intersectionIdx ) const
|
||||
{
|
||||
cvf::Vec3f centroid = cellCentroid( intersectionIdx );
|
||||
double trueVerticalDepth = -centroid.z();
|
||||
double effectiveDepthMeters = trueVerticalDepth + m_rkbDiff;
|
||||
double hydroStaticPorePressurePascal = effectiveDepthMeters * UNIT_WEIGHT_OF_WATER;
|
||||
double hydroStaticPorePressureBar = pascalToBar( hydroStaticPorePressurePascal );
|
||||
return hydroStaticPorePressureBar;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGeoMechWellLogExtractor::isValid( double value )
|
||||
{
|
||||
return value != std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigGeoMechWellLogExtractor::isValid( float value )
|
||||
{
|
||||
return value != std::numeric_limits<float>::infinity();
|
||||
}
|
||||
|
@ -19,10 +19,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RigWbsParameter.h"
|
||||
#include "RigWellLogExtractor.h"
|
||||
|
||||
#include "RigFemResultPosEnum.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafTensor3.h"
|
||||
|
||||
#include "cvfMath.h"
|
||||
@ -48,16 +51,8 @@ class BoundingBox;
|
||||
class RigGeoMechWellLogExtractor : public RigWellLogExtractor
|
||||
{
|
||||
public:
|
||||
enum WbsParameterSource
|
||||
{
|
||||
INVALID = -1,
|
||||
AUTO = 0,
|
||||
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
|
||||
};
|
||||
using WbsParameterSource = RigWbsParameter::Source;
|
||||
using WbsParameterSourceEnum = RigWbsParameter::SourceEnum;
|
||||
|
||||
public:
|
||||
RigGeoMechWellLogExtractor( RigGeoMechCaseData* aCase,
|
||||
@ -74,23 +69,13 @@ public:
|
||||
const RigGeoMechCaseData* caseData();
|
||||
void setRkbDiff( double rkbDiff );
|
||||
|
||||
void setWellLogMdAndMudWeightKgPerM3( const std::vector<std::pair<double, double>>& mudWeightKgPerM3 );
|
||||
void setWellLogMdAndUcsBar( const std::vector<std::pair<double, double>>& ucsValues );
|
||||
void setWellLogMdAndPoissonRatio( const std::vector<std::pair<double, double>>& poissonRatio );
|
||||
void setWbsLasValues( const RigWbsParameter& parameter, const std::vector<std::pair<double, double>>& values );
|
||||
void setWbsParametersSource( RigWbsParameter parameter, WbsParameterSource source );
|
||||
void setWbsUserDefinedValue( RigWbsParameter parameter, double userDefinedValue );
|
||||
|
||||
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 );
|
||||
|
||||
std::vector<double> porePressureIntervals( int frameIndex );
|
||||
std::vector<double> poissonIntervals( int frameIndex );
|
||||
std::vector<double> ucsIntervals( int frameIndex );
|
||||
std::vector<double> porePressureSourceRegions( int frameIndex );
|
||||
std::vector<double> poissonSourceRegions( int frameIndex );
|
||||
std::vector<double> ucsSourceRegions( int frameIndex );
|
||||
|
||||
private:
|
||||
enum WellPathTangentCalculation
|
||||
@ -99,21 +84,25 @@ private:
|
||||
TangentConstantWithinCell
|
||||
};
|
||||
|
||||
std::pair<float, WbsParameterSource>
|
||||
calculatePorePressureInSegment( int64_t intersectionIdx,
|
||||
double effectiveDepthMeters,
|
||||
const std::vector<float>& interpolatedInterfacePorePressuresBar,
|
||||
const std::vector<float>& poreElementPressuresPascal ) const;
|
||||
|
||||
std::pair<float, WbsParameterSource> calculatePoissonRatioInSegment( int64_t intersectionIdx,
|
||||
const std::vector<float>& poissonRatios ) const;
|
||||
std::pair<float, WbsParameterSource> calculateUcsInSegment( int64_t intersectionIdx,
|
||||
const std::vector<float>& ucsValuesPascal ) const;
|
||||
std::vector<WbsParameterSource> calculateWbsParameterForAllSegments( const RigWbsParameter& parameter,
|
||||
WbsParameterSource primarySource,
|
||||
int frameIndex,
|
||||
std::vector<double>* outputValues );
|
||||
std::vector<WbsParameterSource> calculateWbsParameterForAllSegments( const RigWbsParameter& parameter,
|
||||
int frameIndex,
|
||||
std::vector<double>* outputValues );
|
||||
std::vector<WbsParameterSource> calculateWbsParametersForAllSegments( const RigFemResultAddress& resAddr,
|
||||
int frameIndex,
|
||||
std::vector<double>* values );
|
||||
|
||||
void wellPathAngles( const RigFemResultAddress& resAddr, std::vector<double>* values );
|
||||
void wellPathScaledCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
|
||||
std::vector<WbsParameterSource>
|
||||
wellPathScaledCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
|
||||
void wellBoreWallCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
|
||||
void wellPathParameters( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
|
||||
|
||||
void wellBoreFGShale( int frameIndex, std::vector<double>* values );
|
||||
void wellBoreSHMk( int frameIndex, std::vector<double>* values );
|
||||
|
||||
template <typename T>
|
||||
T interpolateGridResultValue( RigFemResultPosEnum resultPosType,
|
||||
const std::vector<T>& gridResultValues,
|
||||
@ -141,7 +130,8 @@ private:
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> interpolateInterfaceValues( RigFemResultAddress nativeAddr,
|
||||
const std::vector<T>& unscaledResultValues ) const;
|
||||
int frameIndex,
|
||||
const std::vector<T>& unscaledResultValues );
|
||||
|
||||
static void initializeResultValues( std::vector<float>& resultValues, size_t resultCount );
|
||||
static void initializeResultValues( std::vector<caf::Ten3d>& resultValues, size_t resultCount );
|
||||
@ -163,18 +153,19 @@ private:
|
||||
|
||||
std::vector<unsigned char> determineFilteringOrSmoothing( const std::vector<double>& porePressures );
|
||||
|
||||
double hydroStaticPorePressureForSegment( size_t intersectionIdx ) const;
|
||||
|
||||
static bool isValid( double value );
|
||||
static bool isValid( float value );
|
||||
|
||||
private:
|
||||
cvf::ref<RigGeoMechCaseData> m_caseData;
|
||||
double m_rkbDiff;
|
||||
std::vector<std::pair<double, double>> m_wellLogMdAndMudWeightKgPerM3;
|
||||
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;
|
||||
std::map<RigWbsParameter, std::vector<std::pair<double, double>>> m_lasFileValues;
|
||||
|
||||
std::map<RigWbsParameter, WbsParameterSource> m_parameterSources;
|
||||
std::map<RigWbsParameter, double> m_userDefinedValues;
|
||||
|
||||
static const double UNIT_WEIGHT_OF_WATER;
|
||||
};
|
||||
|
@ -19,42 +19,283 @@
|
||||
|
||||
#include "cafAssert.h"
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void RigWbsParameter::SourceEnum::setUp()
|
||||
{
|
||||
addItem( RigWbsParameter::GRID, "GRID", "Grid" );
|
||||
addItem( RigWbsParameter::LAS_FILE, "LAS_FILE", "LAS File" );
|
||||
addItem( RigWbsParameter::ELEMENT_PROPERTY_TABLE, "ELEMENT_PROPERTY_TABLE", "Property Table" );
|
||||
addItem( RigWbsParameter::USER_DEFINED, "USER_DEFINED", "User Defined" );
|
||||
addItem( RigWbsParameter::HYDROSTATIC, "HYDROSTATIC", "Hydrostatic" );
|
||||
addItem( RigWbsParameter::MATTHEWS_KELLY, "MATTHEWS_KELLY", "Matthews & Kelly" );
|
||||
addItem( RigWbsParameter::PROPORTIONAL_TO_SH, "PROPORTIONAL_TO_SH", "Proportional to SH" );
|
||||
addItem( RigWbsParameter::INVALID, "UNDEFINED", "Undefined" );
|
||||
setDefault( RigWbsParameter::INVALID );
|
||||
}
|
||||
} // End namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter::RigWbsParameter( const QString& name,
|
||||
const std::vector<std::pair<RigWbsParameter::Source, QString>>& sources )
|
||||
RigWbsParameter::RigWbsParameter( const QString& name, const SourceVector& sources )
|
||||
: m_name( name )
|
||||
, m_currentSource( INVALID )
|
||||
, m_validSources( sources )
|
||||
, m_sources( sources )
|
||||
, m_exclusiveOptions( false )
|
||||
{
|
||||
if ( !m_validSources.empty() )
|
||||
{
|
||||
m_currentSource = m_validSources.front();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWbsParameter::addSource( Source source, const QString& entryName )
|
||||
const QString& RigWbsParameter::name() const
|
||||
{
|
||||
if ( m_currentSource == INVALID )
|
||||
{
|
||||
m_currentSource = source;
|
||||
}
|
||||
m_validSources.push_back( std::make_pair( source, entryName ) );
|
||||
return m_name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter::Source RigWbsParameter::currentSource() const
|
||||
std::vector<RigWbsParameter::Source> RigWbsParameter::sources() const
|
||||
{
|
||||
return m_currentSource;
|
||||
std::vector<RigWbsParameter::Source> allValidSources;
|
||||
for ( auto sourceEntryPair : m_sources )
|
||||
{
|
||||
allValidSources.push_back( sourceEntryPair.first );
|
||||
}
|
||||
return allValidSources;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWbsParameter::setCurrentSource( Source source ) {}
|
||||
QString RigWbsParameter::addressString( Source source ) const
|
||||
{
|
||||
return address( source ).primary;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigFemResultAddress RigWbsParameter::femAddress( Source source ) const
|
||||
{
|
||||
RigFemResultPosEnum posType = RIG_WELLPATH_DERIVED;
|
||||
if ( source == GRID )
|
||||
posType = RIG_ELEMENT_NODAL;
|
||||
else if ( source == ELEMENT_PROPERTY_TABLE )
|
||||
posType = RIG_ELEMENT;
|
||||
|
||||
auto addr = address( source );
|
||||
return RigFemResultAddress( posType, addr.primary.toStdString(), addr.secondary.toStdString() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigWbsParameter::exclusiveOptions() const
|
||||
{
|
||||
return m_exclusiveOptions;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set options to be exclusive rathern than an order of preference
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWbsParameter::setOptionsExclusive( bool exclusive )
|
||||
{
|
||||
m_exclusiveOptions = exclusive;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString>
|
||||
RigWbsParameter::allSourceLabels( const QString& delimiter /*= " "*/,
|
||||
double userDefinedValue /*= std::numeric_limits<double>::infinity() */ )
|
||||
{
|
||||
std::vector<QString> allLabels;
|
||||
for ( size_t i = 0; i < SourceEnum::size(); ++i )
|
||||
{
|
||||
allLabels.push_back( sourceLabel( SourceEnum::fromIndex( i ), delimiter, userDefinedValue ) );
|
||||
}
|
||||
return allLabels;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RigWbsParameter::sourceLabel( Source currentSource,
|
||||
const QString& delimiter,
|
||||
double userDefinedValue /*= std::numeric_limits<double>::infinity() */ )
|
||||
{
|
||||
QString sourceLabel;
|
||||
if ( currentSource == USER_DEFINED )
|
||||
{
|
||||
sourceLabel = QString( "%1 = %2" ).arg( m_name ).arg( userDefinedValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceLabel = QString( "%1 = %2" ).arg( m_name ).arg( SourceEnum::uiText( currentSource ) );
|
||||
}
|
||||
sourceLabel.replace( " ", delimiter );
|
||||
return sourceLabel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigWbsParameter::operator==( const RigWbsParameter& rhs ) const
|
||||
{
|
||||
return m_name == rhs.m_name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigWbsParameter::operator<( const RigWbsParameter& rhs ) const
|
||||
{
|
||||
return m_name < rhs.m_name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::PP_Sand()
|
||||
{
|
||||
SourceVector sources = {{GRID, SourceAddress( "POR-Bar" )},
|
||||
{LAS_FILE, SourceAddress( "POR" )},
|
||||
{ELEMENT_PROPERTY_TABLE, SourceAddress( "POR" )}};
|
||||
return RigWbsParameter( "PP", sources );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::PP_Shale()
|
||||
{
|
||||
return RigWbsParameter( "PP Shale",
|
||||
{{LAS_FILE, SourceAddress( "POR_Shale" )},
|
||||
{HYDROSTATIC, SourceAddress( "Hydrostatic" )},
|
||||
{USER_DEFINED, SourceAddress()}} );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::poissonRatio()
|
||||
{
|
||||
return RigWbsParameter( "Poisson Ratio",
|
||||
{{LAS_FILE, SourceAddress( "POISSON_RATIO" )},
|
||||
{ELEMENT_PROPERTY_TABLE, SourceAddress( "RATIO" )},
|
||||
{USER_DEFINED, SourceAddress()}} );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::UCS()
|
||||
{
|
||||
return RigWbsParameter( "UCS",
|
||||
{{LAS_FILE, SourceAddress( "UCS" )},
|
||||
{ELEMENT_PROPERTY_TABLE, SourceAddress( "RATIO" )},
|
||||
{USER_DEFINED, SourceAddress()}} );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::OBG()
|
||||
{
|
||||
std::vector<std::pair<Source, SourceAddress>> sources = {{GRID, SourceAddress( "ST", "S33" )}};
|
||||
return RigWbsParameter( "OBG", sources );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::OBG0()
|
||||
{
|
||||
std::vector<std::pair<Source, SourceAddress>> sources = {{GRID, SourceAddress( "ST", "S33", 0 )}};
|
||||
return RigWbsParameter( "OBG0", sources );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::SH()
|
||||
{
|
||||
std::vector<std::pair<Source, SourceAddress>> sources = {{GRID, SourceAddress( "ST", "S3" )}};
|
||||
return RigWbsParameter( "SH", sources );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::DF()
|
||||
{
|
||||
return RigWbsParameter( "DF",
|
||||
{{LAS_FILE, SourceAddress( "DF" )},
|
||||
{ELEMENT_PROPERTY_TABLE, SourceAddress( "DF" )},
|
||||
{USER_DEFINED, SourceAddress()}} );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::K0_FG()
|
||||
{
|
||||
return RigWbsParameter( "K0_FG", {{LAS_FILE, SourceAddress( "K0_FG" )}, {USER_DEFINED, SourceAddress()}} );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::K0_SH()
|
||||
{
|
||||
return RigWbsParameter( "K0_SH", {{LAS_FILE, SourceAddress( "K0_SH" )}, {USER_DEFINED, SourceAddress()}} );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter RigWbsParameter::FG_Shale()
|
||||
{
|
||||
RigWbsParameter param( "FG Shale", {{MATTHEWS_KELLY, SourceAddress()}, {PROPORTIONAL_TO_SH, SourceAddress()}} );
|
||||
param.setOptionsExclusive( true );
|
||||
return param;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigWbsParameter> RigWbsParameter::allParameters()
|
||||
{
|
||||
return {PP_Sand(), PP_Shale(), poissonRatio(), UCS(), OBG(), OBG0(), SH(), DF(), K0_FG(), K0_SH(), FG_Shale()};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RigWbsParameter::findParameter( QString parameterName, RigWbsParameter* foundParam /* = nullptr*/ )
|
||||
{
|
||||
auto params = allParameters();
|
||||
auto it = params.find( parameterName );
|
||||
if ( it != params.end() )
|
||||
{
|
||||
if ( foundParam ) *foundParam = *it;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigWbsParameter::SourceAddress RigWbsParameter::address( Source source ) const
|
||||
{
|
||||
for ( auto sourceEntryPair : m_sources )
|
||||
{
|
||||
if ( sourceEntryPair.first == source ) return sourceEntryPair.second;
|
||||
}
|
||||
return SourceAddress();
|
||||
}
|
||||
|
102
ApplicationCode/ReservoirDataModel/RigWbsParameter.h
Normal file
102
ApplicationCode/ReservoirDataModel/RigWbsParameter.h
Normal file
@ -0,0 +1,102 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2019- Ceetron Solutions AS
|
||||
//
|
||||
// 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 "cafAppEnum.h"
|
||||
|
||||
#include "RigFemResultAddress.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <set>
|
||||
|
||||
class RigWbsParameter
|
||||
{
|
||||
struct SourceAddress;
|
||||
|
||||
public:
|
||||
enum Source
|
||||
{
|
||||
GRID = 0,
|
||||
LAS_FILE,
|
||||
ELEMENT_PROPERTY_TABLE,
|
||||
USER_DEFINED,
|
||||
HYDROSTATIC,
|
||||
MATTHEWS_KELLY, // FG in shale
|
||||
PROPORTIONAL_TO_SH, // FG in shale
|
||||
INVALID = 1000,
|
||||
};
|
||||
using SourceEnum = caf::AppEnum<Source>;
|
||||
using SourceVector = std::vector<std::pair<Source, SourceAddress>>;
|
||||
|
||||
public:
|
||||
RigWbsParameter( const QString& name = "", const SourceVector& validSources = {} );
|
||||
|
||||
const QString& name() const;
|
||||
std::vector<Source> sources() const;
|
||||
QString addressString( Source source ) const;
|
||||
RigFemResultAddress femAddress( Source source ) const;
|
||||
bool exclusiveOptions() const;
|
||||
void setOptionsExclusive( bool exclusive );
|
||||
|
||||
std::vector<QString> allSourceLabels( const QString& delimiter = " ",
|
||||
double userDefinedValue = std::numeric_limits<double>::infinity() );
|
||||
QString sourceLabel( Source currentSource,
|
||||
const QString& delimiter = " ",
|
||||
double userDefinedValue = std::numeric_limits<double>::infinity() );
|
||||
|
||||
bool operator==( const RigWbsParameter& rhs ) const;
|
||||
bool operator<( const RigWbsParameter& rhs ) const;
|
||||
|
||||
static RigWbsParameter PP_Sand();
|
||||
static RigWbsParameter PP_Shale();
|
||||
static RigWbsParameter poissonRatio();
|
||||
static RigWbsParameter UCS();
|
||||
static RigWbsParameter OBG();
|
||||
static RigWbsParameter OBG0();
|
||||
static RigWbsParameter SH();
|
||||
static RigWbsParameter DF();
|
||||
static RigWbsParameter K0_FG();
|
||||
static RigWbsParameter K0_SH();
|
||||
static RigWbsParameter FG_Shale();
|
||||
|
||||
static std::set<RigWbsParameter> allParameters();
|
||||
static bool findParameter( QString parameterName, RigWbsParameter* foundParam = nullptr );
|
||||
|
||||
private:
|
||||
struct SourceAddress
|
||||
{
|
||||
RigFemResultPosEnum resType;
|
||||
QString primary; // i.e. grid field name, las entry, etc.
|
||||
QString secondary; // i.e. grid component name
|
||||
int timeStep;
|
||||
SourceAddress( QString primary = "", QString secondary = "", int timeStep = -1 )
|
||||
: primary( primary )
|
||||
, secondary( secondary )
|
||||
, timeStep( timeStep )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
SourceAddress address( Source source ) const;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
std::vector<std::pair<Source, SourceAddress>> m_sources;
|
||||
bool m_exclusiveOptions; // Options are exclusive rather than order of preference
|
||||
};
|
Loading…
Reference in New Issue
Block a user