mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Refactor fracture model result calculation to be independent of display.
This commit is contained in:
parent
f4631e7f9d
commit
7d456f1cbb
@ -94,34 +94,10 @@ RimFractureModelPlot*
|
||||
{
|
||||
auto task = progInfo.task( "Creating parameters track", 15 );
|
||||
|
||||
std::map<QString, PlotDefVector> plots;
|
||||
plots["Porosity"] = {std::make_tuple( "PORO",
|
||||
RiaDefines::ResultCatType::STATIC_NATIVE,
|
||||
RimFractureModelCurve::MissingValueStrategy::DEFAULT_VALUE,
|
||||
false,
|
||||
RiaDefines::CurveProperty::POROSITY )};
|
||||
|
||||
plots["Pressure"] = {std::make_tuple( "PRESSURE",
|
||||
RiaDefines::ResultCatType::DYNAMIC_NATIVE,
|
||||
RimFractureModelCurve::MissingValueStrategy::LINEAR_INTERPOLATION,
|
||||
true,
|
||||
RiaDefines::CurveProperty::INITIAL_PRESSURE ),
|
||||
std::make_tuple( "PRESSURE",
|
||||
RiaDefines::ResultCatType::DYNAMIC_NATIVE,
|
||||
RimFractureModelCurve::MissingValueStrategy::OTHER_CURVE_PROPERTY,
|
||||
false,
|
||||
RiaDefines::CurveProperty::PRESSURE )};
|
||||
|
||||
plots["Permeability"] = {std::make_tuple( "PERMX",
|
||||
RiaDefines::ResultCatType::STATIC_NATIVE,
|
||||
RimFractureModelCurve::MissingValueStrategy::DEFAULT_VALUE,
|
||||
false,
|
||||
RiaDefines::CurveProperty::PERMEABILITY_X ),
|
||||
std::make_tuple( "PERMZ",
|
||||
RiaDefines::ResultCatType::STATIC_NATIVE,
|
||||
RimFractureModelCurve::MissingValueStrategy::DEFAULT_VALUE,
|
||||
false,
|
||||
RiaDefines::CurveProperty::PERMEABILITY_Z )};
|
||||
std::map<QString, std::vector<RiaDefines::CurveProperty>> plots;
|
||||
plots["Porosity"] = {RiaDefines::CurveProperty::POROSITY};
|
||||
plots["Pressure"] = {RiaDefines::CurveProperty::INITIAL_PRESSURE, RiaDefines::CurveProperty::PRESSURE};
|
||||
plots["Permeability"] = {RiaDefines::CurveProperty::PERMEABILITY_X, RiaDefines::CurveProperty::PERMEABILITY_Z};
|
||||
|
||||
std::set<QString> logarithmicPlots;
|
||||
logarithmicPlots.insert( "Permeability" );
|
||||
@ -374,7 +350,7 @@ void RicNewFractureModelPlotFeature::createParametersTrack( RimFractureModelPlot
|
||||
RimEclipseCase* eclipseCase,
|
||||
int timeStep,
|
||||
const QString& trackTitle,
|
||||
const PlotDefVector& curveConfigurations,
|
||||
const std::vector<RiaDefines::CurveProperty>& propertyTypes,
|
||||
bool isPlotLogarithmic )
|
||||
{
|
||||
RimWellLogTrack* plotTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false, trackTitle, plot );
|
||||
@ -387,21 +363,19 @@ void RicNewFractureModelPlotFeature::createParametersTrack( RimFractureModelPlot
|
||||
caf::ColorTable colors = RiaColorTables::wellLogPlotPaletteColors();
|
||||
|
||||
int colorIndex = 0;
|
||||
for ( auto curveConfig : curveConfigurations )
|
||||
for ( const RiaDefines::CurveProperty& propertyType : propertyTypes )
|
||||
{
|
||||
QString resultVariable = std::get<0>( curveConfig );
|
||||
RiaDefines::ResultCatType resultCategoryType = std::get<1>( curveConfig );
|
||||
RimFractureModelCurve::MissingValueStrategy missingValueStrategy = std::get<2>( curveConfig );
|
||||
bool fixedInitialTimeStep = std::get<3>( curveConfig );
|
||||
RiaDefines::CurveProperty curveProperty = std::get<4>( curveConfig );
|
||||
QString resultVariable = fractureModel->eclipseResultVariable( propertyType );
|
||||
RiaDefines::ResultCatType resultCategoryType = fractureModel->eclipseResultCategory( propertyType );
|
||||
// TODO: maybe improve?
|
||||
bool fixedInitialTimeStep = ( propertyType == RiaDefines::CurveProperty::INITIAL_PRESSURE );
|
||||
|
||||
RimFractureModelCurve* curve = new RimFractureModelCurve;
|
||||
curve->setCurveProperty( curveProperty );
|
||||
curve->setCurveProperty( propertyType );
|
||||
curve->setFractureModel( fractureModel );
|
||||
curve->setCase( eclipseCase );
|
||||
curve->setEclipseResultVariable( resultVariable );
|
||||
curve->setEclipseResultCategory( resultCategoryType );
|
||||
curve->setMissingValueStrategy( missingValueStrategy );
|
||||
curve->setColor( colors.cycledColor3f( colorIndex ) );
|
||||
curve->setLineStyle( RiuQwtPlotCurve::STYLE_SOLID );
|
||||
curve->setLineThickness( 2 );
|
||||
@ -418,11 +392,6 @@ void RicNewFractureModelPlotFeature::createParametersTrack( RimFractureModelPlot
|
||||
curve->setCurrentTimeStep( timeStep );
|
||||
}
|
||||
|
||||
if ( curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
{
|
||||
curve->setBurdenStrategy( RimFractureModelCurve::BurdenStrategy::GRADIENT );
|
||||
}
|
||||
|
||||
plotTrack->addCurve( curve );
|
||||
curve->loadDataAndUpdate( true );
|
||||
|
||||
|
@ -31,9 +31,6 @@ class RimFractureModelPlot;
|
||||
class RimFractureModelPlotCollection;
|
||||
class RimFractureModel;
|
||||
|
||||
typedef std::tuple<QString, RiaDefines::ResultCatType, RimFractureModelCurve::MissingValueStrategy, bool, RiaDefines::CurveProperty> PlotDef;
|
||||
typedef std::vector<PlotDef> PlotDefVector;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@ -63,7 +60,7 @@ private:
|
||||
RimEclipseCase* eclipseCase,
|
||||
int timeStep,
|
||||
const QString& trackTitle,
|
||||
const PlotDefVector& curveConfiguration,
|
||||
const std::vector<RiaDefines::CurveProperty>& propertyTypes,
|
||||
bool isPlotLogarithmic );
|
||||
|
||||
static void createElasticPropertiesTrack( RimFractureModelPlot* plot,
|
||||
|
@ -59,7 +59,7 @@ void RicExportFractureModelPlotToFileFeature::onActionTriggered( bool isChecked
|
||||
|
||||
if ( directoryPath.isEmpty() ) return;
|
||||
|
||||
RifFractureModelPlotExporter::writeToDirectory( fractureModelPlot,
|
||||
RifFractureModelPlotExporter::writeToDirectory( fractureModelPlot->fractureModel(),
|
||||
fractureModelPlot->fractureModel()->useDetailedFluidLoss(),
|
||||
directoryPath );
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "RifFractureModelAsymmetricFrkExporter.h"
|
||||
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
@ -27,14 +26,8 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifFractureModelAsymmetricFrkExporter::writeToFile( RimFractureModelPlot* plot, const QString& filepath )
|
||||
bool RifFractureModelAsymmetricFrkExporter::writeToFile( RimFractureModel* fractureModel, const QString& filepath )
|
||||
{
|
||||
RimFractureModel* fractureModel = plot->fractureModel();
|
||||
if ( !fractureModel )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile data( filepath );
|
||||
if ( !data.open( QFile::WriteOnly | QFile::Truncate ) )
|
||||
{
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
class RimFractureModelPlot;
|
||||
class RimFractureModel;
|
||||
|
||||
class QString;
|
||||
class QTextStream;
|
||||
@ -29,7 +29,7 @@ class QTextStream;
|
||||
class RifFractureModelAsymmetricFrkExporter
|
||||
{
|
||||
public:
|
||||
static bool writeToFile( RimFractureModelPlot* plot, const QString& filepath );
|
||||
static bool writeToFile( RimFractureModel* fractureModel, const QString& filepath );
|
||||
|
||||
private:
|
||||
static void appendHeaderToStream( QTextStream& stream );
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "RifFractureModelDeviationFrkExporter.h"
|
||||
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimWellPath.h"
|
||||
|
||||
#include "RigWellPathGeometryExporter.h"
|
||||
@ -30,14 +29,8 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifFractureModelDeviationFrkExporter::writeToFile( RimFractureModelPlot* plot, const QString& filepath )
|
||||
bool RifFractureModelDeviationFrkExporter::writeToFile( RimFractureModel* fractureModel, const QString& filepath )
|
||||
{
|
||||
RimFractureModel* fractureModel = plot->fractureModel();
|
||||
if ( !fractureModel )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RimWellPath* wellPath = fractureModel->wellPath();
|
||||
if ( !wellPath )
|
||||
{
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModelPlot;
|
||||
class RimFractureModel;
|
||||
class QString;
|
||||
class QTextStream;
|
||||
|
||||
@ -30,7 +30,7 @@ class QTextStream;
|
||||
class RifFractureModelDeviationFrkExporter
|
||||
{
|
||||
public:
|
||||
static bool writeToFile( RimFractureModelPlot* plot, const QString& filepath );
|
||||
static bool writeToFile( RimFractureModel* fractureModel, const QString& filepath );
|
||||
|
||||
static void fixupDepthValuesForExport( const std::vector<double>& tvdValues,
|
||||
const std::vector<double>& mdValues,
|
||||
|
@ -18,7 +18,8 @@
|
||||
|
||||
#include "RifFractureModelGeologicalFrkExporter.h"
|
||||
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
@ -26,7 +27,7 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifFractureModelGeologicalFrkExporter::writeToFile( RimFractureModelPlot* plot,
|
||||
bool RifFractureModelGeologicalFrkExporter::writeToFile( RimFractureModel* fractureModel,
|
||||
bool useDetailedLoss,
|
||||
const QString& filepath )
|
||||
{
|
||||
@ -90,24 +91,24 @@ bool RifFractureModelGeologicalFrkExporter::writeToFile( RimFractureModelPlot* p
|
||||
}
|
||||
|
||||
std::map<QString, std::vector<double>> values;
|
||||
values["dpthlyr"] = plot->calculateTrueVerticalDepth();
|
||||
values["strs"] = plot->calculateStress();
|
||||
values["strsg"] = plot->calculateStressGradient();
|
||||
values["elyr"] = plot->calculateYoungsModulus();
|
||||
values["poissonr"] = plot->calculatePoissonsRatio();
|
||||
values["tuflyr"] = plot->calculateKIc();
|
||||
values["clyrc"] = plot->calculateFluidLossCoefficient();
|
||||
values["clyrs"] = plot->calculateSpurtLoss();
|
||||
values["pembed"] = plot->calculateProppandEmbedment();
|
||||
values["zoneResPres"] = plot->calculateReservoirPressure();
|
||||
values["zoneWaterSat"] = plot->calculateImmobileFluidSaturation();
|
||||
values["zonePorosity"] = plot->calculatePorosity();
|
||||
values["zoneHorizPerm"] = plot->calculateHorizontalPermeability();
|
||||
values["zoneVertPerm"] = plot->calculateVerticalPermeability();
|
||||
values["zoneTemp"] = plot->calculateTemperature();
|
||||
values["zoneRelPerm"] = plot->calculateRelativePermeabilityFactor();
|
||||
values["zonePoroElas"] = plot->calculatePoroElasticConstant();
|
||||
values["zoneThermalExp"] = plot->calculateThermalExpansionCoefficient();
|
||||
values["dpthlyr"] = fractureModel->calculator()->calculateTrueVerticalDepth();
|
||||
values["strs"] = fractureModel->calculator()->calculateStress();
|
||||
values["strsg"] = fractureModel->calculator()->calculateStressGradient();
|
||||
values["elyr"] = fractureModel->calculator()->calculateYoungsModulus();
|
||||
values["poissonr"] = fractureModel->calculator()->calculatePoissonsRatio();
|
||||
values["tuflyr"] = fractureModel->calculator()->calculateKIc();
|
||||
values["clyrc"] = fractureModel->calculator()->calculateFluidLossCoefficient();
|
||||
values["clyrs"] = fractureModel->calculator()->calculateSpurtLoss();
|
||||
values["pembed"] = fractureModel->calculator()->calculateProppandEmbedment();
|
||||
values["zoneResPres"] = fractureModel->calculator()->calculateReservoirPressure();
|
||||
values["zoneWaterSat"] = fractureModel->calculator()->calculateImmobileFluidSaturation();
|
||||
values["zonePorosity"] = fractureModel->calculator()->calculatePorosity();
|
||||
values["zoneHorizPerm"] = fractureModel->calculator()->calculateHorizontalPermeability();
|
||||
values["zoneVertPerm"] = fractureModel->calculator()->calculateVerticalPermeability();
|
||||
values["zoneTemp"] = fractureModel->calculator()->calculateTemperature();
|
||||
values["zoneRelPerm"] = fractureModel->calculator()->calculateRelativePermeabilityFactor();
|
||||
values["zonePoroElas"] = fractureModel->calculator()->calculatePoroElasticConstant();
|
||||
values["zoneThermalExp"] = fractureModel->calculator()->calculateThermalExpansionCoefficient();
|
||||
|
||||
QFile data( filepath );
|
||||
if ( !data.open( QFile::WriteOnly | QFile::Truncate ) )
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModelPlot;
|
||||
class RimFractureModel;
|
||||
class QString;
|
||||
class QTextStream;
|
||||
|
||||
@ -30,7 +30,7 @@ class QTextStream;
|
||||
class RifFractureModelGeologicalFrkExporter
|
||||
{
|
||||
public:
|
||||
static bool writeToFile( RimFractureModelPlot* plot, bool useDetailedFluidLoss, const QString& filepath );
|
||||
static bool writeToFile( RimFractureModel* plot, bool useDetailedFluidLoss, const QString& filepath );
|
||||
|
||||
private:
|
||||
static void appendHeaderToStream( QTextStream& stream );
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimWellPath.h"
|
||||
|
||||
#include "RigWellPath.h"
|
||||
@ -35,14 +34,8 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifFractureModelPerfsFrkExporter::writeToFile( RimFractureModelPlot* plot, const QString& filepath )
|
||||
bool RifFractureModelPerfsFrkExporter::writeToFile( RimFractureModel* fractureModel, const QString& filepath )
|
||||
{
|
||||
RimFractureModel* fractureModel = plot->fractureModel();
|
||||
if ( !fractureModel )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RimWellPath* wellPath = fractureModel->wellPath();
|
||||
if ( !wellPath )
|
||||
{
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "cvfVector3.h"
|
||||
|
||||
class RimFractureModelPlot;
|
||||
class RimFractureModel;
|
||||
class RimWellPath;
|
||||
|
||||
class QString;
|
||||
@ -32,7 +32,7 @@ class QTextStream;
|
||||
class RifFractureModelPerfsFrkExporter
|
||||
{
|
||||
public:
|
||||
static bool writeToFile( RimFractureModelPlot* plot, const QString& filepath );
|
||||
static bool writeToFile( RimFractureModel* fractureModel, const QString& filepath );
|
||||
|
||||
private:
|
||||
static void appendHeaderToStream( QTextStream& stream );
|
||||
|
@ -28,12 +28,14 @@
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RifFractureModelPlotExporter::writeToDirectory( RimFractureModelPlot* plot,
|
||||
bool RifFractureModelPlotExporter::writeToDirectory( RimFractureModel* fractureModel,
|
||||
bool useDetailedFluidLoss,
|
||||
const QString& directoryPath )
|
||||
{
|
||||
return RifFractureModelGeologicalFrkExporter::writeToFile( plot, useDetailedFluidLoss, directoryPath + "/Geological.frk" ) &&
|
||||
RifFractureModelDeviationFrkExporter::writeToFile( plot, directoryPath + "/Deviation.frk" ) &&
|
||||
RifFractureModelPerfsFrkExporter::writeToFile( plot, directoryPath + "/Perfs.frk" ) &&
|
||||
RifFractureModelAsymmetricFrkExporter::writeToFile( plot, directoryPath + "/Asymmetric.frk" );
|
||||
return RifFractureModelGeologicalFrkExporter::writeToFile( fractureModel,
|
||||
useDetailedFluidLoss,
|
||||
directoryPath + "/Geological.frk" ) &&
|
||||
RifFractureModelDeviationFrkExporter::writeToFile( fractureModel, directoryPath + "/Deviation.frk" ) &&
|
||||
RifFractureModelPerfsFrkExporter::writeToFile( fractureModel, directoryPath + "/Perfs.frk" ) &&
|
||||
RifFractureModelAsymmetricFrkExporter::writeToFile( fractureModel, directoryPath + "/Asymmetric.frk" );
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModelPlot;
|
||||
class RimFractureModel;
|
||||
class QString;
|
||||
class QTextStream;
|
||||
|
||||
@ -30,5 +30,5 @@ class QTextStream;
|
||||
class RifFractureModelPlotExporter
|
||||
{
|
||||
public:
|
||||
static bool writeToDirectory( RimFractureModelPlot* plot, bool useDetailedFluidLoss, const QString& directoryPath );
|
||||
static bool writeToDirectory( RimFractureModel* fractureModel, bool useDetailedFluidLoss, const QString& directoryPath );
|
||||
};
|
||||
|
@ -170,6 +170,12 @@ ${CMAKE_CURRENT_LIST_DIR}/RimAbstractPlotCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelPropertyCurve.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFaciesProperties.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimNonNetLayers.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelPropertyCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelWellLogCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelElasticPropertyCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelLayerCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelStressCalculator.h
|
||||
)
|
||||
|
||||
|
||||
@ -342,6 +348,11 @@ ${CMAKE_CURRENT_LIST_DIR}/RimLayerCurve.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelStressCurve.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFaciesProperties.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimNonNetLayers.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelWellLogCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelElasticPropertyCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelLayerCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimFractureModelStressCalculator.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
@ -39,9 +39,12 @@
|
||||
#include "RimColorLegendItem.h"
|
||||
#include "RimCompletionTemplateCollection.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimEclipseView.h"
|
||||
#include "RimFaciesProperties.h"
|
||||
#include "RimFaultInView.h"
|
||||
#include "RimFaultInViewCollection.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimFractureModelTemplate.h"
|
||||
#include "RimFractureModelTemplateCollection.h"
|
||||
@ -99,6 +102,25 @@ void caf::AppEnum<RimFractureModel::FractureOrientation>::setUp()
|
||||
|
||||
setDefault( RimFractureModel::FractureOrientation::TRANSVERSE_WELL_PATH );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimFractureModel::MissingValueStrategy>::setUp()
|
||||
{
|
||||
addItem( RimFractureModel::MissingValueStrategy::DEFAULT_VALUE, "DEFAULT_VALUE", "Default value" );
|
||||
addItem( RimFractureModel::MissingValueStrategy::LINEAR_INTERPOLATION, "LINEAR_INTERPOLATION", "Linear interpolation" );
|
||||
addItem( RimFractureModel::MissingValueStrategy::OTHER_CURVE_PROPERTY, "OTHER_CURVE_PROPERTY", "Other Curve Property" );
|
||||
|
||||
setDefault( RimFractureModel::MissingValueStrategy::DEFAULT_VALUE );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimFractureModel::BurdenStrategy>::setUp()
|
||||
{
|
||||
addItem( RimFractureModel::BurdenStrategy::DEFAULT_VALUE, "DEFAULT_VALUE", "Default value" );
|
||||
addItem( RimFractureModel::BurdenStrategy::GRADIENT, "GRADIENT", "Gradient" );
|
||||
|
||||
setDefault( RimFractureModel::BurdenStrategy::DEFAULT_VALUE );
|
||||
}
|
||||
}; // namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -113,6 +135,8 @@ RimFractureModel::RimFractureModel()
|
||||
m_editFractureModelTemplate.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonEditor::uiEditorTypeName() );
|
||||
m_editFractureModelTemplate.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_timeStep, "TimeStep", 0, "Time Step", "", "", "" );
|
||||
|
||||
CAF_PDM_InitScriptableField( &m_MD, "MeasuredDepth", 0.0, "Measured Depth", "", "", "" );
|
||||
m_MD.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
|
||||
|
||||
@ -199,6 +223,9 @@ RimFractureModel::RimFractureModel()
|
||||
"",
|
||||
"" );
|
||||
|
||||
m_calculator = std::shared_ptr<RimFractureModelCalculator>( new RimFractureModelCalculator );
|
||||
m_calculator->setFractureModel( this );
|
||||
|
||||
setDeletable( true );
|
||||
}
|
||||
|
||||
@ -782,6 +809,7 @@ void RimFractureModel::defineUiOrdering( QString uiConfigName, caf::PdmUiOrderin
|
||||
uiOrdering.add( &m_fractureModelTemplate, {true, 2, 1} );
|
||||
uiOrdering.add( &m_editFractureModelTemplate, {false, 1, 0} );
|
||||
|
||||
uiOrdering.add( &m_timeStep );
|
||||
uiOrdering.add( &m_MD );
|
||||
uiOrdering.add( &m_extractionType );
|
||||
uiOrdering.add( &m_anchorPosition );
|
||||
@ -976,19 +1004,21 @@ double RimFractureModel::defaultPermeability() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::getDefaultForMissingValue( const QString& keyword ) const
|
||||
double RimFractureModel::getDefaultForMissingValue( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( keyword == QString( "PORO" ) )
|
||||
if ( curveProperty == RiaDefines::CurveProperty::POROSITY )
|
||||
{
|
||||
return defaultPorosity();
|
||||
}
|
||||
else if ( keyword == QString( "PERMX" ) || keyword == QString( "PERMZ" ) )
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::PERMEABILITY_X ||
|
||||
curveProperty == RiaDefines::CurveProperty::PERMEABILITY_Z )
|
||||
{
|
||||
return defaultPermeability();
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Missing default value for %1." ).arg( keyword ) );
|
||||
RiaLogging::error( QString( "Missing default value for %1." )
|
||||
.arg( caf::AppEnum<RiaDefines::CurveProperty>( curveProperty ).uiText() ) );
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
@ -996,9 +1026,9 @@ double RimFractureModel::getDefaultForMissingValue( const QString& keyword ) con
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaDefines::CurveProperty RimFractureModel::getDefaultPropertyForMissingValues( const QString& keyword ) const
|
||||
RiaDefines::CurveProperty RimFractureModel::getDefaultPropertyForMissingValues( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( keyword == QString( "PRESSURE" ) )
|
||||
if ( curveProperty == RiaDefines::CurveProperty::PRESSURE )
|
||||
{
|
||||
return RiaDefines::CurveProperty::INITIAL_PRESSURE;
|
||||
}
|
||||
@ -1009,19 +1039,27 @@ RiaDefines::CurveProperty RimFractureModel::getDefaultPropertyForMissingValues(
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::getDefaultForMissingOverburdenValue( const QString& keyword ) const
|
||||
double RimFractureModel::getDefaultForMissingOverburdenValue( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( keyword == QString( "PORO" ) )
|
||||
if ( curveProperty == RiaDefines::CurveProperty::POROSITY )
|
||||
{
|
||||
return defaultOverburdenPorosity();
|
||||
}
|
||||
else if ( keyword == QString( "PERMX" ) || keyword == QString( "PERMZ" ) )
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::PERMEABILITY_X ||
|
||||
curveProperty == RiaDefines::CurveProperty::PERMEABILITY_Z )
|
||||
{
|
||||
return defaultOverburdenPermeability();
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::FACIES )
|
||||
{
|
||||
RimColorLegend* faciesColorLegend = getFaciesColorLegend();
|
||||
if ( !faciesColorLegend ) return std::numeric_limits<double>::infinity();
|
||||
return findFaciesValue( *faciesColorLegend, overburdenFacies() );
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Missing default overburden value for %1." ).arg( keyword ) );
|
||||
RiaLogging::error( QString( "Missing default overburden value for %1." )
|
||||
.arg( caf::AppEnum<RiaDefines::CurveProperty>( curveProperty ).uiText() ) );
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
@ -1029,19 +1067,27 @@ double RimFractureModel::getDefaultForMissingOverburdenValue( const QString& key
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::getDefaultForMissingUnderburdenValue( const QString& keyword ) const
|
||||
double RimFractureModel::getDefaultForMissingUnderburdenValue( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( keyword == QString( "PORO" ) )
|
||||
if ( curveProperty == RiaDefines::CurveProperty::POROSITY )
|
||||
{
|
||||
return defaultUnderburdenPorosity();
|
||||
}
|
||||
else if ( keyword == QString( "PERMX" ) || keyword == QString( "PERMZ" ) )
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::PERMEABILITY_X ||
|
||||
curveProperty == RiaDefines::CurveProperty::PERMEABILITY_Z )
|
||||
{
|
||||
return defaultUnderburdenPermeability();
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::FACIES )
|
||||
{
|
||||
RimColorLegend* faciesColorLegend = getFaciesColorLegend();
|
||||
if ( !faciesColorLegend ) return std::numeric_limits<double>::infinity();
|
||||
return findFaciesValue( *faciesColorLegend, underburdenFacies() );
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Missing default underburden value for %1." ).arg( keyword ) );
|
||||
RiaLogging::error( QString( "Missing default underburden value for %1." )
|
||||
.arg( caf::AppEnum<RiaDefines::CurveProperty>( curveProperty ).uiText() ) );
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
@ -1049,9 +1095,10 @@ double RimFractureModel::getDefaultForMissingUnderburdenValue( const QString& ke
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::getOverburdenGradient( const QString& keyword ) const
|
||||
double RimFractureModel::getOverburdenGradient( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( keyword == QString( "PRESSURE" ) )
|
||||
if ( curveProperty == RiaDefines::CurveProperty::PRESSURE ||
|
||||
curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
{
|
||||
if ( !m_fractureModelTemplate )
|
||||
{
|
||||
@ -1061,7 +1108,8 @@ double RimFractureModel::getOverburdenGradient( const QString& keyword ) const
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Missing overburden gradient for %1." ).arg( keyword ) );
|
||||
RiaLogging::error( QString( "Missing overburden gradient for %1." )
|
||||
.arg( caf::AppEnum<RiaDefines::CurveProperty>( curveProperty ).uiText() ) );
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
@ -1069,9 +1117,10 @@ double RimFractureModel::getOverburdenGradient( const QString& keyword ) const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::getUnderburdenGradient( const QString& keyword ) const
|
||||
double RimFractureModel::getUnderburdenGradient( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( keyword == QString( "PRESSURE" ) )
|
||||
if ( curveProperty == RiaDefines::CurveProperty::PRESSURE ||
|
||||
curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
{
|
||||
if ( !m_fractureModelTemplate )
|
||||
{
|
||||
@ -1082,7 +1131,8 @@ double RimFractureModel::getUnderburdenGradient( const QString& keyword ) const
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Missing underburden gradient for %1." ).arg( keyword ) );
|
||||
RiaLogging::error( QString( "Missing underburden gradient for %1." )
|
||||
.arg( caf::AppEnum<RiaDefines::CurveProperty>( curveProperty ).uiText() ) );
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
@ -1112,6 +1162,30 @@ double RimFractureModel::getDefaultValueForProperty( RiaDefines::CurveProperty c
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModel::MissingValueStrategy RimFractureModel::missingValueStrategy( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
return RimFractureModel::MissingValueStrategy::LINEAR_INTERPOLATION;
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::PRESSURE )
|
||||
return RimFractureModel::MissingValueStrategy::OTHER_CURVE_PROPERTY;
|
||||
else
|
||||
return RimFractureModel::MissingValueStrategy::DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModel::BurdenStrategy RimFractureModel::burdenStrategy( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
return RimFractureModel::BurdenStrategy::GRADIENT;
|
||||
|
||||
return RimFractureModel::BurdenStrategy::DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1253,6 +1327,14 @@ void RimFractureModel::setMD( double md )
|
||||
updateBarrierProperties();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimFractureModel::timeStep() const
|
||||
{
|
||||
return m_timeStep;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1445,3 +1527,104 @@ void RimFractureModel::showAllFaults()
|
||||
rimFault->showFault = true;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<RimFractureModelCalculator> RimFractureModel::calculator() const
|
||||
{
|
||||
return m_calculator;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEclipseCase* RimFractureModel::eclipseCase() const
|
||||
{
|
||||
RimProject* proj = RimProject::current();
|
||||
if ( proj->eclipseCases().empty() ) return nullptr;
|
||||
|
||||
return proj->eclipseCases()[0];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaDefines::ResultCatType RimFractureModel::eclipseResultCategory( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( curveProperty == RiaDefines::CurveProperty::PRESSURE ||
|
||||
curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
{
|
||||
return RiaDefines::ResultCatType::DYNAMIC_NATIVE;
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::FACIES )
|
||||
{
|
||||
RimFaciesProperties* faciesProperties = m_fractureModelTemplate->faciesProperties();
|
||||
if ( !faciesProperties ) return RiaDefines::ResultCatType::STATIC_NATIVE;
|
||||
|
||||
const RimEclipseResultDefinition* faciesDefinition = faciesProperties->faciesDefinition();
|
||||
if ( !faciesDefinition ) return RiaDefines::ResultCatType::STATIC_NATIVE;
|
||||
|
||||
return faciesDefinition->resultType();
|
||||
}
|
||||
else
|
||||
{
|
||||
return RiaDefines::ResultCatType::STATIC_NATIVE;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimFractureModel::eclipseResultVariable( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
if ( curveProperty == RiaDefines::CurveProperty::PRESSURE ||
|
||||
curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
return "PRESSURE";
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::PERMEABILITY_X )
|
||||
return "PERMX";
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::PERMEABILITY_Z )
|
||||
return "PERMZ";
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::POROSITY )
|
||||
return "PORO";
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::FACIES )
|
||||
{
|
||||
if ( !m_fractureModelTemplate ) return "";
|
||||
|
||||
RimFaciesProperties* faciesProperties = m_fractureModelTemplate->faciesProperties();
|
||||
if ( !faciesProperties ) return "";
|
||||
|
||||
const RimEclipseResultDefinition* faciesDefinition = faciesProperties->faciesDefinition();
|
||||
if ( !faciesDefinition ) return "";
|
||||
|
||||
return faciesDefinition->resultVariable();
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimColorLegend* RimFractureModel::getFaciesColorLegend() const
|
||||
{
|
||||
if ( !m_fractureModelTemplate ) return nullptr;
|
||||
|
||||
RimFaciesProperties* faciesProperties = m_fractureModelTemplate->faciesProperties();
|
||||
if ( !faciesProperties ) return nullptr;
|
||||
|
||||
return faciesProperties->colorLegend();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModel::findFaciesValue( const RimColorLegend& colorLegend, const QString& name )
|
||||
{
|
||||
for ( auto item : colorLegend.colorLegendItems() )
|
||||
{
|
||||
if ( item->categoryName() == name ) return item->categoryValue();
|
||||
}
|
||||
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ class RimUserDefinedPolylinesAnnotation;
|
||||
class RimFaciesProperties;
|
||||
class RimFractureModelTemplate;
|
||||
class RimTextAnnotation;
|
||||
class RimFractureModelCalculator;
|
||||
class RimColorLegend;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -63,11 +65,26 @@ public:
|
||||
AZIMUTH
|
||||
};
|
||||
|
||||
enum class MissingValueStrategy
|
||||
{
|
||||
DEFAULT_VALUE,
|
||||
LINEAR_INTERPOLATION,
|
||||
OTHER_CURVE_PROPERTY
|
||||
};
|
||||
|
||||
enum class BurdenStrategy
|
||||
{
|
||||
DEFAULT_VALUE,
|
||||
GRADIENT
|
||||
};
|
||||
|
||||
RimFractureModel( void );
|
||||
~RimFractureModel( void ) override;
|
||||
|
||||
void setMD( double md );
|
||||
|
||||
int timeStep() const;
|
||||
|
||||
cvf::Vec3d anchorPosition() const;
|
||||
cvf::Vec3d thicknessDirection() const;
|
||||
|
||||
@ -130,18 +147,28 @@ public:
|
||||
double getDefaultValueForProperty( RiaDefines::CurveProperty ) const;
|
||||
bool hasDefaultValueForProperty( RiaDefines::CurveProperty ) const;
|
||||
|
||||
RiaDefines::CurveProperty getDefaultPropertyForMissingValues( const QString& keyword ) const;
|
||||
double getDefaultForMissingOverburdenValue( const QString& keyword ) const;
|
||||
double getDefaultForMissingUnderburdenValue( const QString& keyword ) const;
|
||||
double getDefaultForMissingValue( const QString& keyword ) const;
|
||||
double getOverburdenGradient( const QString& keyword ) const;
|
||||
double getUnderburdenGradient( const QString& keyword ) const;
|
||||
RiaDefines::CurveProperty getDefaultPropertyForMissingValues( RiaDefines::CurveProperty curveProperty ) const;
|
||||
double getDefaultForMissingOverburdenValue( RiaDefines::CurveProperty curveProperty ) const;
|
||||
double getDefaultForMissingUnderburdenValue( RiaDefines::CurveProperty curveProperty ) const;
|
||||
double getDefaultForMissingValue( RiaDefines::CurveProperty curveProperty ) const;
|
||||
double getOverburdenGradient( RiaDefines::CurveProperty curveProperty ) const;
|
||||
double getUnderburdenGradient( RiaDefines::CurveProperty curveProperty ) const;
|
||||
|
||||
void setFractureModelTemplate( RimFractureModelTemplate* fractureModelTemplate );
|
||||
RimFractureModelTemplate* fractureModelTemplate() const;
|
||||
|
||||
void updateReferringPlots();
|
||||
|
||||
std::shared_ptr<RimFractureModelCalculator> calculator() const;
|
||||
|
||||
RimFractureModel::MissingValueStrategy missingValueStrategy( RiaDefines::CurveProperty curveProperty ) const;
|
||||
RimFractureModel::BurdenStrategy burdenStrategy( RiaDefines::CurveProperty curveProperty ) const;
|
||||
RimEclipseCase* eclipseCase() const;
|
||||
RiaDefines::ResultCatType eclipseResultCategory( RiaDefines::CurveProperty curveProperty ) const;
|
||||
QString eclipseResultVariable( RiaDefines::CurveProperty curveProperty ) const;
|
||||
|
||||
static double findFaciesValue( const RimColorLegend& colorLegend, const QString& name );
|
||||
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
@ -185,8 +212,11 @@ private:
|
||||
void hideOtherFaults( const QString& targetFaultName );
|
||||
void showAllFaults();
|
||||
|
||||
RimColorLegend* getFaciesColorLegend() const;
|
||||
|
||||
protected:
|
||||
caf::PdmField<double> m_MD;
|
||||
caf::PdmField<int> m_timeStep;
|
||||
caf::PdmField<caf::AppEnum<ExtractionType>> m_extractionType;
|
||||
caf::PdmField<cvf::Vec3d> m_anchorPosition;
|
||||
caf::PdmField<cvf::Vec3d> m_thicknessDirection;
|
||||
@ -216,4 +246,6 @@ protected:
|
||||
caf::PdmField<QString> m_barrierFaultName;
|
||||
caf::PdmField<bool> m_showOnlyBarrierFault;
|
||||
caf::PdmField<bool> m_showAllFaults;
|
||||
|
||||
std::shared_ptr<RimFractureModelCalculator> m_calculator;
|
||||
};
|
||||
|
@ -19,44 +19,14 @@
|
||||
#include "RimElasticPropertiesCurve.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseWellLogExtractor.h"
|
||||
#include "RigElasticProperties.h"
|
||||
#include "RigResultAccessorFactory.h"
|
||||
#include "RigWellLogCurveData.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimColorLegend.h"
|
||||
#include "RimColorLegendCollection.h"
|
||||
#include "RimColorLegendItem.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimElasticProperties.h"
|
||||
#include "RimFaciesProperties.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimFractureModelTemplate.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellLogFile.h"
|
||||
#include "RimWellLogPlot.h"
|
||||
#include "RimWellLogTrack.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPlotTools.h"
|
||||
|
||||
#include "RiuQwtPlotCurve.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaFractureDefines.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimElasticPropertiesCurve, "ElasticPropertiesCurve" );
|
||||
|
||||
@ -135,173 +105,16 @@ void RimElasticPropertiesCurve::performDataExtraction( bool* isUsingPseudoLength
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_case.value() );
|
||||
if ( eclipseCase && m_fractureModel )
|
||||
{
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(),
|
||||
m_fractureModel->thicknessDirectionWellPath()->wellPathGeometry(),
|
||||
"fracture model" );
|
||||
|
||||
measuredDepthValues = eclExtractor.cellIntersectionMDs();
|
||||
tvDepthValues = eclExtractor.cellIntersectionTVDs();
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
// Extract formation data
|
||||
cvf::ref<RigResultAccessor> formationResultAccessor = RigResultAccessorFactory::
|
||||
createFromResultAddress( eclipseCase->eclipseCaseData(),
|
||||
0,
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
0,
|
||||
RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES,
|
||||
RiaDefines::activeFormationNamesResultName() ) );
|
||||
if ( !formationResultAccessor.notNull() )
|
||||
{
|
||||
RiaLogging::error( QString( "No formation result found." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
CurveSamplingPointData curveData =
|
||||
RimWellLogTrack::curveSamplingPointData( &eclExtractor, formationResultAccessor.p() );
|
||||
|
||||
std::vector<double> formationValues = curveData.data;
|
||||
|
||||
std::vector<QString> formationNamesVector = RimWellLogTrack::formationNamesVector( eclipseCase );
|
||||
|
||||
RimFractureModelTemplate* fractureModelTemplate = m_fractureModel->fractureModelTemplate();
|
||||
if ( !fractureModelTemplate )
|
||||
{
|
||||
RiaLogging::error( QString( "No fracture model template found" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
RimFaciesProperties* faciesProperties = fractureModelTemplate->faciesProperties();
|
||||
if ( !faciesProperties )
|
||||
{
|
||||
RiaLogging::error( QString( "No facies properties found when extracting elastic properties." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
const RimEclipseResultDefinition* faciesDefinition = faciesProperties->faciesDefinition();
|
||||
|
||||
// Extract facies data
|
||||
m_eclipseResultDefinition->setResultVariable( faciesDefinition->resultVariable() );
|
||||
m_eclipseResultDefinition->setResultType( faciesDefinition->resultType() );
|
||||
m_eclipseResultDefinition->setEclipseCase( eclipseCase );
|
||||
m_eclipseResultDefinition->loadResult();
|
||||
|
||||
cvf::ref<RigResultAccessor> faciesResultAccessor =
|
||||
RigResultAccessorFactory::createFromResultDefinition( eclipseCase->eclipseCaseData(),
|
||||
0,
|
||||
bool isOk = m_fractureModel->calculator()->extractCurveData( curveProperty(),
|
||||
m_timeStep,
|
||||
m_eclipseResultDefinition );
|
||||
|
||||
if ( !faciesResultAccessor.notNull() )
|
||||
{
|
||||
RiaLogging::error( QString( "No facies result found." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<double> faciesValues;
|
||||
eclExtractor.curveData( faciesResultAccessor.p(), &faciesValues );
|
||||
|
||||
// Extract porosity data: get the porosity values from parent
|
||||
RimFractureModelPlot* fractureModelPlot;
|
||||
firstAncestorOrThisOfType( fractureModelPlot );
|
||||
if ( !fractureModelPlot )
|
||||
{
|
||||
RiaLogging::error( QString( "No porosity data found when extracting elastic properties." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<double> poroValues;
|
||||
fractureModelPlot->getPorosityValues( poroValues );
|
||||
if ( poroValues.empty() )
|
||||
{
|
||||
RiaLogging::error( QString( "Empty porosity data found when extracting elastic properties." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
RimColorLegend* colorLegend = faciesProperties->colorLegend();
|
||||
if ( !colorLegend )
|
||||
{
|
||||
RiaLogging::error( QString( "No color legend found when extracting elastic properties." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
RimElasticProperties* elasticProperties = fractureModelTemplate->elasticProperties();
|
||||
if ( !elasticProperties )
|
||||
{
|
||||
RiaLogging::error( QString( "No elastic properties found" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
double overburdenHeight = m_fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
double defaultPoroValue = m_fractureModel->defaultOverburdenPorosity();
|
||||
QString overburdenFormation = m_fractureModel->overburdenFormation();
|
||||
QString overburdenFacies = m_fractureModel->overburdenFacies();
|
||||
|
||||
addOverburden( formationNamesVector,
|
||||
formationValues,
|
||||
faciesValues,
|
||||
tvDepthValues,
|
||||
values,
|
||||
measuredDepthValues,
|
||||
overburdenHeight,
|
||||
defaultPoroValue,
|
||||
overburdenFormation,
|
||||
findFaciesValue( *colorLegend, overburdenFacies ) );
|
||||
}
|
||||
|
||||
double underburdenHeight = m_fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
double defaultPoroValue = m_fractureModel->defaultUnderburdenPorosity();
|
||||
QString underburdenFormation = m_fractureModel->underburdenFormation();
|
||||
QString underburdenFacies = m_fractureModel->underburdenFacies();
|
||||
|
||||
addUnderburden( formationNamesVector,
|
||||
formationValues,
|
||||
faciesValues,
|
||||
tvDepthValues,
|
||||
measuredDepthValues,
|
||||
underburdenHeight,
|
||||
defaultPoroValue,
|
||||
underburdenFormation,
|
||||
findFaciesValue( *colorLegend, underburdenFacies ) );
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < tvDepthValues.size(); i++ )
|
||||
rkbDiff );
|
||||
if ( !isOk )
|
||||
{
|
||||
// Avoid using the field name in the match for now
|
||||
QString fieldName = "";
|
||||
QString faciesName = findFaciesName( *colorLegend, faciesValues[i] );
|
||||
int idx = static_cast<int>( formationValues[i] );
|
||||
QString formationName = formationNamesVector[idx];
|
||||
double porosity = poroValues[i];
|
||||
|
||||
FaciesKey faciesKey = std::make_tuple( fieldName, formationName, faciesName );
|
||||
if ( elasticProperties->hasPropertiesForFacies( faciesKey ) )
|
||||
{
|
||||
if ( RimElasticProperties::isScalableProperty( curveProperty() ) )
|
||||
{
|
||||
const RigElasticProperties& rigElasticProperties = elasticProperties->propertiesForFacies( faciesKey );
|
||||
double scale = elasticProperties->getPropertyScaling( formationName, faciesName, curveProperty() );
|
||||
double val = rigElasticProperties.getValueForPorosity( curveProperty(), porosity, scale );
|
||||
values.push_back( val );
|
||||
}
|
||||
else if ( m_fractureModel->hasDefaultValueForProperty( curveProperty() ) )
|
||||
{
|
||||
double val = m_fractureModel->getDefaultValueForProperty( curveProperty() );
|
||||
values.push_back( val );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Missing elastic properties. Field='%1', formation='%2', facies='%3'" )
|
||||
.arg( fieldName )
|
||||
.arg( formationName )
|
||||
.arg( faciesName ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem eclipseUnitsType = eclipseCase->eclipseCaseData()->unitsType();
|
||||
if ( eclipseUnitsType == RiaEclipseUnitTools::UnitSystem::UNITS_FIELD )
|
||||
@ -338,32 +151,6 @@ void RimElasticPropertiesCurve::performDataExtraction( bool* isUsingPseudoLength
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimElasticPropertiesCurve::findFaciesName( const RimColorLegend& colorLegend, double value )
|
||||
{
|
||||
for ( auto item : colorLegend.colorLegendItems() )
|
||||
{
|
||||
if ( item->categoryValue() == static_cast<int>( value ) ) return item->categoryName();
|
||||
}
|
||||
|
||||
return "not found";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimElasticPropertiesCurve::findFaciesValue( const RimColorLegend& colorLegend, const QString& name )
|
||||
{
|
||||
for ( auto item : colorLegend.colorLegendItems() )
|
||||
{
|
||||
if ( item->categoryName() == name ) return item->categoryValue();
|
||||
}
|
||||
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -371,74 +158,3 @@ QString RimElasticPropertiesCurve::createCurveAutoName()
|
||||
{
|
||||
return caf::AppEnum<RiaDefines::CurveProperty>::uiText( m_curveProperty() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimElasticPropertiesCurve::addOverburden( std::vector<QString>& formationNames,
|
||||
std::vector<double>& formationValues,
|
||||
std::vector<double>& faciesValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
double overburdenHeight,
|
||||
double defaultPoroValue,
|
||||
const QString& formationName,
|
||||
double faciesValue )
|
||||
{
|
||||
if ( !faciesValues.empty() )
|
||||
{
|
||||
// Prepend the new "fake" depth for start of overburden
|
||||
double tvdTop = tvDepthValues[0];
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdTop );
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdTop - overburdenHeight );
|
||||
|
||||
// TODO: this is not always correct
|
||||
double mdTop = measuredDepthValues[0];
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop );
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop - overburdenHeight );
|
||||
|
||||
formationNames.push_back( formationName );
|
||||
|
||||
formationValues.insert( formationValues.begin(), formationNames.size() - 1 );
|
||||
formationValues.insert( formationValues.begin(), formationNames.size() - 1 );
|
||||
|
||||
faciesValues.insert( faciesValues.begin(), faciesValue );
|
||||
faciesValues.insert( faciesValues.begin(), faciesValue );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimElasticPropertiesCurve::addUnderburden( std::vector<QString>& formationNames,
|
||||
std::vector<double>& formationValues,
|
||||
std::vector<double>& faciesValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
double underburdenHeight,
|
||||
double defaultPoroValue,
|
||||
const QString& formationName,
|
||||
double faciesValue )
|
||||
{
|
||||
if ( !faciesValues.empty() )
|
||||
{
|
||||
size_t lastIndex = tvDepthValues.size() - 1;
|
||||
|
||||
double tvdBottom = tvDepthValues[lastIndex];
|
||||
tvDepthValues.push_back( tvdBottom );
|
||||
tvDepthValues.push_back( tvdBottom + underburdenHeight );
|
||||
|
||||
// TODO: this is not always correct
|
||||
double mdBottom = measuredDepthValues[lastIndex];
|
||||
measuredDepthValues.push_back( mdBottom );
|
||||
measuredDepthValues.push_back( mdBottom + underburdenHeight );
|
||||
|
||||
formationNames.push_back( formationName );
|
||||
|
||||
formationValues.push_back( formationNames.size() - 1 );
|
||||
formationValues.push_back( formationNames.size() - 1 );
|
||||
|
||||
faciesValues.push_back( faciesValue );
|
||||
faciesValues.push_back( faciesValue );
|
||||
}
|
||||
}
|
||||
|
571
ApplicationCode/ProjectDataModel/RimFractureModelCalculator.cpp
Normal file
571
ApplicationCode/ProjectDataModel/RimFractureModelCalculator.cpp
Normal file
@ -0,0 +1,571 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RimFractureModelCalculator.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaFractureModelDefines.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimFractureModelElasticPropertyCalculator.h"
|
||||
#include "RimFractureModelLayerCalculator.h"
|
||||
#include "RimFractureModelPropertyCalculator.h"
|
||||
#include "RimFractureModelStressCalculator.h"
|
||||
#include "RimFractureModelWellLogCalculator.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModelCalculator::RimFractureModelCalculator()
|
||||
{
|
||||
m_resultCalculators.push_back(
|
||||
std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelWellLogCalculator( *this ) ) );
|
||||
m_resultCalculators.push_back(
|
||||
std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelElasticPropertyCalculator( this ) ) );
|
||||
m_resultCalculators.push_back(
|
||||
std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelLayerCalculator( this ) ) );
|
||||
m_resultCalculators.push_back(
|
||||
std::unique_ptr<RimFractureModelPropertyCalculator>( new RimFractureModelStressCalculator( this ) ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCalculator::setFractureModel( RimFractureModel* fractureModel )
|
||||
{
|
||||
m_fractureModel = fractureModel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModel* RimFractureModelCalculator::fractureModel()
|
||||
{
|
||||
return m_fractureModel;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelCalculator::extractCurveData( RiaDefines::CurveProperty curveProperty,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const
|
||||
{
|
||||
for ( const auto& calculator : m_resultCalculators )
|
||||
{
|
||||
if ( calculator->isMatching( curveProperty ) )
|
||||
{
|
||||
return calculator
|
||||
->calculate( curveProperty, m_fractureModel, timeStep, values, measuredDepthValues, tvDepthValues, rkbDiff );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::extractValues( RiaDefines::CurveProperty curveProperty, int timeStep ) const
|
||||
{
|
||||
std::vector<double> values;
|
||||
std::vector<double> measuredDepthValues;
|
||||
std::vector<double> tvDepthValues;
|
||||
double rkbDiff;
|
||||
|
||||
extractCurveData( curveProperty, timeStep, values, measuredDepthValues, tvDepthValues, rkbDiff );
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCalculator::calculateLayers( std::vector<std::pair<double, double>>& layerBoundaryDepths,
|
||||
std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes ) const
|
||||
{
|
||||
std::vector<double> layerValues;
|
||||
std::vector<double> measuredDepthValues;
|
||||
std::vector<double> depths;
|
||||
double rkbDiff;
|
||||
|
||||
extractCurveData( RiaDefines::CurveProperty::LAYERS,
|
||||
m_fractureModel->timeStep(),
|
||||
layerValues,
|
||||
measuredDepthValues,
|
||||
depths,
|
||||
rkbDiff );
|
||||
|
||||
size_t startIndex = 0;
|
||||
for ( size_t i = 0; i < depths.size(); i++ )
|
||||
{
|
||||
if ( startIndex != i && ( layerValues[startIndex] != layerValues[i] || i == depths.size() - 1 ) )
|
||||
{
|
||||
layerBoundaryDepths.push_back( std::make_pair( depths[startIndex], depths[i] ) );
|
||||
layerBoundaryIndexes.push_back( std::make_pair( startIndex, i ) );
|
||||
startIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModelCalculator::findValueAtTopOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo )
|
||||
{
|
||||
size_t index = layerBoundaryIndexes[layerNo].first;
|
||||
return values.at( index );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModelCalculator::findValueAtBottomOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo )
|
||||
{
|
||||
size_t index = layerBoundaryIndexes[layerNo].second;
|
||||
return values.at( index );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCalculator::computeAverageByLayer( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result )
|
||||
{
|
||||
for ( auto boundaryIndex : layerBoundaryIndexes )
|
||||
{
|
||||
double sum = 0.0;
|
||||
int nValues = 0;
|
||||
for ( size_t i = boundaryIndex.first; i < boundaryIndex.second; i++ )
|
||||
{
|
||||
sum += inputVector[i];
|
||||
nValues++;
|
||||
}
|
||||
result.push_back( sum / nValues );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCalculator::extractTopOfLayerValues( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result )
|
||||
{
|
||||
for ( size_t i = 0; i < layerBoundaryIndexes.size(); i++ )
|
||||
{
|
||||
result.push_back( findValueAtTopOfLayer( inputVector, layerBoundaryIndexes, i ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateTrueVerticalDepth() const
|
||||
{
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
std::vector<double> tvdTopZone;
|
||||
for ( auto p : layerBoundaryDepths )
|
||||
{
|
||||
double depthInFeet = RiaEclipseUnitTools::meterToFeet( p.first );
|
||||
tvdTopZone.push_back( depthInFeet );
|
||||
}
|
||||
|
||||
return tvdTopZone;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double>
|
||||
RimFractureModelCalculator::findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
std::vector<double> values = extractValues( curveProperty, m_fractureModel->timeStep() );
|
||||
std::vector<double> result;
|
||||
computeAverageByLayer( layerBoundaryIndexes, values, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
std::vector<double> values = extractValues( curveProperty, m_fractureModel->timeStep() );
|
||||
std::vector<double> result;
|
||||
extractTopOfLayerValues( layerBoundaryIndexes, values, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculatePorosity() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::POROSITY );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateReservoirPressure() const
|
||||
{
|
||||
std::vector<double> pressureBar = findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty::PRESSURE );
|
||||
|
||||
std::vector<double> pressurePsi;
|
||||
for ( double p : pressureBar )
|
||||
{
|
||||
pressurePsi.push_back( RiaEclipseUnitTools::barToPsi( p ) );
|
||||
}
|
||||
|
||||
return pressurePsi;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateHorizontalPermeability() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PERMEABILITY_X );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateVerticalPermeability() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PERMEABILITY_Z );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateStress() const
|
||||
{
|
||||
std::vector<double> stress;
|
||||
std::vector<double> stressGradients;
|
||||
std::vector<double> initialStress;
|
||||
calculateStressWithGradients( stress, stressGradients, initialStress );
|
||||
return stress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateInitialStress() const
|
||||
{
|
||||
std::vector<double> stress;
|
||||
std::vector<double> stressGradients;
|
||||
std::vector<double> initialStress;
|
||||
calculateStressWithGradients( stress, stressGradients, initialStress );
|
||||
return initialStress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelCalculator::calculateStressWithGradients( std::vector<double>& stress,
|
||||
std::vector<double>& stressGradients,
|
||||
std::vector<double>& initialStress ) const
|
||||
{
|
||||
// Reference stress
|
||||
const double verticalStressRef = m_fractureModel->verticalStress();
|
||||
const double verticalStressGradientRef = m_fractureModel->verticalStressGradient();
|
||||
const double stressDepthRef = m_fractureModel->stressDepth();
|
||||
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
int timeStep = m_fractureModel->timeStep();
|
||||
|
||||
// Biot coefficient
|
||||
std::vector<double> biotData = extractValues( RiaDefines::CurveProperty::BIOT_COEFFICIENT, timeStep );
|
||||
|
||||
// K0
|
||||
std::vector<double> k0Data = extractValues( RiaDefines::CurveProperty::K0, timeStep );
|
||||
|
||||
// Pressure at the give time step
|
||||
std::vector<double> timeStepPressureData = extractValues( RiaDefines::CurveProperty::PRESSURE, timeStep );
|
||||
|
||||
// Initial pressure
|
||||
std::vector<double> initialPressureData = extractValues( RiaDefines::CurveProperty::INITIAL_PRESSURE, timeStep );
|
||||
|
||||
// Poissons ratio
|
||||
std::vector<double> poissonsRatioData = extractValues( RiaDefines::CurveProperty::POISSONS_RATIO, timeStep );
|
||||
|
||||
// Check that we have data from all curves
|
||||
if ( biotData.empty() || k0Data.empty() || timeStepPressureData.empty() || initialPressureData.empty() ||
|
||||
poissonsRatioData.empty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double> stressForGradients;
|
||||
std::vector<double> pressureForGradients;
|
||||
std::vector<double> depthForGradients;
|
||||
|
||||
// Calculate the stress
|
||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||
{
|
||||
double depthTopOfZone = layerBoundaryDepths[i].first;
|
||||
double depthBottomOfZone = layerBoundaryDepths[i].second;
|
||||
|
||||
// Data from curves at the top zone depth
|
||||
double k0 = findValueAtTopOfLayer( k0Data, layerBoundaryIndexes, i );
|
||||
double biot = findValueAtTopOfLayer( biotData, layerBoundaryIndexes, i );
|
||||
double poissonsRatio = findValueAtTopOfLayer( poissonsRatioData, layerBoundaryIndexes, i );
|
||||
double initialPressure = findValueAtTopOfLayer( initialPressureData, layerBoundaryIndexes, i );
|
||||
double timeStepPressure = findValueAtTopOfLayer( timeStepPressureData, layerBoundaryIndexes, i );
|
||||
|
||||
// Vertical stress
|
||||
// Use difference between reference depth and depth of top of zone
|
||||
double depthDiff = depthTopOfZone - stressDepthRef;
|
||||
double Sv = verticalStressRef + verticalStressGradientRef * depthDiff;
|
||||
|
||||
double Sh_init = k0 * Sv + initialPressure * ( 1.0 - k0 );
|
||||
double pressureDiff = timeStepPressure - initialPressure;
|
||||
|
||||
// Vertical stress diff assumed to be zero
|
||||
double Sv_diff = 0.0;
|
||||
double deltaHorizontalStress = poissonsRatio / ( 1.0 - poissonsRatio ) * ( Sv_diff - biot * pressureDiff ) +
|
||||
( biot * pressureDiff );
|
||||
|
||||
double depletionStress = Sh_init + deltaHorizontalStress;
|
||||
stress.push_back( RiaEclipseUnitTools::barToPsi( depletionStress ) );
|
||||
|
||||
initialStress.push_back( RiaEclipseUnitTools::barToPsi( Sh_init ) );
|
||||
|
||||
// Cache some results for the gradients calculation
|
||||
stressForGradients.push_back( Sv );
|
||||
pressureForGradients.push_back( initialPressure );
|
||||
depthForGradients.push_back( depthTopOfZone );
|
||||
|
||||
if ( i == layerBoundaryDepths.size() - 1 )
|
||||
{
|
||||
// Use the bottom of the last layer to compute gradient for last layer
|
||||
double bottomInitialPressure = findValueAtBottomOfLayer( initialPressureData, layerBoundaryIndexes, i );
|
||||
|
||||
double bottomDepthDiff = depthBottomOfZone - stressDepthRef;
|
||||
double bottomSv = verticalStressRef + verticalStressGradientRef * bottomDepthDiff;
|
||||
stressForGradients.push_back( bottomSv );
|
||||
pressureForGradients.push_back( bottomInitialPressure );
|
||||
depthForGradients.push_back( depthBottomOfZone );
|
||||
}
|
||||
}
|
||||
|
||||
assert( stressForGradients.size() == layerBoundaryDepths.size() + 1 );
|
||||
assert( pressureForGradients.size() == layerBoundaryDepths.size() + 1 );
|
||||
assert( depthForGradients.size() == layerBoundaryDepths.size() + 1 );
|
||||
|
||||
// Second pass to calculate the stress gradients
|
||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||
{
|
||||
double diffStress = stressForGradients[i + 1] - stressForGradients[i];
|
||||
double diffPressure = pressureForGradients[i + 1] - pressureForGradients[i];
|
||||
double diffDepth = depthForGradients[i + 1] - depthForGradients[i];
|
||||
double k0 = findValueAtTopOfLayer( k0Data, layerBoundaryIndexes, i );
|
||||
double stressGradient = ( diffStress * k0 + diffPressure * ( 1.0 - k0 ) ) / diffDepth;
|
||||
stressGradients.push_back( RiaEclipseUnitTools::barPerMeterToPsiPerFeet( stressGradient ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateStressGradient() const
|
||||
{
|
||||
std::vector<double> stress;
|
||||
std::vector<double> stressGradients;
|
||||
std::vector<double> initialStress;
|
||||
calculateStressWithGradients( stress, stressGradients, initialStress );
|
||||
return stressGradients;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCalculator::calculateTemperature( std::vector<double>& temperatures ) const
|
||||
{
|
||||
// Reference temperature. Unit: degrees celsius
|
||||
const double referenceTemperature = m_fractureModel->referenceTemperature();
|
||||
|
||||
// Reference temperature gradient. Unit: degrees Celsius per meter
|
||||
const double referenceTemperatureGradient = m_fractureModel->referenceTemperatureGradient();
|
||||
|
||||
// Reference depth for temperature. Unit: meter.
|
||||
const double referenceTemperatureDepth = m_fractureModel->referenceTemperatureDepth();
|
||||
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
// Calculate the temperatures
|
||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||
{
|
||||
double depthTopOfZone = layerBoundaryDepths[i].first;
|
||||
|
||||
// Use difference between reference depth and depth of top of zone
|
||||
double depthDiff = depthTopOfZone - referenceTemperatureDepth;
|
||||
double temperature = referenceTemperature + referenceTemperatureGradient * depthDiff;
|
||||
|
||||
temperatures.push_back( temperature );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateYoungsModulus() const
|
||||
{
|
||||
std::vector<double> valuesGPa = findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::YOUNGS_MODULUS );
|
||||
std::vector<double> valuesMMpsi;
|
||||
for ( auto value : valuesGPa )
|
||||
{
|
||||
valuesMMpsi.push_back( value * 0.14503773773 );
|
||||
}
|
||||
|
||||
return valuesMMpsi;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculatePoissonsRatio() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::POISSONS_RATIO );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateKIc() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::K_IC );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateFluidLossCoefficient() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::FLUID_LOSS_COEFFICIENT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateSpurtLoss() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::SPURT_LOSS );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateProppandEmbedment() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PROPPANT_EMBEDMENT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateImmobileFluidSaturation() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateTemperature() const
|
||||
{
|
||||
std::vector<double> temperaturesCelsius;
|
||||
calculateTemperature( temperaturesCelsius );
|
||||
|
||||
// Convert to Fahrenheit
|
||||
std::vector<double> temperaturesFahrenheit;
|
||||
for ( double t : temperaturesCelsius )
|
||||
{
|
||||
temperaturesFahrenheit.push_back( t * 1.8 + 32.0 );
|
||||
}
|
||||
|
||||
return temperaturesFahrenheit;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateRelativePermeabilityFactor() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculatePoroElasticConstant() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelCalculator::calculateThermalExpansionCoefficient() const
|
||||
{
|
||||
// SI unit is 1/Celsius
|
||||
std::vector<double> coefficientCelsius =
|
||||
findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT );
|
||||
|
||||
// Field unit is 1/Fahrenheit
|
||||
std::vector<double> coefficientFahrenheit;
|
||||
for ( double c : coefficientCelsius )
|
||||
{
|
||||
coefficientFahrenheit.push_back( c / 1.8 );
|
||||
}
|
||||
|
||||
return coefficientFahrenheit;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include "RimFractureModelPropertyCalculator.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModel;
|
||||
|
||||
class RimFractureModelCalculator
|
||||
{
|
||||
public:
|
||||
RimFractureModelCalculator();
|
||||
|
||||
void setFractureModel( RimFractureModel* fractureModel );
|
||||
RimFractureModel* fractureModel();
|
||||
|
||||
bool extractCurveData( RiaDefines::CurveProperty curveProperty,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const;
|
||||
|
||||
std::vector<double> extractValues( RiaDefines::CurveProperty curveProperty, int timeStep ) const;
|
||||
|
||||
std::vector<double> calculateTrueVerticalDepth() const;
|
||||
std::vector<double> calculatePorosity() const;
|
||||
std::vector<double> calculateVerticalPermeability() const;
|
||||
std::vector<double> calculateHorizontalPermeability() const;
|
||||
std::vector<double> calculateReservoirPressure() const;
|
||||
std::vector<double> calculateStress() const;
|
||||
std::vector<double> calculateInitialStress() const;
|
||||
std::vector<double> calculateStressGradient() const;
|
||||
std::vector<double> calculateYoungsModulus() const;
|
||||
std::vector<double> calculatePoissonsRatio() const;
|
||||
std::vector<double> calculateKIc() const;
|
||||
std::vector<double> calculateFluidLossCoefficient() const;
|
||||
std::vector<double> calculateSpurtLoss() const;
|
||||
std::vector<double> calculateProppandEmbedment() const;
|
||||
|
||||
std::vector<double> calculateImmobileFluidSaturation() const;
|
||||
std::vector<double> calculateTemperature() const;
|
||||
std::vector<double> calculateRelativePermeabilityFactor() const;
|
||||
std::vector<double> calculatePoroElasticConstant() const;
|
||||
std::vector<double> calculateThermalExpansionCoefficient() const;
|
||||
|
||||
void calculateTemperature( std::vector<double>& temperatures ) const;
|
||||
|
||||
protected:
|
||||
std::vector<double> findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty curveProperty ) const;
|
||||
std::vector<double> findCurveXValuesByProperty( RiaDefines::CurveProperty curveProperty ) const;
|
||||
std::vector<double> findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty curveProperty ) const;
|
||||
|
||||
void calculateLayers( std::vector<std::pair<double, double>>& layerBoundaryDepths,
|
||||
std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes ) const;
|
||||
bool calculateStressWithGradients( std::vector<double>& stress,
|
||||
std::vector<double>& stressGradients,
|
||||
std::vector<double>& initialStress ) const;
|
||||
|
||||
static double findValueAtTopOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo );
|
||||
static double findValueAtBottomOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo );
|
||||
static void computeAverageByLayer( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result );
|
||||
static void extractTopOfLayerValues( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result );
|
||||
|
||||
private:
|
||||
RimFractureModel* m_fractureModel;
|
||||
std::vector<std::unique_ptr<RimFractureModelPropertyCalculator>> m_resultCalculators;
|
||||
};
|
@ -18,67 +18,28 @@
|
||||
|
||||
#include "RimFractureModelCurve.h"
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseWellLogExtractor.h"
|
||||
#include "RigResultAccessorFactory.h"
|
||||
#include "RigWellLogCurveData.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseInputProperty.h"
|
||||
#include "RimEclipseInputPropertyCollection.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellLogFile.h"
|
||||
#include "RimWellLogPlot.h"
|
||||
#include "RimWellLogTrack.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPlotTools.h"
|
||||
|
||||
#include "RiuQwtPlotCurve.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaFractureModelDefines.h"
|
||||
#include "RiaInterpolationTools.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
|
||||
#include "RiuQwtPlotCurve.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimFractureModelCurve, "FractureModelCurve" );
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void caf::AppEnum<RimFractureModelCurve::MissingValueStrategy>::setUp()
|
||||
{
|
||||
addItem( RimFractureModelCurve::MissingValueStrategy::DEFAULT_VALUE, "DEFAULT_VALUE", "Default value" );
|
||||
addItem( RimFractureModelCurve::MissingValueStrategy::LINEAR_INTERPOLATION,
|
||||
"LINEAR_INTERPOLATION",
|
||||
"Linear interpolation" );
|
||||
addItem( RimFractureModelCurve::MissingValueStrategy::OTHER_CURVE_PROPERTY,
|
||||
"OTHER_CURVE_PROPERTY",
|
||||
"Other Curve Property" );
|
||||
|
||||
setDefault( RimFractureModelCurve::MissingValueStrategy::DEFAULT_VALUE );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimFractureModelCurve::BurdenStrategy>::setUp()
|
||||
{
|
||||
addItem( RimFractureModelCurve::BurdenStrategy::DEFAULT_VALUE, "DEFAULT_VALUE", "Default value" );
|
||||
addItem( RimFractureModelCurve::BurdenStrategy::GRADIENT, "GRADIENT", "Gradient" );
|
||||
|
||||
setDefault( RimFractureModelCurve::BurdenStrategy::DEFAULT_VALUE );
|
||||
}
|
||||
}; // namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -90,16 +51,6 @@ RimFractureModelCurve::RimFractureModelCurve()
|
||||
m_fractureModel.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_fractureModel.uiCapability()->setUiHidden( true );
|
||||
|
||||
caf::AppEnum<RimFractureModelCurve::MissingValueStrategy> defaultValue =
|
||||
RimFractureModelCurve::MissingValueStrategy::DEFAULT_VALUE;
|
||||
CAF_PDM_InitField( &m_missingValueStrategy, "MissingValueStrategy", defaultValue, "Missing Value Strategy", "", "", "" );
|
||||
m_missingValueStrategy.uiCapability()->setUiHidden( true );
|
||||
|
||||
caf::AppEnum<RimFractureModelCurve::BurdenStrategy> defaultBurdenValue =
|
||||
RimFractureModelCurve::BurdenStrategy::DEFAULT_VALUE;
|
||||
CAF_PDM_InitField( &m_burdenStrategy, "BurdenStrategy", defaultBurdenValue, "Burden Strategy", "", "", "" );
|
||||
m_burdenStrategy.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_curveProperty, "CurveProperty", "Curve Property", "", "", "" );
|
||||
m_curveProperty.uiCapability()->setUiHidden( true );
|
||||
|
||||
@ -181,146 +132,17 @@ void RimFractureModelCurve::performDataExtraction( bool* isUsingPseudoLength )
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_case.value() );
|
||||
if ( eclipseCase && m_fractureModel )
|
||||
{
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(),
|
||||
m_fractureModel->thicknessDirectionWellPath()->wellPathGeometry(),
|
||||
"fracture model" );
|
||||
|
||||
measuredDepthValues = eclExtractor.cellIntersectionMDs();
|
||||
tvDepthValues = eclExtractor.cellIntersectionTVDs();
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
m_eclipseResultDefinition->setEclipseCase( eclipseCase );
|
||||
|
||||
m_eclipseResultDefinition->loadResult();
|
||||
|
||||
cvf::ref<RigResultAccessor> resAcc =
|
||||
RigResultAccessorFactory::createFromResultDefinition( eclipseCase->eclipseCaseData(),
|
||||
0,
|
||||
bool isOk = m_fractureModel->calculator()->extractCurveData( curveProperty(),
|
||||
m_timeStep,
|
||||
m_eclipseResultDefinition );
|
||||
|
||||
if ( resAcc.notNull() )
|
||||
values,
|
||||
measuredDepthValues,
|
||||
tvDepthValues,
|
||||
rkbDiff );
|
||||
if ( !isOk )
|
||||
{
|
||||
eclExtractor.curveData( resAcc.p(), &values );
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "No result found for %1" ).arg( m_eclipseResultDefinition()->resultVariable() ) );
|
||||
}
|
||||
|
||||
double overburdenHeight = m_fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
addOverburden( tvDepthValues, measuredDepthValues, values );
|
||||
}
|
||||
|
||||
double underburdenHeight = m_fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
addUnderburden( tvDepthValues, measuredDepthValues, values );
|
||||
}
|
||||
|
||||
if ( hasMissingValues( values ) )
|
||||
{
|
||||
if ( m_missingValueStrategy() == RimFractureModelCurve::MissingValueStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
// Try to locate a backup accessor (e.g. PORO_1 for PORO)
|
||||
cvf::ref<RigResultAccessor> backupResAcc =
|
||||
findMissingValuesAccessor( eclipseCase->eclipseCaseData(),
|
||||
eclipseCase->inputPropertyCollection(),
|
||||
0,
|
||||
m_timeStep,
|
||||
m_eclipseResultDefinition() );
|
||||
|
||||
if ( backupResAcc.notNull() )
|
||||
{
|
||||
RiaLogging::info( QString( "Reading missing values from input properties for %1." )
|
||||
.arg( m_eclipseResultDefinition()->resultVariable() ) );
|
||||
std::vector<double> replacementValues;
|
||||
eclExtractor.curveData( backupResAcc.p(), &replacementValues );
|
||||
|
||||
double overburdenHeight = m_fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
double defaultOverburdenValue = std::numeric_limits<double>::infinity();
|
||||
if ( m_burdenStrategy() == RimFractureModelCurve::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
defaultOverburdenValue = m_fractureModel->getDefaultForMissingOverburdenValue(
|
||||
m_eclipseResultDefinition()->resultVariable() );
|
||||
}
|
||||
|
||||
replacementValues.insert( replacementValues.begin(), defaultOverburdenValue );
|
||||
replacementValues.insert( replacementValues.begin(), defaultOverburdenValue );
|
||||
}
|
||||
|
||||
double underburdenHeight = m_fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
double defaultUnderburdenValue = std::numeric_limits<double>::infinity();
|
||||
if ( m_burdenStrategy() == RimFractureModelCurve::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
defaultUnderburdenValue = m_fractureModel->getDefaultForMissingUnderburdenValue(
|
||||
m_eclipseResultDefinition()->resultVariable() );
|
||||
}
|
||||
|
||||
replacementValues.push_back( defaultUnderburdenValue );
|
||||
replacementValues.push_back( defaultUnderburdenValue );
|
||||
}
|
||||
|
||||
replaceMissingValues( values, replacementValues );
|
||||
}
|
||||
|
||||
// If the backup accessor is not found, or does not provide all the missing values:
|
||||
// use default value from the fracture model
|
||||
if ( !backupResAcc.notNull() || hasMissingValues( values ) )
|
||||
{
|
||||
RiaLogging::info(
|
||||
QString( "Using default value for %1" ).arg( m_eclipseResultDefinition()->resultVariable() ) );
|
||||
|
||||
double defaultValue =
|
||||
m_fractureModel->getDefaultForMissingValue( m_eclipseResultDefinition.value()->resultVariable() );
|
||||
|
||||
replaceMissingValues( values, defaultValue );
|
||||
}
|
||||
}
|
||||
else if ( m_missingValueStrategy() == RimFractureModelCurve::MissingValueStrategy::LINEAR_INTERPOLATION )
|
||||
{
|
||||
RiaLogging::info(
|
||||
QString( "Interpolating missing values for %1" ).arg( m_eclipseResultDefinition()->resultVariable() ) );
|
||||
RiaInterpolationTools::interpolateMissingValues( measuredDepthValues, values );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the missing data from other curve
|
||||
RimFractureModelPlot* fractureModelPlot;
|
||||
firstAncestorOrThisOfType( fractureModelPlot );
|
||||
if ( !fractureModelPlot )
|
||||
{
|
||||
RiaLogging::error( QString( "No replacement data found for fracture model curve." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
RiaDefines::CurveProperty replacementProperty = m_fractureModel->getDefaultPropertyForMissingValues(
|
||||
m_eclipseResultDefinition.value()->resultVariable() );
|
||||
|
||||
std::vector<double> initialValues;
|
||||
fractureModelPlot->getCurvePropertyValues( replacementProperty, initialValues );
|
||||
if ( initialValues.empty() )
|
||||
{
|
||||
RiaLogging::error( QString( "Empty replacement data found for fracture model curve." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( values.size() != initialValues.size() )
|
||||
{
|
||||
RiaLogging::error( QString( "Inconsistent state." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
replaceMissingValues( values, initialValues );
|
||||
}
|
||||
}
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem eclipseUnitsType = eclipseCase->eclipseCaseData()->unitsType();
|
||||
if ( eclipseUnitsType == RiaEclipseUnitTools::UnitSystem::UNITS_FIELD )
|
||||
{
|
||||
@ -355,187 +177,3 @@ void RimFractureModelCurve::performDataExtraction( bool* isUsingPseudoLength )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCurve::setBurdenStrategy( BurdenStrategy strategy )
|
||||
{
|
||||
m_burdenStrategy = strategy;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCurve::setMissingValueStrategy( MissingValueStrategy strategy )
|
||||
{
|
||||
m_missingValueStrategy = strategy;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelCurve::hasMissingValues( const std::vector<double>& values )
|
||||
{
|
||||
for ( double v : values )
|
||||
{
|
||||
if ( v == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCurve::replaceMissingValues( std::vector<double>& values, double defaultValue )
|
||||
{
|
||||
for ( double& v : values )
|
||||
{
|
||||
if ( v == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
v = defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCurve::replaceMissingValues( std::vector<double>& values, const std::vector<double>& replacementValues )
|
||||
{
|
||||
CVF_ASSERT( values.size() == replacementValues.size() );
|
||||
for ( size_t i = 0; i < values.size(); i++ )
|
||||
{
|
||||
if ( values[i] == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
values[i] = replacementValues[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<RigResultAccessor>
|
||||
RimFractureModelCurve::findMissingValuesAccessor( RigEclipseCaseData* caseData,
|
||||
RimEclipseInputPropertyCollection* inputPropertyCollection,
|
||||
int gridIndex,
|
||||
int timeStepIndex,
|
||||
RimEclipseResultDefinition* eclipseResultDefinition )
|
||||
{
|
||||
QString resultName = eclipseResultDefinition->resultVariable();
|
||||
|
||||
for ( RimEclipseInputProperty* inputProperty : inputPropertyCollection->inputProperties() )
|
||||
{
|
||||
// Look for input properties starting with the same name as result definition
|
||||
if ( inputProperty && inputProperty->resultName().startsWith( resultName ) )
|
||||
{
|
||||
RiaLogging::info(
|
||||
QString( "Found missing values result for %1: %2" ).arg( resultName ).arg( inputProperty->resultName() ) );
|
||||
|
||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::INPUT_PROPERTY, inputProperty->resultName() );
|
||||
caseData->results( eclipseResultDefinition->porosityModel() )->ensureKnownResultLoaded( resultAddress );
|
||||
cvf::ref<RigResultAccessor> resAcc =
|
||||
RigResultAccessorFactory::createFromResultAddress( caseData,
|
||||
gridIndex,
|
||||
eclipseResultDefinition->porosityModel(),
|
||||
timeStepIndex,
|
||||
resultAddress );
|
||||
|
||||
return resAcc;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCurve::addOverburden( std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const
|
||||
{
|
||||
if ( !values.empty() )
|
||||
{
|
||||
double overburdenHeight = m_fractureModel->overburdenHeight();
|
||||
double tvdOverburdenBottom = tvDepthValues[0];
|
||||
double tvdOverburdenTop = tvdOverburdenBottom - overburdenHeight;
|
||||
|
||||
double overburdenTopValue = std::numeric_limits<double>::infinity();
|
||||
double overburdenBottomValue = std::numeric_limits<double>::infinity();
|
||||
if ( m_burdenStrategy() == RimFractureModelCurve::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
overburdenTopValue =
|
||||
m_fractureModel->getDefaultForMissingOverburdenValue( m_eclipseResultDefinition()->resultVariable() );
|
||||
overburdenBottomValue = overburdenTopValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
double gradient = m_fractureModel->getOverburdenGradient( m_eclipseResultDefinition()->resultVariable() );
|
||||
overburdenBottomValue = values[0];
|
||||
overburdenTopValue = overburdenBottomValue + gradient * -overburdenHeight;
|
||||
}
|
||||
|
||||
// Prepend the new "fake" depth for start of overburden
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdOverburdenBottom );
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdOverburdenTop );
|
||||
|
||||
// TODO: this is not always correct
|
||||
double mdTop = measuredDepthValues[0];
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop );
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop - overburdenHeight );
|
||||
|
||||
values.insert( values.begin(), overburdenBottomValue );
|
||||
values.insert( values.begin(), overburdenTopValue );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelCurve::addUnderburden( std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const
|
||||
{
|
||||
if ( !values.empty() )
|
||||
{
|
||||
size_t lastIndex = tvDepthValues.size() - 1;
|
||||
|
||||
double underburdenHeight = m_fractureModel->underburdenHeight();
|
||||
double tvdUnderburdenTop = tvDepthValues[lastIndex];
|
||||
double tvdUnderburdenBottom = tvdUnderburdenTop + underburdenHeight;
|
||||
|
||||
double underburdenTopValue = std::numeric_limits<double>::infinity();
|
||||
double underburdenBottomValue = std::numeric_limits<double>::infinity();
|
||||
if ( m_burdenStrategy() == RimFractureModelCurve::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
underburdenTopValue =
|
||||
m_fractureModel->getDefaultForMissingUnderburdenValue( m_eclipseResultDefinition()->resultVariable() );
|
||||
underburdenBottomValue = underburdenTopValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
double gradient = m_fractureModel->getUnderburdenGradient( m_eclipseResultDefinition()->resultVariable() );
|
||||
underburdenTopValue = values[lastIndex];
|
||||
underburdenBottomValue = underburdenTopValue + gradient * underburdenHeight;
|
||||
}
|
||||
|
||||
// Append the new "fake" depth for start of underburden
|
||||
tvDepthValues.push_back( tvdUnderburdenTop );
|
||||
tvDepthValues.push_back( tvdUnderburdenBottom );
|
||||
|
||||
// Append the new "fake" md
|
||||
// TODO: check if this is correct???
|
||||
double mdBottom = measuredDepthValues[lastIndex];
|
||||
measuredDepthValues.push_back( mdBottom );
|
||||
measuredDepthValues.push_back( mdBottom + underburdenHeight );
|
||||
|
||||
values.push_back( underburdenTopValue );
|
||||
values.push_back( underburdenBottomValue );
|
||||
}
|
||||
}
|
||||
|
@ -21,19 +21,12 @@
|
||||
#include "RimFractureModelPropertyCurve.h"
|
||||
#include "RimWellLogExtractionCurve.h"
|
||||
|
||||
#include "RiuQwtSymbol.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimWellPath;
|
||||
class RimWellMeasurement;
|
||||
class RimFractureModel;
|
||||
class RimEclipseInputPropertyCollection;
|
||||
class RigEclipseCaseData;
|
||||
class RigResultAccessor;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -43,19 +36,6 @@ class RimFractureModelCurve : public RimWellLogExtractionCurve, public RimFractu
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
enum class MissingValueStrategy
|
||||
{
|
||||
DEFAULT_VALUE,
|
||||
LINEAR_INTERPOLATION,
|
||||
OTHER_CURVE_PROPERTY
|
||||
};
|
||||
|
||||
enum class BurdenStrategy
|
||||
{
|
||||
DEFAULT_VALUE,
|
||||
GRADIENT
|
||||
};
|
||||
|
||||
RimFractureModelCurve();
|
||||
~RimFractureModelCurve() override;
|
||||
|
||||
@ -63,10 +43,6 @@ public:
|
||||
|
||||
void setEclipseResultCategory( RiaDefines::ResultCatType catType );
|
||||
|
||||
void setMissingValueStrategy( MissingValueStrategy strategy );
|
||||
|
||||
void setBurdenStrategy( BurdenStrategy strategy );
|
||||
|
||||
void setCurveProperty( RiaDefines::CurveProperty ) override;
|
||||
RiaDefines::CurveProperty curveProperty() const override;
|
||||
|
||||
@ -75,25 +51,6 @@ protected:
|
||||
|
||||
void performDataExtraction( bool* isUsingPseudoLength ) override;
|
||||
|
||||
static bool hasMissingValues( const std::vector<double>& values );
|
||||
static void replaceMissingValues( std::vector<double>& values, double defaultValue );
|
||||
static void replaceMissingValues( std::vector<double>& values, const std::vector<double>& replacementValues );
|
||||
cvf::ref<RigResultAccessor> findMissingValuesAccessor( RigEclipseCaseData* caseData,
|
||||
RimEclipseInputPropertyCollection* inputPropertyCollection,
|
||||
int gridIndex,
|
||||
int timeStepIndex,
|
||||
RimEclipseResultDefinition* eclipseResultDefinition );
|
||||
|
||||
void addOverburden( std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const;
|
||||
|
||||
void addUnderburden( std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const;
|
||||
|
||||
caf::PdmPtrField<RimFractureModel*> m_fractureModel;
|
||||
caf::PdmField<caf::AppEnum<MissingValueStrategy>> m_missingValueStrategy;
|
||||
caf::PdmField<caf::AppEnum<BurdenStrategy>> m_burdenStrategy;
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::CurveProperty>> m_curveProperty;
|
||||
};
|
||||
|
@ -0,0 +1,302 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RimFractureModelElasticPropertyCalculator.h"
|
||||
|
||||
#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 "RimFractureModelElasticPropertyCalculator.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 "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPlotTools.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModelElasticPropertyCalculator::RimFractureModelElasticPropertyCalculator(
|
||||
RimFractureModelCalculator* fractureModelCalculator )
|
||||
: m_fractureModelCalculator( fractureModelCalculator )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelElasticPropertyCalculator::isMatching( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
std::vector<RiaDefines::CurveProperty> matching = {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();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelElasticPropertyCalculator::calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const
|
||||
{
|
||||
RimEclipseCase* eclipseCase = fractureModel->eclipseCase();
|
||||
if ( !eclipseCase )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(),
|
||||
fractureModel->thicknessDirectionWellPath()->wellPathGeometry(),
|
||||
"fracture model" );
|
||||
|
||||
measuredDepthValues = eclExtractor.cellIntersectionMDs();
|
||||
tvDepthValues = eclExtractor.cellIntersectionTVDs();
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
// Extract formation data
|
||||
cvf::ref<RigResultAccessor> formationResultAccessor =
|
||||
RigResultAccessorFactory::createFromResultAddress( eclipseCase->eclipseCaseData(),
|
||||
0,
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
0,
|
||||
RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES,
|
||||
RiaDefines::activeFormationNamesResultName() ) );
|
||||
if ( !formationResultAccessor.notNull() )
|
||||
{
|
||||
RiaLogging::error( QString( "No formation result found." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
CurveSamplingPointData curveData =
|
||||
RimWellLogTrack::curveSamplingPointData( &eclExtractor, formationResultAccessor.p() );
|
||||
|
||||
std::vector<double> formationValues = curveData.data;
|
||||
|
||||
std::vector<QString> formationNamesVector = RimWellLogTrack::formationNamesVector( eclipseCase );
|
||||
|
||||
RimFractureModelTemplate* fractureModelTemplate = fractureModel->fractureModelTemplate();
|
||||
if ( !fractureModelTemplate )
|
||||
{
|
||||
RiaLogging::error( QString( "No fracture model template found" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
RimFaciesProperties* faciesProperties = fractureModelTemplate->faciesProperties();
|
||||
if ( !faciesProperties )
|
||||
{
|
||||
RiaLogging::error( QString( "No facies properties found when extracting elastic properties." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
RimColorLegend* colorLegend = faciesProperties->colorLegend();
|
||||
if ( !colorLegend )
|
||||
{
|
||||
RiaLogging::error( QString( "No color legend found when extracting elastic properties." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
RimElasticProperties* elasticProperties = fractureModelTemplate->elasticProperties();
|
||||
if ( !elasticProperties )
|
||||
{
|
||||
RiaLogging::error( QString( "No elastic properties found" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double> faciesValues =
|
||||
m_fractureModelCalculator->extractValues( RiaDefines::CurveProperty::FACIES, timeStep );
|
||||
std::vector<double> poroValues =
|
||||
m_fractureModelCalculator->extractValues( RiaDefines::CurveProperty::POROSITY, timeStep );
|
||||
|
||||
double overburdenHeight = fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
QString overburdenFormation = fractureModel->overburdenFormation();
|
||||
addOverburden( formationNamesVector,
|
||||
formationValues,
|
||||
tvDepthValues,
|
||||
measuredDepthValues,
|
||||
overburdenHeight,
|
||||
overburdenFormation );
|
||||
}
|
||||
|
||||
double underburdenHeight = fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
QString underburdenFormation = fractureModel->underburdenFormation();
|
||||
addUnderburden( formationNamesVector,
|
||||
formationValues,
|
||||
tvDepthValues,
|
||||
measuredDepthValues,
|
||||
underburdenHeight,
|
||||
underburdenFormation );
|
||||
}
|
||||
|
||||
CAF_ASSERT( tvDepthValues.size() == faciesValues.size() );
|
||||
CAF_ASSERT( tvDepthValues.size() == poroValues.size() );
|
||||
CAF_ASSERT( tvDepthValues.size() == formationValues.size() );
|
||||
|
||||
for ( size_t i = 0; i < tvDepthValues.size(); i++ )
|
||||
{
|
||||
// Avoid using the field name in the match for now
|
||||
QString fieldName = "";
|
||||
QString faciesName = findFaciesName( *colorLegend, faciesValues[i] );
|
||||
int idx = static_cast<int>( formationValues[i] );
|
||||
QString formationName = formationNamesVector[idx];
|
||||
double porosity = poroValues[i];
|
||||
|
||||
FaciesKey faciesKey = std::make_tuple( fieldName, formationName, faciesName );
|
||||
if ( elasticProperties->hasPropertiesForFacies( faciesKey ) )
|
||||
{
|
||||
if ( RimElasticProperties::isScalableProperty( curveProperty ) )
|
||||
{
|
||||
const RigElasticProperties& rigElasticProperties = elasticProperties->propertiesForFacies( faciesKey );
|
||||
double scale = elasticProperties->getPropertyScaling( formationName, faciesName, curveProperty );
|
||||
double val = rigElasticProperties.getValueForPorosity( curveProperty, porosity, scale );
|
||||
values.push_back( val );
|
||||
}
|
||||
else if ( fractureModel->hasDefaultValueForProperty( curveProperty ) )
|
||||
{
|
||||
double val = fractureModel->getDefaultValueForProperty( curveProperty );
|
||||
values.push_back( val );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "Missing elastic properties. Field='%1', formation='%2', facies='%3'" )
|
||||
.arg( fieldName )
|
||||
.arg( formationName )
|
||||
.arg( faciesName ) );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimFractureModelElasticPropertyCalculator::findFaciesName( const RimColorLegend& colorLegend, double value )
|
||||
{
|
||||
for ( auto item : colorLegend.colorLegendItems() )
|
||||
{
|
||||
if ( item->categoryValue() == static_cast<int>( value ) ) return item->categoryName();
|
||||
}
|
||||
|
||||
return "not found";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelElasticPropertyCalculator::addOverburden( std::vector<QString>& formationNames,
|
||||
std::vector<double>& formationValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
double overburdenHeight,
|
||||
const QString& formationName )
|
||||
{
|
||||
if ( !tvDepthValues.empty() )
|
||||
{
|
||||
// Prepend the new "fake" depth for start of overburden
|
||||
double tvdTop = tvDepthValues[0];
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdTop );
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdTop - overburdenHeight );
|
||||
|
||||
// TODO: this is not always correct
|
||||
double mdTop = measuredDepthValues[0];
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop );
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop - overburdenHeight );
|
||||
|
||||
formationNames.push_back( formationName );
|
||||
|
||||
formationValues.insert( formationValues.begin(), formationNames.size() - 1 );
|
||||
formationValues.insert( formationValues.begin(), formationNames.size() - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelElasticPropertyCalculator::addUnderburden( std::vector<QString>& formationNames,
|
||||
std::vector<double>& formationValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
double underburdenHeight,
|
||||
const QString& formationName )
|
||||
{
|
||||
if ( !tvDepthValues.empty() )
|
||||
{
|
||||
size_t lastIndex = tvDepthValues.size() - 1;
|
||||
|
||||
double tvdBottom = tvDepthValues[lastIndex];
|
||||
tvDepthValues.push_back( tvdBottom );
|
||||
tvDepthValues.push_back( tvdBottom + underburdenHeight );
|
||||
|
||||
// TODO: this is not always correct
|
||||
double mdBottom = measuredDepthValues[lastIndex];
|
||||
measuredDepthValues.push_back( mdBottom );
|
||||
measuredDepthValues.push_back( mdBottom + underburdenHeight );
|
||||
|
||||
formationNames.push_back( formationName );
|
||||
|
||||
formationValues.push_back( formationNames.size() - 1 );
|
||||
formationValues.push_back( formationNames.size() - 1 );
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimFractureModelPropertyCalculator.h"
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModelCalculator;
|
||||
class RimFractureModel;
|
||||
class RimColorLegend;
|
||||
|
||||
class QString;
|
||||
|
||||
class RimFractureModelElasticPropertyCalculator : public RimFractureModelPropertyCalculator
|
||||
{
|
||||
public:
|
||||
RimFractureModelElasticPropertyCalculator( RimFractureModelCalculator* calculator );
|
||||
|
||||
bool calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const override;
|
||||
|
||||
bool isMatching( RiaDefines::CurveProperty curveProperty ) const override;
|
||||
|
||||
protected:
|
||||
static void addOverburden( std::vector<QString>& formationNames,
|
||||
std::vector<double>& formationValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
double overburdenHeight,
|
||||
const QString& formationName );
|
||||
|
||||
static void addUnderburden( std::vector<QString>& formationNames,
|
||||
std::vector<double>& formationValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
double underburdenHeight,
|
||||
const QString& formationName );
|
||||
|
||||
static QString findFaciesName( const RimColorLegend& colorLegend, double value );
|
||||
|
||||
private:
|
||||
RimFractureModelCalculator* m_fractureModelCalculator;
|
||||
};
|
@ -0,0 +1,157 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RimFractureModelLayerCalculator.h"
|
||||
|
||||
#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 "RimWellLogTrack.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPlotTools.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModelLayerCalculator::RimFractureModelLayerCalculator( RimFractureModelCalculator* fractureModelCalculator )
|
||||
: m_fractureModelCalculator( fractureModelCalculator )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelLayerCalculator::isMatching( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
return curveProperty == RiaDefines::CurveProperty::LAYERS;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelLayerCalculator::calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const
|
||||
{
|
||||
RimEclipseCase* eclipseCase = fractureModel->eclipseCase();
|
||||
if ( !eclipseCase )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(),
|
||||
fractureModel->thicknessDirectionWellPath()->wellPathGeometry(),
|
||||
"fracture model" );
|
||||
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
// Extract formation data
|
||||
cvf::ref<RigResultAccessor> formationResultAccessor =
|
||||
RigResultAccessorFactory::createFromResultAddress( eclipseCase->eclipseCaseData(),
|
||||
0,
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
0,
|
||||
RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES,
|
||||
RiaDefines::activeFormationNamesResultName() ) );
|
||||
if ( !formationResultAccessor.notNull() )
|
||||
{
|
||||
RiaLogging::error( QString( "No formation result found." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
CurveSamplingPointData curveData =
|
||||
RimWellLogTrack::curveSamplingPointData( &eclExtractor, formationResultAccessor.p() );
|
||||
|
||||
std::vector<QString> formationNamesVector = RimWellLogTrack::formationNamesVector( eclipseCase );
|
||||
|
||||
double overburdenHeight = fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
RimWellLogTrack::addOverburden( formationNamesVector, curveData, overburdenHeight );
|
||||
}
|
||||
|
||||
double underburdenHeight = fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
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 );
|
||||
if ( faciesValues.empty() )
|
||||
{
|
||||
RiaLogging::error( QString( "Empty facies data found for layer curve." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
values.resize( faciesValues.size() );
|
||||
|
||||
int layerNo = 0;
|
||||
double previousFormation = -1.0;
|
||||
double previousFacies = -1.0;
|
||||
for ( size_t i = 0; i < faciesValues.size(); i++ )
|
||||
{
|
||||
if ( previousFormation != curveData.data[i] || previousFacies != faciesValues[i] )
|
||||
{
|
||||
layerNo++;
|
||||
}
|
||||
|
||||
values[i] = layerNo;
|
||||
previousFormation = curveData.data[i];
|
||||
previousFacies = faciesValues[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimFractureModelPropertyCalculator.h"
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModelCalculator;
|
||||
class RimFractureModel;
|
||||
|
||||
class RimFractureModelLayerCalculator : public RimFractureModelPropertyCalculator
|
||||
{
|
||||
public:
|
||||
RimFractureModelLayerCalculator( RimFractureModelCalculator* calculator );
|
||||
|
||||
bool calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const override;
|
||||
|
||||
bool isMatching( RiaDefines::CurveProperty curveProperty ) const override;
|
||||
|
||||
private:
|
||||
RimFractureModelCalculator* m_fractureModelCalculator;
|
||||
};
|
@ -19,22 +19,16 @@
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaFractureModelDefines.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RicfCommandObject.h"
|
||||
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelCurve.h"
|
||||
#include "RimFractureModelPropertyCurve.h"
|
||||
#include "RimLayerCurve.h"
|
||||
#include "RimWellLogTrack.h"
|
||||
|
||||
#include "RigWellLogCurveData.h"
|
||||
|
||||
#include "cafPdmBase.h"
|
||||
#include "cafPdmFieldScriptingCapability.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmObjectScriptingCapability.h"
|
||||
#include "cafPdmUiGroup.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimFractureModelPlot, "FractureModelPlot" );
|
||||
@ -128,124 +122,6 @@ void RimFractureModelPlot::applyDataSource()
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::getCurvePropertyValues( RiaDefines::CurveProperty curveProperty, std::vector<double>& values ) const
|
||||
{
|
||||
RimWellLogExtractionCurve* curve = findCurveByProperty( curveProperty );
|
||||
if ( curve )
|
||||
{
|
||||
values = curve->curveData()->xValues();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::getPorosityValues( std::vector<double>& values ) const
|
||||
{
|
||||
getCurvePropertyValues( RiaDefines::CurveProperty::POROSITY, values );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::getFaciesValues( std::vector<double>& values ) const
|
||||
{
|
||||
getCurvePropertyValues( RiaDefines::CurveProperty::FACIES, values );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::calculateLayers( std::vector<std::pair<double, double>>& layerBoundaryDepths,
|
||||
std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes ) const
|
||||
{
|
||||
std::vector<RimLayerCurve*> curves;
|
||||
descendantsIncludingThisOfType( curves );
|
||||
|
||||
if ( curves.empty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Expect to have only one of these
|
||||
RimLayerCurve* layerCurve = curves[0];
|
||||
|
||||
const RigWellLogCurveData* curveData = layerCurve->curveData();
|
||||
|
||||
// Find
|
||||
std::vector<double> depths = curveData->depths( RiaDefines::DepthTypeEnum::TRUE_VERTICAL_DEPTH );
|
||||
std::vector<double> layerValues = curveData->xValues();
|
||||
|
||||
size_t startIndex = 0;
|
||||
for ( size_t i = 0; i < depths.size(); i++ )
|
||||
{
|
||||
if ( startIndex != i && ( layerValues[startIndex] != layerValues[i] || i == depths.size() - 1 ) )
|
||||
{
|
||||
layerBoundaryDepths.push_back( std::make_pair( depths[startIndex], depths[i] ) );
|
||||
layerBoundaryIndexes.push_back( std::make_pair( startIndex, i ) );
|
||||
startIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModelPlot::findValueAtTopOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo )
|
||||
{
|
||||
size_t index = layerBoundaryIndexes[layerNo].first;
|
||||
return values.at( index );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimFractureModelPlot::findValueAtBottomOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo )
|
||||
{
|
||||
size_t index = layerBoundaryIndexes[layerNo].second;
|
||||
return values.at( index );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::computeAverageByLayer( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result )
|
||||
{
|
||||
for ( auto boundaryIndex : layerBoundaryIndexes )
|
||||
{
|
||||
double sum = 0.0;
|
||||
int nValues = 0;
|
||||
for ( size_t i = boundaryIndex.first; i < boundaryIndex.second; i++ )
|
||||
{
|
||||
sum += inputVector[i];
|
||||
nValues++;
|
||||
}
|
||||
result.push_back( sum / nValues );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::extractTopOfLayerValues( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result )
|
||||
{
|
||||
for ( size_t i = 0; i < layerBoundaryIndexes.size(); i++ )
|
||||
{
|
||||
result.push_back( findValueAtTopOfLayer( inputVector, layerBoundaryIndexes, i ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -264,418 +140,3 @@ RimWellLogExtractionCurve* RimFractureModelPlot::findCurveByProperty( RiaDefines
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateTrueVerticalDepth() const
|
||||
{
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
std::vector<double> tvdTopZone;
|
||||
for ( auto p : layerBoundaryDepths )
|
||||
{
|
||||
double depthInFeet = RiaEclipseUnitTools::meterToFeet( p.first );
|
||||
tvdTopZone.push_back( depthInFeet );
|
||||
}
|
||||
|
||||
return tvdTopZone;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
RimWellLogExtractionCurve* curve = findCurveByProperty( curveProperty );
|
||||
if ( !curve )
|
||||
{
|
||||
QString curveName = caf::AppEnum<RiaDefines::CurveProperty>::uiText( curveProperty );
|
||||
RiaLogging::error( QString( "No curve for '%1' found" ).arg( curveName ) );
|
||||
return std::vector<double>();
|
||||
}
|
||||
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
const RigWellLogCurveData* curveData = curve->curveData();
|
||||
std::vector<double> values = curveData->xValues();
|
||||
std::vector<double> result;
|
||||
computeAverageByLayer( layerBoundaryIndexes, values, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
RimWellLogExtractionCurve* curve = findCurveByProperty( curveProperty );
|
||||
if ( !curve )
|
||||
{
|
||||
QString curveName = caf::AppEnum<RiaDefines::CurveProperty>::uiText( curveProperty );
|
||||
RiaLogging::error( QString( "No curve for '%1' found" ).arg( curveName ) );
|
||||
return std::vector<double>();
|
||||
}
|
||||
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
const RigWellLogCurveData* curveData = curve->curveData();
|
||||
std::vector<double> values = curveData->xValues();
|
||||
std::vector<double> result;
|
||||
extractTopOfLayerValues( layerBoundaryIndexes, values, result );
|
||||
return result;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculatePorosity() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::POROSITY );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateReservoirPressure() const
|
||||
{
|
||||
std::vector<double> pressureBar = findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty::PRESSURE );
|
||||
|
||||
std::vector<double> pressurePsi;
|
||||
for ( double p : pressureBar )
|
||||
{
|
||||
pressurePsi.push_back( RiaEclipseUnitTools::barToPsi( p ) );
|
||||
}
|
||||
|
||||
return pressurePsi;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateHorizontalPermeability() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PERMEABILITY_X );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateVerticalPermeability() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PERMEABILITY_Z );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateStress() const
|
||||
{
|
||||
std::vector<double> stress;
|
||||
std::vector<double> stressGradients;
|
||||
std::vector<double> initialStress;
|
||||
calculateStressWithGradients( stress, stressGradients, initialStress );
|
||||
return stress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateInitialStress() const
|
||||
{
|
||||
std::vector<double> stress;
|
||||
std::vector<double> stressGradients;
|
||||
std::vector<double> initialStress;
|
||||
calculateStressWithGradients( stress, stressGradients, initialStress );
|
||||
return initialStress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::findCurveXValuesByProperty( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
RimWellLogExtractionCurve* curve = findCurveByProperty( curveProperty );
|
||||
if ( !curve )
|
||||
{
|
||||
QString curveName = caf::AppEnum<RiaDefines::CurveProperty>::uiText( curveProperty );
|
||||
RiaLogging::error( QString( "%1 data not found." ).arg( curveName ) );
|
||||
return std::vector<double>();
|
||||
}
|
||||
return curve->curveData()->xValues();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelPlot::calculateStressWithGradients( std::vector<double>& stress,
|
||||
std::vector<double>& stressGradients,
|
||||
std::vector<double>& initialStress ) const
|
||||
{
|
||||
// Reference stress
|
||||
const double verticalStressRef = m_fractureModel->verticalStress();
|
||||
const double verticalStressGradientRef = m_fractureModel->verticalStressGradient();
|
||||
const double stressDepthRef = m_fractureModel->stressDepth();
|
||||
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
// Biot coefficient
|
||||
std::vector<double> biotData = findCurveXValuesByProperty( RiaDefines::CurveProperty::BIOT_COEFFICIENT );
|
||||
|
||||
// K0
|
||||
std::vector<double> k0Data = findCurveXValuesByProperty( RiaDefines::CurveProperty::K0 );
|
||||
|
||||
// Pressure at the give time step
|
||||
std::vector<double> timeStepPressureData = findCurveXValuesByProperty( RiaDefines::CurveProperty::PRESSURE );
|
||||
|
||||
// Initial pressure
|
||||
std::vector<double> initialPressureData = findCurveXValuesByProperty( RiaDefines::CurveProperty::INITIAL_PRESSURE );
|
||||
|
||||
// Poissons ratio
|
||||
std::vector<double> poissonsRatioData = findCurveXValuesByProperty( RiaDefines::CurveProperty::POISSONS_RATIO );
|
||||
|
||||
// Check that we have data from all curves
|
||||
if ( biotData.empty() || k0Data.empty() || timeStepPressureData.empty() || initialPressureData.empty() ||
|
||||
poissonsRatioData.empty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double> stressForGradients;
|
||||
std::vector<double> pressureForGradients;
|
||||
std::vector<double> depthForGradients;
|
||||
|
||||
// Calculate the stress
|
||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||
{
|
||||
double depthTopOfZone = layerBoundaryDepths[i].first;
|
||||
double depthBottomOfZone = layerBoundaryDepths[i].second;
|
||||
|
||||
// Data from curves at the top zone depth
|
||||
double k0 = findValueAtTopOfLayer( k0Data, layerBoundaryIndexes, i );
|
||||
double biot = findValueAtTopOfLayer( biotData, layerBoundaryIndexes, i );
|
||||
double poissonsRatio = findValueAtTopOfLayer( poissonsRatioData, layerBoundaryIndexes, i );
|
||||
double initialPressure = findValueAtTopOfLayer( initialPressureData, layerBoundaryIndexes, i );
|
||||
double timeStepPressure = findValueAtTopOfLayer( timeStepPressureData, layerBoundaryIndexes, i );
|
||||
|
||||
// Vertical stress
|
||||
// Use difference between reference depth and depth of top of zone
|
||||
double depthDiff = depthTopOfZone - stressDepthRef;
|
||||
double Sv = verticalStressRef + verticalStressGradientRef * depthDiff;
|
||||
|
||||
double Sh_init = k0 * Sv + initialPressure * ( 1.0 - k0 );
|
||||
double pressureDiff = timeStepPressure - initialPressure;
|
||||
|
||||
// Vertical stress diff assumed to be zero
|
||||
double Sv_diff = 0.0;
|
||||
double deltaHorizontalStress = poissonsRatio / ( 1.0 - poissonsRatio ) * ( Sv_diff - biot * pressureDiff ) +
|
||||
( biot * pressureDiff );
|
||||
|
||||
double depletionStress = Sh_init + deltaHorizontalStress;
|
||||
stress.push_back( RiaEclipseUnitTools::barToPsi( depletionStress ) );
|
||||
|
||||
initialStress.push_back( RiaEclipseUnitTools::barToPsi( Sh_init ) );
|
||||
|
||||
// Cache some results for the gradients calculation
|
||||
stressForGradients.push_back( Sv );
|
||||
pressureForGradients.push_back( initialPressure );
|
||||
depthForGradients.push_back( depthTopOfZone );
|
||||
|
||||
if ( i == layerBoundaryDepths.size() - 1 )
|
||||
{
|
||||
// Use the bottom of the last layer to compute gradient for last layer
|
||||
double bottomInitialPressure = findValueAtBottomOfLayer( initialPressureData, layerBoundaryIndexes, i );
|
||||
|
||||
double bottomDepthDiff = depthBottomOfZone - stressDepthRef;
|
||||
double bottomSv = verticalStressRef + verticalStressGradientRef * bottomDepthDiff;
|
||||
stressForGradients.push_back( bottomSv );
|
||||
pressureForGradients.push_back( bottomInitialPressure );
|
||||
depthForGradients.push_back( depthBottomOfZone );
|
||||
}
|
||||
}
|
||||
|
||||
assert( stressForGradients.size() == layerBoundaryDepths.size() + 1 );
|
||||
assert( pressureForGradients.size() == layerBoundaryDepths.size() + 1 );
|
||||
assert( depthForGradients.size() == layerBoundaryDepths.size() + 1 );
|
||||
|
||||
// Second pass to calculate the stress gradients
|
||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||
{
|
||||
double diffStress = stressForGradients[i + 1] - stressForGradients[i];
|
||||
double diffPressure = pressureForGradients[i + 1] - pressureForGradients[i];
|
||||
double diffDepth = depthForGradients[i + 1] - depthForGradients[i];
|
||||
double k0 = findValueAtTopOfLayer( k0Data, layerBoundaryIndexes, i );
|
||||
double stressGradient = ( diffStress * k0 + diffPressure * ( 1.0 - k0 ) ) / diffDepth;
|
||||
stressGradients.push_back( RiaEclipseUnitTools::barPerMeterToPsiPerFeet( stressGradient ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateStressGradient() const
|
||||
{
|
||||
std::vector<double> stress;
|
||||
std::vector<double> stressGradients;
|
||||
std::vector<double> initialStress;
|
||||
calculateStressWithGradients( stress, stressGradients, initialStress );
|
||||
return stressGradients;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelPlot::calculateTemperature( std::vector<double>& temperatures ) const
|
||||
{
|
||||
// Reference temperature. Unit: degrees celsius
|
||||
const double referenceTemperature = m_fractureModel->referenceTemperature();
|
||||
|
||||
// Reference temperature gradient. Unit: degrees Celsius per meter
|
||||
const double referenceTemperatureGradient = m_fractureModel->referenceTemperatureGradient();
|
||||
|
||||
// Reference depth for temperature. Unit: meter.
|
||||
const double referenceTemperatureDepth = m_fractureModel->referenceTemperatureDepth();
|
||||
|
||||
std::vector<std::pair<double, double>> layerBoundaryDepths;
|
||||
std::vector<std::pair<size_t, size_t>> layerBoundaryIndexes;
|
||||
calculateLayers( layerBoundaryDepths, layerBoundaryIndexes );
|
||||
|
||||
// Calculate the temperatures
|
||||
for ( size_t i = 0; i < layerBoundaryDepths.size(); i++ )
|
||||
{
|
||||
double depthTopOfZone = layerBoundaryDepths[i].first;
|
||||
|
||||
// Use difference between reference depth and depth of top of zone
|
||||
double depthDiff = depthTopOfZone - referenceTemperatureDepth;
|
||||
double temperature = referenceTemperature + referenceTemperatureGradient * depthDiff;
|
||||
|
||||
temperatures.push_back( temperature );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateYoungsModulus() const
|
||||
{
|
||||
std::vector<double> valuesGPa = findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::YOUNGS_MODULUS );
|
||||
std::vector<double> valuesMMpsi;
|
||||
for ( auto value : valuesGPa )
|
||||
{
|
||||
valuesMMpsi.push_back( value * 0.14503773773 );
|
||||
}
|
||||
|
||||
return valuesMMpsi;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculatePoissonsRatio() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::POISSONS_RATIO );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateKIc() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::K_IC );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateFluidLossCoefficient() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::FLUID_LOSS_COEFFICIENT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateSpurtLoss() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::SPURT_LOSS );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateProppandEmbedment() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PROPPANT_EMBEDMENT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateImmobileFluidSaturation() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::IMMOBILE_FLUID_SATURATION );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateTemperature() const
|
||||
{
|
||||
std::vector<double> temperaturesCelsius;
|
||||
calculateTemperature( temperaturesCelsius );
|
||||
|
||||
// Convert to Fahrenheit
|
||||
std::vector<double> temperaturesFahrenheit;
|
||||
for ( double t : temperaturesCelsius )
|
||||
{
|
||||
temperaturesFahrenheit.push_back( t * 1.8 + 32.0 );
|
||||
}
|
||||
|
||||
return temperaturesFahrenheit;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateRelativePermeabilityFactor() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::RELATIVE_PERMEABILITY_FACTOR );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculatePoroElasticConstant() const
|
||||
{
|
||||
return findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::PORO_ELASTIC_CONSTANT );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimFractureModelPlot::calculateThermalExpansionCoefficient() const
|
||||
{
|
||||
// SI unit is 1/Celsius
|
||||
std::vector<double> coefficientCelsius =
|
||||
findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty::THERMAL_EXPANSION_COEFFICIENT );
|
||||
|
||||
// Field unit is 1/Fahrenheit
|
||||
std::vector<double> coefficientFahrenheit;
|
||||
for ( double c : coefficientCelsius )
|
||||
{
|
||||
coefficientFahrenheit.push_back( c / 1.8 );
|
||||
}
|
||||
|
||||
return coefficientFahrenheit;
|
||||
}
|
||||
|
@ -21,13 +21,10 @@
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimWellLogExtractionCurve;
|
||||
class RimFractureModel;
|
||||
class RimWellLogExtractionCurve;
|
||||
|
||||
class RimFractureModelPlot : public RimDepthTrackPlot
|
||||
{
|
||||
@ -39,57 +36,8 @@ public:
|
||||
void setFractureModel( RimFractureModel* fractureModel );
|
||||
RimFractureModel* fractureModel();
|
||||
|
||||
void getPorosityValues( std::vector<double>& values ) const;
|
||||
void getFaciesValues( std::vector<double>& values ) const;
|
||||
void getCurvePropertyValues( RiaDefines::CurveProperty curveProperty, std::vector<double>& values ) const;
|
||||
|
||||
std::vector<double> calculateTrueVerticalDepth() const;
|
||||
std::vector<double> calculatePorosity() const;
|
||||
std::vector<double> calculateVerticalPermeability() const;
|
||||
std::vector<double> calculateHorizontalPermeability() const;
|
||||
std::vector<double> calculateReservoirPressure() const;
|
||||
std::vector<double> calculateStress() const;
|
||||
std::vector<double> calculateInitialStress() const;
|
||||
std::vector<double> calculateStressGradient() const;
|
||||
std::vector<double> calculateYoungsModulus() const;
|
||||
std::vector<double> calculatePoissonsRatio() const;
|
||||
std::vector<double> calculateKIc() const;
|
||||
std::vector<double> calculateFluidLossCoefficient() const;
|
||||
std::vector<double> calculateSpurtLoss() const;
|
||||
std::vector<double> calculateProppandEmbedment() const;
|
||||
|
||||
std::vector<double> calculateImmobileFluidSaturation() const;
|
||||
std::vector<double> calculateTemperature() const;
|
||||
std::vector<double> calculateRelativePermeabilityFactor() const;
|
||||
std::vector<double> calculatePoroElasticConstant() const;
|
||||
std::vector<double> calculateThermalExpansionCoefficient() const;
|
||||
|
||||
void calculateTemperature( std::vector<double>& temperatures ) const;
|
||||
|
||||
protected:
|
||||
std::vector<double> findCurveAndComputeLayeredAverage( RiaDefines::CurveProperty curveProperty ) const;
|
||||
std::vector<double> findCurveXValuesByProperty( RiaDefines::CurveProperty curveProperty ) const;
|
||||
std::vector<double> findCurveAndComputeTopOfLayer( RiaDefines::CurveProperty curveProperty ) const;
|
||||
|
||||
void calculateLayers( std::vector<std::pair<double, double>>& layerBoundaryDepths,
|
||||
std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes ) const;
|
||||
RimWellLogExtractionCurve* findCurveByProperty( RiaDefines::CurveProperty curveProperty ) const;
|
||||
bool calculateStressWithGradients( std::vector<double>& stress,
|
||||
std::vector<double>& stressGradients,
|
||||
std::vector<double>& initialStress ) const;
|
||||
|
||||
static double findValueAtTopOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo );
|
||||
static double findValueAtBottomOfLayer( const std::vector<double>& values,
|
||||
const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
size_t layerNo );
|
||||
static void computeAverageByLayer( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result );
|
||||
static void extractTopOfLayerValues( const std::vector<std::pair<size_t, size_t>>& layerBoundaryIndexes,
|
||||
const std::vector<double>& inputVector,
|
||||
std::vector<double>& result );
|
||||
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
|
@ -0,0 +1,44 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModelCalculator;
|
||||
class RimFractureModel;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimFractureModelPropertyCalculator
|
||||
{
|
||||
public:
|
||||
virtual ~RimFractureModelPropertyCalculator(){};
|
||||
|
||||
virtual bool isMatching( RiaDefines::CurveProperty curveProperty ) const = 0;
|
||||
virtual bool calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const = 0;
|
||||
};
|
@ -0,0 +1,150 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RimFractureModelStressCalculator.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseWellLogExtractor.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RigWellPathGeometryTools.h"
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimFractureModelStressCalculator.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModelStressCalculator::RimFractureModelStressCalculator( RimFractureModelCalculator* fractureModelCalculator )
|
||||
: m_fractureModelCalculator( fractureModelCalculator )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelStressCalculator::isMatching( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
std::vector<RiaDefines::CurveProperty> matching = {RiaDefines::CurveProperty::INITIAL_STRESS,
|
||||
RiaDefines::CurveProperty::STRESS,
|
||||
RiaDefines::CurveProperty::STRESS_GRADIENT,
|
||||
RiaDefines::CurveProperty::TEMPERATURE};
|
||||
|
||||
return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelStressCalculator::calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const
|
||||
{
|
||||
RimEclipseCase* eclipseCase = fractureModel->eclipseCase();
|
||||
if ( !eclipseCase )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<double> tvDepthInFeet = m_fractureModelCalculator->calculateTrueVerticalDepth();
|
||||
for ( double f : tvDepthInFeet )
|
||||
{
|
||||
tvDepthValues.push_back( RiaEclipseUnitTools::feetToMeter( f ) );
|
||||
}
|
||||
|
||||
if ( curveProperty == RiaDefines::CurveProperty::STRESS )
|
||||
{
|
||||
values = m_fractureModelCalculator->calculateStress();
|
||||
std::vector<double> stressGradients = m_fractureModelCalculator->calculateStressGradient();
|
||||
addDatapointsForBottomOfLayers( tvDepthValues, values, stressGradients );
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::INITIAL_STRESS )
|
||||
{
|
||||
values = m_fractureModelCalculator->calculateInitialStress();
|
||||
std::vector<double> stressGradients = m_fractureModelCalculator->calculateStressGradient();
|
||||
addDatapointsForBottomOfLayers( tvDepthValues, values, stressGradients );
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::STRESS_GRADIENT )
|
||||
{
|
||||
values = m_fractureModelCalculator->calculateStressGradient();
|
||||
}
|
||||
else if ( curveProperty == RiaDefines::CurveProperty::TEMPERATURE )
|
||||
{
|
||||
m_fractureModelCalculator->calculateTemperature( values );
|
||||
}
|
||||
|
||||
if ( eclipseCase )
|
||||
{
|
||||
RigWellPath* wellPathGeometry = fractureModel->thicknessDirectionWellPath()->wellPathGeometry();
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(), wellPathGeometry, "fracture model" );
|
||||
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
// Generate MD data by interpolation
|
||||
const std::vector<double>& mdValuesOfWellPath = wellPathGeometry->measureDepths();
|
||||
std::vector<double> tvdValuesOfWellPath = wellPathGeometry->trueVerticalDepths();
|
||||
|
||||
measuredDepthValues =
|
||||
RigWellPathGeometryTools::interpolateMdFromTvd( mdValuesOfWellPath, tvdValuesOfWellPath, tvDepthValues );
|
||||
CVF_ASSERT( measuredDepthValues.size() == tvDepthValues.size() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelStressCalculator::addDatapointsForBottomOfLayers( std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& stress,
|
||||
const std::vector<double>& stressGradients )
|
||||
{
|
||||
std::vector<double> tvdWithBottomLayers;
|
||||
std::vector<double> valuesWithBottomLayers;
|
||||
for ( size_t i = 0; i < stress.size(); i++ )
|
||||
{
|
||||
// Add the data point at top of the layer
|
||||
double topLayerDepth = tvDepthValues[i];
|
||||
double stressValue = stress[i];
|
||||
tvdWithBottomLayers.push_back( topLayerDepth );
|
||||
valuesWithBottomLayers.push_back( stressValue );
|
||||
|
||||
// Add extra data points for bottom part of the layer
|
||||
if ( i < stress.size() - 1 )
|
||||
{
|
||||
double bottomLayerDepth = tvDepthValues[i + 1];
|
||||
double diffDepthFeet = RiaEclipseUnitTools::meterToFeet( bottomLayerDepth - topLayerDepth );
|
||||
double bottomStress = stressValue + diffDepthFeet * stressGradients[i];
|
||||
|
||||
tvdWithBottomLayers.push_back( bottomLayerDepth );
|
||||
valuesWithBottomLayers.push_back( bottomStress );
|
||||
}
|
||||
}
|
||||
|
||||
stress = valuesWithBottomLayers;
|
||||
tvDepthValues = tvdWithBottomLayers;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimFractureModelPropertyCalculator.h"
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimFractureModelCalculator;
|
||||
class RimFractureModel;
|
||||
|
||||
class QString;
|
||||
|
||||
class RimFractureModelStressCalculator : public RimFractureModelPropertyCalculator
|
||||
{
|
||||
public:
|
||||
RimFractureModelStressCalculator( RimFractureModelCalculator* calculator );
|
||||
|
||||
bool calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const override;
|
||||
|
||||
bool isMatching( RiaDefines::CurveProperty curveProperty ) const override;
|
||||
|
||||
private:
|
||||
static void addDatapointsForBottomOfLayers( std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& stress,
|
||||
const std::vector<double>& stressGradients );
|
||||
|
||||
RimFractureModelCalculator* m_fractureModelCalculator;
|
||||
};
|
@ -30,6 +30,7 @@
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimWellLogFile.h"
|
||||
@ -107,59 +108,14 @@ void RimFractureModelStressCurve::performDataExtraction( bool* isUsingPseudoLeng
|
||||
|
||||
*isUsingPseudoLength = false;
|
||||
|
||||
// Extract porosity data: get the porosity values from parent
|
||||
RimFractureModelPlot* fractureModelPlot;
|
||||
firstAncestorOrThisOfType( fractureModelPlot );
|
||||
if ( !fractureModelPlot || !m_fractureModel )
|
||||
bool isOk = m_fractureModel->calculator()
|
||||
->extractCurveData( curveProperty(), m_timeStep, values, measuredDepthValues, tvDepthValues, rkbDiff );
|
||||
if ( !isOk )
|
||||
{
|
||||
RiaLogging::error( QString( "No fracture model plot found." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<double> tvDepthInFeet = fractureModelPlot->calculateTrueVerticalDepth();
|
||||
for ( double f : tvDepthInFeet )
|
||||
{
|
||||
tvDepthValues.push_back( RiaEclipseUnitTools::feetToMeter( f ) );
|
||||
}
|
||||
|
||||
if ( m_curveProperty() == RiaDefines::CurveProperty::STRESS )
|
||||
{
|
||||
values = fractureModelPlot->calculateStress();
|
||||
std::vector<double> stressGradients = fractureModelPlot->calculateStressGradient();
|
||||
addDatapointsForBottomOfLayers( tvDepthValues, values, stressGradients );
|
||||
}
|
||||
else if ( m_curveProperty() == RiaDefines::CurveProperty::INITIAL_STRESS )
|
||||
{
|
||||
values = fractureModelPlot->calculateInitialStress();
|
||||
std::vector<double> stressGradients = fractureModelPlot->calculateStressGradient();
|
||||
addDatapointsForBottomOfLayers( tvDepthValues, values, stressGradients );
|
||||
}
|
||||
else if ( m_curveProperty() == RiaDefines::CurveProperty::STRESS_GRADIENT )
|
||||
{
|
||||
values = fractureModelPlot->calculateStressGradient();
|
||||
}
|
||||
else if ( m_curveProperty() == RiaDefines::CurveProperty::TEMPERATURE )
|
||||
{
|
||||
fractureModelPlot->calculateTemperature( values );
|
||||
}
|
||||
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_case.value() );
|
||||
if ( eclipseCase )
|
||||
{
|
||||
RigWellPath* wellPathGeometry = m_fractureModel->thicknessDirectionWellPath()->wellPathGeometry();
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(), wellPathGeometry, "fracture model" );
|
||||
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
// Generate MD data by interpolation
|
||||
const std::vector<double>& mdValuesOfWellPath = wellPathGeometry->measureDepths();
|
||||
std::vector<double> tvdValuesOfWellPath = wellPathGeometry->trueVerticalDepths();
|
||||
|
||||
measuredDepthValues =
|
||||
RigWellPathGeometryTools::interpolateMdFromTvd( mdValuesOfWellPath, tvdValuesOfWellPath, tvDepthValues );
|
||||
CVF_ASSERT( measuredDepthValues.size() == tvDepthValues.size() );
|
||||
}
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem eclipseUnitsType = eclipseCase->eclipseCaseData()->unitsType();
|
||||
if ( eclipseUnitsType == RiaEclipseUnitTools::UnitSystem::UNITS_FIELD )
|
||||
{
|
||||
@ -201,36 +157,3 @@ QString RimFractureModelStressCurve::createCurveAutoName()
|
||||
{
|
||||
return caf::AppEnum<RiaDefines::CurveProperty>::uiText( m_curveProperty() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelStressCurve::addDatapointsForBottomOfLayers( std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& stress,
|
||||
const std::vector<double>& stressGradients )
|
||||
{
|
||||
std::vector<double> tvdWithBottomLayers;
|
||||
std::vector<double> valuesWithBottomLayers;
|
||||
for ( size_t i = 0; i < stress.size(); i++ )
|
||||
{
|
||||
// Add the data point at top of the layer
|
||||
double topLayerDepth = tvDepthValues[i];
|
||||
double stressValue = stress[i];
|
||||
tvdWithBottomLayers.push_back( topLayerDepth );
|
||||
valuesWithBottomLayers.push_back( stressValue );
|
||||
|
||||
// Add extra data points for bottom part of the layer
|
||||
if ( i < stress.size() - 1 )
|
||||
{
|
||||
double bottomLayerDepth = tvDepthValues[i + 1];
|
||||
double diffDepthFeet = RiaEclipseUnitTools::meterToFeet( bottomLayerDepth - topLayerDepth );
|
||||
double bottomStress = stressValue + diffDepthFeet * stressGradients[i];
|
||||
|
||||
tvdWithBottomLayers.push_back( bottomLayerDepth );
|
||||
valuesWithBottomLayers.push_back( bottomStress );
|
||||
}
|
||||
}
|
||||
|
||||
stress = valuesWithBottomLayers;
|
||||
tvDepthValues = tvdWithBottomLayers;
|
||||
}
|
||||
|
@ -0,0 +1,401 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#include "RimFractureModelWellLogCalculator.h"
|
||||
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaFractureModelDefines.h"
|
||||
#include "RiaInterpolationTools.h"
|
||||
#include "RiaLogging.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseWellLogExtractor.h"
|
||||
#include "RigResultAccessor.h"
|
||||
#include "RigResultAccessorFactory.h"
|
||||
#include "RigWellLogCurveData.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseInputProperty.h"
|
||||
#include "RimEclipseInputPropertyCollection.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimLayerCurve.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellLogFile.h"
|
||||
#include "RimWellLogPlot.h"
|
||||
#include "RimWellLogTrack.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPlotTools.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimFractureModelWellLogCalculator::RimFractureModelWellLogCalculator( RimFractureModelCalculator& )
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelWellLogCalculator::isMatching( RiaDefines::CurveProperty curveProperty ) const
|
||||
{
|
||||
std::vector<RiaDefines::CurveProperty> matching = {
|
||||
RiaDefines::CurveProperty::FACIES,
|
||||
RiaDefines::CurveProperty::POROSITY,
|
||||
RiaDefines::CurveProperty::PERMEABILITY_X,
|
||||
RiaDefines::CurveProperty::PERMEABILITY_Z,
|
||||
RiaDefines::CurveProperty::INITIAL_PRESSURE,
|
||||
RiaDefines::CurveProperty::PRESSURE,
|
||||
};
|
||||
|
||||
return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelWellLogCalculator::calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const
|
||||
{
|
||||
RimEclipseCase* eclipseCase = fractureModel->eclipseCase();
|
||||
if ( !eclipseCase )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: improve this..
|
||||
if ( curveProperty == RiaDefines::CurveProperty::INITIAL_PRESSURE )
|
||||
{
|
||||
timeStep = 0;
|
||||
}
|
||||
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(),
|
||||
fractureModel->thicknessDirectionWellPath()->wellPathGeometry(),
|
||||
"fracture model" );
|
||||
|
||||
measuredDepthValues = eclExtractor.cellIntersectionMDs();
|
||||
tvDepthValues = eclExtractor.cellIntersectionTVDs();
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
RimEclipseResultDefinition eclipseResultDefinition;
|
||||
eclipseResultDefinition.setEclipseCase( eclipseCase );
|
||||
eclipseResultDefinition.setResultType( fractureModel->eclipseResultCategory( curveProperty ) );
|
||||
eclipseResultDefinition.setPorosityModel( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
||||
eclipseResultDefinition.setResultVariable( fractureModel->eclipseResultVariable( curveProperty ) );
|
||||
|
||||
eclipseResultDefinition.loadResult();
|
||||
|
||||
cvf::ref<RigResultAccessor> resAcc =
|
||||
RigResultAccessorFactory::createFromResultDefinition( eclipseCase->eclipseCaseData(),
|
||||
0,
|
||||
timeStep,
|
||||
&eclipseResultDefinition );
|
||||
|
||||
if ( resAcc.notNull() )
|
||||
{
|
||||
eclExtractor.curveData( resAcc.p(), &values );
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( QString( "No result found for %1" ).arg( eclipseResultDefinition.resultVariable() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
double overburdenHeight = fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
addOverburden( curveProperty, fractureModel, tvDepthValues, measuredDepthValues, values );
|
||||
}
|
||||
|
||||
double underburdenHeight = fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
addUnderburden( curveProperty, fractureModel, tvDepthValues, measuredDepthValues, values );
|
||||
}
|
||||
|
||||
if ( hasMissingValues( values ) )
|
||||
{
|
||||
if ( fractureModel->missingValueStrategy( curveProperty ) == RimFractureModel::MissingValueStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
// Try to locate a backup accessor (e.g. PORO_1 for PORO)
|
||||
cvf::ref<RigResultAccessor> backupResAcc = findMissingValuesAccessor( eclipseCase->eclipseCaseData(),
|
||||
eclipseCase->inputPropertyCollection(),
|
||||
0,
|
||||
timeStep,
|
||||
&eclipseResultDefinition );
|
||||
|
||||
if ( backupResAcc.notNull() )
|
||||
{
|
||||
RiaLogging::info( QString( "Reading missing values from input properties for %1." )
|
||||
.arg( eclipseResultDefinition.resultVariable() ) );
|
||||
std::vector<double> replacementValues;
|
||||
eclExtractor.curveData( backupResAcc.p(), &replacementValues );
|
||||
|
||||
double overburdenHeight = fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
double defaultOverburdenValue = std::numeric_limits<double>::infinity();
|
||||
if ( fractureModel->burdenStrategy( curveProperty ) == RimFractureModel::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
defaultOverburdenValue = fractureModel->getDefaultForMissingOverburdenValue( curveProperty );
|
||||
}
|
||||
|
||||
replacementValues.insert( replacementValues.begin(), defaultOverburdenValue );
|
||||
replacementValues.insert( replacementValues.begin(), defaultOverburdenValue );
|
||||
}
|
||||
|
||||
double underburdenHeight = fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
double defaultUnderburdenValue = std::numeric_limits<double>::infinity();
|
||||
if ( fractureModel->burdenStrategy( curveProperty ) == RimFractureModel::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
defaultUnderburdenValue = fractureModel->getDefaultForMissingUnderburdenValue( curveProperty );
|
||||
}
|
||||
|
||||
replacementValues.push_back( defaultUnderburdenValue );
|
||||
replacementValues.push_back( defaultUnderburdenValue );
|
||||
}
|
||||
|
||||
replaceMissingValues( values, replacementValues );
|
||||
}
|
||||
|
||||
// If the backup accessor is not found, or does not provide all the missing values:
|
||||
// use default value from the fracture model
|
||||
if ( !backupResAcc.notNull() || hasMissingValues( values ) )
|
||||
{
|
||||
RiaLogging::info( QString( "Using default value for %1" ).arg( eclipseResultDefinition.resultVariable() ) );
|
||||
|
||||
double defaultValue = fractureModel->getDefaultForMissingValue( curveProperty );
|
||||
|
||||
replaceMissingValues( values, defaultValue );
|
||||
}
|
||||
}
|
||||
else if ( fractureModel->missingValueStrategy( curveProperty ) ==
|
||||
RimFractureModel::MissingValueStrategy::LINEAR_INTERPOLATION )
|
||||
{
|
||||
RiaLogging::info(
|
||||
QString( "Interpolating missing values for %1" ).arg( eclipseResultDefinition.resultVariable() ) );
|
||||
RiaInterpolationTools::interpolateMissingValues( measuredDepthValues, values );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the missing data from other curve
|
||||
RiaDefines::CurveProperty replacementProperty =
|
||||
fractureModel->getDefaultPropertyForMissingValues( curveProperty );
|
||||
|
||||
std::vector<double> initialValues;
|
||||
std::vector<double> initialMds;
|
||||
std::vector<double> initialTvds;
|
||||
double initialRkbDiff = -1.0;
|
||||
calculate( replacementProperty, fractureModel, timeStep, initialValues, initialMds, initialTvds, initialRkbDiff );
|
||||
|
||||
if ( initialValues.empty() )
|
||||
{
|
||||
RiaLogging::error( QString( "Empty replacement data found for fracture model curve." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
CVF_ASSERT( values.size() == initialValues.size() );
|
||||
replaceMissingValues( values, initialValues );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimFractureModelWellLogCalculator::hasMissingValues( const std::vector<double>& values )
|
||||
{
|
||||
for ( double v : values )
|
||||
{
|
||||
if ( v == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelWellLogCalculator::replaceMissingValues( std::vector<double>& values, double defaultValue )
|
||||
{
|
||||
for ( double& v : values )
|
||||
{
|
||||
if ( v == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
v = defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelWellLogCalculator::replaceMissingValues( std::vector<double>& values,
|
||||
const std::vector<double>& replacementValues )
|
||||
{
|
||||
CVF_ASSERT( values.size() == replacementValues.size() );
|
||||
for ( size_t i = 0; i < values.size(); i++ )
|
||||
{
|
||||
if ( values[i] == std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
values[i] = replacementValues[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<RigResultAccessor>
|
||||
RimFractureModelWellLogCalculator::findMissingValuesAccessor( RigEclipseCaseData* caseData,
|
||||
RimEclipseInputPropertyCollection* inputPropertyCollection,
|
||||
int gridIndex,
|
||||
int timeStepIndex,
|
||||
RimEclipseResultDefinition* eclipseResultDefinition ) const
|
||||
{
|
||||
QString resultName = eclipseResultDefinition->resultVariable();
|
||||
|
||||
for ( RimEclipseInputProperty* inputProperty : inputPropertyCollection->inputProperties() )
|
||||
{
|
||||
// Look for input properties starting with the same name as result definition
|
||||
if ( inputProperty && inputProperty->resultName().startsWith( resultName ) )
|
||||
{
|
||||
RiaLogging::info(
|
||||
QString( "Found missing values result for %1: %2" ).arg( resultName ).arg( inputProperty->resultName() ) );
|
||||
|
||||
RigEclipseResultAddress resultAddress( RiaDefines::ResultCatType::INPUT_PROPERTY, inputProperty->resultName() );
|
||||
caseData->results( eclipseResultDefinition->porosityModel() )->ensureKnownResultLoaded( resultAddress );
|
||||
cvf::ref<RigResultAccessor> resAcc =
|
||||
RigResultAccessorFactory::createFromResultAddress( caseData,
|
||||
gridIndex,
|
||||
eclipseResultDefinition->porosityModel(),
|
||||
timeStepIndex,
|
||||
resultAddress );
|
||||
|
||||
return resAcc;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelWellLogCalculator::addOverburden( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const
|
||||
{
|
||||
if ( !values.empty() )
|
||||
{
|
||||
double overburdenHeight = fractureModel->overburdenHeight();
|
||||
double tvdOverburdenBottom = tvDepthValues[0];
|
||||
double tvdOverburdenTop = tvdOverburdenBottom - overburdenHeight;
|
||||
|
||||
double overburdenTopValue = std::numeric_limits<double>::infinity();
|
||||
double overburdenBottomValue = std::numeric_limits<double>::infinity();
|
||||
if ( fractureModel->burdenStrategy( curveProperty ) == RimFractureModel::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
overburdenTopValue = fractureModel->getDefaultForMissingOverburdenValue( curveProperty );
|
||||
overburdenBottomValue = overburdenTopValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
double gradient = fractureModel->getOverburdenGradient( curveProperty );
|
||||
overburdenBottomValue = values[0];
|
||||
overburdenTopValue = overburdenBottomValue + gradient * -overburdenHeight;
|
||||
}
|
||||
|
||||
// Prepend the new "fake" depth for start of overburden
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdOverburdenBottom );
|
||||
tvDepthValues.insert( tvDepthValues.begin(), tvdOverburdenTop );
|
||||
|
||||
// TODO: this is not always correct
|
||||
double mdTop = measuredDepthValues[0];
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop );
|
||||
measuredDepthValues.insert( measuredDepthValues.begin(), mdTop - overburdenHeight );
|
||||
|
||||
values.insert( values.begin(), overburdenBottomValue );
|
||||
values.insert( values.begin(), overburdenTopValue );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimFractureModelWellLogCalculator::addUnderburden( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const
|
||||
{
|
||||
if ( !values.empty() )
|
||||
{
|
||||
size_t lastIndex = tvDepthValues.size() - 1;
|
||||
|
||||
double underburdenHeight = fractureModel->underburdenHeight();
|
||||
double tvdUnderburdenTop = tvDepthValues[lastIndex];
|
||||
double tvdUnderburdenBottom = tvdUnderburdenTop + underburdenHeight;
|
||||
|
||||
double underburdenTopValue = std::numeric_limits<double>::infinity();
|
||||
double underburdenBottomValue = std::numeric_limits<double>::infinity();
|
||||
if ( fractureModel->burdenStrategy( curveProperty ) == RimFractureModel::BurdenStrategy::DEFAULT_VALUE )
|
||||
{
|
||||
underburdenTopValue = fractureModel->getDefaultForMissingUnderburdenValue( curveProperty );
|
||||
underburdenBottomValue = underburdenTopValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
double gradient = fractureModel->getUnderburdenGradient( curveProperty );
|
||||
underburdenTopValue = values[lastIndex];
|
||||
underburdenBottomValue = underburdenTopValue + gradient * underburdenHeight;
|
||||
}
|
||||
|
||||
// Append the new "fake" depth for start of underburden
|
||||
tvDepthValues.push_back( tvdUnderburdenTop );
|
||||
tvDepthValues.push_back( tvdUnderburdenBottom );
|
||||
|
||||
// Append the new "fake" md
|
||||
// TODO: check if this is correct???
|
||||
double mdBottom = measuredDepthValues[lastIndex];
|
||||
measuredDepthValues.push_back( mdBottom );
|
||||
measuredDepthValues.push_back( mdBottom + underburdenHeight );
|
||||
|
||||
values.push_back( underburdenTopValue );
|
||||
values.push_back( underburdenBottomValue );
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor ASA
|
||||
//
|
||||
// ResInsight is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimFractureModelPropertyCalculator.h"
|
||||
|
||||
#include "RiaFractureModelDefines.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RigEclipseCaseData;
|
||||
class RimEclipseInputPropertyCollection;
|
||||
class RimEclipseResultDefinition;
|
||||
class RigResultAccessor;
|
||||
|
||||
class RimFractureModelWellLogCalculator : public RimFractureModelPropertyCalculator
|
||||
{
|
||||
public:
|
||||
RimFractureModelWellLogCalculator( RimFractureModelCalculator& fractureModelCalculator );
|
||||
|
||||
bool calculate( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
int timeStep,
|
||||
std::vector<double>& values,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& tvDepthValues,
|
||||
double& rkbDiff ) const override;
|
||||
|
||||
bool isMatching( RiaDefines::CurveProperty curveProperty ) const override;
|
||||
|
||||
protected:
|
||||
static bool hasMissingValues( const std::vector<double>& values );
|
||||
static void replaceMissingValues( std::vector<double>& values, double defaultValue );
|
||||
static void replaceMissingValues( std::vector<double>& values, const std::vector<double>& replacementValues );
|
||||
cvf::ref<RigResultAccessor> findMissingValuesAccessor( RigEclipseCaseData* caseData,
|
||||
RimEclipseInputPropertyCollection* inputPropertyCollection,
|
||||
int gridIndex,
|
||||
int timeStepIndex,
|
||||
RimEclipseResultDefinition* eclipseResultDefinition ) const;
|
||||
|
||||
void addOverburden( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const;
|
||||
|
||||
void addUnderburden( RiaDefines::CurveProperty curveProperty,
|
||||
const RimFractureModel* fractureModel,
|
||||
std::vector<double>& tvDepthValues,
|
||||
std::vector<double>& measuredDepthValues,
|
||||
std::vector<double>& values ) const;
|
||||
};
|
@ -15,45 +15,14 @@
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimLayerCurve.h"
|
||||
|
||||
#include "RigEclipseCaseData.h"
|
||||
#include "RigEclipseWellLogExtractor.h"
|
||||
#include "RigElasticProperties.h"
|
||||
#include "RigResultAccessorFactory.h"
|
||||
#include "RigWellLogCurveData.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimCase.h"
|
||||
#include "RimColorLegend.h"
|
||||
#include "RimColorLegendCollection.h"
|
||||
#include "RimColorLegendItem.h"
|
||||
#include "RimEclipseCase.h"
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
#include "RimElasticProperties.h"
|
||||
#include "RimFractureModel.h"
|
||||
#include "RimFractureModelPlot.h"
|
||||
#include "RimFractureModelCalculator.h"
|
||||
#include "RimModeledWellPath.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimTools.h"
|
||||
#include "RimWellLogFile.h"
|
||||
#include "RimWellLogPlot.h"
|
||||
#include "RimWellLogTrack.h"
|
||||
#include "RimWellPath.h"
|
||||
#include "RimWellPathCollection.h"
|
||||
#include "RimWellPlotTools.h"
|
||||
|
||||
#include "RiuQwtPlotCurve.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "RiaApplication.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimLayerCurve, "LayerCurve" );
|
||||
|
||||
@ -108,82 +77,17 @@ void RimLayerCurve::performDataExtraction( bool* isUsingPseudoLength )
|
||||
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_case.value() );
|
||||
if ( eclipseCase && m_fractureModel )
|
||||
{
|
||||
RigEclipseWellLogExtractor eclExtractor( eclipseCase->eclipseCaseData(),
|
||||
m_fractureModel->thicknessDirectionWellPath()->wellPathGeometry(),
|
||||
"fracture model" );
|
||||
|
||||
rkbDiff = eclExtractor.wellPathData()->rkbDiff();
|
||||
|
||||
// Extract formation data
|
||||
cvf::ref<RigResultAccessor> formationResultAccessor = RigResultAccessorFactory::
|
||||
createFromResultAddress( eclipseCase->eclipseCaseData(),
|
||||
0,
|
||||
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
||||
0,
|
||||
RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES,
|
||||
RiaDefines::activeFormationNamesResultName() ) );
|
||||
if ( !formationResultAccessor.notNull() )
|
||||
bool isOk = m_fractureModel->calculator()->extractCurveData( curveProperty(),
|
||||
m_timeStep,
|
||||
values,
|
||||
measuredDepthValues,
|
||||
tvDepthValues,
|
||||
rkbDiff );
|
||||
if ( !isOk )
|
||||
{
|
||||
RiaLogging::error( QString( "No formation result found." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
CurveSamplingPointData curveData =
|
||||
RimWellLogTrack::curveSamplingPointData( &eclExtractor, formationResultAccessor.p() );
|
||||
|
||||
std::vector<QString> formationNamesVector = RimWellLogTrack::formationNamesVector( eclipseCase );
|
||||
|
||||
double overburdenHeight = m_fractureModel->overburdenHeight();
|
||||
if ( overburdenHeight > 0.0 )
|
||||
{
|
||||
RimWellLogTrack::addOverburden( formationNamesVector, curveData, overburdenHeight );
|
||||
}
|
||||
|
||||
double underburdenHeight = m_fractureModel->underburdenHeight();
|
||||
if ( underburdenHeight > 0.0 )
|
||||
{
|
||||
RimWellLogTrack::addUnderburden( formationNamesVector, curveData, underburdenHeight );
|
||||
}
|
||||
|
||||
measuredDepthValues = curveData.md;
|
||||
tvDepthValues = curveData.tvd;
|
||||
|
||||
// Extract facies data
|
||||
RimFractureModelPlot* fractureModelPlot;
|
||||
firstAncestorOrThisOfType( fractureModelPlot );
|
||||
if ( !fractureModelPlot )
|
||||
{
|
||||
RiaLogging::error( QString( "No facies data found for layer curve." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<double> faciesValues;
|
||||
fractureModelPlot->getFaciesValues( faciesValues );
|
||||
if ( faciesValues.empty() )
|
||||
{
|
||||
RiaLogging::error( QString( "Empty facies data found for layer curve." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( faciesValues.size() != curveData.data.size() || faciesValues.size() != measuredDepthValues.size() ) return;
|
||||
|
||||
values.resize( faciesValues.size() );
|
||||
|
||||
int layerNo = 0;
|
||||
double previousFormation = -1.0;
|
||||
double previousFacies = -1.0;
|
||||
for ( size_t i = 0; i < faciesValues.size(); i++ )
|
||||
{
|
||||
if ( previousFormation != curveData.data[i] || previousFacies != faciesValues[i] )
|
||||
{
|
||||
layerNo++;
|
||||
}
|
||||
|
||||
values[i] = layerNo;
|
||||
previousFormation = curveData.data[i];
|
||||
previousFacies = faciesValues[i];
|
||||
}
|
||||
|
||||
RiaEclipseUnitTools::UnitSystem eclipseUnitsType = eclipseCase->eclipseCaseData()->unitsType();
|
||||
if ( eclipseUnitsType == RiaEclipseUnitTools::UnitSystem::UNITS_FIELD )
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ caf::PdmObjectHandle* RimcFractureModelPlot_exportToFile::execute()
|
||||
{
|
||||
RimFractureModelPlot* fractureModelPlot = self<RimFractureModelPlot>();
|
||||
|
||||
RifFractureModelPlotExporter::writeToDirectory( fractureModelPlot,
|
||||
RifFractureModelPlotExporter::writeToDirectory( fractureModelPlot->fractureModel(),
|
||||
fractureModelPlot->fractureModel()->useDetailedFluidLoss(),
|
||||
m_directoryPath() );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user