#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" );
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 );
}

View File

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

View File

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

View File

@@ -49,6 +49,7 @@
#include "RimFractureModelTemplate.h"
#include "RimFractureModelTemplateCollection.h"
#include "RimModeledWellPath.h"
#include "RimNonNetLayers.h"
#include "RimOilField.h"
#include "RimPolylineTarget.h"
#include "RimProject.h"
@@ -1015,6 +1016,10 @@ double RimFractureModel::getDefaultForMissingValue( RiaDefines::CurveProperty cu
{
return defaultPermeability();
}
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
return 1.0;
}
else
{
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();
return findFaciesValue( *faciesColorLegend, overburdenFacies() );
}
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
return 1.0;
}
else
{
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();
return findFaciesValue( *faciesColorLegend, underburdenFacies() );
}
else if ( curveProperty == RiaDefines::CurveProperty::NET_TO_GROSS )
{
return 1.0;
}
else
{
RiaLogging::error( QString( "Missing default underburden value for %1." )
@@ -1567,6 +1580,18 @@ RiaDefines::ResultCatType RimFractureModel::eclipseResultCategory( RiaDefines::C
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
{
return RiaDefines::ResultCatType::STATIC_NATIVE;
@@ -1599,6 +1624,18 @@ QString RimFractureModel::eclipseResultVariable( RiaDefines::CurveProperty curve
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
return "";
}
@@ -1628,3 +1665,27 @@ double RimFractureModel::findFaciesValue( const RimColorLegend& colorLegend, con
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 );
bool isScaledByNetToGross( RiaDefines::CurveProperty curveProperty ) const;
protected:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,

View File

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

View File

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

View File

@@ -46,6 +46,7 @@
#include "RimFractureModelTemplate.h"
#include "RimLayerCurve.h"
#include "RimModeledWellPath.h"
#include "RimNonNetLayers.h"
#include "RimTools.h"
#include "RimWellLogFile.h"
#include "RimWellLogPlot.h"
@@ -187,10 +188,26 @@ bool RimFractureModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp
underburdenFormation );
}
std::vector<double> netToGrossValues =
m_fractureModelCalculator->extractValues( RiaDefines::CurveProperty::NET_TO_GROSS, timeStep );
CAF_ASSERT( tvDepthValues.size() == faciesValues.size() );
CAF_ASSERT( tvDepthValues.size() == poroValues.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++ )
{
// 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 );
double scale = elasticProperties->getPropertyScaling( formationName, faciesName, curveProperty );
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 );
}
else if ( fractureModel->hasDefaultValueForProperty( curveProperty ) )

View File

@@ -19,40 +19,27 @@
#include "RiaDefines.h"
#include "RiaFractureModelDefines.h"
#include "RiaInterpolationTools.h"
#include "RiaLogging.h"
#include "RigEclipseCaseData.h"
#include "RigEclipseWellLogExtractor.h"
#include "RigElasticProperties.h"
#include "RigResultAccessor.h"
#include "RigResultAccessorFactory.h"
#include "RigWellLogCurveData.h"
#include "RigWellPath.h"
#include "RimCase.h"
#include "RimColorLegend.h"
#include "RimColorLegendItem.h"
#include "RimEclipseCase.h"
#include "RimEclipseInputProperty.h"
#include "RimEclipseInputPropertyCollection.h"
#include "RimEclipseResultDefinition.h"
#include "RimElasticProperties.h"
#include "RimFaciesProperties.h"
#include "RimFractureModel.h"
#include "RimFractureModelCalculator.h"
#include "RimFractureModelLayerCalculator.h"
#include "RimFractureModelPlot.h"
#include "RimFractureModelTemplate.h"
#include "RimLayerCurve.h"
#include "RimModeledWellPath.h"
#include "RimTools.h"
#include "RimWellLogFile.h"
#include "RimWellLogPlot.h"
#include "RimNonNetLayers.h"
#include "RimWellLogTrack.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;
}
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() );
int layerNo = 0;
double previousFormation = -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++ )
{
if ( previousFormation != curveData.data[i] || previousFacies != faciesValues[i] )
if ( previousFormation != curveData.data[i] || previousFacies != faciesValues[i] ||
( useNetToGross && netToGrossValues[i] <= netToGrossCutoff && previousNetToGross != netToGrossValues[i] ) )
{
layerNo++;
}
@@ -151,6 +155,10 @@ bool RimFractureModelLayerCalculator::calculate( RiaDefines::CurveProperty curve
values[i] = layerNo;
previousFormation = curveData.data[i];
previousFacies = faciesValues[i];
if ( useNetToGross )
{
previousNetToGross = netToGrossValues[i];
}
}
return true;

View File

@@ -36,21 +36,17 @@
#include "RimEclipseResultDefinition.h"
#include "RimFractureModel.h"
#include "RimFractureModelCalculator.h"
#include "RimFractureModelPlot.h"
#include "RimFractureModelTemplate.h"
#include "RimLayerCurve.h"
#include "RimModeledWellPath.h"
#include "RimTools.h"
#include "RimWellLogFile.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimNonNetLayers.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::INITIAL_PRESSURE,
RiaDefines::CurveProperty::PRESSURE,
RiaDefines::CurveProperty::NET_TO_GROSS,
};
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;
}
@@ -399,3 +404,32 @@ void RimFractureModelWellLogCalculator::addUnderburden( RiaDefines::CurvePropert
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
{
public:
RimFractureModelWellLogCalculator( RimFractureModelCalculator& fractureModelCalculator );
RimFractureModelWellLogCalculator( RimFractureModelCalculator* fractureModelCalculator );
bool calculate( RiaDefines::CurveProperty curveProperty,
const RimFractureModel* fractureModel,
@@ -67,4 +67,10 @@ protected:
std::vector<double>& tvDepthValues,
std::vector<double>& measuredDepthValues,
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;
}

View File

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