mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#2125 Curve Calculations : Add TimeHistoryCurveMerger
This commit is contained in:
parent
c366c04fcc
commit
686a47587b
@ -64,6 +64,7 @@ ${CEE_CURRENT_LIST_DIR}RigTofAccumulatedPhaseFractionsCalculator.h
|
|||||||
${CEE_CURRENT_LIST_DIR}RigTransmissibilityEquations.h
|
${CEE_CURRENT_LIST_DIR}RigTransmissibilityEquations.h
|
||||||
${CEE_CURRENT_LIST_DIR}RigNumberOfFloodedPoreVolumesCalculator.h
|
${CEE_CURRENT_LIST_DIR}RigNumberOfFloodedPoreVolumesCalculator.h
|
||||||
${CEE_CURRENT_LIST_DIR}RigWeightedMeanCalc.h
|
${CEE_CURRENT_LIST_DIR}RigWeightedMeanCalc.h
|
||||||
|
${CEE_CURRENT_LIST_DIR}RigTimeHistoryCurveMerger.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)
|
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)
|
||||||
@ -134,6 +135,7 @@ ${CEE_CURRENT_LIST_DIR}RigTofAccumulatedPhaseFractionsCalculator.cpp
|
|||||||
${CEE_CURRENT_LIST_DIR}RigTransmissibilityEquations.cpp
|
${CEE_CURRENT_LIST_DIR}RigTransmissibilityEquations.cpp
|
||||||
${CEE_CURRENT_LIST_DIR}RigNumberOfFloodedPoreVolumesCalculator.cpp
|
${CEE_CURRENT_LIST_DIR}RigNumberOfFloodedPoreVolumesCalculator.cpp
|
||||||
${CEE_CURRENT_LIST_DIR}RigWeightedMeanCalc.cpp
|
${CEE_CURRENT_LIST_DIR}RigWeightedMeanCalc.cpp
|
||||||
|
${CEE_CURRENT_LIST_DIR}RigTimeHistoryCurveMerger.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)
|
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)
|
||||||
|
@ -19,10 +19,8 @@
|
|||||||
|
|
||||||
#include "RigCurveDataTools.h"
|
#include "RigCurveDataTools.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
|
||||||
|
|
||||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||||
#include <set>
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
@ -107,220 +105,3 @@ bool RigCurveDataTools::isValidValue(double value, bool removeNegativeValues)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
bool RigCurveDataTools::isValidValue(double value)
|
|
||||||
{
|
|
||||||
if (value == HUGE_VAL || value == -HUGE_VAL || value != value)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
RigCurveDataInterpolationTools::RigCurveDataInterpolationTools(const std::vector<double>& valuesA,
|
|
||||||
const std::vector<QDateTime>& timeStepsA,
|
|
||||||
const std::vector<double>& valuesB,
|
|
||||||
const std::vector<QDateTime>& timeStepsB)
|
|
||||||
: m_valuesA(valuesA),
|
|
||||||
m_timeStepsA(timeStepsA),
|
|
||||||
m_valuesB(valuesB),
|
|
||||||
m_timeStepsB(timeStepsB)
|
|
||||||
{
|
|
||||||
computeInterpolatedValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
RigCurveDataTools::CurveIntervals RigCurveDataInterpolationTools::validIntervals() const
|
|
||||||
{
|
|
||||||
return m_curveIntervals;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
std::vector<std::tuple<QDateTime, double, double>> RigCurveDataInterpolationTools::interpolatedCurveData() const
|
|
||||||
{
|
|
||||||
return m_interpolatedValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
void RigCurveDataInterpolationTools::computeInterpolatedValues()
|
|
||||||
{
|
|
||||||
if (m_valuesA.size() != m_timeStepsA.size() || m_valuesB.size() != m_timeStepsB.size())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool removeNegativeValues = false;
|
|
||||||
|
|
||||||
auto validIntervalsA = RigCurveDataTools::calculateIntervalsOfValidValues(m_valuesA, removeNegativeValues);
|
|
||||||
|
|
||||||
std::vector<std::pair<QDateTime, QDateTime>> validTimeStepsA;
|
|
||||||
for (const auto& interval : validIntervalsA)
|
|
||||||
{
|
|
||||||
validTimeStepsA.push_back(std::make_pair(m_timeStepsA[interval.first], m_timeStepsA[interval.second]));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto validIntervalsB = RigCurveDataTools::calculateIntervalsOfValidValues(m_valuesB, removeNegativeValues);
|
|
||||||
for (const auto& interval : validIntervalsB)
|
|
||||||
{
|
|
||||||
const QDateTime& from = m_timeStepsB[interval.first];
|
|
||||||
const QDateTime& to = m_timeStepsB[interval.second];
|
|
||||||
|
|
||||||
auto intervals = intersectingValidIntervals(from, to, validTimeStepsA);
|
|
||||||
|
|
||||||
for (const auto& i : intervals)
|
|
||||||
{
|
|
||||||
std::set<QDateTime> validTimeSteps;
|
|
||||||
|
|
||||||
// Add all time steps from curve A inside interval
|
|
||||||
for (const auto& d : m_timeStepsA)
|
|
||||||
{
|
|
||||||
if (i.first <= d && d <= i.second)
|
|
||||||
{
|
|
||||||
validTimeSteps.insert(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add all time steps from curve B inside interval
|
|
||||||
for (const auto& d : m_timeStepsB)
|
|
||||||
{
|
|
||||||
if (i.first <= d && d <= i.second)
|
|
||||||
{
|
|
||||||
validTimeSteps.insert(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t firstIndex = m_interpolatedValues.size();
|
|
||||||
for (const auto& dt : validTimeSteps)
|
|
||||||
{
|
|
||||||
double valueA = RigCurveDataInterpolationTools::interpolatedValue(dt, m_valuesA, m_timeStepsA);
|
|
||||||
double valueB = RigCurveDataInterpolationTools::interpolatedValue(dt, m_valuesB, m_timeStepsB);
|
|
||||||
|
|
||||||
m_interpolatedValues.push_back(std::make_tuple(dt, valueA, valueB));
|
|
||||||
}
|
|
||||||
size_t lastIndex = m_interpolatedValues.size() - 1;
|
|
||||||
|
|
||||||
m_curveIntervals.push_back(std::make_pair(firstIndex, lastIndex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
std::vector<std::pair<QDateTime, QDateTime>> RigCurveDataInterpolationTools::intersectingValidIntervals(const QDateTime& a,
|
|
||||||
const QDateTime& b,
|
|
||||||
const std::vector<std::pair<QDateTime, QDateTime>>& intervals)
|
|
||||||
{
|
|
||||||
std::vector<std::pair<QDateTime, QDateTime>> validIntervals;
|
|
||||||
|
|
||||||
for (const auto& interval : intervals)
|
|
||||||
{
|
|
||||||
const QDateTime& c = interval.first;
|
|
||||||
const QDateTime& d = interval.second;
|
|
||||||
|
|
||||||
if (d < a)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b < c)
|
|
||||||
{
|
|
||||||
// We assume the intervals are increasing, and all other intervals are larger
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c <= a)
|
|
||||||
{
|
|
||||||
if (b <= d)
|
|
||||||
{
|
|
||||||
validIntervals.push_back(std::make_pair(a, b));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
validIntervals.push_back(std::make_pair(a, d));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (b <= d)
|
|
||||||
{
|
|
||||||
validIntervals.push_back(std::make_pair(c, b));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
validIntervals.push_back(std::make_pair(c, d));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return validIntervals;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
double RigCurveDataInterpolationTools::interpolatedValue(const QDateTime& dt, const std::vector<double>& values, const std::vector<QDateTime>& timeSteps)
|
|
||||||
{
|
|
||||||
if (values.size() != timeSteps.size()) return HUGE_VAL;
|
|
||||||
|
|
||||||
for (size_t firstI = 0; firstI < timeSteps.size(); firstI++)
|
|
||||||
{
|
|
||||||
size_t secondI = firstI + 1;
|
|
||||||
|
|
||||||
if (secondI == timeSteps.size())
|
|
||||||
{
|
|
||||||
if (timeSteps[firstI] == dt)
|
|
||||||
{
|
|
||||||
return values[firstI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondI < timeSteps.size() &&
|
|
||||||
timeSteps[firstI] <= dt &&
|
|
||||||
timeSteps[secondI] > dt)
|
|
||||||
{
|
|
||||||
const double& firstValue = values[firstI];
|
|
||||||
const double& secondValue = values[secondI];
|
|
||||||
|
|
||||||
bool isFirstValid = RigCurveDataTools::isValidValue(firstValue);
|
|
||||||
bool isSecondValid = RigCurveDataTools::isValidValue(secondValue);
|
|
||||||
|
|
||||||
if (!isFirstValid && !isSecondValid)
|
|
||||||
{
|
|
||||||
CVF_ASSERT(false);
|
|
||||||
|
|
||||||
return HUGE_VAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isFirstValid) return secondValue;
|
|
||||||
if (!isSecondValid) return firstValue;
|
|
||||||
|
|
||||||
double firstDiff = timeSteps[firstI].secsTo(dt);
|
|
||||||
double secondDiff = dt.secsTo(timeSteps[secondI]);
|
|
||||||
|
|
||||||
double firstWeight = secondDiff / (firstDiff + secondDiff);
|
|
||||||
double secondWeight = firstDiff / (firstDiff + secondDiff);
|
|
||||||
|
|
||||||
double val = (firstValue * firstWeight) + (secondValue * secondWeight);
|
|
||||||
|
|
||||||
CVF_ASSERT(RigCurveDataTools::isValidValue(val));
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return HUGE_VAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <tuple>
|
#include <set>
|
||||||
|
|
||||||
class QDateTime;
|
class QDateTime;
|
||||||
|
|
||||||
@ -63,48 +63,5 @@ public:
|
|||||||
// Helper methods, available as public to be able to access from unit tests
|
// Helper methods, available as public to be able to access from unit tests
|
||||||
|
|
||||||
static bool isValidValue(double value, bool removeNegativeValues);
|
static bool isValidValue(double value, bool removeNegativeValues);
|
||||||
static bool isValidValue(double value);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//==================================================================================================
|
|
||||||
///
|
|
||||||
//==================================================================================================
|
|
||||||
class RigCurveDataInterpolationTools
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RigCurveDataInterpolationTools(const std::vector<double>& valuesA,
|
|
||||||
const std::vector<QDateTime>& timeStepsA,
|
|
||||||
const std::vector<double>& valuesB,
|
|
||||||
const std::vector<QDateTime>& timeStepsB);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RigCurveDataTools::CurveIntervals validIntervals() const;
|
|
||||||
std::vector<std::tuple<QDateTime, double, double>> interpolatedCurveData() const;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Helper methods, available as public to be able to access from unit tests
|
|
||||||
|
|
||||||
static std::vector<std::pair<QDateTime, QDateTime>> intersectingValidIntervals(const QDateTime& from,
|
|
||||||
const QDateTime& to,
|
|
||||||
const std::vector<std::pair<QDateTime, QDateTime>>& intervals);
|
|
||||||
|
|
||||||
static double interpolatedValue(const QDateTime& dt,
|
|
||||||
const std::vector<double>& values,
|
|
||||||
const std::vector<QDateTime>& timeSteps);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void computeInterpolatedValues();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::vector<double>& m_valuesA;
|
|
||||||
const std::vector<QDateTime>& m_timeStepsA;
|
|
||||||
const std::vector<double>& m_valuesB;
|
|
||||||
const std::vector<QDateTime>& m_timeStepsB;
|
|
||||||
|
|
||||||
std::vector<std::tuple<QDateTime, double, double>> m_interpolatedValues;
|
|
||||||
RigCurveDataTools::CurveIntervals m_curveIntervals;
|
|
||||||
};
|
|
||||||
|
215
ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.cpp
Normal file
215
ApplicationCode/ReservoirDataModel/RigTimeHistoryCurveMerger.cpp
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 Statoil 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 "RigTimeHistoryCurveMerger.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RigTimeHistoryCurveMerger::RigTimeHistoryCurveMerger()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigTimeHistoryCurveMerger::addCurveData(const std::vector<double>& values, const std::vector<time_t>& timeSteps)
|
||||||
|
{
|
||||||
|
CVF_ASSERT(values.size() == timeSteps.size());
|
||||||
|
|
||||||
|
m_originalValues.push_back(std::make_pair(values, timeSteps));
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
RigCurveDataTools::CurveIntervals RigTimeHistoryCurveMerger::validIntervalsForAllTimeSteps() const
|
||||||
|
{
|
||||||
|
return m_validIntervalsForAllTimeSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
const std::vector<time_t>& RigTimeHistoryCurveMerger::allTimeSteps() const
|
||||||
|
{
|
||||||
|
return m_allTimeSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
const std::vector<double>& RigTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const
|
||||||
|
{
|
||||||
|
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||||
|
|
||||||
|
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
std::vector<double>& RigTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx)
|
||||||
|
{
|
||||||
|
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||||
|
|
||||||
|
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigTimeHistoryCurveMerger::computeInterpolatedValues()
|
||||||
|
{
|
||||||
|
m_validIntervalsForAllTimeSteps.clear();
|
||||||
|
m_allTimeSteps.clear();
|
||||||
|
m_interpolatedValuesForAllCurves.clear();
|
||||||
|
|
||||||
|
computeUnionOfTimeSteps();
|
||||||
|
|
||||||
|
const size_t curveCount = m_originalValues.size();
|
||||||
|
if (curveCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t dataValueCount = m_allTimeSteps.size();
|
||||||
|
if (dataValueCount == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_interpolatedValuesForAllCurves.resize(curveCount);
|
||||||
|
|
||||||
|
std::vector<double> accumulatedValidValues(dataValueCount, 1.0);
|
||||||
|
|
||||||
|
for (size_t curveIdx = 0; curveIdx < curveCount; curveIdx++)
|
||||||
|
{
|
||||||
|
std::vector<double>& curveValues = m_interpolatedValuesForAllCurves[curveIdx];
|
||||||
|
curveValues.resize(dataValueCount);
|
||||||
|
|
||||||
|
for (size_t valueIndex = 0; valueIndex < dataValueCount; valueIndex++)
|
||||||
|
{
|
||||||
|
double interpolValue = interpolationValue(m_allTimeSteps[valueIndex], m_originalValues[curveIdx].first, m_originalValues[curveIdx].second);
|
||||||
|
if (!RigCurveDataTools::isValidValue(interpolValue, false))
|
||||||
|
{
|
||||||
|
accumulatedValidValues[valueIndex] = HUGE_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
curveValues[valueIndex] = interpolValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_validIntervalsForAllTimeSteps = RigCurveDataTools::calculateIntervalsOfValidValues(accumulatedValidValues, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
void RigTimeHistoryCurveMerger::computeUnionOfTimeSteps()
|
||||||
|
{
|
||||||
|
m_allTimeSteps.clear();
|
||||||
|
|
||||||
|
std::set<time_t> unionOfTimeSteps;
|
||||||
|
|
||||||
|
for (const auto& curveData : m_originalValues)
|
||||||
|
{
|
||||||
|
for (const auto& dt : curveData.second)
|
||||||
|
{
|
||||||
|
unionOfTimeSteps.insert(dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& dt : unionOfTimeSteps)
|
||||||
|
{
|
||||||
|
m_allTimeSteps.push_back(dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
double RigTimeHistoryCurveMerger::interpolationValue(const time_t& interpolationTimeStep,
|
||||||
|
const std::vector<double>& curveValues,
|
||||||
|
const std::vector<time_t>& curveTimeSteps)
|
||||||
|
{
|
||||||
|
if (curveValues.size() != curveTimeSteps.size()) return HUGE_VAL;
|
||||||
|
|
||||||
|
const bool removeInterpolatedValues = false;
|
||||||
|
|
||||||
|
for (size_t firstI = 0; firstI < curveTimeSteps.size(); firstI++)
|
||||||
|
{
|
||||||
|
if (curveTimeSteps.at(firstI) == interpolationTimeStep)
|
||||||
|
{
|
||||||
|
const double& firstValue = curveValues.at(firstI);
|
||||||
|
if (!RigCurveDataTools::isValidValue(firstValue, removeInterpolatedValues))
|
||||||
|
{
|
||||||
|
return HUGE_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t secondI = firstI + 1;
|
||||||
|
|
||||||
|
if (secondI < curveTimeSteps.size() &&
|
||||||
|
curveTimeSteps.at(firstI) <= interpolationTimeStep &&
|
||||||
|
curveTimeSteps.at(secondI) > interpolationTimeStep)
|
||||||
|
{
|
||||||
|
if (curveTimeSteps.at(secondI) == interpolationTimeStep)
|
||||||
|
{
|
||||||
|
const double& secondValue = curveValues.at(secondI);
|
||||||
|
if (!RigCurveDataTools::isValidValue(secondValue, removeInterpolatedValues))
|
||||||
|
{
|
||||||
|
return HUGE_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return secondValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double& firstValue = curveValues.at(firstI);
|
||||||
|
const double& secondValue = curveValues.at(secondI);
|
||||||
|
|
||||||
|
bool isFirstValid = RigCurveDataTools::isValidValue(firstValue, removeInterpolatedValues);
|
||||||
|
if (!isFirstValid) return HUGE_VAL;
|
||||||
|
|
||||||
|
bool isSecondValid = RigCurveDataTools::isValidValue(secondValue, removeInterpolatedValues);
|
||||||
|
if (!isSecondValid) return HUGE_VAL;
|
||||||
|
|
||||||
|
double firstDiff = interpolationTimeStep - curveTimeSteps.at(firstI);
|
||||||
|
double secondDiff = curveTimeSteps.at(secondI) - interpolationTimeStep;
|
||||||
|
|
||||||
|
double firstWeight = secondDiff / (firstDiff + secondDiff);
|
||||||
|
double secondWeight = firstDiff / (firstDiff + secondDiff);
|
||||||
|
|
||||||
|
double val = (firstValue * firstWeight) + (secondValue * secondWeight);
|
||||||
|
|
||||||
|
CVF_ASSERT(RigCurveDataTools::isValidValue(val, removeInterpolatedValues));
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return HUGE_VAL;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (C) 2017 Statoil 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 "RigCurveDataTools.h"
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
///
|
||||||
|
//==================================================================================================
|
||||||
|
class RigTimeHistoryCurveMerger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RigTimeHistoryCurveMerger();
|
||||||
|
|
||||||
|
|
||||||
|
void addCurveData(const std::vector<double>& values,
|
||||||
|
const std::vector<time_t>& timeSteps);
|
||||||
|
|
||||||
|
void computeInterpolatedValues();
|
||||||
|
|
||||||
|
RigCurveDataTools::CurveIntervals validIntervalsForAllTimeSteps() const;
|
||||||
|
const std::vector<time_t>& allTimeSteps() const;
|
||||||
|
const std::vector<double>& interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const;
|
||||||
|
|
||||||
|
// Non-const access is not required by any clients, but the expression parser has no available const interface
|
||||||
|
// for specifying a data source for an expression variable. Allow non-const access to avoid copy of the contained
|
||||||
|
// values, interpolated for all time steps
|
||||||
|
//
|
||||||
|
// See ExpressionParserImpl::assignVector()
|
||||||
|
std::vector<double>& interpolatedCurveValuesForAllTimeSteps(size_t curveIdx);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Helper methods, available as public to be able to access from unit tests
|
||||||
|
|
||||||
|
static double interpolationValue(const time_t& interpolationTimeStep,
|
||||||
|
const std::vector<double>& curveValues,
|
||||||
|
const std::vector<time_t>& curveTimeSteps);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void computeUnionOfTimeSteps();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::pair<std::vector<double>, std::vector<time_t>>> m_originalValues;
|
||||||
|
|
||||||
|
RigCurveDataTools::CurveIntervals m_validIntervalsForAllTimeSteps;
|
||||||
|
|
||||||
|
std::vector<time_t> m_allTimeSteps;
|
||||||
|
std::vector<std::vector<double>> m_interpolatedValuesForAllCurves;
|
||||||
|
};
|
@ -33,6 +33,7 @@ ${CEE_CURRENT_LIST_DIR}EclipseRftReader-Test.cpp
|
|||||||
${CEE_CURRENT_LIST_DIR}RicExpressionParser-Test.cpp
|
${CEE_CURRENT_LIST_DIR}RicExpressionParser-Test.cpp
|
||||||
${CEE_CURRENT_LIST_DIR}RiuSummaryVectorDescriptionMap-Test.cpp
|
${CEE_CURRENT_LIST_DIR}RiuSummaryVectorDescriptionMap-Test.cpp
|
||||||
${CEE_CURRENT_LIST_DIR}FixedWidthDataParser-Test.cpp
|
${CEE_CURRENT_LIST_DIR}FixedWidthDataParser-Test.cpp
|
||||||
|
${CEE_CURRENT_LIST_DIR}RigTimeCurveHistoryMerger-Test.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)
|
if (RESINSIGHT_ENABLE_PROTOTYPE_FEATURE_FRACTURES)
|
||||||
|
187
ApplicationCode/UnitTests/RigTimeCurveHistoryMerger-Test.cpp
Normal file
187
ApplicationCode/UnitTests/RigTimeCurveHistoryMerger-Test.cpp
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "RigTimeHistoryCurveMerger.h"
|
||||||
|
|
||||||
|
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(RigTimeHistoryCurveMergerTest, TestDateInterpolation)
|
||||||
|
{
|
||||||
|
std::vector<double> values{ 2.0, 3.5, 5.0, 6.0};
|
||||||
|
std::vector<time_t> timeSteps{ 1, 5, 10, 15};
|
||||||
|
|
||||||
|
{
|
||||||
|
double val = RigTimeHistoryCurveMerger::interpolationValue(1, values, timeSteps);
|
||||||
|
|
||||||
|
EXPECT_EQ(2.0, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
double val = RigTimeHistoryCurveMerger::interpolationValue(0, values, timeSteps);
|
||||||
|
|
||||||
|
EXPECT_EQ(HUGE_VAL, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
double val = RigTimeHistoryCurveMerger::interpolationValue(20, values, timeSteps);
|
||||||
|
|
||||||
|
EXPECT_EQ(HUGE_VAL, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
double val = RigTimeHistoryCurveMerger::interpolationValue(3, values, timeSteps);
|
||||||
|
|
||||||
|
EXPECT_EQ(2.75, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeSteps)
|
||||||
|
{
|
||||||
|
std::vector<double> valuesA { HUGE_VAL, 1.0, HUGE_VAL, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, HUGE_VAL };
|
||||||
|
std::vector<double> valuesB { 10, 20, 30, 40, 45, HUGE_VAL, HUGE_VAL, 5.0, 6.0, HUGE_VAL };
|
||||||
|
|
||||||
|
EXPECT_EQ(valuesA.size(), valuesB.size());
|
||||||
|
|
||||||
|
std::vector<time_t> timeSteps;
|
||||||
|
for (size_t i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
timeSteps.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
RigTimeHistoryCurveMerger interpolate;
|
||||||
|
interpolate.addCurveData(valuesA, timeSteps);
|
||||||
|
interpolate.addCurveData(valuesB, timeSteps);
|
||||||
|
interpolate.computeInterpolatedValues();
|
||||||
|
|
||||||
|
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||||
|
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||||
|
|
||||||
|
EXPECT_EQ(10, static_cast<int>(interpolatedTimeSteps.size()));
|
||||||
|
EXPECT_EQ(3, static_cast<int>(intervals.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsOneComplete)
|
||||||
|
{
|
||||||
|
std::vector<double> valuesA { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
|
||||||
|
std::vector<double> valuesB { 10, 20, 30, HUGE_VAL, 50, HUGE_VAL, 70 };
|
||||||
|
|
||||||
|
EXPECT_EQ(valuesA.size(), valuesB.size());
|
||||||
|
|
||||||
|
std::vector<time_t> timeSteps;
|
||||||
|
for (size_t i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
timeSteps.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
RigTimeHistoryCurveMerger interpolate;
|
||||||
|
interpolate.addCurveData(valuesA, timeSteps);
|
||||||
|
interpolate.addCurveData(valuesB, timeSteps);
|
||||||
|
interpolate.computeInterpolatedValues();
|
||||||
|
|
||||||
|
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||||
|
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||||
|
|
||||||
|
EXPECT_EQ(7, static_cast<int>(interpolatedTimeSteps.size()));
|
||||||
|
EXPECT_EQ(3, static_cast<int>(intervals.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(RigTimeHistoryCurveMergerTest, ExtractIntervalsWithSameTimeStepsBothComplete)
|
||||||
|
{
|
||||||
|
std::vector<double> valuesA{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
|
||||||
|
std::vector<double> valuesB{ 10, 20, 30, 40, 50, 60, 70 };
|
||||||
|
|
||||||
|
EXPECT_EQ(valuesA.size(), valuesB.size());
|
||||||
|
|
||||||
|
std::vector<time_t> timeSteps;
|
||||||
|
for (size_t i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
timeSteps.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
RigTimeHistoryCurveMerger interpolate;
|
||||||
|
interpolate.addCurveData(valuesA, timeSteps);
|
||||||
|
interpolate.addCurveData(valuesB, timeSteps);
|
||||||
|
interpolate.computeInterpolatedValues();
|
||||||
|
|
||||||
|
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||||
|
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||||
|
|
||||||
|
EXPECT_EQ(7, static_cast<int>(interpolatedTimeSteps.size()));
|
||||||
|
EXPECT_EQ(1, static_cast<int>(intervals.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(RigTimeHistoryCurveMergerTest, OverlappintTimes)
|
||||||
|
{
|
||||||
|
std::vector<double> valuesA{ 1, 2, 3, 4, 5 };
|
||||||
|
std::vector<double> valuesB{ 10, 20, 30, 40, 50 };
|
||||||
|
|
||||||
|
EXPECT_EQ(valuesA.size(), valuesB.size());
|
||||||
|
|
||||||
|
std::vector<time_t> timeStepsA{ 0, 10, 11, 15, 20 };
|
||||||
|
std::vector<time_t> timeStepsB{ 1, 2, 3, 5, 7 };
|
||||||
|
|
||||||
|
RigTimeHistoryCurveMerger interpolate;
|
||||||
|
interpolate.addCurveData(valuesA, timeStepsA);
|
||||||
|
interpolate.addCurveData(valuesB, timeStepsB);
|
||||||
|
interpolate.computeInterpolatedValues();
|
||||||
|
|
||||||
|
auto interpolatedTimeSteps = interpolate.allTimeSteps();
|
||||||
|
auto intervals = interpolate.validIntervalsForAllTimeSteps();
|
||||||
|
|
||||||
|
EXPECT_EQ(10, static_cast<int>(interpolatedTimeSteps.size()));
|
||||||
|
EXPECT_EQ(1, static_cast<int>(intervals.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
TEST(RigTimeHistoryCurveMergerTest, RobustUse)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
RigTimeHistoryCurveMerger curveMerger;
|
||||||
|
curveMerger.computeInterpolatedValues();
|
||||||
|
EXPECT_EQ(0, static_cast<int>(curveMerger.allTimeSteps().size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> valuesA{ 1, 2, 3, 4, 5 };
|
||||||
|
std::vector<double> valuesB{ 10, 20, 30 };
|
||||||
|
|
||||||
|
std::vector<time_t> timeStepsA{ 0, 10, 11, 15, 20 };
|
||||||
|
std::vector<time_t> timeStepsB{ 1, 2, 3 };
|
||||||
|
|
||||||
|
{
|
||||||
|
RigTimeHistoryCurveMerger curveMerger;
|
||||||
|
curveMerger.addCurveData(valuesA, timeStepsA);
|
||||||
|
curveMerger.computeInterpolatedValues();
|
||||||
|
EXPECT_EQ(timeStepsA.size(), curveMerger.allTimeSteps().size());
|
||||||
|
EXPECT_EQ(timeStepsA.size(), curveMerger.interpolatedCurveValuesForAllTimeSteps(0).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
RigTimeHistoryCurveMerger curveMerger;
|
||||||
|
curveMerger.addCurveData(valuesA, timeStepsA);
|
||||||
|
curveMerger.addCurveData(valuesB, timeStepsB);
|
||||||
|
|
||||||
|
// Execute interpolation twice is allowed
|
||||||
|
curveMerger.computeInterpolatedValues();
|
||||||
|
curveMerger.computeInterpolatedValues();
|
||||||
|
EXPECT_EQ(8, static_cast<int>(curveMerger.allTimeSteps().size()));
|
||||||
|
EXPECT_EQ(8, static_cast<int>(curveMerger.interpolatedCurveValuesForAllTimeSteps(0).size()));
|
||||||
|
EXPECT_EQ(8, static_cast<int>(curveMerger.interpolatedCurveValuesForAllTimeSteps(1).size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@
|
|||||||
#include "RigCurveDataTools.h"
|
#include "RigCurveDataTools.h"
|
||||||
|
|
||||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||||
#include "QDateTime"
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
|
|
||||||
@ -52,243 +51,3 @@ TEST(RimWellLogExtractionCurveImplTest, StripOffHugeValAtEndsAndInteriorOfVector
|
|||||||
EXPECT_EQ(6, static_cast<int>(valuesIntervals[1].second));
|
EXPECT_EQ(6, static_cast<int>(valuesIntervals[1].second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
TEST(RimWellLogExtractionCurveImplTest, DateOverlap)
|
|
||||||
{
|
|
||||||
std::vector<std::pair<int, int>> dayIntervalsA { {5, 7}, {9, 12}, {15, 15}, {20, 30} , {30, 31}};
|
|
||||||
std::vector<std::pair<int, int>> dayIntervalsB { {3, 5}, {8, 13}, {15, 15}, {21, 22}, {25, 27}};
|
|
||||||
|
|
||||||
QDateTime startDate;
|
|
||||||
|
|
||||||
std::vector<std::pair<QDateTime, QDateTime>> intervalsA;
|
|
||||||
for (const auto& interval : dayIntervalsA)
|
|
||||||
{
|
|
||||||
intervalsA.push_back(std::make_pair(startDate.addDays(interval.first), startDate.addDays(interval.second)));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::pair<QDateTime, QDateTime>> intervalsB;
|
|
||||||
for (const auto& interval : dayIntervalsB)
|
|
||||||
{
|
|
||||||
intervalsB.push_back(std::make_pair(startDate.addDays(interval.first), startDate.addDays(interval.second)));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::pair<int, int>> allDayIntervals;
|
|
||||||
|
|
||||||
for (const auto& intervalA : intervalsA)
|
|
||||||
{
|
|
||||||
auto intersecting = RigCurveDataInterpolationTools::intersectingValidIntervals(intervalA.first, intervalA.second, intervalsB);
|
|
||||||
for (const auto& i : intersecting)
|
|
||||||
{
|
|
||||||
allDayIntervals.push_back(std::make_pair(startDate.daysTo(i.first), startDate.daysTo(i.second)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(5, static_cast<int>(allDayIntervals.size()));
|
|
||||||
|
|
||||||
EXPECT_EQ(5, allDayIntervals[0].first);
|
|
||||||
EXPECT_EQ(5, allDayIntervals[0].second);
|
|
||||||
|
|
||||||
EXPECT_EQ( 9, allDayIntervals[1].first);
|
|
||||||
EXPECT_EQ(12, allDayIntervals[1].second);
|
|
||||||
|
|
||||||
EXPECT_EQ(15, allDayIntervals[2].first);
|
|
||||||
EXPECT_EQ(15, allDayIntervals[2].second);
|
|
||||||
|
|
||||||
EXPECT_EQ(21, allDayIntervals[3].first);
|
|
||||||
EXPECT_EQ(22, allDayIntervals[3].second);
|
|
||||||
|
|
||||||
EXPECT_EQ(25, allDayIntervals[4].first);
|
|
||||||
EXPECT_EQ(27, allDayIntervals[4].second);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
TEST(RimWellLogExtractionCurveImplTest, TestDateInterpolation)
|
|
||||||
{
|
|
||||||
std::vector<double> values{ 2.0, 3.5, 5.0, 6.0};
|
|
||||||
std::vector<int> days{ 1, 5, 10, 15};
|
|
||||||
|
|
||||||
QDateTime startDate;
|
|
||||||
|
|
||||||
std::vector<QDateTime> timeSteps;
|
|
||||||
for (const auto& day : days)
|
|
||||||
{
|
|
||||||
timeSteps.push_back(startDate.addDays(day));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
QDateTime dt = startDate.addDays(1);
|
|
||||||
double val = RigCurveDataInterpolationTools::interpolatedValue(dt, values, timeSteps);
|
|
||||||
|
|
||||||
EXPECT_EQ(2.0, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
QDateTime dt = startDate.addDays(0);
|
|
||||||
double val = RigCurveDataInterpolationTools::interpolatedValue(dt, values, timeSteps);
|
|
||||||
|
|
||||||
EXPECT_EQ(HUGE_VAL, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
QDateTime dt = startDate.addDays(20);
|
|
||||||
double val = RigCurveDataInterpolationTools::interpolatedValue(dt, values, timeSteps);
|
|
||||||
|
|
||||||
EXPECT_EQ(HUGE_VAL, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
QDateTime dt = startDate.addDays(3);
|
|
||||||
double val = RigCurveDataInterpolationTools::interpolatedValue(dt, values, timeSteps);
|
|
||||||
|
|
||||||
EXPECT_EQ(2.75, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
TEST(RimWellLogExtractionCurveImplTest, ExtractIntervalsWithSameTimeSteps)
|
|
||||||
{
|
|
||||||
std::vector<double> valuesA { HUGE_VAL, 1.0, HUGE_VAL, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, HUGE_VAL };
|
|
||||||
std::vector<double> valuesB { 10, 20, 30, 40, 45, HUGE_VAL, HUGE_VAL, 5.0, 6.0, HUGE_VAL };
|
|
||||||
|
|
||||||
EXPECT_EQ(valuesA.size(), valuesB.size());
|
|
||||||
|
|
||||||
std::vector<int> days(10);
|
|
||||||
std::iota(days.begin(), days.end(), 10);
|
|
||||||
|
|
||||||
QDateTime startDate;
|
|
||||||
|
|
||||||
std::vector<QDateTime> timeSteps;
|
|
||||||
for (const auto& day : days)
|
|
||||||
{
|
|
||||||
timeSteps.push_back(startDate.addDays(day));
|
|
||||||
}
|
|
||||||
|
|
||||||
RigCurveDataInterpolationTools interpolate(valuesA, timeSteps, valuesB, timeSteps);
|
|
||||||
|
|
||||||
auto values = interpolate.interpolatedCurveData();
|
|
||||||
auto intervals = interpolate.validIntervals();
|
|
||||||
|
|
||||||
EXPECT_EQ(5, static_cast<int>(values.size()));
|
|
||||||
EXPECT_EQ(3, static_cast<int>(intervals.size()));
|
|
||||||
|
|
||||||
EXPECT_EQ( 1.0, std::get<1>(values[0]));
|
|
||||||
EXPECT_EQ(20.0, std::get<2>(values[0]));
|
|
||||||
|
|
||||||
EXPECT_EQ( 2.0, std::get<1>(values[1]));
|
|
||||||
EXPECT_EQ(40.0, std::get<2>(values[1]));
|
|
||||||
|
|
||||||
EXPECT_EQ( 2.5, std::get<1>(values[2]));
|
|
||||||
EXPECT_EQ(45.0, std::get<2>(values[2]));
|
|
||||||
|
|
||||||
EXPECT_EQ(5.0, std::get<1>(values[3]));
|
|
||||||
EXPECT_EQ(5.0, std::get<2>(values[3]));
|
|
||||||
|
|
||||||
EXPECT_EQ(6.0, std::get<1>(values[4]));
|
|
||||||
EXPECT_EQ(6.0, std::get<2>(values[4]));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
TEST(RimWellLogExtractionCurveImplTest, ExtractIntervalsWithSameTimeStepsOneComplete)
|
|
||||||
{
|
|
||||||
std::vector<double> valuesA { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
|
|
||||||
std::vector<double> valuesB { 10, 20, 30, HUGE_VAL, 50, HUGE_VAL, 70 };
|
|
||||||
|
|
||||||
EXPECT_EQ(valuesA.size(), valuesB.size());
|
|
||||||
|
|
||||||
std::vector<int> days(7);
|
|
||||||
std::iota(days.begin(), days.end(), 10);
|
|
||||||
|
|
||||||
QDateTime startDate;
|
|
||||||
|
|
||||||
std::vector<QDateTime> timeSteps;
|
|
||||||
for (const auto& day : days)
|
|
||||||
{
|
|
||||||
timeSteps.push_back(startDate.addDays(day));
|
|
||||||
}
|
|
||||||
|
|
||||||
RigCurveDataInterpolationTools interpolate(valuesA, timeSteps, valuesB, timeSteps);
|
|
||||||
|
|
||||||
auto values = interpolate.interpolatedCurveData();
|
|
||||||
auto intervals = interpolate.validIntervals();
|
|
||||||
|
|
||||||
EXPECT_EQ(5, static_cast<int>(values.size()));
|
|
||||||
EXPECT_EQ(3, static_cast<int>(intervals.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
TEST(RimWellLogExtractionCurveImplTest, ExtractIntervalsWithSameTimeStepsBothComplete)
|
|
||||||
{
|
|
||||||
std::vector<double> valuesA{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };
|
|
||||||
std::vector<double> valuesB{ 10, 20, 30, 40, 50, 60, 70 };
|
|
||||||
|
|
||||||
EXPECT_EQ(valuesA.size(), valuesB.size());
|
|
||||||
|
|
||||||
std::vector<int> days(7);
|
|
||||||
std::iota(days.begin(), days.end(), 10);
|
|
||||||
|
|
||||||
QDateTime startDate;
|
|
||||||
|
|
||||||
std::vector<QDateTime> timeSteps;
|
|
||||||
for (const auto& day : days)
|
|
||||||
{
|
|
||||||
timeSteps.push_back(startDate.addDays(day));
|
|
||||||
}
|
|
||||||
|
|
||||||
RigCurveDataInterpolationTools interpolate(valuesA, timeSteps, valuesB, timeSteps);
|
|
||||||
|
|
||||||
auto values = interpolate.interpolatedCurveData();
|
|
||||||
auto intervals = interpolate.validIntervals();
|
|
||||||
|
|
||||||
EXPECT_EQ(7, static_cast<int>(values.size()));
|
|
||||||
EXPECT_EQ(1, static_cast<int>(intervals.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
///
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
|
||||||
TEST(RimWellLogExtractionCurveImplTest, OverlappintTimes)
|
|
||||||
{
|
|
||||||
std::vector<double> valuesA{ 1, 2, 3, 4, 5 };
|
|
||||||
std::vector<double> valuesB{ 10, 20, 30, 40, 50 };
|
|
||||||
|
|
||||||
EXPECT_EQ(valuesA.size(), valuesB.size());
|
|
||||||
|
|
||||||
std::vector<int> daysA{ 0, 10, 11, 15, 20 };
|
|
||||||
std::vector<int> daysB{ 1, 2, 3, 5, 7 };
|
|
||||||
|
|
||||||
QDateTime startDate;
|
|
||||||
|
|
||||||
std::vector<QDateTime> timeStepsA;
|
|
||||||
for (const auto& day : daysA)
|
|
||||||
{
|
|
||||||
timeStepsA.push_back(startDate.addDays(day));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<QDateTime> timeStepsB;
|
|
||||||
for (const auto& day : daysB)
|
|
||||||
{
|
|
||||||
timeStepsB.push_back(startDate.addDays(day));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RigCurveDataInterpolationTools interpolate(valuesA, timeStepsA, valuesB, timeStepsB);
|
|
||||||
|
|
||||||
auto values = interpolate.interpolatedCurveData();
|
|
||||||
auto intervals = interpolate.validIntervals();
|
|
||||||
|
|
||||||
EXPECT_EQ(5, static_cast<int>(values.size()));
|
|
||||||
EXPECT_EQ(1, static_cast<int>(intervals.size()));
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user