mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#4580 Import Eclipse RFT data as part of ensemble import
This commit is contained in:
@@ -1,52 +1,69 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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>
|
||||
//
|
||||
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RiaRftPltCurveDefinition.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaRftPltCurveDefinition::RiaRftPltCurveDefinition(RifDataSourceForRftPlt address, const QDateTime timeStep)
|
||||
RiaRftPltCurveDefinition::RiaRftPltCurveDefinition(const RifDataSourceForRftPlt& address, const QString& wellName, const QDateTime& timeStep)
|
||||
: m_curveAddress(address)
|
||||
, m_wellName(wellName)
|
||||
, m_timeStep(timeStep)
|
||||
{
|
||||
m_curveDefinition = std::make_pair(address, timeStep);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifDataSourceForRftPlt RiaRftPltCurveDefinition::address() const
|
||||
const RifDataSourceForRftPlt& RiaRftPltCurveDefinition::address() const
|
||||
{
|
||||
return m_curveDefinition.first;
|
||||
return m_curveAddress;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QDateTime RiaRftPltCurveDefinition::timeStep() const
|
||||
const QString& RiaRftPltCurveDefinition::wellName() const
|
||||
{
|
||||
return m_curveDefinition.second;
|
||||
return m_wellName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const QDateTime& RiaRftPltCurveDefinition::timeStep() const
|
||||
{
|
||||
return m_timeStep;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RiaRftPltCurveDefinition::operator<(const RiaRftPltCurveDefinition& other) const
|
||||
{
|
||||
return m_curveDefinition < other.m_curveDefinition;
|
||||
if (m_curveAddress == other.m_curveAddress)
|
||||
{
|
||||
if (m_wellName == other.m_wellName)
|
||||
{
|
||||
return m_timeStep < other.m_timeStep;
|
||||
}
|
||||
return m_wellName < other.m_wellName;
|
||||
}
|
||||
return m_curveAddress < other.m_curveAddress;
|
||||
}
|
||||
|
||||
@@ -33,13 +33,16 @@ class RimSummaryCase;
|
||||
class RiaRftPltCurveDefinition
|
||||
{
|
||||
public:
|
||||
explicit RiaRftPltCurveDefinition(RifDataSourceForRftPlt address, const QDateTime timeStep);
|
||||
explicit RiaRftPltCurveDefinition(const RifDataSourceForRftPlt& address, const QString& wellName, const QDateTime& timeStep);
|
||||
|
||||
RifDataSourceForRftPlt address() const;
|
||||
QDateTime timeStep() const;
|
||||
const RifDataSourceForRftPlt& address() const;
|
||||
const QString& wellName() const;
|
||||
const QDateTime& timeStep() const;
|
||||
|
||||
bool operator < (const RiaRftPltCurveDefinition& other) const;
|
||||
|
||||
private:
|
||||
std::pair<RifDataSourceForRftPlt, QDateTime> m_curveDefinition;
|
||||
RifDataSourceForRftPlt m_curveAddress;
|
||||
QString m_wellName;
|
||||
QDateTime m_timeStep;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaExtractionTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaFilePathTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveMerger.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveMerger.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveMerger.inl
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveDataTools.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveResampler.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaStatisticsTools.h
|
||||
@@ -67,7 +68,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RiaTextFileCompare.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaRegressionTestRunner.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaExtractionTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaFilePathTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveMerger.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveMerger.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaCurveDataTools.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaTimeHistoryCurveResampler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiaStatisticsTools.cpp
|
||||
|
||||
@@ -142,6 +142,21 @@ cvf::Color3f RiaColorTools::fromQColorTo3f(QColor color)
|
||||
return cvf::Color3f(color.redF(), color.greenF(), color.blueF());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RiaColorTools::blendCvfColors(const cvf::Color3f& color1,
|
||||
const cvf::Color3f& color2,
|
||||
int weight1 /*= 1*/,
|
||||
int weight2 /*= 1*/)
|
||||
{
|
||||
CVF_ASSERT(weight1 > 0 && weight2 > 0);
|
||||
int weightsum = weight1 + weight2;
|
||||
return cvf::Color3f((color1.r() * weight1 + color2.r() * weight2) / weightsum,
|
||||
(color1.g() * weight1 + color2.g() * weight2) / weightsum,
|
||||
(color1.b() * weight1 + color2.b() * weight2) / weightsum);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -43,7 +43,8 @@ public:
|
||||
static QColor toQColor(cvf::Color4f color);
|
||||
static cvf::Color3f fromQColorTo3f(QColor);
|
||||
|
||||
static QColor blendQColors(const QColor& color1, const QColor& color2, int weight1 = 1, int weight2 = 1);
|
||||
static cvf::Color3f blendCvfColors(const cvf::Color3f& color1, const cvf::Color3f& color2, int weight1 = 1, int weight2 = 1);
|
||||
static QColor blendQColors(const QColor& color1, const QColor& color2, int weight1 = 1, int weight2 = 1);
|
||||
|
||||
private:
|
||||
static float relativeLuminance(cvf::Color3f backgroundColor);
|
||||
|
||||
20
ApplicationCode/Application/Tools/RiaCurveMerger.cpp
Normal file
20
ApplicationCode/Application/Tools/RiaCurveMerger.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "RiaCurveMerger.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <time.h>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<>
|
||||
bool XValueComparator<double>::equals(const double& lhs, const double& rhs)
|
||||
{
|
||||
double eps = 1.0e-12 * std::max(std::fabs(lhs), std::fabs(rhs));
|
||||
return std::fabs(lhs - rhs) < eps;
|
||||
}
|
||||
|
||||
template<>
|
||||
double XValueComparator<time_t>::diff(const time_t& lhs, const time_t& rhs)
|
||||
{
|
||||
return difftime(lhs, rhs);
|
||||
}
|
||||
87
ApplicationCode/Application/Tools/RiaCurveMerger.h
Normal file
87
ApplicationCode/Application/Tools/RiaCurveMerger.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiaCurveDataTools.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
template<typename XValueType>
|
||||
class XValueComparator
|
||||
{
|
||||
public:
|
||||
bool operator()(const XValueType& lhs, const XValueType& rhs) const;
|
||||
static bool equals(const XValueType& lhs, const XValueType& rhs);
|
||||
static double diff(const XValueType& lhs, const XValueType& rhs);
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
template<typename XValueType>
|
||||
class RiaCurveMerger
|
||||
{
|
||||
public:
|
||||
typedef XValueComparator<XValueType> XComparator;
|
||||
RiaCurveMerger();
|
||||
|
||||
|
||||
void addCurveData(const std::vector<XValueType>& xValues, const std::vector<double>& yValues);
|
||||
size_t curveCount() const;
|
||||
|
||||
void computeInterpolatedValues(bool includeValuesFromPartialCurves = true);
|
||||
|
||||
RiaCurveDataTools::CurveIntervals validIntervalsForAllXValues() const;
|
||||
const std::vector<XValueType>& allXValues() const;
|
||||
const std::vector<double>& interpolatedYValuesForAllXValues(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>& interpolatedYValuesForAllXValues(size_t curveIdx);
|
||||
|
||||
public:
|
||||
// Helper methods, available as public to be able to access from unit tests
|
||||
|
||||
static double interpolatedYValue(const XValueType& xValue,
|
||||
const std::vector<XValueType>& curveXValues,
|
||||
const std::vector<double>& curveYValues);
|
||||
|
||||
private:
|
||||
void computeUnionOfXValues(bool includeValuesFromPartialCurves);
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::vector<XValueType>, std::vector<double>>> m_originalValues;
|
||||
|
||||
RiaCurveDataTools::CurveIntervals m_validIntervalsForAllXValues;
|
||||
|
||||
std::vector<XValueType> m_allXValues;
|
||||
std::vector<std::vector<double>> m_interpolatedValuesForAllCurves;
|
||||
};
|
||||
|
||||
typedef RiaCurveMerger<time_t> RiaTimeHistoryCurveMerger;
|
||||
|
||||
template<>
|
||||
bool XValueComparator<double>::equals(const double& lhs, const double& rhs);
|
||||
template<>
|
||||
double XValueComparator<time_t>::diff(const time_t& lhs, const time_t& rhs);
|
||||
|
||||
#include "RiaCurveMerger.inl"
|
||||
286
ApplicationCode/Application/Tools/RiaCurveMerger.inl
Normal file
286
ApplicationCode/Application/Tools/RiaCurveMerger.inl
Normal file
@@ -0,0 +1,286 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 <algorithm>
|
||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
bool XValueComparator<XValueType>::operator()(const XValueType& lhs, const XValueType& rhs) const
|
||||
{
|
||||
if (XValueComparator<XValueType>::equals(lhs, rhs))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return lhs < rhs;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
double XValueComparator<XValueType>::diff(const XValueType& lhs, const XValueType& rhs)
|
||||
{
|
||||
return lhs - rhs;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
bool XValueComparator<XValueType>::equals(const XValueType& lhs, const XValueType& rhs)
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
RiaCurveMerger<XValueType>::RiaCurveMerger()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
void RiaCurveMerger<XValueType>::addCurveData(const std::vector<XValueType>& xValues, const std::vector<double>& yValues)
|
||||
{
|
||||
CVF_ASSERT(xValues.size() == yValues.size());
|
||||
|
||||
m_originalValues.push_back(std::make_pair(xValues, yValues));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
size_t RiaCurveMerger<XValueType>::curveCount() const
|
||||
{
|
||||
return m_interpolatedValuesForAllCurves.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
RiaCurveDataTools::CurveIntervals RiaCurveMerger<XValueType>::validIntervalsForAllXValues() const
|
||||
{
|
||||
return m_validIntervalsForAllXValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
const std::vector<XValueType>& RiaCurveMerger<XValueType>::allXValues() const
|
||||
{
|
||||
return m_allXValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
const std::vector<double>& RiaCurveMerger<XValueType>::interpolatedYValuesForAllXValues(size_t curveIdx) const
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
std::vector<double>& RiaCurveMerger<XValueType>::interpolatedYValuesForAllXValues(size_t curveIdx)
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
void RiaCurveMerger<XValueType>::computeInterpolatedValues(bool includeValuesFromPartialCurves)
|
||||
{
|
||||
m_validIntervalsForAllXValues.clear();
|
||||
m_allXValues.clear();
|
||||
m_interpolatedValuesForAllCurves.clear();
|
||||
|
||||
computeUnionOfXValues(includeValuesFromPartialCurves);
|
||||
|
||||
const size_t curveCount = m_originalValues.size();
|
||||
if (curveCount == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t dataValueCount = m_allXValues.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 = interpolatedYValue(m_allXValues[valueIndex], m_originalValues[curveIdx].first, m_originalValues[curveIdx].second);
|
||||
if (!RiaCurveDataTools::isValidValue(interpolValue, false))
|
||||
{
|
||||
accumulatedValidValues[valueIndex] = HUGE_VAL;
|
||||
}
|
||||
|
||||
curveValues[valueIndex] = interpolValue;
|
||||
}
|
||||
}
|
||||
|
||||
m_validIntervalsForAllXValues = RiaCurveDataTools::calculateIntervalsOfValidValues(accumulatedValidValues, false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
void RiaCurveMerger<XValueType>::computeUnionOfXValues(bool includeValuesForPartialCurves)
|
||||
{
|
||||
m_allXValues.clear();
|
||||
|
||||
std::set<XValueType, XComparator> unionOfXValues;
|
||||
|
||||
for (const auto& curveData : m_originalValues)
|
||||
{
|
||||
for (const auto& x : curveData.first)
|
||||
{
|
||||
unionOfXValues.insert(x);
|
||||
}
|
||||
}
|
||||
|
||||
if (!includeValuesForPartialCurves)
|
||||
{
|
||||
for (auto it = unionOfXValues.begin(); it != unionOfXValues.end();)
|
||||
{
|
||||
bool outsideBounds = false;
|
||||
for (const auto& curveData : m_originalValues)
|
||||
{
|
||||
if (curveData.first.empty()) continue;
|
||||
|
||||
if (*it < curveData.first.front() || *it > curveData.first.back())
|
||||
{
|
||||
outsideBounds = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outsideBounds)
|
||||
{
|
||||
it = unionOfXValues.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_allXValues = std::vector<XValueType>(unionOfXValues.begin(), unionOfXValues.end());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename XValueType>
|
||||
double RiaCurveMerger<XValueType>::interpolatedYValue(const XValueType& interpolationXValue,
|
||||
const std::vector<XValueType>& xValues,
|
||||
const std::vector<double>& yValues)
|
||||
{
|
||||
if (yValues.size() != xValues.size()) return HUGE_VAL;
|
||||
|
||||
const bool removeInterpolatedValues = false;
|
||||
|
||||
for (size_t firstI = 0; firstI < xValues.size(); firstI++)
|
||||
{
|
||||
if (XComparator::equals(xValues.at(firstI), interpolationXValue))
|
||||
{
|
||||
const double& firstValue = yValues.at(firstI);
|
||||
if (!RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues))
|
||||
{
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
return firstValue;
|
||||
}
|
||||
|
||||
size_t secondI = firstI + 1;
|
||||
|
||||
if (secondI < xValues.size())
|
||||
{
|
||||
if (XComparator::equals(xValues.at(secondI), interpolationXValue))
|
||||
{
|
||||
const double& secondValue = yValues.at(secondI);
|
||||
if (!RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues))
|
||||
{
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
if (xValues.at(firstI) < interpolationXValue && xValues.at(secondI) > interpolationXValue)
|
||||
{
|
||||
const double& firstValue = yValues.at(firstI);
|
||||
const double& secondValue = yValues.at(secondI);
|
||||
|
||||
bool isFirstValid = RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues);
|
||||
if (!isFirstValid) return HUGE_VAL;
|
||||
|
||||
bool isSecondValid = RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues);
|
||||
if (!isSecondValid) return HUGE_VAL;
|
||||
|
||||
double firstDiff = fabs(XComparator::diff(interpolationXValue, xValues.at(firstI)));
|
||||
double secondDiff = fabs(XComparator::diff(xValues.at(secondI), interpolationXValue));
|
||||
|
||||
double firstWeight = secondDiff / (firstDiff + secondDiff);
|
||||
double secondWeight = firstDiff / (firstDiff + secondDiff);
|
||||
|
||||
double val = (firstValue * firstWeight) + (secondValue * secondWeight);
|
||||
|
||||
CVF_ASSERT(RiaCurveDataTools::isValidValue(val, removeInterpolatedValues));
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
|
||||
#include <cmath> // Needed for HUGE_VAL on Linux
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaTimeHistoryCurveMerger::RiaTimeHistoryCurveMerger()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaTimeHistoryCurveMerger::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));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaCurveDataTools::CurveIntervals RiaTimeHistoryCurveMerger::validIntervalsForAllTimeSteps() const
|
||||
{
|
||||
return m_validIntervalsForAllTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<time_t>& RiaTimeHistoryCurveMerger::allTimeSteps() const
|
||||
{
|
||||
return m_allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<double>& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx) const
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double>& RiaTimeHistoryCurveMerger::interpolatedCurveValuesForAllTimeSteps(size_t curveIdx)
|
||||
{
|
||||
CVF_ASSERT(curveIdx < m_interpolatedValuesForAllCurves.size());
|
||||
|
||||
return m_interpolatedValuesForAllCurves[curveIdx];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaTimeHistoryCurveMerger::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 (!RiaCurveDataTools::isValidValue(interpolValue, false))
|
||||
{
|
||||
accumulatedValidValues[valueIndex] = HUGE_VAL;
|
||||
}
|
||||
|
||||
curveValues[valueIndex] = interpolValue;
|
||||
}
|
||||
}
|
||||
|
||||
m_validIntervalsForAllTimeSteps = RiaCurveDataTools::calculateIntervalsOfValidValues(accumulatedValidValues, false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaTimeHistoryCurveMerger::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 RiaTimeHistoryCurveMerger::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 (!RiaCurveDataTools::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 (!RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues))
|
||||
{
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
return secondValue;
|
||||
}
|
||||
|
||||
const double& firstValue = curveValues.at(firstI);
|
||||
const double& secondValue = curveValues.at(secondI);
|
||||
|
||||
bool isFirstValid = RiaCurveDataTools::isValidValue(firstValue, removeInterpolatedValues);
|
||||
if (!isFirstValid) return HUGE_VAL;
|
||||
|
||||
bool isSecondValid = RiaCurveDataTools::isValidValue(secondValue, removeInterpolatedValues);
|
||||
if (!isSecondValid) return HUGE_VAL;
|
||||
|
||||
double firstDiff = fabs(difftime(interpolationTimeStep, curveTimeSteps.at(firstI)));
|
||||
double secondDiff = fabs(difftime(curveTimeSteps.at(secondI), interpolationTimeStep));
|
||||
|
||||
double firstWeight = secondDiff / (firstDiff + secondDiff);
|
||||
double secondWeight = firstDiff / (firstDiff + secondDiff);
|
||||
|
||||
double val = (firstValue * firstWeight) + (secondValue * secondWeight);
|
||||
|
||||
CVF_ASSERT(RiaCurveDataTools::isValidValue(val, removeInterpolatedValues));
|
||||
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
return HUGE_VAL;
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiaCurveDataTools.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RiaTimeHistoryCurveMerger
|
||||
{
|
||||
public:
|
||||
RiaTimeHistoryCurveMerger();
|
||||
|
||||
|
||||
void addCurveData(const std::vector<double>& values,
|
||||
const std::vector<time_t>& timeSteps);
|
||||
|
||||
void computeInterpolatedValues();
|
||||
|
||||
RiaCurveDataTools::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;
|
||||
|
||||
RiaCurveDataTools::CurveIntervals m_validIntervalsForAllTimeSteps;
|
||||
|
||||
std::vector<time_t> m_allTimeSteps;
|
||||
std::vector<std::vector<double>> m_interpolatedValuesForAllCurves;
|
||||
};
|
||||
Reference in New Issue
Block a user