mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#11895 Always show Oil Saturation as available
If no SOIL is found on file, compute based on available SWAT and SGAS.
This commit is contained in:
parent
e0878fb691
commit
06fb3e1241
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "RiaLogging.h"
|
#include "RiaLogging.h"
|
||||||
#include "RiaQDateTimeTools.h"
|
#include "RiaQDateTimeTools.h"
|
||||||
|
#include "RiaResultNames.h"
|
||||||
#include "RiaRftDefines.h"
|
#include "RiaRftDefines.h"
|
||||||
#include "RiaStdStringTools.h"
|
#include "RiaStdStringTools.h"
|
||||||
|
|
||||||
@ -138,7 +139,43 @@ void RifReaderOpmRft::values( const RifEclipseRftAddress& rftAddress, std::vecto
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::vector<float> data = resultAsFloat( resultName, wellName, y, m, d );
|
std::vector<float> data;
|
||||||
|
|
||||||
|
if ( rftAddress.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SOIL &&
|
||||||
|
!isNativeResultAvailable( RiaResultNames::soil().toStdString(), wellName, y, m, d ) )
|
||||||
|
{
|
||||||
|
// Compute SOIL from SWAT and SGAS
|
||||||
|
// There is a similar function in RigSoilResultCalculator, but they are too different to be merged
|
||||||
|
auto computeSoil = [&]( const std::string& wellName, int y, int m, int d ) -> std::vector<float>
|
||||||
|
{
|
||||||
|
auto swat = resultAsFloat( RiaResultNames::swat().toStdString(), wellName, y, m, d );
|
||||||
|
auto sgas = resultAsFloat( RiaResultNames::sgas().toStdString(), wellName, y, m, d );
|
||||||
|
|
||||||
|
auto maxItems = std::max( swat.size(), sgas.size() );
|
||||||
|
std::vector<float> data( maxItems, 1.0f );
|
||||||
|
|
||||||
|
for ( size_t i = 0; i < maxItems; ++i )
|
||||||
|
{
|
||||||
|
if ( i < swat.size() )
|
||||||
|
{
|
||||||
|
data[i] -= swat[i];
|
||||||
|
}
|
||||||
|
if ( i < sgas.size() )
|
||||||
|
{
|
||||||
|
data[i] -= sgas[i];
|
||||||
|
}
|
||||||
|
data[i] = std::clamp( data[i], 0.0f, 1.0f );
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
data = computeSoil( wellName, y, m, d );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = resultAsFloat( resultName, wellName, y, m, d );
|
||||||
|
}
|
||||||
|
|
||||||
if ( !data.empty() )
|
if ( !data.empty() )
|
||||||
{
|
{
|
||||||
@ -241,6 +278,17 @@ std::set<QDateTime> RifReaderOpmRft::availableTimeSteps( const QString&
|
|||||||
timeSteps.insert( address.timeStep() );
|
timeSteps.insert( address.timeStep() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( timeSteps.empty() && wellLogChannelName == RifEclipseRftAddress::RftWellLogChannelType::SOIL )
|
||||||
|
{
|
||||||
|
auto sgasTimeSteps = availableTimeSteps( wellName, RifEclipseRftAddress::RftWellLogChannelType::SGAS );
|
||||||
|
auto swatTimeSteps = availableTimeSteps( wellName, RifEclipseRftAddress::RftWellLogChannelType::SWAT );
|
||||||
|
|
||||||
|
// Combine time steps from SGAS and SWAT
|
||||||
|
timeSteps.insert( sgasTimeSteps.begin(), sgasTimeSteps.end() );
|
||||||
|
timeSteps.insert( swatTimeSteps.begin(), swatTimeSteps.end() );
|
||||||
|
}
|
||||||
|
|
||||||
return timeSteps;
|
return timeSteps;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +329,13 @@ std::set<RifEclipseRftAddress::RftWellLogChannelType> RifReaderOpmRft::available
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( types.contains( RifEclipseRftAddress::RftWellLogChannelType::SWAT ) ||
|
||||||
|
types.contains( RifEclipseRftAddress::RftWellLogChannelType::SGAS ) )
|
||||||
|
{
|
||||||
|
// Add SOIL if SGAS or SWAT are available, SOIL can be computed from these
|
||||||
|
types.insert( RifEclipseRftAddress::RftWellLogChannelType::SOIL );
|
||||||
|
}
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,8 +528,8 @@ std::vector<RifReaderOpmRft::SegmentConnectionStartEnd>
|
|||||||
{
|
{
|
||||||
if ( !isFirstSegment && std::fabs( startMD[i] - endMD[i - 1] ) > 0.1 )
|
if ( !isFirstSegment && std::fabs( startMD[i] - endMD[i - 1] ) > 0.1 )
|
||||||
{
|
{
|
||||||
// Insert a segment representing the connection between the segments. Assign infinity as value to this segment
|
// Insert a segment representing the connection between the segments. Assign infinity as value to this
|
||||||
// to allow discontinuous plotting.
|
// segment to allow discontinuous plotting.
|
||||||
startEndValues.emplace_back( endMD[i - 1], startMD[i], false );
|
startEndValues.emplace_back( endMD[i - 1], startMD[i], false );
|
||||||
}
|
}
|
||||||
startEndValues.emplace_back( startMD[i], endMD[i], true );
|
startEndValues.emplace_back( startMD[i], endMD[i], true );
|
||||||
@ -1081,13 +1136,14 @@ RifEclipseRftAddress::RftWellLogChannelType RifReaderOpmRft::identifyChannelType
|
|||||||
{
|
{
|
||||||
if ( resultName == "DEPTH" ) return RifEclipseRftAddress::RftWellLogChannelType::TVD;
|
if ( resultName == "DEPTH" ) return RifEclipseRftAddress::RftWellLogChannelType::TVD;
|
||||||
if ( resultName == "PRESSURE" ) return RifEclipseRftAddress::RftWellLogChannelType::PRESSURE;
|
if ( resultName == "PRESSURE" ) return RifEclipseRftAddress::RftWellLogChannelType::PRESSURE;
|
||||||
if ( resultName == "SWAT" ) return RifEclipseRftAddress::RftWellLogChannelType::SWAT;
|
|
||||||
if ( resultName == "SOIL" ) return RifEclipseRftAddress::RftWellLogChannelType::SOIL;
|
|
||||||
if ( resultName == "SGAS" ) return RifEclipseRftAddress::RftWellLogChannelType::SGAS;
|
|
||||||
if ( resultName == "WRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::WRAT;
|
if ( resultName == "WRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::WRAT;
|
||||||
if ( resultName == "ORAT" ) return RifEclipseRftAddress::RftWellLogChannelType::ORAT;
|
if ( resultName == "ORAT" ) return RifEclipseRftAddress::RftWellLogChannelType::ORAT;
|
||||||
if ( resultName == "GRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::GRAT;
|
if ( resultName == "GRAT" ) return RifEclipseRftAddress::RftWellLogChannelType::GRAT;
|
||||||
|
|
||||||
|
if ( resultName == RiaResultNames::swat().toStdString() ) return RifEclipseRftAddress::RftWellLogChannelType::SWAT;
|
||||||
|
if ( resultName == RiaResultNames::soil().toStdString() ) return RifEclipseRftAddress::RftWellLogChannelType::SOIL;
|
||||||
|
if ( resultName == RiaResultNames::sgas().toStdString() ) return RifEclipseRftAddress::RftWellLogChannelType::SGAS;
|
||||||
|
|
||||||
return RifEclipseRftAddress::RftWellLogChannelType::NONE;
|
return RifEclipseRftAddress::RftWellLogChannelType::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,13 +1154,14 @@ std::string RifReaderOpmRft::resultNameFromChannelType( RifEclipseRftAddress::Rf
|
|||||||
{
|
{
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::TVD ) return "DEPTH";
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::TVD ) return "DEPTH";
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) return "PRESSURE";
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) return "PRESSURE";
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SWAT ) return "SWAT";
|
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SOIL ) return "SOIL";
|
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SGAS ) return "SGAS";
|
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::WRAT ) return "WRAT";
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::WRAT ) return "WRAT";
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::ORAT ) return "ORAT";
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::ORAT ) return "ORAT";
|
||||||
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::GRAT ) return "GRAT";
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::GRAT ) return "GRAT";
|
||||||
|
|
||||||
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SWAT ) return RiaResultNames::swat().toStdString();
|
||||||
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SOIL ) return RiaResultNames::soil().toStdString();
|
||||||
|
if ( channelType == RifEclipseRftAddress::RftWellLogChannelType::SGAS ) return RiaResultNames::sgas().toStdString();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1145,6 +1202,22 @@ std::vector<float> RifReaderOpmRft::resultAsFloat( const std::string& resultName
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
bool RifReaderOpmRft::isNativeResultAvailable( const std::string& resultName, const std::string& wellName, int year, int month, int day ) const
|
||||||
|
{
|
||||||
|
if ( !m_opm_rft ) return false;
|
||||||
|
|
||||||
|
auto results = m_opm_rft->listOfRftArrays( wellName, year, month, day );
|
||||||
|
for ( const auto& [name, arrayType, size] : results )
|
||||||
|
{
|
||||||
|
if ( resultName == name ) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
@ -87,6 +87,7 @@ private:
|
|||||||
static std::string resultNameFromChannelType( RifEclipseRftAddress::RftWellLogChannelType channelType );
|
static std::string resultNameFromChannelType( RifEclipseRftAddress::RftWellLogChannelType channelType );
|
||||||
|
|
||||||
std::vector<float> resultAsFloat( const std::string& resultName, const std::string& wellName, int year, int month, int day ) const;
|
std::vector<float> resultAsFloat( const std::string& resultName, const std::string& wellName, int year, int month, int day ) const;
|
||||||
|
bool isNativeResultAvailable( const std::string& resultName, const std::string& wellName, int year, int month, int day ) const;
|
||||||
|
|
||||||
bool openFiles();
|
bool openFiles();
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ bool RigSoilResultCalculator::isMatching( const RigEclipseResultAddress& resVarA
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
void RigSoilResultCalculator::calculate( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex )
|
void RigSoilResultCalculator::calculate( const RigEclipseResultAddress& resVarAddr, size_t timeStepIndex )
|
||||||
{
|
{
|
||||||
|
// See similar function in RifReaderOpmRft::values, but the current implementation is not suitable for merging
|
||||||
// Compute SGAS based on SWAT if the simulation contains no oil
|
// Compute SGAS based on SWAT if the simulation contains no oil
|
||||||
m_resultsData->testAndComputeSgasForTimeStep( timeStepIndex );
|
m_resultsData->testAndComputeSgasForTimeStep( timeStepIndex );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user