diff --git a/ApplicationLibCode/Application/RiaSummaryDefines.cpp b/ApplicationLibCode/Application/RiaSummaryDefines.cpp index 26fff23313..3ef5bac537 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::SummaryCurveTypeMode::AUTO, "AUTO", "Auto" ); + addItem( RiaDefines::SummaryCurveTypeMode::CUSTOM, "CUSTOM", "Custom" ); + setDefault( RiaDefines::SummaryCurveTypeMode::AUTO ); +} + } // namespace caf //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/Application/RiaSummaryDefines.h b/ApplicationLibCode/Application/RiaSummaryDefines.h index cdc26b3854..eeff79fe40 100644 --- a/ApplicationLibCode/Application/RiaSummaryDefines.h +++ b/ApplicationLibCode/Application/RiaSummaryDefines.h @@ -35,6 +35,12 @@ enum class HorizontalAxisType SUMMARY_VECTOR }; +enum class SummaryCurveTypeMode +{ + AUTO, + CUSTOM +}; + QString summaryField(); QString summaryAquifer(); QString summaryNetwork(); diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp b/ApplicationLibCode/Application/Tools/RiaSummaryTools.cpp index 699fae29b7..d6081ba623 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::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> RiaSummaryTools::resampledVa const std::vector& timeSteps, const std::vector& 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> + RiaSummaryTools::resampledValuesForPeriod( RifEclipseSummaryAddressDefines::CurveType accumulatedOrRate, + const std::vector& timeSteps, + const std::vector& values, + RiaDefines::DateTimePeriod period ) { RiaTimeHistoryCurveResampler resampler; resampler.setCurveData( values, timeSteps ); - if ( RiaSummaryTools::hasAccumulatedData( address ) ) + if ( accumulatedOrRate == CurveType::ACCUMULATED ) { resampler.resampleAndComputePeriodEndValues( period ); } diff --git a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h index e210015408..b97b8a52c0 100644 --- a/ApplicationLibCode/Application/Tools/RiaSummaryTools.h +++ b/ApplicationLibCode/Application/Tools/RiaSummaryTools.h @@ -19,6 +19,9 @@ #pragma once #include "RiaDateTimeDefines.h" + +#include "RifEclipseSummaryAddressDefines.h" + #include "RimObservedDataCollection.h" #include @@ -66,16 +69,22 @@ public: 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::CurveType 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::CurveType 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..339c47a1a0 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.cpp @@ -32,6 +32,15 @@ void caf::AppEnum::setUp() addItem( RifEclipseSummaryAddressDefines::StatisticsType::MEAN, "MEAN", "Mean" ); setDefault( RifEclipseSummaryAddressDefines::StatisticsType::NONE ); } + +template <> +void caf::AppEnum::setUp() +{ + addItem( RifEclipseSummaryAddressDefines::CurveType::RATE, "RATE", "Rate" ); + addItem( RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED, "ACCUMULATED", "Accumulated" ); + setDefault( RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED ); +} + } // namespace caf //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h index 7eff78ef04..c79ddcb240 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h @@ -73,6 +73,12 @@ enum class StatisticsType MEAN }; +enum class CurveType +{ + 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..a67bb77046 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.cpp @@ -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& 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,17 +1390,30 @@ std::vector RimSummaryCurve::timeStepsX() const //-------------------------------------------------------------------------------------------------- void RimSummaryCurve::calculateCurveInterpolationFromAddress() { - if ( m_yValuesSummaryAddress() ) + if ( !m_yValuesSummaryAddress() ) return; + + calculateCurveTypeFromAddress(); + + if ( curveType() == RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED ) { - auto address = m_yValuesSummaryAddress()->address(); - if ( RiaSummaryTools::hasAccumulatedData( address ) ) - { - m_curveAppearance->setInterpolation( RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_POINT_TO_POINT ); - } - else - { - m_curveAppearance->setInterpolation( RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_STEP_LEFT ); - } + m_curveAppearance->setInterpolation( RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_POINT_TO_POINT ); + } + else + { + 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() ); } } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h index 9e9dc33acd..4dd28e7b32 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurve.h @@ -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& xValues, const std::vector& 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* options, RimSummaryCase* summaryCase ); @@ -152,6 +157,9 @@ private: caf::PdmPtrField m_yPlotAxisProperties; caf::PdmField m_yValuesResampling; + caf::PdmField> m_yCurveTypeMode; + caf::PdmField> m_yCurveType; + // 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..75a465542e 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp @@ -49,7 +49,7 @@ void RimSummaryCurvesData::populateTimeHistoryCurvesData( std::vectorisChecked() ) 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::vectorisChecked() ) 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 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::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 +244,7 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vectorcurveDefinition().ensemble()->name(); } - CurveData curveData = { curve->curveExportDescription( {} ), curve->summaryAddressY(), curve->valuesY() }; + CurveData curveData = { curve->curveExportDescription( {} ), curve->curveType(), curve->valuesY() }; CurveData errorCurveData; // Error data @@ -258,9 +253,9 @@ void RimSummaryCurvesData::populateSummaryCurvesData( std::vectorcurveExportDescription( curve->errorSummaryAddressY() ); - errorCurveData.address = curve->errorSummaryAddressY(); - errorCurveData.values = errorValues; + errorCurveData.name = curve->curveExportDescription( curve->errorSummaryAddressY() ); + errorCurveData.curveType = curve->curveType(); + errorCurveData.values = errorValues; } auto curveDataList = std::vector( { curveData } ); @@ -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; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h index 4aa19cc99c..b7396d4cba 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::CurveType curveType; + 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..a2f3281494 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.cpp @@ -86,11 +86,7 @@ std::vector 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 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() ); } //-------------------------------------------------------------------------------------------------- @@ -134,11 +126,11 @@ 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::CurveType curveType ) const { if ( values.empty() || timeSteps.empty() ) return values; @@ -147,8 +139,7 @@ std::vector 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 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 RimSummaryDeclineCurve::createDeclineCurveValues( const std: //-------------------------------------------------------------------------------------------------- std::pair RimSummaryDeclineCurve::computeInitialProductionAndDeclineRate( const std::vector& values, const std::vector& 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,42 +188,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() ); + // 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]; - // 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 ); + // 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 decline rate using the rates at the two points - double initialDeclineRate = RigDeclineCurveCalculator::computeDeclineRate( t0.toSecsSinceEpoch(), - productionRate0, - initialTime.toSecsSinceEpoch(), - initialProductionRate ); - return { initialProductionRate, initialDeclineRate }; - } + // 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::CurveType curveType ) const { - if ( isAccumulatedResult ) + if ( curveType == RifEclipseSummaryAddressDefines::CurveType::ACCUMULATED ) { if ( m_declineCurveType == RimSummaryDeclineCurve::DeclineCurveType::EXPONENTIAL ) { diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h index 35e2b6aa38..7e59e4d639 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryDeclineCurve.h @@ -72,11 +72,11 @@ private: 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::CurveType curveType ) const; static std::pair, std::vector> getInRangeValues( const std::vector& timeSteps, const std::vector& values, time_t minTimeStep, time_t maxTimeStep ); @@ -85,11 +85,14 @@ private: 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::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 fullTimeStepRange() const; std::pair selectedTimeStepRange() const;