#6754 Scale porosity, permeability and elastic props by net-to-gross.

This commit is contained in:
Kristian Bendiksen
2020-10-19 15:11:01 +02:00
parent 390dbe5cc5
commit 82c7042eeb
13 changed files with 185 additions and 40 deletions

View File

@@ -51,6 +51,7 @@ void AppEnum<RiaDefines::CurveProperty>::setUp()
"THERMAL_EXPANSION_COEFFICIENT", "THERMAL_EXPANSION_COEFFICIENT",
"Thermal Expansion Coefficient" ); "Thermal Expansion Coefficient" );
addItem( RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION, "IMMOBILE_FLUID_SATURATION", "Immobile Fluid Saturation" ); addItem( RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION, "IMMOBILE_FLUID_SATURATION", "Immobile Fluid Saturation" );
addItem( RiaDefines::CurveProperty::NET_TO_GROSS, "NET_TO_GROSS", "Net-To-Gross" );
setDefault( RiaDefines::CurveProperty::UNDEFINED ); setDefault( RiaDefines::CurveProperty::UNDEFINED );
} }

View File

@@ -50,5 +50,6 @@ enum class CurveProperty
PORO_ELASTIC_CONSTANT, PORO_ELASTIC_CONSTANT,
THERMAL_EXPANSION_COEFFICIENT, THERMAL_EXPANSION_COEFFICIENT,
IMMOBILE_FLUID_SATURATION, IMMOBILE_FLUID_SATURATION,
NET_TO_GROSS,
}; };
}; // namespace RiaDefines }; // namespace RiaDefines

View File

@@ -98,6 +98,7 @@ RimFractureModelPlot*
plots["Porosity"] = {RiaDefines::CurveProperty::POROSITY}; plots["Porosity"] = {RiaDefines::CurveProperty::POROSITY};
plots["Pressure"] = {RiaDefines::CurveProperty::INITIAL_PRESSURE, RiaDefines::CurveProperty::PRESSURE}; plots["Pressure"] = {RiaDefines::CurveProperty::INITIAL_PRESSURE, RiaDefines::CurveProperty::PRESSURE};
plots["Permeability"] = {RiaDefines::CurveProperty::PERMEABILITY_X, RiaDefines::CurveProperty::PERMEABILITY_Z}; plots["Permeability"] = {RiaDefines::CurveProperty::PERMEABILITY_X, RiaDefines::CurveProperty::PERMEABILITY_Z};
plots["Net-To-Gross"] = {RiaDefines::CurveProperty::NET_TO_GROSS};
std::set<QString> logarithmicPlots; std::set<QString> logarithmicPlots;
logarithmicPlots.insert( "Permeability" ); logarithmicPlots.insert( "Permeability" );

View File

@@ -49,6 +49,7 @@
#include "RimFractureModelTemplate.h" #include "RimFractureModelTemplate.h"
#include "RimFractureModelTemplateCollection.h" #include "RimFractureModelTemplateCollection.h"
#include "RimModeledWellPath.h" #include "RimModeledWellPath.h"
#include "RimNonNetLayers.h"
#include "RimOilField.h" #include "RimOilField.h"
#include "RimPolylineTarget.h" #include "RimPolylineTarget.h"
#include "RimProject.h" #include "RimProject.h"
@@ -1015,6 +1016,10 @@ double RimFractureModel::getDefaultForMissingValue( RiaDefines::CurveProperty cu
{ {
return defaultPermeability(); return defaultPermeability();
} }
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
return 1.0;
}
else else
{ {
RiaLogging::error( QString( "Missing default value for %1." ) RiaLogging::error( QString( "Missing default value for %1." )
@@ -1056,6 +1061,10 @@ double RimFractureModel::getDefaultForMissingOverburdenValue( RiaDefines::CurveP
if ( !faciesColorLegend ) return std::numeric_limits<double>::infinity(); if ( !faciesColorLegend ) return std::numeric_limits<double>::infinity();
return findFaciesValue( *faciesColorLegend, overburdenFacies() ); return findFaciesValue( *faciesColorLegend, overburdenFacies() );
} }
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
return 1.0;
}
else else
{ {
RiaLogging::error( QString( "Missing default overburden value for %1." ) RiaLogging::error( QString( "Missing default overburden value for %1." )
@@ -1084,6 +1093,10 @@ double RimFractureModel::getDefaultForMissingUnderburdenValue( RiaDefines::Curve
if ( !faciesColorLegend ) return std::numeric_limits<double>::infinity(); if ( !faciesColorLegend ) return std::numeric_limits<double>::infinity();
return findFaciesValue( *faciesColorLegend, underburdenFacies() ); return findFaciesValue( *faciesColorLegend, underburdenFacies() );
} }
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
return 1.0;
}
else else
{ {
RiaLogging::error( QString( "Missing default underburden value for %1." ) RiaLogging::error( QString( "Missing default underburden value for %1." )
@@ -1567,6 +1580,18 @@ RiaDefines::ResultCatType RimFractureModel::eclipseResultCategory( RiaDefines::C
return faciesDefinition->resultType(); return faciesDefinition->resultType();
} }
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
if ( !m_fractureModelTemplate ) return RiaDefines::ResultCatType::STATIC_NATIVE;
RimNonNetLayers* nonNetLayers = m_fractureModelTemplate->nonNetLayers();
if ( !nonNetLayers ) return RiaDefines::ResultCatType::STATIC_NATIVE;
const RimEclipseResultDefinition* resultDef = nonNetLayers->resultDefinition();
if ( !resultDef ) return RiaDefines::ResultCatType::STATIC_NATIVE;
return resultDef->resultType();
}
else else
{ {
return RiaDefines::ResultCatType::STATIC_NATIVE; return RiaDefines::ResultCatType::STATIC_NATIVE;
@@ -1599,6 +1624,18 @@ QString RimFractureModel::eclipseResultVariable( RiaDefines::CurveProperty curve
return faciesDefinition->resultVariable(); return faciesDefinition->resultVariable();
} }
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
if ( !m_fractureModelTemplate ) return "";
RimNonNetLayers* nonNetLayers = m_fractureModelTemplate->nonNetLayers();
if ( !nonNetLayers ) return "";
const RimEclipseResultDefinition* resultDef = nonNetLayers->resultDefinition();
if ( !resultDef ) return "";
return resultDef->resultVariable();
}
else else
return ""; return "";
} }
@@ -1628,3 +1665,27 @@ double RimFractureModel::findFaciesValue( const RimColorLegend& colorLegend, con
return std::numeric_limits<double>::infinity(); return std::numeric_limits<double>::infinity();
} }
//-------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimFractureModel::isScaledByNetToGross( RiaDefines::CurveProperty curveProperty ) const
{
std::vector<RiaDefines::CurveProperty> matching = {RiaDefines::CurveProperty::POROSITY,
RiaDefines::CurveProperty::PERMEABILITY_X,
RiaDefines::CurveProperty::PERMEABILITY_Z,
RiaDefines::CurveProperty::YOUNGS_MODULUS,
RiaDefines::CurveProperty::POISSONS_RATIO,
RiaDefines::CurveProperty::BIOT_COEFFICIENT,
RiaDefines::CurveProperty::K0,
RiaDefines::CurveProperty::K_IC,
RiaDefines::CurveProperty::PROPPANT_EMBEDMENT,
RiaDefines::CurveProperty::FLUID_LOSS_COEFFICIENT,
RiaDefines::CurveProperty::SPURT_LOSS,
RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR,
RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT,
RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT,
RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION};
return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end();
}

View File

@@ -169,6 +169,8 @@ public:
static double findFaciesValue( const RimColorLegend& colorLegend, const QString& name ); static double findFaciesValue( const RimColorLegend& colorLegend, const QString& name );
bool isScaledByNetToGross( RiaDefines::CurveProperty curveProperty ) const;
protected: protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,

View File

@@ -390,13 +390,18 @@ RimNonNetLayers* RimFractureModelTemplate::nonNetLayers() const
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimFractureModelTemplate::initAfterRead() void RimFractureModelTemplate::initAfterRead()
{ {
if ( m_faciesProperties )
{
RimEclipseCase* eclipseCase = getEclipseCase(); RimEclipseCase* eclipseCase = getEclipseCase();
if ( !eclipseCase ) return; if ( !eclipseCase ) return;
if ( m_faciesProperties )
{
m_faciesProperties->setEclipseCase( eclipseCase ); m_faciesProperties->setEclipseCase( eclipseCase );
} }
if ( m_nonNetLayers )
{
m_nonNetLayers->setEclipseCase( eclipseCase );
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@@ -38,7 +38,7 @@
RimFractureModelCalculator::RimFractureModelCalculator() RimFractureModelCalculator::RimFractureModelCalculator()
{ {
m_resultCalculators.push_back( m_resultCalculators.push_back(
std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelWellLogCalculator( *this ) ) ); std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelWellLogCalculator( this ) ) );
m_resultCalculators.push_back( m_resultCalculators.push_back(
std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelElasticPropertyCalculator( this ) ) ); std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelElasticPropertyCalculator( this ) ) );
m_resultCalculators.push_back( m_resultCalculators.push_back(

View File

@@ -46,6 +46,7 @@
#include "RimFractureModelTemplate.h" #include "RimFractureModelTemplate.h"
#include "RimLayerCurve.h" #include "RimLayerCurve.h"
#include "RimModeledWellPath.h" #include "RimModeledWellPath.h"
#include "RimNonNetLayers.h"
#include "RimTools.h" #include "RimTools.h"
#include "RimWellLogFile.h" #include "RimWellLogFile.h"
#include "RimWellLogPlot.h" #include "RimWellLogPlot.h"
@@ -187,10 +188,26 @@ bool RimFractureModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp
underburdenFormation ); underburdenFormation );
} }
std::vector<double> netToGrossValues =
m_fractureModelCalculator->extractValues( RiaDefines::CurveProperty::NET_TO_GROSS, timeStep );
CAF_ASSERT( tvDepthValues.size() == faciesValues.size() ); CAF_ASSERT( tvDepthValues.size() == faciesValues.size() );
CAF_ASSERT( tvDepthValues.size() == poroValues.size() ); CAF_ASSERT( tvDepthValues.size() == poroValues.size() );
CAF_ASSERT( tvDepthValues.size() == formationValues.size() ); CAF_ASSERT( tvDepthValues.size() == formationValues.size() );
bool isScaledByNetToGross = fractureModel->isScaledByNetToGross( curveProperty ) && !netToGrossValues.empty();
double netToGrossCutoff = 1.0;
QString netToGrossFaciesName = "";
QString netToGrossFormationName = "";
if ( fractureModel->fractureModelTemplate() && fractureModel->fractureModelTemplate()->nonNetLayers() )
{
netToGrossCutoff = fractureModel->fractureModelTemplate()->nonNetLayers()->cutOff();
netToGrossFaciesName = fractureModel->fractureModelTemplate()->nonNetLayers()->facies();
netToGrossFormationName = fractureModel->fractureModelTemplate()->nonNetLayers()->formation();
}
FaciesKey ntgFaciesKey = std::make_tuple( "", netToGrossFormationName, netToGrossFaciesName );
for ( size_t i = 0; i < tvDepthValues.size(); i++ ) for ( size_t i = 0; i < tvDepthValues.size(); i++ )
{ {
// Avoid using the field name in the match for now // Avoid using the field name in the match for now
@@ -208,6 +225,21 @@ bool RimFractureModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp
const RigElasticProperties& rigElasticProperties = elasticProperties->propertiesForFacies( faciesKey ); const RigElasticProperties& rigElasticProperties = elasticProperties->propertiesForFacies( faciesKey );
double scale = elasticProperties->getPropertyScaling( formationName, faciesName, curveProperty ); double scale = elasticProperties->getPropertyScaling( formationName, faciesName, curveProperty );
double val = rigElasticProperties.getValueForPorosity( curveProperty, porosity, scale ); double val = rigElasticProperties.getValueForPorosity( curveProperty, porosity, scale );
//
if ( isScaledByNetToGross )
{
double netToGross = netToGrossValues[i];
if ( netToGross < netToGrossCutoff )
{
double ntgScale = elasticProperties->getPropertyScaling( netToGrossFormationName,
netToGrossFaciesName,
curveProperty );
double ntgValue = rigElasticProperties.getValueForPorosity( curveProperty, porosity, ntgScale );
val = val * netToGross + ( 1.0 - netToGross ) * ntgValue;
}
}
values.push_back( val ); values.push_back( val );
} }
else if ( fractureModel->hasDefaultValueForProperty( curveProperty ) ) else if ( fractureModel->hasDefaultValueForProperty( curveProperty ) )

View File

@@ -19,40 +19,27 @@
#include "RiaDefines.h" #include "RiaDefines.h"
#include "RiaFractureModelDefines.h" #include "RiaFractureModelDefines.h"
#include "RiaInterpolationTools.h"
#include "RiaLogging.h" #include "RiaLogging.h"
#include "RigEclipseCaseData.h" #include "RigEclipseCaseData.h"
#include "RigEclipseWellLogExtractor.h" #include "RigEclipseWellLogExtractor.h"
#include "RigElasticProperties.h"
#include "RigResultAccessor.h" #include "RigResultAccessor.h"
#include "RigResultAccessorFactory.h" #include "RigResultAccessorFactory.h"
#include "RigWellLogCurveData.h"
#include "RigWellPath.h" #include "RigWellPath.h"
#include "RimCase.h" #include "RimCase.h"
#include "RimColorLegend.h"
#include "RimColorLegendItem.h"
#include "RimEclipseCase.h" #include "RimEclipseCase.h"
#include "RimEclipseInputProperty.h"
#include "RimEclipseInputPropertyCollection.h"
#include "RimEclipseResultDefinition.h" #include "RimEclipseResultDefinition.h"
#include "RimElasticProperties.h"
#include "RimFaciesProperties.h"
#include "RimFractureModel.h" #include "RimFractureModel.h"
#include "RimFractureModelCalculator.h" #include "RimFractureModelCalculator.h"
#include "RimFractureModelLayerCalculator.h" #include "RimFractureModelLayerCalculator.h"
#include "RimFractureModelPlot.h"
#include "RimFractureModelTemplate.h" #include "RimFractureModelTemplate.h"
#include "RimLayerCurve.h"
#include "RimModeledWellPath.h" #include "RimModeledWellPath.h"
#include "RimTools.h" #include "RimNonNetLayers.h"
#include "RimWellLogFile.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h" #include "RimWellLogTrack.h"
#include "RimWellPath.h" #include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "RimWellPlotTools.h" #include "cafAssert.h"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
@@ -136,14 +123,31 @@ bool RimFractureModelLayerCalculator::calculate( RiaDefines::CurveProperty curve
return false; return false;
} }
std::vector<double> netToGrossValues =
m_fractureModelCalculator->extractValues( RiaDefines::CurveProperty::NET_TO_GROSS, timeStep );
if ( netToGrossValues.empty() )
{
RiaLogging::warning( QString( "Empty net-to-gross data found for layer curve." ) );
}
CAF_ASSERT( faciesValues.size() == curveData.data.size() );
values.resize( faciesValues.size() ); values.resize( faciesValues.size() );
int layerNo = 0; int layerNo = 0;
double previousFormation = -1.0; double previousFormation = -1.0;
double previousFacies = -1.0; double previousFacies = -1.0;
double previousNetToGross = -1.0;
double netToGrossCutoff = 1.0;
if ( fractureModel->fractureModelTemplate() && fractureModel->fractureModelTemplate()->nonNetLayers() )
{
netToGrossCutoff = fractureModel->fractureModelTemplate()->nonNetLayers()->cutOff();
}
bool useNetToGross = !netToGrossValues.empty();
for ( size_t i = 0; i < faciesValues.size(); i++ ) for ( size_t i = 0; i < faciesValues.size(); i++ )
{ {
if ( previousFormation != curveData.data[i] || previousFacies != faciesValues[i] ) if ( previousFormation != curveData.data[i] || previousFacies != faciesValues[i] ||
( useNetToGross && netToGrossValues[i] <= netToGrossCutoff && previousNetToGross != netToGrossValues[i] ) )
{ {
layerNo++; layerNo++;
} }
@@ -151,6 +155,10 @@ bool RimFractureModelLayerCalculator::calculate( RiaDefines::CurveProperty curve
values[i] = layerNo; values[i] = layerNo;
previousFormation = curveData.data[i]; previousFormation = curveData.data[i];
previousFacies = faciesValues[i]; previousFacies = faciesValues[i];
if ( useNetToGross )
{
previousNetToGross = netToGrossValues[i];
}
} }
return true; return true;

View File

@@ -36,21 +36,17 @@
#include "RimEclipseResultDefinition.h" #include "RimEclipseResultDefinition.h"
#include "RimFractureModel.h" #include "RimFractureModel.h"
#include "RimFractureModelCalculator.h" #include "RimFractureModelCalculator.h"
#include "RimFractureModelPlot.h" #include "RimFractureModelTemplate.h"
#include "RimLayerCurve.h" #include "RimLayerCurve.h"
#include "RimModeledWellPath.h" #include "RimModeledWellPath.h"
#include "RimTools.h" #include "RimNonNetLayers.h"
#include "RimWellLogFile.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimWellPath.h" #include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "RimWellPlotTools.h"
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RimFractureModelWellLogCalculator::RimFractureModelWellLogCalculator( RimFractureModelCalculator& ) RimFractureModelWellLogCalculator::RimFractureModelWellLogCalculator( RimFractureModelCalculator* fractureModelCalculator )
: m_fractureModelCalculator( fractureModelCalculator )
{ {
} }
@@ -66,6 +62,7 @@ bool RimFractureModelWellLogCalculator::isMatching( RiaDefines::CurveProperty cu
RiaDefines::CurveProperty::PERMEABILITY_Z, RiaDefines::CurveProperty::PERMEABILITY_Z,
RiaDefines::CurveProperty::INITIAL_PRESSURE, RiaDefines::CurveProperty::INITIAL_PRESSURE,
RiaDefines::CurveProperty::PRESSURE, RiaDefines::CurveProperty::PRESSURE,
RiaDefines::CurveProperty::NET_TO_GROSS,
}; };
return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end(); return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end();
@@ -226,6 +223,14 @@ bool RimFractureModelWellLogCalculator::calculate( RiaDefines::CurveProperty cur
} }
} }
if ( fractureModel->isScaledByNetToGross( curveProperty ) )
{
std::vector<double> netToGross =
m_fractureModelCalculator->extractValues( RiaDefines::CurveProperty::NET_TO_GROSS, timeStep );
scaleByNetToGross( fractureModel, netToGross, values );
}
return true; return true;
} }
@@ -399,3 +404,32 @@ void RimFractureModelWellLogCalculator::addUnderburden( RiaDefines::CurvePropert
values.push_back( underburdenBottomValue ); values.push_back( underburdenBottomValue );
} }
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFractureModelWellLogCalculator::scaleByNetToGross( const RimFractureModel* fractureModel,
const std::vector<double>& netToGross,
std::vector<double>& values )
{
if ( netToGross.size() != values.size() )
{
RiaLogging::error( QString( "Different sizes for net to gross calculation." ) );
return;
}
double cutoff = 1.0;
if ( fractureModel->fractureModelTemplate() && fractureModel->fractureModelTemplate()->nonNetLayers() )
{
cutoff = fractureModel->fractureModelTemplate()->nonNetLayers()->cutOff();
}
for ( size_t i = 0; i < values.size(); i++ )
{
double ntg = netToGross[i];
if ( ntg <= cutoff )
{
values[i] = ntg * values[i];
}
}
}

View File

@@ -34,7 +34,7 @@ class RigResultAccessor;
class RimFractureModelWellLogCalculator : public RimFractureModelPropertyCalculator class RimFractureModelWellLogCalculator : public RimFractureModelPropertyCalculator
{ {
public: public:
RimFractureModelWellLogCalculator( RimFractureModelCalculator& fractureModelCalculator ); RimFractureModelWellLogCalculator( RimFractureModelCalculator* fractureModelCalculator );
bool calculate( RiaDefines::CurveProperty curveProperty, bool calculate( RiaDefines::CurveProperty curveProperty,
const RimFractureModel* fractureModel, const RimFractureModel* fractureModel,
@@ -67,4 +67,10 @@ protected:
std::vector<double>& tvDepthValues, std::vector<double>& tvDepthValues,
std::vector<double>& measuredDepthValues, std::vector<double>& measuredDepthValues,
std::vector<double>& values ) const; std::vector<double>& values ) const;
static void scaleByNetToGross( const RimFractureModel* fractureModel,
const std::vector<double>& netToGross,
std::vector<double>& values );
RimFractureModelCalculator* m_fractureModelCalculator;
}; };

View File

@@ -92,12 +92,6 @@ QList<caf::PdmOptionItemInfo> RimNonNetLayers::calculateValueOptions( const caf:
} }
} }
// QList<caf::PdmOptionItemInfo> options;
// if ( fieldNeedingOptions == &m_colorLegend )
// {
// RimTools::colorLegendOptionItems( &options );
// }
return options; return options;
} }

View File

@@ -53,7 +53,7 @@ public:
const QString& facies() const; const QString& facies() const;
protected: protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ); void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override; bool* useOptionsOnly ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;