From 44727d6c88f74e21dd64179283ecc157af46375c Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 27 Aug 2024 14:50:26 +0200 Subject: [PATCH] Allow user to specify Auto, Accumulated or Rate for a summary curve Default setting is Auto, and use the summary address to derive Accumulated/Rate. User can set curve type explicitly. --- .../Application/RiaSummaryDefines.cpp | 9 ++ .../Application/RiaSummaryDefines.h | 7 ++ .../Application/Tools/RiaSummaryTools.cpp | 23 +++-- .../Application/Tools/RiaSummaryTools.h | 15 +++- .../RifEclipseSummaryAddressDefines.cpp | 1 + .../RifEclipseSummaryAddressDefines.h | 6 ++ .../Summary/RimSummaryCurve.cpp | 63 +++++++++++++- .../Summary/RimSummaryCurve.h | 10 +++ .../Summary/RimSummaryCurvesData.cpp | 41 +++++---- .../Summary/RimSummaryCurvesData.h | 8 +- .../Summary/RimSummaryDeclineCurve.cpp | 87 ++++++++++--------- .../Summary/RimSummaryDeclineCurve.h | 22 +++-- 12 files changed, 203 insertions(+), 89 deletions(-) diff --git a/ApplicationLibCode/Application/RiaSummaryDefines.cpp b/ApplicationLibCode/Application/RiaSummaryDefines.cpp index 26fff23313..1cdf9ba453 100644 --- a/ApplicationLibCode/Application/RiaSummaryDefines.cpp +++ b/ApplicationLibCode/Application/RiaSummaryDefines.cpp @@ -28,6 +28,15 @@ void caf::AppEnum::setUp() addItem( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR, "SUMMARY_VECTOR", "Summary Vector" ); setDefault( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ); } + +template <> +void caf::AppEnum::setUp() +{ + addItem( RiaDefines::AccumulatedOrRateType::AUTO, "AUTO", "Auto" ); + addItem( RiaDefines::AccumulatedOrRateType::ACCUMULATED, "ACCUMULATED", "Accumulated" ); + addItem( RiaDefines::AccumulatedOrRateType::RATE, "RATE", "Rate" ); + setDefault( RiaDefines::AccumulatedOrRateType::AUTO ); +} } // namespace caf //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaSummaryDefines.h b/ApplicationLibCode/Application/RiaSummaryDefines.h index cdc26b3854..7d114dd6a9 100644 --- a/ApplicationLibCode/Application/RiaSummaryDefines.h +++ b/ApplicationLibCode/Application/RiaSummaryDefines.h @@ -35,6 +35,13 @@ enum class HorizontalAxisType SUMMARY_VECTOR }; +enum class AccumulatedOrRateType +{ + AUTO, + ACCUMULATED, + RATE +}; + QString summaryField(); QString summaryAquifer(); QString summaryNetwork(); diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp b/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp index 699fae29b7..677f97f8e7 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp +++ b/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp @@ -175,7 +175,7 @@ RimSummaryTableCollection* RiaSummaryTools::parentSummaryTableCollection( caf::P //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RiaSummaryTools::hasAccumulatedData( const RifEclipseSummaryAddress& address ) +RifEclipseSummaryAddressDefines::AccumulatedOrRateType 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::AccumulatedOrRateType::RATE; } } // All the variables are accumulated - return true; + return RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED; } - return address.hasAccumulatedData(); + return address.hasAccumulatedData() ? RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED + : RifEclipseSummaryAddressDefines::AccumulatedOrRateType::RATE; } //-------------------------------------------------------------------------------------------------- @@ -231,11 +232,23 @@ std::pair, std::vector> RiaSummaryTools::resampledVa const std::vector& timeSteps, const std::vector& values, RiaDefines::DateTimePeriod period ) +{ + return resampledValuesForPeriod( RiaSummaryTools::identifyCurveType( address ), timeSteps, values, period ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::pair, std::vector> + RiaSummaryTools::resampledValuesForPeriod( RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate, + const std::vector& timeSteps, + const std::vector& values, + RiaDefines::DateTimePeriod period ) { RiaTimeHistoryCurveResampler resampler; resampler.setCurveData( values, timeSteps ); - if ( RiaSummaryTools::hasAccumulatedData( address ) ) + if ( accumulatedOrRate == AccumulatedOrRateType::ACCUMULATED ) { resampler.resampleAndComputePeriodEndValues( period ); } diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h index e210015408..c130124ce7 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h +++ b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h @@ -19,6 +19,7 @@ #pragma once #include "RiaDateTimeDefines.h" +#include "RifEclipseSummaryAddressDefines.h" #include "RimObservedDataCollection.h" #include @@ -66,16 +67,22 @@ class RiaSummaryTools static RimSummaryTable* parentSummaryTable( caf::PdmObject* object ); static RimSummaryTableCollection* parentSummaryTableCollection( caf::PdmObject* object ); - static bool hasAccumulatedData( const RifEclipseSummaryAddress& address ); - static void getSummaryCasesAndAddressesForCalculation( int id, - std::vector& cases, - std::vector& addresses ); + static RifEclipseSummaryAddressDefines::AccumulatedOrRateType identifyCurveType( const RifEclipseSummaryAddress& address ); + static void getSummaryCasesAndAddressesForCalculation( int id, + std::vector& cases, + std::vector& addresses ); static std::pair, std::vector> resampledValuesForPeriod( const RifEclipseSummaryAddress& address, const std::vector& timeSteps, const std::vector& values, RiaDefines::DateTimePeriod period ); + static std::pair, std::vector> + resampledValuesForPeriod( RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate, + const std::vector& timeSteps, + const std::vector& values, + RiaDefines::DateTimePeriod period ); + static RimSummaryCase* summaryCaseById( int caseId ); static RimSummaryEnsemble* ensembleById( int ensembleId ); diff --git a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.cpp b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.cpp index df4a459575..c591c2897e 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.cpp @@ -32,6 +32,7 @@ void caf::AppEnum::setUp() addItem( RifEclipseSummaryAddressDefines::StatisticsType::MEAN, "MEAN", "Mean" ); setDefault( RifEclipseSummaryAddressDefines::StatisticsType::NONE ); } + } // namespace caf //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h index 7eff78ef04..624573f3cf 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h @@ -73,6 +73,12 @@ enum class StatisticsType MEAN }; +enum class AccumulatedOrRateType +{ + ACCUMULATED, + RATE +}; + std::string statisticsNameP10(); std::string statisticsNameP50(); std::string statisticsNameP90(); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp index 2012c41db1..5ff2345798 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -87,6 +87,11 @@ RimSummaryCurve::RimSummaryCurve() CAF_PDM_InitFieldNoDefault( &m_yValuesResampling, "Resampling", "Resampling" ); + CAF_PDM_InitFieldNoDefault( &m_yAccumulatedOrRate, "AccumulatedOrRate", "Accumulated/Rate Curve Values" ); + CAF_PDM_InitFieldNoDefault( &m_yAccumulatedOrRateText, "CurveType", "Curve Type" ); + m_yAccumulatedOrRateText.registerGetMethod( this, &RimSummaryCurve::accumulatedOrRateText ); + m_yAccumulatedOrRateText.uiCapability()->setUiReadOnly( true ); + // X Values CAF_PDM_InitField( &m_xAxisType, @@ -419,6 +424,25 @@ void RimSummaryCurve::setOverrideCurveDataY( const std::vector& dateTime setSamplesFromTimeTAndYValues( dateTimes, yValues, true ); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddressDefines::AccumulatedOrRateType RimSummaryCurve::accumulatedOrRate() const +{ + switch ( m_yAccumulatedOrRate() ) + { + case RiaDefines::AccumulatedOrRateType::AUTO: + return RiaSummaryTools::identifyCurveType( m_yValuesSummaryAddress()->address() ); + case RiaDefines::AccumulatedOrRateType::ACCUMULATED: + return RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED; + case RiaDefines::AccumulatedOrRateType::RATE: + return RifEclipseSummaryAddressDefines::AccumulatedOrRateType::RATE; + default: + CAF_ASSERT( false ); + return RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED; + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -899,9 +923,14 @@ 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" ); + detailGroup->setCollapsedByDefault(); + detailGroup->add( &m_yValuesResampling, { .newRow = true, .totalColumnSpan = 3, .leftLabelColumnSpan = 1 } ); + detailGroup->add( &m_showErrorBars ); + detailGroup->add( &m_yAccumulatedOrRate ); + detailGroup->add( &m_yAccumulatedOrRateText ); } if ( m_showXAxisGroup ) @@ -1350,6 +1379,34 @@ RifSummaryReaderInterface* RimSummaryCurve::valuesSummaryReaderY() const return m_yValuesSummaryCase()->summaryReader(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimSummaryCurve::accumulatedOrRateText() const +{ + QString text; + + if ( m_yAccumulatedOrRate() == RiaDefines::AccumulatedOrRateType::AUTO ) + { + text = "Auto : "; + } + else + { + text = "User Defined : "; + } + + if ( accumulatedOrRate() == RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED ) + { + text += "Accumulated"; + } + else + { + text += "Rate"; + } + + return text; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1372,7 +1429,7 @@ void RimSummaryCurve::calculateCurveInterpolationFromAddress() if ( m_yValuesSummaryAddress() ) { auto address = m_yValuesSummaryAddress()->address(); - if ( RiaSummaryTools::hasAccumulatedData( address ) ) + if ( RiaSummaryTools::identifyCurveType( address ) == RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED ) { m_curveAppearance->setInterpolation( RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_POINT_TO_POINT ); } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h index 9e9dc33acd..b7dbb1855b 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h @@ -29,10 +29,13 @@ #include "RiaSummaryCurveAddress.h" #include "RiaSummaryDefines.h" +#include "RifEclipseSummaryAddressDefines.h" #include "RifEclipseSummaryAddressQMetaType.h" + #include "RimStackablePlotCurve.h" #include "cafAppEnum.h" +#include "cafPdmProxyValueField.h" #include "cafTristate.h" class RifSummaryReaderInterface; @@ -76,6 +79,8 @@ class RimSummaryCurve : public RimStackablePlotCurve double yValueAtTimeT( time_t time ) const; void setOverrideCurveDataY( const std::vector& xValues, const std::vector& yValues ); + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate() const; + // X Axis functions void setAxisTypeX( RiaDefines::HorizontalAxisType axisType ); RiaDefines::HorizontalAxisType axisTypeX() const; @@ -139,6 +144,8 @@ class RimSummaryCurve : public RimStackablePlotCurve RifSummaryReaderInterface* valuesSummaryReaderX() const; RifSummaryReaderInterface* valuesSummaryReaderY() const; + QString accumulatedOrRateText() const; + void calculateCurveInterpolationFromAddress(); static void appendOptionItemsForSummaryAddresses( QList* options, RimSummaryCase* summaryCase ); @@ -152,6 +159,9 @@ class RimSummaryCurve : public RimStackablePlotCurve caf::PdmPtrField m_yPlotAxisProperties; caf::PdmField m_yValuesResampling; + caf::PdmField> m_yAccumulatedOrRate; + caf::PdmProxyValueField m_yAccumulatedOrRateText; + // X values caf::PdmField> m_xAxisType; caf::PdmPtrField m_xValuesSummaryCase; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp index b831a2ba0b..0da6b8b7da 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp @@ -49,7 +49,9 @@ void RimSummaryCurvesData::populateTimeHistoryCurvesData( std::vectorisChecked() ) continue; QString curveCaseName = curve->caseName(); - CurveData curveData = { curve->curveExportDescription( {} ), RifEclipseSummaryAddress(), curve->yValues() }; + CurveData curveData = { curve->curveExportDescription( {} ), + RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED, + curve->yValues() }; curvesData->addCurveData( curveCaseName, "", curve->timeStepValues(), curveData ); } @@ -68,7 +70,9 @@ void RimSummaryCurvesData::populateAsciiDataCurvesData( std::vectorisChecked() ) continue; - CurveData curveData = { curve->curveExportDescription( {} ), RifEclipseSummaryAddress(), curve->yValues() }; + CurveData curveData = { curve->curveExportDescription( {} ), + RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED, + curve->yValues() }; curvesData->addCurveDataNoSearch( "", "", curve->timeSteps(), { curveData } ); } @@ -145,30 +149,25 @@ QString RimSummaryCurvesData::createTextForExport( const std::vector exportData( 2 ); - // Summary grid data for export - RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::DATA_DECIDES, summaryCurvesGridData, &exportData[0] ); - - // Time history data for export - RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::PERIOD_END, timeHistoryCurvesData, &exportData[1] ); + RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::DATA_DECIDES, summaryCurvesData, &exportData[0] ); + RimSummaryCurvesData::prepareCaseCurvesForExport( resamplingPeriod, ResampleAlgorithm::PERIOD_END, gridCurvesData, &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 +238,7 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vectorisChecked() ) 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 +248,7 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vectorcurveDefinition().ensemble()->name(); } - CurveData curveData = { curve->curveExportDescription( {} ), curve->summaryAddressY(), curve->valuesY() }; + CurveData curveData = { curve->curveExportDescription( {} ), curve->accumulatedOrRate(), curve->valuesY() }; CurveData errorCurveData; // Error data @@ -258,9 +257,9 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vectorcurveExportDescription( curve->errorSummaryAddressY() ); - errorCurveData.address = curve->errorSummaryAddressY(); - errorCurveData.values = errorValues; + errorCurveData.name = curve->curveExportDescription( curve->errorSummaryAddressY() ); + errorCurveData.accumulatedOrRate = curve->accumulatedOrRate(); + errorCurveData.values = errorValues; } auto curveDataList = std::vector( { curveData } ); @@ -307,7 +306,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.accumulatedOrRate, caseTimeSteps, curveDataItem.values, period ); auto cd = curveDataItem; cd.values = resampledValues; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h index 4aa19cc99c..abb26b3ff1 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h @@ -29,14 +29,14 @@ class RimAsciiDataCurve; struct CurveData { - QString name; - RifEclipseSummaryAddress address; - std::vector values; + QString name; + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate; + std::vector values; }; enum class SummaryCurveType { - CURVE_TYPE_GRID = 0x1, + CURVE_TYPE_SUMMARY = 0x1, CURVE_TYPE_OBSERVED = 0x2 }; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.cpp index 4576cac93d..b33ce0a863 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.cpp @@ -90,7 +90,7 @@ std::vector RimSummaryDeclineCurve::valuesY() const RimSummaryCurve::timeStepsY(), minTimeStep, maxTimeStep, - RiaSummaryTools::hasAccumulatedData( summaryAddressY() ) ); + RiaSummaryTools::identifyCurveType( summaryAddressY() ) ); } //-------------------------------------------------------------------------------------------------- @@ -104,7 +104,7 @@ std::vector RimSummaryDeclineCurve::valuesX() const RimSummaryCurve::timeStepsX(), minTimeStep, maxTimeStep, - RiaSummaryTools::hasAccumulatedData( summaryAddressX() ) ); + RiaSummaryTools::identifyCurveType( summaryAddressX() ) ); } //-------------------------------------------------------------------------------------------------- @@ -134,11 +134,12 @@ std::vector RimSummaryDeclineCurve::timeStepsX() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimSummaryDeclineCurve::createDeclineCurveValues( const std::vector& values, - const std::vector& timeSteps, - time_t minTimeStep, - time_t maxTimeStep, - bool isAccumulatedResult ) const +std::vector + RimSummaryDeclineCurve::createDeclineCurveValues( const std::vector& values, + const std::vector& timeSteps, + time_t minTimeStep, + time_t maxTimeStep, + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate ) const { if ( values.empty() || timeSteps.empty() ) return values; @@ -148,7 +149,7 @@ std::vector RimSummaryDeclineCurve::createDeclineCurveValues( const std: if ( timeStepsInRange.empty() || valuesInRange.empty() ) return values; auto [initialProductionRate, initialDeclineRate] = - computeInitialProductionAndDeclineRate( valuesInRange, timeStepsInRange, isAccumulatedResult ); + computeInitialProductionAndDeclineRate( valuesInRange, timeStepsInRange, accumulatedOrRate ); if ( std::isinf( initialProductionRate ) || std::isnan( initialProductionRate ) || std::isinf( initialDeclineRate ) || std::isnan( initialDeclineRate ) ) { @@ -162,8 +163,9 @@ std::vector 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, accumulatedOrRate ); + if ( accumulatedOrRate == RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED ) + predictedValue += valuesInRange.back(); outValues.push_back( predictedValue ); } @@ -173,15 +175,16 @@ std::vector RimSummaryDeclineCurve::createDeclineCurveValues( const std: //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::pair RimSummaryDeclineCurve::computeInitialProductionAndDeclineRate( const std::vector& values, - const std::vector& timeSteps, - bool isAccumulatedResult ) +std::pair + RimSummaryDeclineCurve::computeInitialProductionAndDeclineRate( const std::vector& values, + const std::vector& timeSteps, + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate ) { CAF_ASSERT( values.size() == timeSteps.size() ); auto computeProductionRate = []( double t0, double v0, double t1, double v1 ) { return ( v1 - v0 ) / ( t1 - t0 ); }; - if ( !isAccumulatedResult ) + if ( accumulatedOrRate == RifEclipseSummaryAddressDefines::AccumulatedOrRateType::RATE ) { // Use the first (time step, value) pair as t0 const size_t idx0 = 0; @@ -197,42 +200,40 @@ std::pair 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( timeSteps.size() * historyStep ); - const QDateTime t0 = RiaQDateTimeTools::fromTime_t( timeSteps[idx0] ); - const double v0 = values[idx0]; - - // For accumulated result: compute the initial production rate from the two points. - const QDateTime initialTime = RiaQDateTimeTools::fromTime_t( timeSteps.back() ); - double initialProductionRate = computeProductionRate( t0.toSecsSinceEpoch(), v0, initialTime.toSecsSinceEpoch(), values.back() ); - - // Compute the at production rate at time t0 by using a point even further back in the existing curve (tx). - size_t idxX = 0; - QDateTime tx = RiaQDateTimeTools::fromTime_t( timeSteps[idxX] ); - double vx = values[idxX]; - double productionRate0 = computeProductionRate( tx.toSecsSinceEpoch(), vx, t0.toSecsSinceEpoch(), v0 ); - // Compute the decline rate using the rates at the two points - double initialDeclineRate = RigDeclineCurveCalculator::computeDeclineRate( t0.toSecsSinceEpoch(), - productionRate0, - initialTime.toSecsSinceEpoch(), - initialProductionRate ); - return { initialProductionRate, initialDeclineRate }; - } + // Select a point (t0) 1/4 into the user-specified range + const double historyStep = 0.25; + const size_t idx0 = static_cast( timeSteps.size() * historyStep ); + const QDateTime t0 = RiaQDateTimeTools::fromTime_t( timeSteps[idx0] ); + const double v0 = values[idx0]; + + // For accumulated result: compute the initial production rate from the two points. + const QDateTime initialTime = RiaQDateTimeTools::fromTime_t( timeSteps.back() ); + double initialProductionRate = computeProductionRate( t0.toSecsSinceEpoch(), v0, initialTime.toSecsSinceEpoch(), values.back() ); + + // Compute the at production rate at time t0 by using a point even further back in the existing curve (tx). + size_t idxX = 0; + QDateTime tx = RiaQDateTimeTools::fromTime_t( timeSteps[idxX] ); + double vx = values[idxX]; + double productionRate0 = computeProductionRate( tx.toSecsSinceEpoch(), vx, t0.toSecsSinceEpoch(), v0 ); + + // Compute the decline rate using the rates at the two points + double initialDeclineRate = RigDeclineCurveCalculator::computeDeclineRate( t0.toSecsSinceEpoch(), + productionRate0, + initialTime.toSecsSinceEpoch(), + initialProductionRate ); + return { initialProductionRate, initialDeclineRate }; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -double RimSummaryDeclineCurve::computePredictedValue( double initialProductionRate, - double initialDeclineRate, - double timeSinceStart, - bool isAccumulatedResult ) const +double RimSummaryDeclineCurve::computePredictedValue( double initialProductionRate, + double initialDeclineRate, + double timeSinceStart, + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate ) const { - if ( isAccumulatedResult ) + if ( accumulatedOrRate == RifEclipseSummaryAddressDefines::AccumulatedOrRateType::ACCUMULATED ) { if ( m_declineCurveType == RimSummaryDeclineCurve::DeclineCurveType::EXPONENTIAL ) { diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h index 35e2b6aa38..158d4b5470 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h @@ -72,11 +72,11 @@ class RimSummaryDeclineCurve : public RimSummaryCurve void appendFutureTimeSteps( std::vector& timeSteps ) const; - std::vector createDeclineCurveValues( const std::vector& values, - const std::vector& timeSteps, - time_t minTimeStep, - time_t maxTimeStep, - bool isAccumulatedResult ) const; + std::vector createDeclineCurveValues( const std::vector& values, + const std::vector& timeSteps, + time_t minTimeStep, + time_t maxTimeStep, + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate ) const; static std::pair, std::vector> getInRangeValues( const std::vector& timeSteps, const std::vector& values, time_t minTimeStep, time_t maxTimeStep ); @@ -85,11 +85,15 @@ class RimSummaryDeclineCurve : public RimSummaryCurve std::set createFutureTimeSteps( const std::vector& timeSteps ) const; static void appendTimeSteps( std::vector& timeSteps, const std::set& moreTimeSteps ); - static std::pair computeInitialProductionAndDeclineRate( const std::vector& values, - const std::vector& timeSteps, - bool isAccumulatedResult ); + static std::pair + computeInitialProductionAndDeclineRate( const std::vector& values, + const std::vector& timeSteps, + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate ); - double computePredictedValue( double initialProductionRate, double initialDeclineRate, double timeSinceStart, bool isAccumulatedResult ) const; + double computePredictedValue( double initialProductionRate, + double initialDeclineRate, + double timeSinceStart, + RifEclipseSummaryAddressDefines::AccumulatedOrRateType accumulatedOrRate ) const; std::pair fullTimeStepRange() const; std::pair selectedTimeStepRange() const;