mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4799 WBS: Make PP go up to seabed and ensure sources are kept valid when source stepping.
This commit is contained in:
parent
62c48d3cdb
commit
2d2a5201d0
@ -68,12 +68,16 @@ RimWellBoreStabilityPlot::RimWellBoreStabilityPlot()
|
||||
"" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_ucsSource, "UcsSource", "Uniaxial Compressive Strength", "", "Data source for UCS", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_userDefinedPoissionRatio, "UserPoissionRatio", 0.25, "", "", "User defined Poisson Ratio", "" );
|
||||
m_userDefinedPoissionRatio.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
CAF_PDM_InitField( &m_userDefinedPoissionRatio,
|
||||
"UserPoissionRatio",
|
||||
0.25,
|
||||
"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]", "" );
|
||||
m_userDefinedUcs.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
CAF_PDM_InitField( &m_userDefinedUcs, "UserUcs", 100.0, "User defined UCS [bar]", "", "User defined UCS [bar]", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -126,13 +130,9 @@ void RimWellBoreStabilityPlot::defineUiOrdering( QString uiConfigName, caf::PdmU
|
||||
caf::PdmUiGroup* parameterSources = uiOrdering.addNewGroup( "Parameter Sources" );
|
||||
parameterSources->add( &m_porePressureSource );
|
||||
parameterSources->add( &m_poissonRatioSource );
|
||||
parameterSources->add( &m_userDefinedPoissionRatio, {false, 1, 1} );
|
||||
parameterSources->add( &m_userDefinedPoissionRatio );
|
||||
parameterSources->add( &m_ucsSource );
|
||||
parameterSources->add( &m_userDefinedUcs, {false, 1, 1} );
|
||||
|
||||
m_userDefinedPoissionRatio.uiCapability()->setUiReadOnly( m_poissonRatioSource() !=
|
||||
RigGeoMechWellLogExtractor::USER_DEFINED );
|
||||
m_userDefinedUcs.uiCapability()->setUiReadOnly( m_ucsSource() != RigGeoMechWellLogExtractor::USER_DEFINED );
|
||||
parameterSources->add( &m_userDefinedUcs );
|
||||
|
||||
uiOrderingForDepthAxis( uiOrdering );
|
||||
uiOrderingForPlotSettings( uiOrdering );
|
||||
@ -148,89 +148,25 @@ QList<caf::PdmOptionItemInfo>
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options = RimWellLogPlot::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
||||
|
||||
RimWellPath* wellPath = m_commonDataSource->wellPathToApply();
|
||||
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>( m_commonDataSource->caseToApply() );
|
||||
int timeStep = m_commonDataSource->timeStepToApply();
|
||||
|
||||
RigFemPartResultsCollection* femPartResults = nullptr;
|
||||
if ( geoMechCase )
|
||||
{
|
||||
femPartResults = geoMechCase->geoMechData()->femPartResults();
|
||||
}
|
||||
|
||||
if ( fieldNeedingOptions == &m_porePressureSource )
|
||||
{
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForPorePressure() )
|
||||
for ( auto source : supportedSourcesForPorePressure() )
|
||||
{
|
||||
if ( source == RigGeoMechWellLogExtractor::LAS_FILE )
|
||||
{
|
||||
if ( wellPath && !RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "PP" ).empty() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
RigFemResultAddress resAddr( RIG_ELEMENT, "POR", "" );
|
||||
if ( timeStep > 0 && femPartResults && !femPartResults->resultValues( resAddr, 0, timeStep ).empty() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_poissonRatioSource )
|
||||
{
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForPoissonRatio() )
|
||||
for ( auto source : supportedSourcesForPoisson() )
|
||||
{
|
||||
if ( source == RigGeoMechWellLogExtractor::LAS_FILE )
|
||||
{
|
||||
if ( wellPath && !RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "POISSON_RATIO" ).empty() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
RigFemResultAddress resAddr( RIG_ELEMENT, "RATIO", "" );
|
||||
if ( timeStep > 0 && femPartResults && !femPartResults->resultValues( resAddr, 0, timeStep ).empty() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_ucsSource )
|
||||
{
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForUcs() )
|
||||
for ( auto source : supportedSourcesForUcs() )
|
||||
{
|
||||
if ( source == RigGeoMechWellLogExtractor::LAS_FILE )
|
||||
{
|
||||
if ( wellPath && !RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, "UCS" ).empty() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
RigFemResultAddress resAddr( RIG_ELEMENT, "UCS", "" );
|
||||
if ( timeStep > 0 && femPartResults && !femPartResults->resultValues( resAddr, 0, timeStep ).empty() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
options.push_back( caf::PdmOptionItemInfo( ParameterSourceEnum::uiText( source ), source ) );
|
||||
}
|
||||
}
|
||||
return options;
|
||||
@ -251,3 +187,155 @@ void RimWellBoreStabilityPlot::fieldChangedByUi( const caf::PdmFieldHandle* chan
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellBoreStabilityPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
if ( !supportedSourcesForPorePressure().count( m_porePressureSource() ) )
|
||||
{
|
||||
m_porePressureSource = RigGeoMechWellLogExtractor::AUTO;
|
||||
}
|
||||
|
||||
if ( !supportedSourcesForPoisson().count( m_poissonRatioSource() ) )
|
||||
{
|
||||
m_poissonRatioSource = RigGeoMechWellLogExtractor::AUTO;
|
||||
}
|
||||
|
||||
if ( !supportedSourcesForUcs().count( m_ucsSource() ) )
|
||||
{
|
||||
m_ucsSource = RigGeoMechWellLogExtractor::AUTO;
|
||||
}
|
||||
|
||||
RimWellLogPlot::onLoadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimWellBoreStabilityPlot::hasLasFileWithChannel( const QString& channel ) const
|
||||
{
|
||||
RimWellPath* wellPath = m_commonDataSource->wellPathToApply();
|
||||
if ( wellPath && !RimWellLogFile::findMdAndChannelValuesForWellPath( wellPath, channel ).empty() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimWellBoreStabilityPlot::hasElementPropertyEntry( const RigFemResultAddress& resAddr ) const
|
||||
{
|
||||
int timeStep = m_commonDataSource->timeStepToApply();
|
||||
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>( m_commonDataSource->caseToApply() );
|
||||
|
||||
RigFemPartResultsCollection* femPartResults = nullptr;
|
||||
if ( geoMechCase && timeStep > 0 )
|
||||
{
|
||||
femPartResults = geoMechCase->geoMechData()->femPartResults();
|
||||
if ( femPartResults )
|
||||
{
|
||||
return !femPartResults->resultValues( resAddr, 0, timeStep ).empty();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RimWellBoreStabilityPlot::supportedSourcesForPorePressure() const
|
||||
{
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> sources;
|
||||
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForPorePressure() )
|
||||
{
|
||||
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 sources;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> RimWellBoreStabilityPlot::supportedSourcesForPoisson() const
|
||||
{
|
||||
std::set<RigGeoMechWellLogExtractor::WbsParameterSource> sources;
|
||||
|
||||
for ( auto source : RigGeoMechWellLogExtractor::supportedSourcesForPoissonRatio() )
|
||||
{
|
||||
if ( source == RigGeoMechWellLogExtractor::LAS_FILE )
|
||||
{
|
||||
if ( hasLasFileWithChannel( "POISSON_RATIO" ) )
|
||||
{
|
||||
sources.insert( source );
|
||||
}
|
||||
}
|
||||
else if ( source == RigGeoMechWellLogExtractor::ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
RigFemResultAddress resAddr( RIG_ELEMENT, "RATIO", "" );
|
||||
if ( hasElementPropertyEntry( resAddr ) )
|
||||
{
|
||||
sources.insert( 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 );
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
@ -57,6 +57,15 @@ protected:
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue ) override;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
caf::PdmField<ParameterSourceEnum> m_porePressureSource;
|
||||
caf::PdmField<ParameterSourceEnum> m_poissonRatioSource;
|
||||
|
@ -109,23 +109,23 @@ void RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAddr,
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float RigGeoMechWellLogExtractor::calculatePorePressureInSegment( int64_t intersectionIdx,
|
||||
float averageSegmentPorePressureBar,
|
||||
double hydroStaticPorePressureBar,
|
||||
double effectiveDepthMeters,
|
||||
const std::vector<float>& poreElementPressuresPascal ) const
|
||||
std::pair<float, RigGeoMechWellLogExtractor::WbsParameterSource> RigGeoMechWellLogExtractor::calculatePorePressureInSegment(
|
||||
int64_t intersectionIdx,
|
||||
double effectiveDepthMeters,
|
||||
const std::vector<float>& interpolatedInterfacePorePressuresBar,
|
||||
const std::vector<float>& poreElementPressuresPascal ) const
|
||||
{
|
||||
// Priority 4: Assign a default of hydrostatic pore pressure
|
||||
double porePressure = hydroStaticPorePressureBar;
|
||||
|
||||
// Priority 3: Try element property tables
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == ELEMENT_PROPERTY_TABLE )
|
||||
// Priority 1: Try pore pressure from the grid
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == GRID )
|
||||
{
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
if ( elmIdx < poreElementPressuresPascal.size() )
|
||||
float averagePorePressureBar = std::numeric_limits<float>::infinity();
|
||||
bool validGridPorePressure = averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
interpolatedInterfacePorePressuresBar,
|
||||
std::numeric_limits<float>::infinity(),
|
||||
&averagePorePressureBar );
|
||||
if ( validGridPorePressure )
|
||||
{
|
||||
// Pore pressure from element property tables are in pascal.
|
||||
porePressure = pascalToBar( poreElementPressuresPascal[elmIdx] );
|
||||
return std::make_pair( averagePorePressureBar, GRID );
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,43 +137,32 @@ float RigGeoMechWellLogExtractor::calculatePorePressureInSegment( int64_t inters
|
||||
{
|
||||
double specificMudWeightNPerM3 = lasMudWeightKgPerM3 * 9.81;
|
||||
double porePressurePascal = specificMudWeightNPerM3 * effectiveDepthMeters;
|
||||
porePressure = pascalToBar( porePressurePascal );
|
||||
double porePressureBar = pascalToBar( porePressurePascal );
|
||||
return std::make_pair( (float)porePressureBar, LAS_FILE );
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 1: Try pore pressure from the grid
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == GRID )
|
||||
// Priority 3: Try element property tables
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
if ( averageSegmentPorePressureBar != std::numeric_limits<double>::infinity() &&
|
||||
averageSegmentPorePressureBar > 0.0 )
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
if ( elmIdx < poreElementPressuresPascal.size() )
|
||||
{
|
||||
porePressure = averageSegmentPorePressureBar;
|
||||
float porePressureBar = pascalToBar( poreElementPressuresPascal[elmIdx] );
|
||||
return std::make_pair( porePressureBar, ELEMENT_PROPERTY_TABLE );
|
||||
}
|
||||
}
|
||||
|
||||
CVF_ASSERT( porePressure >= 0.0 );
|
||||
return porePressure;
|
||||
return std::make_pair( std::numeric_limits<float>::infinity(), INVALID );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float RigGeoMechWellLogExtractor::calculatePoissonRatio( int64_t intersectionIdx,
|
||||
const std::vector<float>& poissonRatios ) const
|
||||
std::pair<float, RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::calculatePoissonRatioInSegment( int64_t intersectionIdx,
|
||||
const std::vector<float>& poissonRatios ) const
|
||||
{
|
||||
// Priority 3: User defined poisson ratio
|
||||
double poissonRatio = m_userDefinedPoissonRatio;
|
||||
|
||||
// Priority 2: Element property table ratio
|
||||
if ( m_poissonRatioSource == AUTO || m_poissonRatioSource == ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
if ( elmIdx < poissonRatios.size() )
|
||||
{
|
||||
poissonRatio = poissonRatios[elmIdx];
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 1: Las-file poisson ratio
|
||||
if ( m_poissonRatioSource == AUTO || m_poissonRatioSource == LAS_FILE )
|
||||
{
|
||||
@ -182,33 +171,32 @@ float RigGeoMechWellLogExtractor::calculatePoissonRatio( int64_t
|
||||
double lasPoissionRatio = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndPoissonRatios );
|
||||
if ( lasPoissionRatio != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
poissonRatio = lasPoissionRatio;
|
||||
return std::make_pair( lasPoissionRatio, LAS_FILE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return poissonRatio;
|
||||
// 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 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
float RigGeoMechWellLogExtractor::calculateUcs( int64_t intersectionIdx, const std::vector<float>& ucsValuesPascal ) const
|
||||
std::pair<float, RigGeoMechWellLogExtractor::WbsParameterSource>
|
||||
RigGeoMechWellLogExtractor::calculateUcsInSegment( int64_t intersectionIdx,
|
||||
const std::vector<float>& ucsValuesPascal ) const
|
||||
{
|
||||
// Priority 3: User defined UCS
|
||||
double uniaxialStrengthInBar = m_userDefinedUcs;
|
||||
|
||||
// Priority 2: From element property table
|
||||
if ( m_ucsSource == AUTO || m_ucsSource == ELEMENT_PROPERTY_TABLE )
|
||||
{
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
if ( elmIdx < ucsValuesPascal.size() )
|
||||
{
|
||||
// Read UCS from element table in Pascal
|
||||
uniaxialStrengthInBar = pascalToBar( ucsValuesPascal[elmIdx] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_ucsSource == AUTO || m_ucsSource == LAS_FILE )
|
||||
{
|
||||
if ( !m_wellLogMdAndUcsBar.empty() )
|
||||
@ -216,12 +204,23 @@ float RigGeoMechWellLogExtractor::calculateUcs( int64_t intersectionIdx, const s
|
||||
double lasUniaxialStrengthInBar = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndUcsBar );
|
||||
if ( lasUniaxialStrengthInBar != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
uniaxialStrengthInBar = lasUniaxialStrengthInBar;
|
||||
return std::make_pair( lasUniaxialStrengthInBar, LAS_FILE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return uniaxialStrengthInBar;
|
||||
// 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
|
||||
float uniaxialStrengthInBar = pascalToBar( ucsValuesPascal[elmIdx] );
|
||||
return std::make_pair( uniaxialStrengthInBar, ELEMENT_PROPERTY_TABLE );
|
||||
}
|
||||
}
|
||||
// Priority 3: User defined UCS (in bar)
|
||||
return std::make_pair( m_userDefinedUcs, USER_DEFINED );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -348,19 +347,21 @@ void RigGeoMechWellLogExtractor::wellPathScaledCurveData( const RigFemResultAddr
|
||||
double hydroStaticPorePressureBar = pascalToBar( effectiveDepthMeters * UNIT_WEIGHT_OF_WATER );
|
||||
|
||||
float averageUnscaledValue = std::numeric_limits<float>::infinity();
|
||||
bool validAverage = averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
interpolatedInterfaceValues,
|
||||
std::numeric_limits<float>::infinity(),
|
||||
&averageUnscaledValue );
|
||||
|
||||
if ( resAddr.fieldName == "PP" && validAverage )
|
||||
if ( resAddr.fieldName == "PP" )
|
||||
{
|
||||
double segmentPorePressureFromGrid = averageUnscaledValue;
|
||||
averageUnscaledValue = calculatePorePressureInSegment( intersectionIdx,
|
||||
segmentPorePressureFromGrid,
|
||||
hydroStaticPorePressureBar,
|
||||
effectiveDepthMeters,
|
||||
poreElementPressuresPascal );
|
||||
auto ppSourcePair = calculatePorePressureInSegment( intersectionIdx,
|
||||
effectiveDepthMeters,
|
||||
interpolatedInterfaceValues,
|
||||
poreElementPressuresPascal );
|
||||
if ( ppSourcePair.second == INVALID )
|
||||
{
|
||||
averageUnscaledValue = hydroStaticPorePressureBar;
|
||||
}
|
||||
else
|
||||
{
|
||||
averageUnscaledValue = ppSourcePair.first;
|
||||
}
|
||||
}
|
||||
|
||||
( *values )[intersectionIdx] = static_cast<double>( averageUnscaledValue ) / hydroStaticPorePressureBar;
|
||||
@ -404,8 +405,8 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
std::vector<float> poissonRatios = resultCollection->resultValues( poissonResAddr, 0, frameIndex );
|
||||
std::vector<float> ucsValuesPascal = resultCollection->resultValues( ucsResAddr, 0, frameIndex );
|
||||
|
||||
std::vector<float> interpolatedInterfacePorePressureBar;
|
||||
interpolatedInterfacePorePressureBar.resize( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
std::vector<float> interpolatedInterfacePorePressuresBar;
|
||||
interpolatedInterfacePorePressuresBar.resize( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
|
||||
std::vector<caf::Ten3d> interpolatedInterfaceStressBar;
|
||||
interpolatedInterfaceStressBar.resize( m_intersections.size() );
|
||||
@ -416,11 +417,11 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
RigElementType elmType = femPart->elementType( elmIdx );
|
||||
if ( !( elmType == HEX8 || elmType == HEX8P ) ) continue;
|
||||
|
||||
interpolatedInterfacePorePressureBar[intersectionIdx] = interpolateGridResultValue( porBarResAddr.resultPosType,
|
||||
porePressures,
|
||||
intersectionIdx,
|
||||
false );
|
||||
interpolatedInterfaceStressBar[intersectionIdx] = interpolateGridResultValue( stressResAddr.resultPosType,
|
||||
interpolatedInterfacePorePressuresBar[intersectionIdx] = interpolateGridResultValue( porBarResAddr.resultPosType,
|
||||
porePressures,
|
||||
intersectionIdx,
|
||||
false );
|
||||
interpolatedInterfaceStressBar[intersectionIdx] = interpolateGridResultValue( stressResAddr.resultPosType,
|
||||
vertexStresses,
|
||||
intersectionIdx,
|
||||
false );
|
||||
@ -442,20 +443,22 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres
|
||||
double effectiveDepthMeters = trueVerticalDepth + m_rkbDiff;
|
||||
double hydroStaticPorePressureBar = pascalToBar( effectiveDepthMeters * UNIT_WEIGHT_OF_WATER );
|
||||
|
||||
float averagePorePressureBar = std::numeric_limits<float>::infinity();
|
||||
bool validGridPorePressure = averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
interpolatedInterfacePorePressureBar,
|
||||
std::numeric_limits<float>::infinity(),
|
||||
&averagePorePressureBar );
|
||||
bool isFGregion = validGridPorePressure; // FG is for sands, SFG for shale. Sands has PP, shale does not.
|
||||
auto ppSourcePair = calculatePorePressureInSegment( intersectionIdx,
|
||||
effectiveDepthMeters,
|
||||
interpolatedInterfacePorePressuresBar,
|
||||
poreElementPressuresPascal );
|
||||
double porePressureBar = ppSourcePair.first;
|
||||
|
||||
double porePressureBar = calculatePorePressureInSegment( intersectionIdx,
|
||||
averagePorePressureBar,
|
||||
hydroStaticPorePressureBar,
|
||||
effectiveDepthMeters,
|
||||
poreElementPressuresPascal );
|
||||
double poissonRatio = calculatePoissonRatio( intersectionIdx, poissonRatios );
|
||||
double ucsBar = calculateUcs( intersectionIdx, ucsValuesPascal );
|
||||
// FG is for sands, SFG for shale. Sands has valid PP, shale does not.
|
||||
bool isFGregion = ppSourcePair.second != INVALID;
|
||||
|
||||
if ( ppSourcePair.second == INVALID )
|
||||
{
|
||||
porePressureBar = hydroStaticPorePressureBar;
|
||||
}
|
||||
|
||||
double poissonRatio = calculatePoissonRatioInSegment( intersectionIdx, poissonRatios ).first;
|
||||
double ucsBar = calculateUcsInSegment( intersectionIdx, ucsValuesPascal ).first;
|
||||
|
||||
caf::Ten3d segmentStress;
|
||||
bool validSegmentStress = averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
@ -592,7 +595,7 @@ std::vector<double> RigGeoMechWellLogExtractor::porePressureIntervals( int frame
|
||||
std::vector<float> poreElementPressuresPascal = resultCollection->resultValues( porElementResAddr, 0, frameIndex );
|
||||
|
||||
std::vector<float> interpolatedInterfacePorePressureBar;
|
||||
interpolatedInterfacePorePressureBar.resize( m_intersections.size(), std::numeric_limits<double>::infinity() );
|
||||
interpolatedInterfacePorePressureBar.resize( m_intersections.size(), std::numeric_limits<float>::infinity() );
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
@ -610,41 +613,17 @@ std::vector<double> RigGeoMechWellLogExtractor::porePressureIntervals( int frame
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
// Priority 4: Hydrostatic pore pressure
|
||||
ppValues[intersectionIdx] = static_cast<double>( HYDROSTATIC_PP );
|
||||
|
||||
// Priority 3: Try element property tables
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == ELEMENT_PROPERTY_TABLE )
|
||||
auto ppSourcePair = calculatePorePressureInSegment( intersectionIdx,
|
||||
0.0,
|
||||
interpolatedInterfacePorePressureBar,
|
||||
poreElementPressuresPascal );
|
||||
if ( ppSourcePair.second == INVALID )
|
||||
{
|
||||
size_t elmIdx = m_intersectedCellsGlobIdx[intersectionIdx];
|
||||
if ( elmIdx < poreElementPressuresPascal.size() )
|
||||
{
|
||||
ppValues[intersectionIdx] = static_cast<double>( ELEMENT_PROPERTY_TABLE );
|
||||
}
|
||||
ppValues[intersectionIdx] = static_cast<double>( HYDROSTATIC_PP );
|
||||
}
|
||||
|
||||
// Priority 2: Try LAS-file
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == LAS_FILE )
|
||||
else
|
||||
{
|
||||
double lasMudWeightKgPerM3 = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndMudWeightKgPerM3 );
|
||||
if ( lasMudWeightKgPerM3 != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
ppValues[intersectionIdx] = static_cast<double>( LAS_FILE );
|
||||
}
|
||||
}
|
||||
|
||||
// Priority 1: Try pore pressure from the grid
|
||||
if ( m_porePressureSource == AUTO || m_porePressureSource == GRID )
|
||||
{
|
||||
float averagePorePressureBar = std::numeric_limits<float>::infinity();
|
||||
bool validGridPorePressure = averageIntersectionValuesToSegmentValue( intersectionIdx,
|
||||
interpolatedInterfacePorePressureBar,
|
||||
std::numeric_limits<float>::infinity(),
|
||||
&averagePorePressureBar );
|
||||
if ( validGridPorePressure )
|
||||
{
|
||||
ppValues[intersectionIdx] = static_cast<double>( GRID );
|
||||
}
|
||||
ppValues[intersectionIdx] = static_cast<double>( ppSourcePair.second );
|
||||
}
|
||||
}
|
||||
return ppValues;
|
||||
@ -665,31 +644,8 @@ std::vector<double> RigGeoMechWellLogExtractor::poissonIntervals( int frameIndex
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
// Priority 3: User defined Poisson ratio
|
||||
poissonValues[intersectionIdx] = static_cast<double>( USER_DEFINED );
|
||||
|
||||
// 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() )
|
||||
{
|
||||
poissonValues[intersectionIdx] = static_cast<double>( ELEMENT_PROPERTY_TABLE );
|
||||
}
|
||||
}
|
||||
|
||||
// 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() )
|
||||
{
|
||||
poissonValues[intersectionIdx] = static_cast<double>( LAS_FILE );
|
||||
}
|
||||
}
|
||||
}
|
||||
auto poissonSourcePair = calculatePoissonRatioInSegment( intersectionIdx, poissonRatios );
|
||||
poissonValues[intersectionIdx] = static_cast<double>( poissonSourcePair.second );
|
||||
}
|
||||
return poissonValues;
|
||||
}
|
||||
@ -710,30 +666,8 @@ std::vector<double> RigGeoMechWellLogExtractor::ucsIntervals( int frameIndex )
|
||||
#pragma omp parallel for
|
||||
for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx )
|
||||
{
|
||||
// Priority 3: User defined Poisson ratio
|
||||
ucsValues[intersectionIdx] = static_cast<double>( USER_DEFINED );
|
||||
|
||||
// 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() )
|
||||
{
|
||||
ucsValues[intersectionIdx] = static_cast<double>( ELEMENT_PROPERTY_TABLE );
|
||||
}
|
||||
}
|
||||
// Priority 1: Las-file
|
||||
if ( m_ucsSource == AUTO || m_ucsSource == LAS_FILE )
|
||||
{
|
||||
if ( !m_wellLogMdAndUcsBar.empty() )
|
||||
{
|
||||
double lasUniaxialStrengthInBar = getWellLogSegmentValue( intersectionIdx, m_wellLogMdAndUcsBar );
|
||||
if ( lasUniaxialStrengthInBar != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
ucsValues[intersectionIdx] = static_cast<double>( LAS_FILE );
|
||||
}
|
||||
}
|
||||
}
|
||||
auto ucsSourcePair = calculateUcsInSegment( intersectionIdx, ucsValuesPascal );
|
||||
ucsValues[intersectionIdx] = static_cast<double>( ucsSourcePair.second );
|
||||
}
|
||||
return ucsValues;
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ class RigGeoMechWellLogExtractor : public RigWellLogExtractor
|
||||
public:
|
||||
enum WbsParameterSource
|
||||
{
|
||||
AUTO,
|
||||
INVALID = -1,
|
||||
AUTO = 0,
|
||||
GRID, // Only relevant for Pore Pressure
|
||||
LAS_FILE,
|
||||
ELEMENT_PROPERTY_TABLE,
|
||||
@ -92,14 +93,16 @@ private:
|
||||
TangentConstantWithinCell
|
||||
};
|
||||
|
||||
float calculatePorePressureInSegment( int64_t intersectionIdx,
|
||||
float averageSegmentPorePressureBar,
|
||||
double hydroStaticPorePressureBar,
|
||||
double effectiveDepthMeters,
|
||||
const std::vector<float>& poreElementPressuresPascal ) const;
|
||||
std::pair<float, WbsParameterSource>
|
||||
calculatePorePressureInSegment( int64_t intersectionIdx,
|
||||
double effectiveDepthMeters,
|
||||
const std::vector<float>& interpolatedInterfacePorePressuresBar,
|
||||
const std::vector<float>& poreElementPressuresPascal ) const;
|
||||
|
||||
float calculatePoissonRatio( int64_t intersectionIdx, const std::vector<float>& poissonRatios ) const;
|
||||
float calculateUcs( int64_t intersectionIdx, const std::vector<float>& ucsValuesPascal ) const;
|
||||
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;
|
||||
|
||||
void wellPathAngles( const RigFemResultAddress& resAddr, std::vector<double>* values );
|
||||
void wellPathScaledCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector<double>* values );
|
||||
|
Loading…
Reference in New Issue
Block a user