mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Improve user control on resampling operations
Allow user to specify Accumulated or Rate for a summary curve. Default setting is Auto, and summary address is used to derive Accumulated/Rate. User can set curve type explicitly.
This commit is contained in:
@@ -28,6 +28,15 @@ void caf::AppEnum<RiaDefines::HorizontalAxisType>::setUp()
|
||||
addItem( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR, "SUMMARY_VECTOR", "Summary Vector" );
|
||||
setDefault( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RiaDefines::SummaryCurveTypeMode>::setUp()
|
||||
{
|
||||
addItem( RiaDefines::SummaryCurveTypeMode::AUTO, "AUTO", "Auto" );
|
||||
addItem( RiaDefines::SummaryCurveTypeMode::CUSTOM, "CUSTOM", "Custom" );
|
||||
setDefault( RiaDefines::SummaryCurveTypeMode::AUTO );
|
||||
}
|
||||
|
||||
} // namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -35,6 +35,12 @@ enum class HorizontalAxisType
|
||||
SUMMARY_VECTOR
|
||||
};
|
||||
|
||||
enum class SummaryCurveTypeMode
|
||||
{
|
||||
AUTO,
|
||||
CUSTOM
|
||||
};
|
||||
|
||||
QString summaryField();
|
||||
QString summaryAquifer();
|
||||
QString summaryNetwork();
|
||||
|
||||
@@ -175,7 +175,7 @@ RimSummaryTableCollection* RiaSummaryTools::parentSummaryTableCollection( caf::P
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaSummaryTools::hasAccumulatedData( const RifEclipseSummaryAddress& address )
|
||||
RifEclipseSummaryAddressDefines::CurveType RiaSummaryTools::identifyCurveType( const RifEclipseSummaryAddress& address )
|
||||
{
|
||||
if ( address.isCalculated() )
|
||||
{
|
||||
@@ -187,15 +187,16 @@ bool RiaSummaryTools::hasAccumulatedData( const RifEclipseSummaryAddress& addres
|
||||
{
|
||||
if ( !variableAddress.hasAccumulatedData() )
|
||||
{
|
||||
return false;
|
||||
return RifEclipseSummaryAddressDefines::CurveType::RATE;
|
||||
}
|
||||
}
|
||||
|
||||
// All the variables are accumulated
|
||||
return true;
|
||||
return RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED;
|
||||
}
|
||||
|
||||
return address.hasAccumulatedData();
|
||||
return address.hasAccumulatedData() ? RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED
|
||||
: RifEclipseSummaryAddressDefines::CurveType::RATE;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -231,11 +232,27 @@ std::pair<std::vector<time_t>, std::vector<double>> RiaSummaryTools::resampledVa
|
||||
const std::vector<time_t>& timeSteps,
|
||||
const std::vector<double>& values,
|
||||
RiaDefines::DateTimePeriod period )
|
||||
{
|
||||
// NB! The curve type can be overridden by the user, so there might be a discrepancy between the curve type and the curve type derived
|
||||
// from the address
|
||||
// See RimSummaryCurve::curveType()
|
||||
|
||||
return resampledValuesForPeriod( RiaSummaryTools::identifyCurveType( address ), timeSteps, values, period );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<std::vector<time_t>, std::vector<double>>
|
||||
RiaSummaryTools::resampledValuesForPeriod( RifEclipseSummaryAddressDefines::CurveType accumulatedOrRate,
|
||||
const std::vector<time_t>& timeSteps,
|
||||
const std::vector<double>& values,
|
||||
RiaDefines::DateTimePeriod period )
|
||||
{
|
||||
RiaTimeHistoryCurveResampler resampler;
|
||||
resampler.setCurveData( values, timeSteps );
|
||||
|
||||
if ( RiaSummaryTools::hasAccumulatedData( address ) )
|
||||
if ( accumulatedOrRate == CurveType::ACCUMULATED )
|
||||
{
|
||||
resampler.resampleAndComputePeriodEndValues( period );
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "RiaDateTimeDefines.h"
|
||||
|
||||
#include "RifEclipseSummaryAddressDefines.h"
|
||||
|
||||
#include "RimObservedDataCollection.h"
|
||||
|
||||
#include <QString>
|
||||
@@ -66,7 +69,7 @@ public:
|
||||
static RimSummaryTable* parentSummaryTable( caf::PdmObject* object );
|
||||
static RimSummaryTableCollection* parentSummaryTableCollection( caf::PdmObject* object );
|
||||
|
||||
static bool hasAccumulatedData( const RifEclipseSummaryAddress& address );
|
||||
static RifEclipseSummaryAddressDefines::CurveType identifyCurveType( const RifEclipseSummaryAddress& address );
|
||||
static void getSummaryCasesAndAddressesForCalculation( int id,
|
||||
std::vector<RimSummaryCase*>& cases,
|
||||
std::vector<RifEclipseSummaryAddress>& addresses );
|
||||
@@ -76,6 +79,12 @@ public:
|
||||
const std::vector<double>& values,
|
||||
RiaDefines::DateTimePeriod period );
|
||||
|
||||
static std::pair<std::vector<time_t>, std::vector<double>>
|
||||
resampledValuesForPeriod( RifEclipseSummaryAddressDefines::CurveType accumulatedOrRate,
|
||||
const std::vector<time_t>& timeSteps,
|
||||
const std::vector<double>& values,
|
||||
RiaDefines::DateTimePeriod period );
|
||||
|
||||
static RimSummaryCase* summaryCaseById( int caseId );
|
||||
static RimSummaryEnsemble* ensembleById( int ensembleId );
|
||||
|
||||
|
||||
@@ -32,6 +32,15 @@ void caf::AppEnum<RifEclipseSummaryAddressDefines::StatisticsType>::setUp()
|
||||
addItem( RifEclipseSummaryAddressDefines::StatisticsType::MEAN, "MEAN", "Mean" );
|
||||
setDefault( RifEclipseSummaryAddressDefines::StatisticsType::NONE );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RifEclipseSummaryAddressDefines::CurveType>::setUp()
|
||||
{
|
||||
addItem( RifEclipseSummaryAddressDefines::CurveType::RATE, "RATE", "Rate" );
|
||||
addItem( RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED, "ACCUMULATED", "Accumulated" );
|
||||
setDefault( RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED );
|
||||
}
|
||||
|
||||
} // namespace caf
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -73,6 +73,12 @@ enum class StatisticsType
|
||||
MEAN
|
||||
};
|
||||
|
||||
enum class CurveType
|
||||
{
|
||||
ACCUMULATED,
|
||||
RATE
|
||||
};
|
||||
|
||||
std::string statisticsNameP10();
|
||||
std::string statisticsNameP50();
|
||||
std::string statisticsNameP90();
|
||||
|
||||
@@ -87,6 +87,9 @@ RimSummaryCurve::RimSummaryCurve()
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_yValuesResampling, "Resampling", "Resampling" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_yCurveTypeMode, "CurveTypeMode", "Curve Type" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_yCurveType, "CurveType", "" );
|
||||
|
||||
// X Values
|
||||
|
||||
CAF_PDM_InitField( &m_xAxisType,
|
||||
@@ -419,6 +422,14 @@ void RimSummaryCurve::setOverrideCurveDataY( const std::vector<time_t>& dateTime
|
||||
setSamplesFromTimeTAndYValues( dateTimes, yValues, true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseSummaryAddressDefines::CurveType RimSummaryCurve::curveType() const
|
||||
{
|
||||
return m_yCurveType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -899,9 +910,15 @@ void RimSummaryCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering
|
||||
curveDataGroup->add( &m_yValuesSummaryCase, { .newRow = true, .totalColumnSpan = 3, .leftLabelColumnSpan = 1 } );
|
||||
curveDataGroup->add( &m_yValuesSummaryAddressUiField, { .newRow = true, .totalColumnSpan = 2, .leftLabelColumnSpan = 1 } );
|
||||
curveDataGroup->add( &m_yPushButtonSelectSummaryAddress, { .newRow = false, .totalColumnSpan = 1, .leftLabelColumnSpan = 0 } );
|
||||
curveDataGroup->add( &m_yValuesResampling, { .newRow = true, .totalColumnSpan = 3, .leftLabelColumnSpan = 1 } );
|
||||
curveDataGroup->add( &m_yPlotAxisProperties, { .newRow = true, .totalColumnSpan = 3, .leftLabelColumnSpan = 1 } );
|
||||
curveDataGroup->add( &m_showErrorBars );
|
||||
|
||||
caf::PdmUiGroup* detailGroup = curveDataGroup->addNewGroup( "Advanced Properties" );
|
||||
detailGroup->setCollapsedByDefault();
|
||||
detailGroup->add( &m_yValuesResampling );
|
||||
detailGroup->add( &m_showErrorBars );
|
||||
detailGroup->add( &m_yCurveTypeMode );
|
||||
detailGroup->add( &m_yCurveType );
|
||||
m_yCurveType.uiCapability()->setUiReadOnly( m_yCurveTypeMode() == RiaDefines::SummaryCurveTypeMode::AUTO );
|
||||
}
|
||||
|
||||
if ( m_showXAxisGroup )
|
||||
@@ -1251,6 +1268,10 @@ void RimSummaryCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
|
||||
m_xPushButtonSelectSummaryAddress = false;
|
||||
}
|
||||
else if ( changedField == &m_yCurveTypeMode )
|
||||
{
|
||||
calculateCurveTypeFromAddress();
|
||||
}
|
||||
|
||||
if ( crossPlotTestForMatchingTimeSteps )
|
||||
{
|
||||
@@ -1369,10 +1390,11 @@ std::vector<time_t> RimSummaryCurve::timeStepsX() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCurve::calculateCurveInterpolationFromAddress()
|
||||
{
|
||||
if ( m_yValuesSummaryAddress() )
|
||||
{
|
||||
auto address = m_yValuesSummaryAddress()->address();
|
||||
if ( RiaSummaryTools::hasAccumulatedData( address ) )
|
||||
if ( !m_yValuesSummaryAddress() ) return;
|
||||
|
||||
calculateCurveTypeFromAddress();
|
||||
|
||||
if ( curveType() == RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED )
|
||||
{
|
||||
m_curveAppearance->setInterpolation( RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_POINT_TO_POINT );
|
||||
}
|
||||
@@ -1381,6 +1403,18 @@ void RimSummaryCurve::calculateCurveInterpolationFromAddress()
|
||||
m_curveAppearance->setInterpolation( RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_STEP_LEFT );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCurve::calculateCurveTypeFromAddress()
|
||||
{
|
||||
if ( !m_yValuesSummaryAddress() ) return;
|
||||
|
||||
if ( m_yCurveTypeMode() == RiaDefines::SummaryCurveTypeMode::AUTO )
|
||||
{
|
||||
m_yCurveType = RiaSummaryTools::identifyCurveType( m_yValuesSummaryAddress()->address() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
#include "RiaSummaryCurveAddress.h"
|
||||
#include "RiaSummaryDefines.h"
|
||||
|
||||
#include "RifEclipseSummaryAddressDefines.h"
|
||||
#include "RifEclipseSummaryAddressQMetaType.h"
|
||||
|
||||
#include "RimStackablePlotCurve.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
@@ -76,6 +78,8 @@ public:
|
||||
double yValueAtTimeT( time_t time ) const;
|
||||
void setOverrideCurveDataY( const std::vector<time_t>& xValues, const std::vector<double>& yValues );
|
||||
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType() const;
|
||||
|
||||
// X Axis functions
|
||||
void setAxisTypeX( RiaDefines::HorizontalAxisType axisType );
|
||||
RiaDefines::HorizontalAxisType axisTypeX() const;
|
||||
@@ -140,6 +144,7 @@ private:
|
||||
RifSummaryReaderInterface* valuesSummaryReaderY() const;
|
||||
|
||||
void calculateCurveInterpolationFromAddress();
|
||||
void calculateCurveTypeFromAddress();
|
||||
|
||||
static void appendOptionItemsForSummaryAddresses( QList<caf::PdmOptionItemInfo>* options, RimSummaryCase* summaryCase );
|
||||
|
||||
@@ -152,6 +157,9 @@ private:
|
||||
caf::PdmPtrField<RimPlotAxisPropertiesInterface*> m_yPlotAxisProperties;
|
||||
caf::PdmField<RiaDefines::DateTimePeriodEnum> m_yValuesResampling;
|
||||
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::SummaryCurveTypeMode>> m_yCurveTypeMode;
|
||||
caf::PdmField<caf::AppEnum<RifEclipseSummaryAddressDefines::CurveType>> m_yCurveType;
|
||||
|
||||
// X values
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::HorizontalAxisType>> m_xAxisType;
|
||||
caf::PdmPtrField<RimSummaryCase*> m_xValuesSummaryCase;
|
||||
|
||||
@@ -49,7 +49,7 @@ void RimSummaryCurvesData::populateTimeHistoryCurvesData( std::vector<RimGridTim
|
||||
if ( !curve->isChecked() ) continue;
|
||||
QString curveCaseName = curve->caseName();
|
||||
|
||||
CurveData curveData = { curve->curveExportDescription( {} ), RifEclipseSummaryAddress(), curve->yValues() };
|
||||
CurveData curveData = { curve->curveExportDescription( {} ), RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED, curve->yValues() };
|
||||
|
||||
curvesData->addCurveData( curveCaseName, "", curve->timeStepValues(), curveData );
|
||||
}
|
||||
@@ -68,7 +68,7 @@ void RimSummaryCurvesData::populateAsciiDataCurvesData( std::vector<RimAsciiData
|
||||
{
|
||||
if ( !curve->isChecked() ) continue;
|
||||
|
||||
CurveData curveData = { curve->curveExportDescription( {} ), RifEclipseSummaryAddress(), curve->yValues() };
|
||||
CurveData curveData = { curve->curveExportDescription( {} ), RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED, curve->yValues() };
|
||||
|
||||
curvesData->addCurveDataNoSearch( "", "", curve->timeSteps(), { curveData } );
|
||||
}
|
||||
@@ -145,30 +145,25 @@ QString RimSummaryCurvesData::createTextForExport( const std::vector<RimSummaryC
|
||||
|
||||
QString out;
|
||||
|
||||
RimSummaryCurvesData summaryCurvesGridData;
|
||||
RimSummaryCurvesData summaryCurvesData;
|
||||
RimSummaryCurvesData summaryCurvesObsData;
|
||||
RimSummaryCurvesData::populateSummaryCurvesData( curves, SummaryCurveType::CURVE_TYPE_GRID, &summaryCurvesGridData );
|
||||
RimSummaryCurvesData gridCurvesData;
|
||||
RimSummaryCurvesData::populateSummaryCurvesData( curves, SummaryCurveType::CURVE_TYPE_SUMMARY, &summaryCurvesData );
|
||||
RimSummaryCurvesData::populateSummaryCurvesData( curves, SummaryCurveType::CURVE_TYPE_OBSERVED, &summaryCurvesObsData );
|
||||
RimSummaryCurvesData::populateTimeHistoryCurvesData( gridCurves, &gridCurvesData );
|
||||
|
||||
RimSummaryCurvesData timeHistoryCurvesData;
|
||||
RimSummaryCurvesData::populateTimeHistoryCurvesData( gridCurves, &timeHistoryCurvesData );
|
||||
|
||||
// Export observed data
|
||||
RimSummaryCurvesData::appendToExportData( out, { summaryCurvesObsData }, showTimeAsLongString );
|
||||
|
||||
std::vector<RimSummaryCurvesData> exportData( 2 );
|
||||
|
||||
// Summary grid data for export
|
||||
RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::DATA_DECIDES, summaryCurvesGridData, &exportData[0] );
|
||||
RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::DATA_DECIDES, summaryCurvesData, &exportData[0] );
|
||||
RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::PERIOD_END, gridCurvesData, &exportData[1] );
|
||||
|
||||
// Time history data for export
|
||||
RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::PERIOD_END, timeHistoryCurvesData, &exportData[1] );
|
||||
|
||||
// Export resampled summary and time history data
|
||||
RimSummaryCurvesData::appendToExportData( out, exportData, showTimeAsLongString );
|
||||
|
||||
// Pasted observed data
|
||||
{
|
||||
// Handle observed data pasted into plot from clipboard
|
||||
|
||||
RimSummaryCurvesData asciiCurvesData;
|
||||
RimSummaryCurvesData::populateAsciiDataCurvesData( asciiCurves, &asciiCurvesData );
|
||||
|
||||
@@ -239,7 +234,7 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vector<RimSummaryCurv
|
||||
|
||||
if ( !curve->isChecked() ) continue;
|
||||
if ( isObservedCurve && ( curveType != SummaryCurveType::CURVE_TYPE_OBSERVED ) ) continue;
|
||||
if ( !isObservedCurve && ( curveType != SummaryCurveType::CURVE_TYPE_GRID ) ) continue;
|
||||
if ( !isObservedCurve && ( curveType != SummaryCurveType::CURVE_TYPE_SUMMARY ) ) continue;
|
||||
if ( !curve->summaryCaseY() ) continue;
|
||||
|
||||
QString curveCaseName = curve->summaryCaseY()->displayCaseName();
|
||||
@@ -249,7 +244,7 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vector<RimSummaryCurv
|
||||
ensembleName = curve->curveDefinition().ensemble()->name();
|
||||
}
|
||||
|
||||
CurveData curveData = { curve->curveExportDescription( {} ), curve->summaryAddressY(), curve->valuesY() };
|
||||
CurveData curveData = { curve->curveExportDescription( {} ), curve->curveType(), curve->valuesY() };
|
||||
CurveData errorCurveData;
|
||||
|
||||
// Error data
|
||||
@@ -259,7 +254,7 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vector<RimSummaryCurv
|
||||
if ( hasErrorData )
|
||||
{
|
||||
errorCurveData.name = curve->curveExportDescription( curve->errorSummaryAddressY() );
|
||||
errorCurveData.address = curve->errorSummaryAddressY();
|
||||
errorCurveData.curveType = curve->curveType();
|
||||
errorCurveData.values = errorValues;
|
||||
}
|
||||
|
||||
@@ -307,7 +302,7 @@ void RimSummaryCurvesData::prepareCaseCurvesForExport( RiaDefines::DateTimePerio
|
||||
for ( auto& curveDataItem : caseCurveData )
|
||||
{
|
||||
const auto [resampledTime, resampledValues] =
|
||||
RiaSummaryTools::resampledValuesForPeriod( curveDataItem.address, caseTimeSteps, curveDataItem.values, period );
|
||||
RiaSummaryTools::resampledValuesForPeriod( curveDataItem.curveType, caseTimeSteps, curveDataItem.values, period );
|
||||
|
||||
auto cd = curveDataItem;
|
||||
cd.values = resampledValues;
|
||||
|
||||
@@ -30,13 +30,13 @@ class RimAsciiDataCurve;
|
||||
struct CurveData
|
||||
{
|
||||
QString name;
|
||||
RifEclipseSummaryAddress address;
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType;
|
||||
std::vector<double> values;
|
||||
};
|
||||
|
||||
enum class SummaryCurveType
|
||||
{
|
||||
CURVE_TYPE_GRID = 0x1,
|
||||
CURVE_TYPE_SUMMARY = 0x1,
|
||||
CURVE_TYPE_OBSERVED = 0x2
|
||||
};
|
||||
|
||||
|
||||
@@ -86,11 +86,7 @@ std::vector<double> RimSummaryDeclineCurve::valuesY() const
|
||||
{
|
||||
auto [minTimeStep, maxTimeStep] = selectedTimeStepRange();
|
||||
|
||||
return createDeclineCurveValues( RimSummaryCurve::valuesY(),
|
||||
RimSummaryCurve::timeStepsY(),
|
||||
minTimeStep,
|
||||
maxTimeStep,
|
||||
RiaSummaryTools::hasAccumulatedData( summaryAddressY() ) );
|
||||
return createDeclineCurveValues( RimSummaryCurve::valuesY(), RimSummaryCurve::timeStepsY(), minTimeStep, maxTimeStep, curveType() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -100,11 +96,7 @@ std::vector<double> RimSummaryDeclineCurve::valuesX() const
|
||||
{
|
||||
auto [minTimeStep, maxTimeStep] = selectedTimeStepRange();
|
||||
|
||||
return createDeclineCurveValues( RimSummaryCurve::valuesX(),
|
||||
RimSummaryCurve::timeStepsX(),
|
||||
minTimeStep,
|
||||
maxTimeStep,
|
||||
RiaSummaryTools::hasAccumulatedData( summaryAddressX() ) );
|
||||
return createDeclineCurveValues( RimSummaryCurve::valuesX(), RimSummaryCurve::timeStepsX(), minTimeStep, maxTimeStep, curveType() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -138,7 +130,7 @@ std::vector<double> RimSummaryDeclineCurve::createDeclineCurveValues( const std:
|
||||
const std::vector<time_t>& timeSteps,
|
||||
time_t minTimeStep,
|
||||
time_t maxTimeStep,
|
||||
bool isAccumulatedResult ) const
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType ) const
|
||||
{
|
||||
if ( values.empty() || timeSteps.empty() ) return values;
|
||||
|
||||
@@ -147,8 +139,7 @@ std::vector<double> RimSummaryDeclineCurve::createDeclineCurveValues( const std:
|
||||
|
||||
if ( timeStepsInRange.empty() || valuesInRange.empty() ) return values;
|
||||
|
||||
auto [initialProductionRate, initialDeclineRate] =
|
||||
computeInitialProductionAndDeclineRate( valuesInRange, timeStepsInRange, isAccumulatedResult );
|
||||
auto [initialProductionRate, initialDeclineRate] = computeInitialProductionAndDeclineRate( valuesInRange, timeStepsInRange, curveType );
|
||||
if ( std::isinf( initialProductionRate ) || std::isnan( initialProductionRate ) || std::isinf( initialDeclineRate ) ||
|
||||
std::isnan( initialDeclineRate ) )
|
||||
{
|
||||
@@ -162,8 +153,8 @@ std::vector<double> RimSummaryDeclineCurve::createDeclineCurveValues( const std:
|
||||
for ( const QDateTime& futureTime : futureTimeSteps )
|
||||
{
|
||||
double timeSinceStart = futureTime.toSecsSinceEpoch() - initialTime.toSecsSinceEpoch();
|
||||
double predictedValue = computePredictedValue( initialProductionRate, initialDeclineRate, timeSinceStart, isAccumulatedResult );
|
||||
if ( isAccumulatedResult ) predictedValue += valuesInRange.back();
|
||||
double predictedValue = computePredictedValue( initialProductionRate, initialDeclineRate, timeSinceStart, curveType );
|
||||
if ( curveType == RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED ) predictedValue += valuesInRange.back();
|
||||
outValues.push_back( predictedValue );
|
||||
}
|
||||
|
||||
@@ -175,13 +166,13 @@ std::vector<double> RimSummaryDeclineCurve::createDeclineCurveValues( const std:
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<double, double> RimSummaryDeclineCurve::computeInitialProductionAndDeclineRate( const std::vector<double>& values,
|
||||
const std::vector<time_t>& timeSteps,
|
||||
bool isAccumulatedResult )
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType )
|
||||
{
|
||||
CAF_ASSERT( values.size() == timeSteps.size() );
|
||||
|
||||
auto computeProductionRate = []( double t0, double v0, double t1, double v1 ) { return ( v1 - v0 ) / ( t1 - t0 ); };
|
||||
|
||||
if ( !isAccumulatedResult )
|
||||
if ( curveType == RifEclipseSummaryAddressDefines::CurveType::RATE )
|
||||
{
|
||||
// Use the first (time step, value) pair as t0
|
||||
const size_t idx0 = 0;
|
||||
@@ -197,8 +188,7 @@ std::pair<double, double> RimSummaryDeclineCurve::computeInitialProductionAndDec
|
||||
RigDeclineCurveCalculator::computeDeclineRate( t0.toSecsSinceEpoch(), v0, initialTime.toSecsSinceEpoch(), initialProductionRate );
|
||||
return { initialProductionRate, initialDeclineRate };
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Select a point (t0) 1/4 into the user-specified range
|
||||
const double historyStep = 0.25;
|
||||
const size_t idx0 = static_cast<size_t>( timeSteps.size() * historyStep );
|
||||
@@ -222,7 +212,6 @@ std::pair<double, double> RimSummaryDeclineCurve::computeInitialProductionAndDec
|
||||
initialProductionRate );
|
||||
return { initialProductionRate, initialDeclineRate };
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
@@ -230,9 +219,9 @@ std::pair<double, double> RimSummaryDeclineCurve::computeInitialProductionAndDec
|
||||
double RimSummaryDeclineCurve::computePredictedValue( double initialProductionRate,
|
||||
double initialDeclineRate,
|
||||
double timeSinceStart,
|
||||
bool isAccumulatedResult ) const
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType ) const
|
||||
{
|
||||
if ( isAccumulatedResult )
|
||||
if ( curveType == RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED )
|
||||
{
|
||||
if ( m_declineCurveType == RimSummaryDeclineCurve::DeclineCurveType::EXPONENTIAL )
|
||||
{
|
||||
|
||||
@@ -76,7 +76,7 @@ private:
|
||||
const std::vector<time_t>& timeSteps,
|
||||
time_t minTimeStep,
|
||||
time_t maxTimeStep,
|
||||
bool isAccumulatedResult ) const;
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType ) const;
|
||||
|
||||
static std::pair<std::vector<time_t>, std::vector<double>>
|
||||
getInRangeValues( const std::vector<time_t>& timeSteps, const std::vector<double>& values, time_t minTimeStep, time_t maxTimeStep );
|
||||
@@ -87,9 +87,12 @@ private:
|
||||
|
||||
static std::pair<double, double> computeInitialProductionAndDeclineRate( const std::vector<double>& values,
|
||||
const std::vector<time_t>& timeSteps,
|
||||
bool isAccumulatedResult );
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType );
|
||||
|
||||
double computePredictedValue( double initialProductionRate, double initialDeclineRate, double timeSinceStart, bool isAccumulatedResult ) const;
|
||||
double computePredictedValue( double initialProductionRate,
|
||||
double initialDeclineRate,
|
||||
double timeSinceStart,
|
||||
RifEclipseSummaryAddressDefines::CurveType curveType ) const;
|
||||
|
||||
std::pair<time_t, time_t> fullTimeStepRange() const;
|
||||
std::pair<time_t, time_t> selectedTimeStepRange() const;
|
||||
|
||||
Reference in New Issue
Block a user