#6835 Stimplan Model: Improve non-net layers.

- Add checkbox to toggle non-net layers on/off
- Remove formation option, and use current formation for each element.
- Set default cutoff to 1.0
- Add range for cutoff input [0, 1.0]
- Scale elastic properties if less than cutoff.
- Introduce one new layer per element for each non-identical NTG less than cutoff.
This commit is contained in:
Kristian Bendiksen 2020-10-26 14:25:48 +01:00
parent 88d30b74af
commit 935a2d11d7
5 changed files with 51 additions and 82 deletions

View File

@ -195,19 +195,18 @@ bool RimFractureModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp
CAF_ASSERT( tvDepthValues.size() == poroValues.size() );
CAF_ASSERT( tvDepthValues.size() == formationValues.size() );
bool isScaledByNetToGross = fractureModel->isScaledByNetToGross( curveProperty ) && !netToGrossValues.empty();
bool isScaledByNetToGross = false;
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();
isScaledByNetToGross = fractureModel->isScaledByNetToGross( curveProperty ) && !netToGrossValues.empty() &&
fractureModel->fractureModelTemplate()->nonNetLayers()->isChecked();
netToGrossCutoff = fractureModel->fractureModelTemplate()->nonNetLayers()->cutOff();
netToGrossFaciesName = fractureModel->fractureModelTemplate()->nonNetLayers()->facies();
}
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
@ -232,10 +231,12 @@ bool RimFractureModelElasticPropertyCalculator::calculate( RiaDefines::CurveProp
double netToGross = netToGrossValues[i];
if ( netToGross < netToGrossCutoff )
{
double ntgScale = elasticProperties->getPropertyScaling( netToGrossFormationName,
netToGrossFaciesName,
curveProperty );
double ntgValue = rigElasticProperties.getValueForPorosity( curveProperty, porosity, ntgScale );
FaciesKey ntgFaciesKey = std::make_tuple( "", formationName, netToGrossFaciesName );
const RigElasticProperties& rigNtgElasticProperties =
elasticProperties->propertiesForFacies( ntgFaciesKey );
double ntgScale =
elasticProperties->getPropertyScaling( formationName, netToGrossFaciesName, curveProperty );
double ntgValue = rigNtgElasticProperties.getValueForPorosity( curveProperty, porosity, ntgScale );
val = val * netToGross + ( 1.0 - netToGross ) * ntgValue;
}
}

View File

@ -111,9 +111,6 @@ bool RimFractureModelLayerCalculator::calculate( RiaDefines::CurveProperty curve
RimWellLogTrack::addUnderburden( formationNamesVector, curveData, underburdenHeight );
}
measuredDepthValues = curveData.md;
tvDepthValues = curveData.tvd;
// Extract facies data
std::vector<double> faciesValues =
m_fractureModelCalculator->extractValues( RiaDefines::CurveProperty::FACIES, timeStep );
@ -130,6 +127,9 @@ bool RimFractureModelLayerCalculator::calculate( RiaDefines::CurveProperty curve
RiaLogging::warning( QString( "Empty net-to-gross data found for layer curve." ) );
}
measuredDepthValues = curveData.md;
tvDepthValues = curveData.tvd;
CAF_ASSERT( faciesValues.size() == curveData.data.size() );
values.resize( faciesValues.size() );
@ -139,11 +139,14 @@ bool RimFractureModelLayerCalculator::calculate( RiaDefines::CurveProperty curve
double previousFacies = -1.0;
double previousNetToGross = -1.0;
double netToGrossCutoff = 1.0;
bool useNetToGross = false;
if ( fractureModel->fractureModelTemplate() && fractureModel->fractureModelTemplate()->nonNetLayers() )
{
netToGrossCutoff = fractureModel->fractureModelTemplate()->nonNetLayers()->cutOff();
useNetToGross = !netToGrossValues.empty() && fractureModel->fractureModelTemplate()->nonNetLayers()->isChecked();
}
bool useNetToGross = !netToGrossValues.empty();
for ( size_t i = 0; i < faciesValues.size(); i++ )
{
if ( previousFormation != curveData.data[i] || previousFacies != faciesValues[i] ||

View File

@ -419,7 +419,8 @@ void RimFractureModelWellLogCalculator::scaleByNetToGross( const RimFractureMode
}
double cutoff = 1.0;
if ( fractureModel->fractureModelTemplate() && fractureModel->fractureModelTemplate()->nonNetLayers() )
if ( fractureModel->fractureModelTemplate() && fractureModel->fractureModelTemplate()->nonNetLayers() &&
fractureModel->fractureModelTemplate()->nonNetLayers()->isChecked() )
{
cutoff = fractureModel->fractureModelTemplate()->nonNetLayers()->cutOff();
}

View File

@ -18,7 +18,6 @@
#include "RimNonNetLayers.h"
#include "RigFormationNames.h"
#include "RimColorLegend.h"
#include "RimColorLegendItem.h"
#include "RimEclipseCase.h"
@ -26,16 +25,15 @@
#include "RimFaciesProperties.h"
#include "RimFractureModelTemplate.h"
#include "RimProject.h"
#include "RimRegularLegendConfig.h"
#include "RimTools.h"
#include "RigEclipseCaseData.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
#include "cafPdmUiDoubleValueEditor.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiTextEditor.h"
#include <QDoubleValidator>
CAF_PDM_SOURCE_INIT( RimNonNetLayers, "NonNetLayers" );
//--------------------------------------------------------------------------------------------------
@ -46,8 +44,9 @@ RimNonNetLayers::RimNonNetLayers()
{
CAF_PDM_InitScriptableObject( "RimNonNetLayers", "", "", "" );
CAF_PDM_InitScriptableField( &m_cutOff, "Cutoff", 0.5, "Cutoff", "", "", "" );
CAF_PDM_InitScriptableFieldNoDefault( &m_formation, "Formation", "Formation", "", "", "" );
CAF_PDM_InitScriptableField( &m_cutOff, "Cutoff", 1.0, "Cutoff", "", "", "" );
m_cutOff.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleValueEditor::uiEditorTypeName() );
CAF_PDM_InitScriptableFieldNoDefault( &m_facies, "Facies", "Facies", "", "", "" );
CAF_PDM_InitScriptableFieldNoDefault( &m_resultDefinition, "FaciesDefinition", "", "", "", "" );
@ -73,15 +72,7 @@ QList<caf::PdmOptionItemInfo> RimNonNetLayers::calculateValueOptions( const caf:
bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_formation )
{
std::vector<QString> formationNames = getFormationNames();
for ( const QString& formationName : formationNames )
{
options.push_back( caf::PdmOptionItemInfo( formationName, formationName ) );
}
}
else if ( fieldNeedingOptions == &m_facies )
if ( fieldNeedingOptions == &m_facies )
{
RimColorLegend* faciesColors = getFaciesColorLegend();
if ( !faciesColors ) return options;
@ -95,6 +86,23 @@ QList<caf::PdmOptionItemInfo> RimNonNetLayers::calculateValueOptions( const caf:
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimNonNetLayers::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_cutOff )
{
auto uiDoubleValueEditorAttr = dynamic_cast<caf::PdmUiDoubleValueEditorAttribute*>( attribute );
if ( uiDoubleValueEditorAttr )
{
uiDoubleValueEditorAttr->m_validator = new QDoubleValidator( 0.0, 1.0, 2 );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -138,14 +146,6 @@ double RimNonNetLayers::cutOff() const
return m_cutOff;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString& RimNonNetLayers::formation() const
{
return m_formation();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -168,38 +168,3 @@ RimColorLegend* RimNonNetLayers::getFaciesColorLegend()
return faciesProperties->colorLegend();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RimNonNetLayers::getFormationNames()
{
RigEclipseCaseData* eclipseCaseData = getEclipseCaseData();
if ( !eclipseCaseData ) return std::vector<QString>();
return eclipseCaseData->formationNames();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseCase* RimNonNetLayers::getEclipseCase()
{
// Find an eclipse case
RimProject* proj = RimProject::current();
if ( proj->eclipseCases().empty() ) return nullptr;
return proj->eclipseCases()[0];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseCaseData* RimNonNetLayers::getEclipseCaseData()
{
// Find an eclipse case
RimEclipseCase* eclipseCase = getEclipseCase();
if ( !eclipseCase ) return nullptr;
return eclipseCase->eclipseCaseData();
}

View File

@ -18,6 +18,8 @@
#pragma once
#include "RimCheckableObject.h"
#include "cafFilePath.h"
#include "cafPdmChildField.h"
#include "cafPdmField.h"
@ -30,12 +32,11 @@
class RimEclipseResultDefinition;
class RimEclipseCase;
class RimColorLegend;
class RigEclipseCaseData;
//==================================================================================================
///
//==================================================================================================
class RimNonNetLayers : public caf::PdmObject
class RimNonNetLayers : public RimCheckableObject
{
CAF_PDM_HEADER_INIT;
@ -49,7 +50,6 @@ public:
const RimEclipseResultDefinition* resultDefinition() const;
double cutOff() const;
const QString& formation() const;
const QString& facies() const;
protected:
@ -57,15 +57,14 @@ protected:
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute ) override;
RimColorLegend* getFaciesColorLegend();
static std::vector<QString> getFormationNames();
static RimEclipseCase* getEclipseCase();
static RigEclipseCaseData* getEclipseCaseData();
RimColorLegend* getFaciesColorLegend();
private:
caf::PdmField<double> m_cutOff;
caf::PdmChildField<RimEclipseResultDefinition*> m_resultDefinition;
caf::PdmField<QString> m_formation;
caf::PdmField<QString> m_facies;
};