mirror of
https://github.com/OPM/ResInsight.git
synced 2025-01-08 23:23:01 -06:00
196 lines
8.5 KiB
C++
196 lines
8.5 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 "RimStimPlanModelPressureCalculator.h"
|
|
|
|
#include "RiaDefines.h"
|
|
#include "RiaInterpolationTools.h"
|
|
#include "RiaStimPlanModelDefines.h"
|
|
|
|
#include "RimStimPlanModel.h"
|
|
#include "RimStimPlanModelCalculator.h"
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimStimPlanModelPressureCalculator::RimStimPlanModelPressureCalculator( RimStimPlanModelCalculator* stimPlanModelCalculator )
|
|
: RimStimPlanModelWellLogCalculator( stimPlanModelCalculator )
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimStimPlanModelPressureCalculator::isMatching( RiaDefines::CurveProperty curveProperty ) const
|
|
{
|
|
std::vector<RiaDefines::CurveProperty> matching = {
|
|
RiaDefines::CurveProperty::INITIAL_PRESSURE,
|
|
RiaDefines::CurveProperty::PRESSURE,
|
|
};
|
|
|
|
return std::find( matching.begin(), matching.end(), curveProperty ) != matching.end();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
size_t findFirstIndex( double depth, const std::vector<double>& depths )
|
|
{
|
|
if ( !depths.empty() )
|
|
{
|
|
for ( size_t i = 0; i < depths.size(); i++ )
|
|
if ( depths[i] > depth ) return i - 1;
|
|
}
|
|
|
|
// Not found
|
|
return depths.size();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
size_t findLastIndex( double depth, const std::vector<double>& depths, size_t firstIndex )
|
|
{
|
|
if ( !depths.empty() )
|
|
{
|
|
for ( size_t i = firstIndex; i < depths.size(); i++ )
|
|
if ( depths[i] >= depth ) return i;
|
|
}
|
|
|
|
// Not found
|
|
return depths.size();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::pair<size_t, size_t> findIndex( double depth, const std::vector<double>& depths )
|
|
{
|
|
size_t firstIndex = findFirstIndex( depth, depths );
|
|
size_t lastIndex = findLastIndex( depth, depths, firstIndex );
|
|
return std::make_pair( firstIndex, lastIndex );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimStimPlanModelPressureCalculator::extractValuesForProperty( RiaDefines::CurveProperty curveProperty,
|
|
const RimStimPlanModel* stimPlanModel,
|
|
int timeStep,
|
|
std::vector<double>& values,
|
|
std::vector<double>& measuredDepthValues,
|
|
std::vector<double>& tvDepthValues,
|
|
double& rkbDiff ) const
|
|
{
|
|
// Get depth from the static eclipse case
|
|
std::vector<double> staticTvDepthValues;
|
|
std::vector<double> staticMeasuredDepthValues;
|
|
|
|
{
|
|
std::vector<double> dummyValues;
|
|
double dummyRkbDiff;
|
|
if ( !RimStimPlanModelWellLogCalculator::extractValuesForProperty( RiaDefines::CurveProperty::POROSITY_UNSCALED,
|
|
stimPlanModel,
|
|
timeStep,
|
|
dummyValues,
|
|
staticMeasuredDepthValues,
|
|
staticTvDepthValues,
|
|
dummyRkbDiff ) )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Extract the property we care about
|
|
RimStimPlanModelWellLogCalculator::extractValuesForProperty( curveProperty,
|
|
stimPlanModel,
|
|
timeStep,
|
|
values,
|
|
measuredDepthValues,
|
|
tvDepthValues,
|
|
rkbDiff );
|
|
|
|
if ( staticTvDepthValues.size() != tvDepthValues.size() )
|
|
{
|
|
// Populate the original tvds/mds with interpolated values
|
|
std::vector<double> tvds;
|
|
std::vector<double> mds;
|
|
std::vector<double> results;
|
|
|
|
double prevEndIndex = 0;
|
|
for ( size_t i = 0; i < staticTvDepthValues.size(); i++ )
|
|
{
|
|
double tvd = staticTvDepthValues[i];
|
|
double md = staticMeasuredDepthValues[i];
|
|
|
|
// Find value before and after this depth in the static data
|
|
auto [startIndex, endIndex] = findIndex( md, measuredDepthValues );
|
|
double value = std::numeric_limits<double>::infinity();
|
|
|
|
if ( startIndex < values.size() && endIndex < values.size() )
|
|
{
|
|
double prevValue = values[startIndex];
|
|
double nextValue = values[endIndex];
|
|
|
|
if ( startIndex == endIndex )
|
|
{
|
|
const double delta = 0.001;
|
|
double prevMd = staticMeasuredDepthValues[i - 1];
|
|
double diffMd = std::fabs( prevMd - md );
|
|
if ( startIndex > prevEndIndex && diffMd > delta )
|
|
{
|
|
// Avoid skipping datapoints in the original data:
|
|
// this can happen when multiple point have same measured depth.
|
|
// Need to get the "stair step" look of the pressure data after interpolation.
|
|
value = values[prevEndIndex];
|
|
}
|
|
else
|
|
{
|
|
// Exact match: not need to interpolate
|
|
value = prevValue;
|
|
}
|
|
}
|
|
else if ( !std::isinf( prevValue ) && !std::isinf( nextValue ) )
|
|
{
|
|
// Interpolate a value for the given md
|
|
std::vector<double> xs = { measuredDepthValues[startIndex], md, measuredDepthValues[endIndex] };
|
|
std::vector<double> ys = { prevValue, std::numeric_limits<double>::infinity(), values[endIndex] };
|
|
RiaInterpolationTools::interpolateMissingValues( xs, ys );
|
|
value = ys[1];
|
|
}
|
|
|
|
prevEndIndex = endIndex;
|
|
}
|
|
else
|
|
{
|
|
// The last point is added without interpolation
|
|
value = values.back();
|
|
}
|
|
|
|
results.push_back( value );
|
|
tvds.push_back( tvd );
|
|
mds.push_back( md );
|
|
}
|
|
|
|
tvDepthValues = tvds;
|
|
measuredDepthValues = mds;
|
|
values = results;
|
|
}
|
|
|
|
return true;
|
|
}
|