Add additional WBS curves and rewrite parameters

This commit is contained in:
Gaute Lindkvist 2019-11-06 10:07:56 +01:00
parent 4f4c48635b
commit 431f0ff347
15 changed files with 1251 additions and 734 deletions

View File

@ -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(),
};
}
//--------------------------------------------------------------------------------------------------

View File

@ -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

View File

@ -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};

View File

@ -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()];

View File

@ -186,12 +186,12 @@ QList<caf::PdmOptionItemInfo>
{
if ( &m_resultPositionTypeUiField == fieldNeedingOptions )
{
std::vector<RigFemResultPosEnum> optionItems = {RIG_NODAL,
RIG_ELEMENT_NODAL,
RIG_INTEGRATION_POINT,
RIG_ELEMENT_NODAL_FACE,
RIG_FORMATION_NAMES,
RIG_ELEMENT};
std::vector<RigFemResultPosEnum> optionItems = { RIG_NODAL,
RIG_ELEMENT_NODAL,
RIG_INTEGRATION_POINT,
RIG_ELEMENT_NODAL_FACE,
RIG_FORMATION_NAMES,
RIG_ELEMENT };
if ( m_addWellPathDerivedResults )
{
optionItems.push_back( RIG_WELLPATH_DERIVED );
@ -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" ), "" );

View File

@ -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();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimWellBoreStabilityPlot::userDefinedUcs() const
{
return m_userDefinedUcs();
auto field = sourceField( parameter );
if ( field )
{
*field = source;
}
}
//--------------------------------------------------------------------------------------------------
@ -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 ) );
}
}
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 ) );
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] ) );
}
}
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;
}
if ( !supportedSourcesForUcs().count( m_ucsSource() ) )
{
m_ucsSource = RigGeoMechWellLogExtractor::AUTO;
caf::PdmField<ParameterSourceEnum>* field = sourceField( parameter );
if ( field )
{
assignValidSource( field, supportedSources( parameter ) );
}
}
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 );
}
}
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
{
RigFemResultAddress resAddr( RIG_ELEMENT, "POR", "" );
if ( hasElementPropertyEntry( resAddr ) )
{
sources.insert( source );
}
}
else
{
sources.insert( source );
}
return it->second;
}
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;

View File

@ -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;
};

View File

@ -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,38 +527,92 @@ 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 );
}
geomExtractor->setWellLogMdAndMudWeightKgPerM3( logFileMudWeights );
}
std::vector<std::pair<double, double>> logFileUcs = RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath,
"UCS" );
if ( !logFileUcs.empty() )
{
// TODO: UCS is typically in MPa, but not necessarily.
// We need to at least give a warning if the units don't match
// ... and preferable do a conversion.
for ( auto& ucsValue : logFileUcs )
else if ( parameter == RigWbsParameter::UCS() )
{
ucsValue.second *= 10.0; // MPa -> Bar
findAndLoadUcsFromLasFiles( wellPath, geomExtractor );
}
geomExtractor->setWellLogMdAndUcsBar( logFileUcs );
}
else
{
// Generic LAS
QString lasAddress = parameter.addressString( RigWbsParameter::LAS_FILE );
std::vector<std::pair<double, double>> logFilePoissonRatio =
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "POISSON_RATIO" );
if ( !logFilePoissonRatio.empty() )
std::vector<std::pair<double, double>> lasFileValues =
RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, lasAddress );
if ( !lasFileValues.empty() )
{
geomExtractor->setWbsLasValues( parameter, lasFileValues );
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::findAndLoadUcsFromLasFiles( const RimWellPath* wellPath,
RigGeoMechWellLogExtractor* geomExtractor )
{
{
geomExtractor->setWellLogMdAndPoissonRatio( logFilePoissonRatio );
QString lasAddress = RigWbsParameter::UCS().addressString( RigWbsParameter::LAS_FILE );
std::vector<std::pair<double, double>> logFileUcs = RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath,
lasAddress );
if ( !logFileUcs.empty() )
{
// TODO: UCS is typically in MPa, but not necessarily.
// We need to at least give a warning if the units don't match
// ... and preferable do a conversion.
for ( auto& ucsValue : logFileUcs )
{
ucsValue.second *= 10.0; // MPa -> Bar
}
geomExtractor->setWbsLasValues( RigWbsParameter::UCS(), logFileUcs );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::findAndLoadPorePressuresFromLasFiles( const RimWellPath* wellPath,
const RigWbsParameter& parameter,
RigGeoMechWellLogExtractor* geomExtractor )
{
{
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 );
}
}
}

View File

@ -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:

View File

@ -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
minValue = 0;
maxValue = 0;
}
// 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,25 +688,38 @@ void RimWellLogTrack::updateXAxisAndGridTickIntervals()
{
if ( !m_plotWidget ) return;
if ( m_explicitTickIntervals )
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->setMajorAndMinorTickIntervals( QwtPlot::xTop,
m_majorTickInterval(),
m_minorTickInterval(),
m_visibleXRangeMin(),
m_visibleXRangeMax() );
m_plotWidget->enableGridLines( QwtPlot::xTop, false, false );
m_plotWidget->setAxisRange( QwtPlot::xTop, 0.0, 0.0 );
m_plotWidget->setAxisLabelsAndTicksEnabled( QwtPlot::xTop, false );
}
else
{
int majorTickIntervals = 5;
int minorTickIntervals = 10;
m_plotWidget->setAutoTickIntervalCounts( QwtPlot::xTop, majorTickIntervals, minorTickIntervals );
m_plotWidget->setAxisRange( QwtPlot::xTop, m_visibleXRangeMin, m_visibleXRangeMax );
}
m_plotWidget->setAxisLabelsAndTicksEnabled( QwtPlot::xTop, true );
if ( m_explicitTickIntervals )
{
m_plotWidget->setMajorAndMinorTickIntervals( QwtPlot::xTop,
m_majorTickInterval(),
m_minorTickInterval(),
m_visibleXRangeMin(),
m_visibleXRangeMax() );
}
else
{
int majorTickIntervals = 5;
int minorTickIntervals = 10;
m_plotWidget->setAutoTickIntervalCounts( QwtPlot::xTop, majorTickIntervals, minorTickIntervals );
m_plotWidget->setAxisRange( QwtPlot::xTop, m_visibleXRangeMin, m_visibleXRangeMax );
}
m_plotWidget->enableGridLines( QwtPlot::xTop,
m_xAxisGridVisibility() & RimWellLogPlot::AXIS_GRID_MAJOR,
m_xAxisGridVisibility() & RimWellLogPlot::AXIS_GRID_MINOR );
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;

View File

@ -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

View File

@ -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 );
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;
double hydroStaticPorePressureForSegment( size_t intersectionIdx ) const;
WbsParameterSource m_porePressureSource;
WbsParameterSource m_poissonRatioSource;
WbsParameterSource m_ucsSource;
double m_userDefinedPoissonRatio;
double m_userDefinedUcs;
static bool isValid( double value );
static bool isValid( float value );
private:
cvf::ref<RigGeoMechCaseData> m_caseData;
double m_rkbDiff;
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;
};

View File

@ -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() )
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString& RigWbsParameter::name() const
{
return m_name;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigWbsParameter::Source> RigWbsParameter::sources() const
{
std::vector<RigWbsParameter::Source> allValidSources;
for ( auto sourceEntryPair : m_sources )
{
m_currentSource = m_validSources.front();
allValidSources.push_back( sourceEntryPair.first );
}
return allValidSources;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigWbsParameter::addSource( Source source, const QString& entryName )
QString RigWbsParameter::addressString( Source source ) const
{
if ( m_currentSource == INVALID )
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 )
{
m_currentSource = source;
allLabels.push_back( sourceLabel( SourceEnum::fromIndex( i ), delimiter, userDefinedValue ) );
}
m_validSources.push_back( std::make_pair( source, entryName ) );
return allLabels;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigWbsParameter::Source RigWbsParameter::currentSource() const
QString RigWbsParameter::sourceLabel( Source currentSource,
const QString& delimiter,
double userDefinedValue /*= std::numeric_limits<double>::infinity() */ )
{
return m_currentSource;
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;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigWbsParameter::setCurrentSource( Source source ) {}
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();
}

View 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
};