From 6481813eeb3c839d337bb65ed454d03c5f530213 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 5 Mar 2021 15:07:07 +0100 Subject: [PATCH] #7116 Add extrapolation for missing elastic properties. Also improve error message. --- ...StimPlanModelElasticPropertyCalculator.cpp | 43 +++++++++++-------- .../RigElasticProperties.cpp | 8 +++- .../ReservoirDataModel/RigElasticProperties.h | 3 +- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelElasticPropertyCalculator.cpp b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelElasticPropertyCalculator.cpp index 16d15ee377..146cabb969 100644 --- a/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelElasticPropertyCalculator.cpp +++ b/ApplicationLibCode/ProjectDataModel/StimPlanModel/RimStimPlanModelElasticPropertyCalculator.cpp @@ -247,18 +247,21 @@ bool RimStimPlanModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp { const RigElasticProperties& rigElasticProperties = elasticProperties->propertiesForFacies( faciesKey ); double scale = elasticProperties->getPropertyScaling( formationName, faciesName, curveProperty ); - double val = rigElasticProperties.getValueForPorosity( curveProperty, porosity, scale ); - if ( std::isinf( val ) ) + auto [val, isExtrapolated] = rigElasticProperties.getValueForPorosity( curveProperty, porosity, scale ); + if ( isExtrapolated ) { + QString propertyName = caf::AppEnum( curveProperty ).uiText(); RiaLogging::error( - QString( "Elastic property interpolation failed. Formation='%1', " - "facies='%2', depth=%3, porosity=%4. Property defined for porosity range: [%5, %6]" ) + QString( "Elastic property '%1' outside porosity range [%2, %3] for formation='%4', " + "facies='%5', depth=%6, porosity=%7. Extrapolated value: %8" ) + .arg( propertyName ) + .arg( rigElasticProperties.porosityMin() ) + .arg( rigElasticProperties.porosityMax() ) .arg( formationName ) .arg( faciesName ) .arg( tvDepthValues[i] ) .arg( porosity ) - .arg( rigElasticProperties.porosityMin() ) - .arg( rigElasticProperties.porosityMax() ) ); + .arg( val ) ); } // @@ -272,19 +275,23 @@ bool RimStimPlanModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp elasticProperties->propertiesForFacies( ntgFaciesKey ); double ntgScale = elasticProperties->getPropertyScaling( formationName, netToGrossFaciesName, curveProperty ); - double ntgValue = rigNtgElasticProperties.getValueForPorosity( curveProperty, porosity, ntgScale ); - val = val * netToGross + ( 1.0 - netToGross ) * ntgValue; - if ( std::isinf( val ) ) + auto [ntgValue, isExtrapolated] = + rigNtgElasticProperties.getValueForPorosity( curveProperty, porosity, ntgScale ); + val = val * netToGross + ( 1.0 - netToGross ) * ntgValue; + if ( std::isinf( val ) || isExtrapolated ) { - RiaLogging::error( QString( "Elastic property (NTG) interpolation failed. Formation='%1', " - "facies='%2', depth=%3, porosity=%4. Property defined for " - "porosity range: [%5, %6]" ) - .arg( formationName ) - .arg( netToGrossFaciesName ) - .arg( tvDepthValues[i] ) - .arg( porosity ) - .arg( rigNtgElasticProperties.porosityMin() ) - .arg( rigNtgElasticProperties.porosityMax() ) ); + QString propertyName = caf::AppEnum( curveProperty ).uiText(); + RiaLogging::error( + QString( "Elastic property '%1' outside porosity range [%2, %3] for formation='%4', " + "facies='%5', depth=%6, porosity=%7 (NTG). Extrapolated value: %8" ) + .arg( propertyName ) + .arg( rigNtgElasticProperties.porosityMin() ) + .arg( rigNtgElasticProperties.porosityMax() ) + .arg( formationName ) + .arg( netToGrossFaciesName ) + .arg( tvDepthValues[i] ) + .arg( porosity ) + .arg( val ) ); } } } diff --git a/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.cpp b/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.cpp index 19cc5d3a0b..b74a70abfc 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.cpp +++ b/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.cpp @@ -148,7 +148,8 @@ const std::vector& RigElasticProperties::getVector( RiaDefines::CurvePro //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RigElasticProperties::getValueForPorosity( RiaDefines::CurveProperty property, double porosity, double scale ) const +std::pair + RigElasticProperties::getValueForPorosity( RiaDefines::CurveProperty property, double porosity, double scale ) const { const std::vector& unscaledValues = getVector( property ); std::vector scaledValues; @@ -157,5 +158,8 @@ double RigElasticProperties::getValueForPorosity( RiaDefines::CurveProperty prop scaledValues.push_back( unscaled * scale ); } - return RiaInterpolationTools::linear( m_porosity, scaledValues, porosity ); + bool isExtrapolated = porosity > porosityMax() || porosity < porosityMin(); + double value = + RiaInterpolationTools::linear( m_porosity, scaledValues, porosity, RiaInterpolationTools::ExtrapolationMode::CLOSEST ); + return std::make_pair( value, isExtrapolated ); } diff --git a/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.h b/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.h index b45a00b003..6f83beb738 100644 --- a/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.h +++ b/ApplicationLibCode/ReservoirDataModel/RigElasticProperties.h @@ -48,7 +48,8 @@ public: size_t numValues() const; double getValue( RiaDefines::CurveProperty property, size_t index, double scale = 1.0 ) const; - double getValueForPorosity( RiaDefines::CurveProperty property, double porosity, double scale = 1.0 ) const; + std::pair + getValueForPorosity( RiaDefines::CurveProperty property, double porosity, double scale = 1.0 ) const; const std::vector& porosity() const; double porosityMin() const;