#7072 Warn when geological frk export produces NaN or inf.

This can happen when the elastic properties are not defined for the
entire range of porosity in the grid.
This commit is contained in:
Kristian Bendiksen 2020-12-07 13:03:46 +01:00 committed by Magne Sjaastad
parent 050899d90e
commit c61329bf9a
5 changed files with 86 additions and 11 deletions

View File

@ -137,6 +137,7 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToFile( RimStimPlanModel* stimP
for ( QString label : labels )
{
warnOnInvalidData( label, values[label] );
appendToStream( stream, label, values[label] );
}
@ -210,3 +211,30 @@ void RifStimPlanModelGeologicalFrkExporter::fixupStressGradients( std::vector<do
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifStimPlanModelGeologicalFrkExporter::warnOnInvalidData( const QString& label, const std::vector<double>& values )
{
bool isInvalid = hasInvalidData( values );
if ( isInvalid )
{
RiaLogging::warning( QString( "Found invalid data in Geological.FRK export of property '%1'." ).arg( label ) );
}
return isInvalid;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifStimPlanModelGeologicalFrkExporter::hasInvalidData( const std::vector<double>& values )
{
for ( auto v : values )
{
if ( std::isinf( v ) || std::isnan( v ) ) return true;
}
return false;
}

View File

@ -46,4 +46,7 @@ private:
double minStressGradient,
double maxStressGradient,
double defaultStressGradient );
static bool warnOnInvalidData( const QString& label, const std::vector<double>& values );
static bool hasInvalidData( const std::vector<double>& values );
};

View File

@ -239,9 +239,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 ) )
{
RiaLogging::error(
QString( "Elastic property interpolation failed. Formation='%1', "
"facies='%2', depth=%3, porosity=%4. Property defined for porosity range: [%5, %6]" )
.arg( formationName )
.arg( faciesName )
.arg( tvDepthValues[i] )
.arg( porosity )
.arg( rigElasticProperties.porosityMin() )
.arg( rigElasticProperties.porosityMax() ) );
}
//
if ( isScaledByNetToGross )
if ( isScaledByNetToGross && !std::isinf( val ) )
{
double netToGross = netToGrossValues[i];
if ( netToGross < netToGrossCutoff )
@ -253,6 +265,18 @@ bool RimStimPlanModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp
elasticProperties->getPropertyScaling( formationName, netToGrossFaciesName, curveProperty );
double ntgValue = rigNtgElasticProperties.getValueForPorosity( curveProperty, porosity, ntgScale );
val = val * netToGross + ( 1.0 - netToGross ) * ntgValue;
if ( std::isinf( val ) )
{
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() ) );
}
}
}

View File

@ -64,6 +64,24 @@ const std::vector<double>& RigElasticProperties::porosity() const
return m_porosity;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigElasticProperties::porosityMin() const
{
if ( m_porosity.empty() ) return 0.0;
return m_porosity[0];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RigElasticProperties::porosityMax() const
{
if ( m_porosity.empty() ) return 0.0;
return m_porosity[m_porosity.size() - 1];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -35,22 +35,24 @@ public:
const QString& formationName() const;
const QString& faciesName() const;
void appendValues( double porosity,
double youngsModulus,
double poissonsRatio,
double m_K_Ic,
double proppantEmbedment,
double biotCoefficient,
double k0,
double fluidLossCoefficient,
double spurtLoss,
double immobileFluidSaturation );
void appendValues( double porosity,
double youngsModulus,
double poissonsRatio,
double m_K_Ic,
double proppantEmbedment,
double biotCoefficient,
double k0,
double fluidLossCoefficient,
double spurtLoss,
double immobileFluidSaturation );
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;
const std::vector<double>& porosity() const;
double porosityMin() const;
double porosityMax() const;
private:
const std::vector<double>& getVector( RiaDefines::CurveProperty property ) const;