mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
196 lines
7.1 KiB
C++
196 lines
7.1 KiB
C++
|
/////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (C) 2021 Equinor 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 "RiaWellLogCurveMerger.h"
|
||
|
|
||
|
#include "RiaCurveMerger.h"
|
||
|
|
||
|
#include <algorithm>
|
||
|
#include <cmath>
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
RiaWellLogCurveMerger::RiaWellLogCurveMerger()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
void RiaWellLogCurveMerger::addCurveData( const std::vector<double>& xValues, const std::vector<double>& yValues )
|
||
|
{
|
||
|
CVF_ASSERT( xValues.size() == yValues.size() );
|
||
|
|
||
|
if ( !xValues.empty() )
|
||
|
{
|
||
|
m_originalValues.push_back( std::make_pair( xValues, yValues ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
size_t RiaWellLogCurveMerger::curveCount() const
|
||
|
{
|
||
|
return m_lookupValuesForAllCurves.size();
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
RiaCurveDataTools::CurveIntervals RiaWellLogCurveMerger::validIntervalsForAllXValues() const
|
||
|
{
|
||
|
return m_validIntervalsForAllXValues;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
const std::vector<double>& RiaWellLogCurveMerger::allXValues() const
|
||
|
{
|
||
|
return m_allXValues;
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
const std::vector<double>& RiaWellLogCurveMerger::lookupYValuesForAllXValues( size_t curveIdx ) const
|
||
|
{
|
||
|
CVF_ASSERT( curveIdx < m_lookupValuesForAllCurves.size() );
|
||
|
|
||
|
return m_lookupValuesForAllCurves[curveIdx];
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
void RiaWellLogCurveMerger::computeLookupValues( bool includeValuesFromPartialCurves )
|
||
|
{
|
||
|
m_validIntervalsForAllXValues.clear();
|
||
|
m_allXValues.clear();
|
||
|
m_lookupValuesForAllCurves.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_lookupValuesForAllCurves.resize( curveCount );
|
||
|
|
||
|
std::vector<double> accumulatedValidValues( dataValueCount, 1.0 );
|
||
|
|
||
|
for ( size_t curveIdx = 0; curveIdx < curveCount; curveIdx++ )
|
||
|
{
|
||
|
std::vector<double>& curveValues = m_lookupValuesForAllCurves[curveIdx];
|
||
|
curveValues.resize( dataValueCount );
|
||
|
|
||
|
for ( size_t valueIndex = 0; valueIndex < dataValueCount; valueIndex++ )
|
||
|
{
|
||
|
double interpolValue = lookupYValue( 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 );
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
|
||
|
void RiaWellLogCurveMerger::computeUnionOfXValues( bool includeValuesForPartialCurves )
|
||
|
{
|
||
|
m_allXValues.clear();
|
||
|
|
||
|
std::set<double, XValueComparator<double>> unionOfXValues;
|
||
|
|
||
|
std::vector<std::pair<double, double>> originalXBounds;
|
||
|
for ( const auto& curveData : m_originalValues )
|
||
|
{
|
||
|
if ( curveData.first.empty() ) continue;
|
||
|
|
||
|
// Well log data has top and bottom depth for each zone
|
||
|
// Find the mid point in the zone to
|
||
|
const std::vector<double>& xValues = curveData.first;
|
||
|
for ( size_t i = 0; i < xValues.size(); i += 2 )
|
||
|
{
|
||
|
if ( i + 1 < xValues.size() )
|
||
|
{
|
||
|
double top = xValues.at( i );
|
||
|
double bottom = xValues.at( i + 1 );
|
||
|
double mid = ( top + bottom ) / 2.0;
|
||
|
unionOfXValues.insert( mid );
|
||
|
}
|
||
|
}
|
||
|
auto minmax_it = std::minmax_element( curveData.first.begin(), curveData.first.end() );
|
||
|
originalXBounds.push_back( std::make_pair( *( minmax_it.first ), *( minmax_it.second ) ) );
|
||
|
}
|
||
|
|
||
|
if ( !includeValuesForPartialCurves )
|
||
|
RiaCurveMerger<double>::removeValuesForPartialCurves( unionOfXValues, originalXBounds );
|
||
|
|
||
|
m_allXValues = std::vector<double>( unionOfXValues.begin(), unionOfXValues.end() );
|
||
|
}
|
||
|
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
///
|
||
|
//--------------------------------------------------------------------------------------------------
|
||
|
double RiaWellLogCurveMerger::lookupYValue( const double& interpolationXValue,
|
||
|
const std::vector<double>& xValues,
|
||
|
const std::vector<double>& yValues )
|
||
|
{
|
||
|
if ( yValues.size() != xValues.size() ) return HUGE_VAL;
|
||
|
|
||
|
const bool removeInterpolatedValues = false;
|
||
|
|
||
|
if ( interpolationXValue < xValues[0] ) return HUGE_VAL;
|
||
|
|
||
|
for ( size_t firstI = 0; firstI < xValues.size(); firstI++ )
|
||
|
{
|
||
|
if ( xValues.at( firstI ) >= interpolationXValue )
|
||
|
{
|
||
|
double firstValue = yValues.at( firstI );
|
||
|
if ( !RiaCurveDataTools::isValidValue( firstValue, removeInterpolatedValues ) )
|
||
|
{
|
||
|
return HUGE_VAL;
|
||
|
}
|
||
|
|
||
|
return firstValue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return HUGE_VAL;
|
||
|
}
|