Files
ResInsight/ApplicationLibCode/UnitTests/opm-summary-Test.cpp
T
Magne Sjaastad 9229e48191 #14964: Use correct depth unit when creating RFT plots
Read the summary unit system from SMSPEC INTEHEAD, and fall back to vector
units for ESMRY files without SMSPEC. The unit system is read on first
request to keep summary import fast. Ensembles use the same realization as
for addresses. New RFT plots get the depth unit from their data sources.
2026-10-19 14:15:55 +02:00

670 lines
27 KiB
C++

#include "gtest/gtest.h"
#include "RiaLogging.h"
#include "RiaRftDefines.h"
#include "RiaTestDataDirectory.h"
#include "RifEclipseSummaryAddress.h"
#include "RifEclipseSummaryTools.h"
#include "RifOpmCommonSummary.h"
#include "RifReaderEclipseSummary.h"
#include "RifReaderOpmRft.h"
#ifdef _MSC_VER
// Disable warning from external library to make sure treat warnings as error works
#pragma warning( disable : 4267 )
#endif
#include "opm/io/eclipse/EGrid.hpp"
#include "opm/io/eclipse/ERft.hpp"
#include "opm/io/eclipse/ESmry.hpp"
#include "opm/io/eclipse/ExtESmry.hpp"
#include <QDebug>
#include <QFile>
#include <QTemporaryDir>
#include <iomanip>
static const QString H5_TEST_DATA_DIRECTORY = QString( "%1/h5-file/" ).arg( TEST_DATA_DIR );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, DISABLED_PerformanceReadOfRestartFilename )
{
// 2024-11-14
// This test is intended to measure the performance of reading restart filenames from a summary file
// Both resdata and opm-common are used, and for some cases resdata is much slower than opm-common
//
// Performance comparison
// BRENT-PRED_IAM_NSA_F - 100 iterations
// opm-common: 10 ms
// resdata: 10000 ms
QString filePath = H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.SMSPEC";
filePath = "C:/gitroot/ResInsight-regression-test/ModelData/ensemble_reek_with_params/realization-7/iter-0/eclipse/model/"
"3_R001_REEK-7.SMSPEC";
filePath = "c:/gitroot/ResInsight-regression-test/ModelData/TestCase_MultiCaseStatistics/SIMPLE_R1.SMSPEC";
filePath = "f:/Models/equinor_azure/Sum_File/BRENT-PRED_IAM_NSA_F.SMSPEC";
const int N = 100;
auto startTime = RiaLogging::currentTime();
for ( int i = 0; i < N; i++ )
{
std::vector<QString> warnings;
auto restartFileInfos = RifEclipseSummaryTools::getRestartFileNames( filePath, warnings );
}
RiaLogging::logElapsedTime( "Completed opm-common", startTime );
auto startTime2 = RiaLogging::currentTime();
for ( int i = 0; i < N; i++ )
{
std::vector<QString> warnings;
auto restartFileInfos = RifEclipseSummaryTools::getRestartFileNames( filePath, warnings );
}
RiaLogging::logElapsedTime( "Completed resdata", startTime2 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, ReadOpmSummaryDataListContent )
{
std::vector<std::string> esmryKeywords;
{
QString filePath = H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.SMSPEC";
Opm::EclIO::ESmry eSmry( filePath.toStdString() );
esmryKeywords = eSmry.keywordList();
eSmry.make_esmry_file();
}
std::vector<std::string> extEsmryKeywords;
{
QString filePath = H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.ESMRY";
Opm::EclIO::ExtESmry extEsmry( filePath.toStdString() );
extEsmryKeywords = extEsmry.keywordList();
}
EXPECT_EQ( esmryKeywords.size(), extEsmryKeywords.size() );
for ( size_t i = 0; i < esmryKeywords.size(); i++ )
{
auto s1 = esmryKeywords[i];
auto s2 = extEsmryKeywords[i];
EXPECT_STREQ( s1.c_str(), s2.c_str() );
RifEclipseSummaryAddress eclAdr = RifEclipseSummaryAddress::fromEclipseTextAddressParseErrorTokens( s1 );
EXPECT_TRUE( eclAdr.isValid() );
}
}
//--------------------------------------------------------------------------------------------------
/// For ensembles, RimSummaryEnsemble::ensembleSummaryAddresses() only builds the address-to-keyword
/// map (by calling createAndSetAddresses()) for the realization with the most keywords, for
/// performance reasons. For all other realizations, RifOpmCommonEclipseSummary::values() has to
/// reconstruct the keyword text for a given address without having built that map.
///
/// This must work for region-to-region addresses (e.g. RGFT:1-2) using the standard (non-ESMRY)
/// opm-common reader, matching the "R1-R2" (no spaces) keyword format used by opm-common. Using
/// RifEclipseSummaryAddress::toEclipseTextAddress() directly is not correct here, as it formats
/// region-to-region addresses with spaces ("R1 - R2") for UI display purposes.
///
/// See https://github.com/OPM/ResInsight/issues/14853
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, ReadRegionToRegionValuesWithoutPrebuiltAddressMap )
{
QString filePath = H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.SMSPEC";
// Reader with addresses built, used to obtain a valid region-to-region address and reference values.
RifOpmCommonEclipseSummary readerWithAddresses;
readerWithAddresses.useEnhancedSummaryFiles( false );
readerWithAddresses.createEnhancedSummaryFiles( false );
ASSERT_TRUE( readerWithAddresses.open( filePath, false, nullptr ) );
readerWithAddresses.createAddressesIfRequired();
RifEclipseSummaryAddress regionToRegionAddress;
for ( const auto& adr : readerWithAddresses.allResultAddresses() )
{
if ( adr.category() == RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_REGION_2_REGION )
{
regionToRegionAddress = adr;
break;
}
}
ASSERT_TRUE( regionToRegionAddress.isValid() );
auto [referenceOk, referenceValues] = readerWithAddresses.values( regionToRegionAddress );
ASSERT_TRUE( referenceOk );
ASSERT_FALSE( referenceValues.empty() );
// Reader for the same file, but createAndSetAddresses()/createAddressesIfRequired() is deliberately never
// called. This mirrors the state of a realization in an ensemble that was not selected to provide the
// ensemble's address list.
RifOpmCommonEclipseSummary readerWithoutAddresses;
readerWithoutAddresses.useEnhancedSummaryFiles( false );
readerWithoutAddresses.createEnhancedSummaryFiles( false );
ASSERT_TRUE( readerWithoutAddresses.open( filePath, false, nullptr ) );
auto [ok, values] = readerWithoutAddresses.values( regionToRegionAddress );
EXPECT_TRUE( ok );
ASSERT_EQ( referenceValues.size(), values.size() );
for ( size_t i = 0; i < values.size(); i++ )
{
EXPECT_DOUBLE_EQ( referenceValues[i], values[i] );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, ReadUnitSystem )
{
{
RifOpmCommonEclipseSummary reader;
reader.useEnhancedSummaryFiles( false );
reader.createEnhancedSummaryFiles( false );
ASSERT_TRUE( reader.open( H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.SMSPEC", false, nullptr ) );
EXPECT_EQ( RiaDefines::EclipseUnitSystem::UNITS_METRIC, reader.unitSystem() );
}
{
// ESMRY without SMSPEC, the unit system is derived from the vector units. Create the ESMRY file in a temporary folder, as the
// ESMRY file in the test data folder is rewritten by other tests.
QTemporaryDir tempDir;
ASSERT_TRUE( tempDir.isValid() );
const QString smspecFilePath = tempDir.filePath( "NORNE_ATW2013_RFTPLT_V2.SMSPEC" );
const QString unsmryFilePath = tempDir.filePath( "NORNE_ATW2013_RFTPLT_V2.UNSMRY" );
const QString esmryFilePath = tempDir.filePath( "NORNE_ATW2013_RFTPLT_V2.ESMRY" );
ASSERT_TRUE( QFile::copy( H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.SMSPEC", smspecFilePath ) );
ASSERT_TRUE( QFile::copy( H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.UNSMRY", unsmryFilePath ) );
{
Opm::EclIO::ESmry eSmry( smspecFilePath.toStdString() );
ASSERT_TRUE( eSmry.make_esmry_file() );
}
ASSERT_TRUE( QFile::remove( smspecFilePath ) );
ASSERT_TRUE( QFile::remove( unsmryFilePath ) );
RifOpmCommonEclipseSummary reader;
reader.useEnhancedSummaryFiles( true );
reader.createEnhancedSummaryFiles( false );
ASSERT_TRUE( reader.open( esmryFilePath, false, nullptr ) );
EXPECT_EQ( RiaDefines::EclipseUnitSystem::UNITS_METRIC, reader.unitSystem() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, DISABLED_OpmImportRftData )
{
std::vector<std::string> esmryKeywords;
{
// QString filePath = "e:/gitroot/opm-tests/model1/opm-simulation-reference/flow/MSW_MODEL_1.RFT";
// QString filePath = "e:/gitroot/opm-tests/norne/ECL.2014.2/NORNE_ATW2013.RFT";
// QString filePath = "d:/Models/Statoil/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT";
QString filePath = "e:/models/from_equinor_sftp/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT";
Opm::EclIO::ERft eRft( filePath.toStdString() );
auto wells = eRft.listOfWells();
auto dates = eRft.listOfdates();
auto reports = eRft.listOfRftReports();
std::cout << "\nWells:\n";
for ( const auto& w : wells )
{
std::cout << w << "\n";
}
std::cout << "\nDates:\n";
for ( const auto& date : dates )
{
auto [year, month, day] = date;
std::cout << year << ", " << month << ", " << day << "\n";
}
std::cout << "\nReports:\n";
for ( const auto& report : reports )
{
auto [text, date, floatValue] = report;
std::cout << text << ", " << floatValue << "\n";
}
std::cout << "\nRFT Arrays:\n";
for ( int i = 0; i < eRft.numberOfReports(); i++ )
{
std::cout << "\n";
auto results = eRft.listOfRftArrays( i );
for ( const auto& [name, arrayType, size] : results )
{
std::cout << name << ", " << size << "\n";
}
}
}
}
// std::vector<int> getValues(Opm::EclIO::ERft& fileReader, std::)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, DISABLED_OpmComputeSegmentTopology )
{
std::vector<std::string> esmryKeywords;
{
// QString filePath = "e:/gitroot/opm-tests/model1/opm-simulation-reference/flow/MSW_MODEL_1.RFT";
// QString filePath = "e:/gitroot/opm-tests/norne/ECL.2014.2/NORNE_ATW2013.RFT";
// QString filePath = "d:/Models/Statoil/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT";
// QString filePath = "e:/models/from_equinor_sftp/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT";
QString filePath = "e:/models/from_equinor_sftp/MSWRFT_toCS/MSWLOOPED_UN_RFT.RFT";
Opm::EclIO::ERft eRft( filePath.toStdString() );
auto wells = eRft.listOfWells();
auto dates = eRft.listOfdates();
class RftSegmentData
{
public:
RftSegmentData( int segnxt, int brno, int brnst, int brnen, int segNo )
: m_segNext( segnxt )
, m_segbrno( brno )
, m_brnst( brnst )
, m_brnen( brnen )
, m_segmentNo( segNo )
{
}
int segNext() const { return m_segNext; }
int segBrno() const { return m_segbrno; }
int segBrnst() const { return m_brnst; }
int segBrnen() const { return m_brnen; }
int segNo() const { return m_segmentNo; }
private:
int m_segNext;
int m_segbrno;
int m_brnst;
int m_brnen;
int m_segmentNo;
};
using RftSegmentKey = std::pair<std::string, Opm::EclIO::ERft::RftDate>;
std::map<RftSegmentKey, std::vector<RftSegmentData>> rftWellDateSegments;
for ( const auto& well : wells )
{
for ( const auto& date : dates )
{
std::vector<RftSegmentData> segmentsForWellDate;
std::vector<int> segnxt;
std::vector<int> segbrno;
std::vector<int> brnstValues;
std::vector<int> brnenValues;
std::vector<int> segNo;
{
std::string resultName = "SEGNXT";
if ( eRft.hasArray( resultName, well, date ) )
{
segnxt = eRft.getRft<int>( resultName, well, date );
}
}
{
std::string resultName = "SEGBRNO";
if ( eRft.hasArray( resultName, well, date ) )
{
segbrno = eRft.getRft<int>( resultName, well, date );
}
}
{
std::string resultName = "BRNST";
if ( eRft.hasArray( resultName, well, date ) )
{
brnstValues = eRft.getRft<int>( resultName, well, date );
}
}
{
std::string resultName = "BRNEN";
if ( eRft.hasArray( resultName, well, date ) )
{
brnenValues = eRft.getRft<int>( resultName, well, date );
}
}
if ( segnxt.empty() ) continue;
if ( segnxt.size() != segbrno.size() ) continue;
if ( brnenValues.empty() || brnstValues.empty() ) continue;
for ( size_t i = 0; i < segnxt.size(); i++ )
{
int branchIndex = segbrno[i] - 1;
int nextBranchIndex = -1;
if ( i + 1 < segbrno.size() ) nextBranchIndex = segbrno[i + 1] - 1;
bool isLastSegmentOnBranch = branchIndex != nextBranchIndex;
int brnst = brnstValues[branchIndex];
int brnen = brnenValues[branchIndex];
int segmentId = -1;
if ( !isLastSegmentOnBranch )
{
if ( i + 1 < segnxt.size() ) segmentId = segnxt[i + 1];
}
else
{
segmentId = brnen;
}
segNo.push_back( segmentId );
segmentsForWellDate.emplace_back( RftSegmentData( segnxt[i], segbrno[i], brnst, brnen, segmentId ) );
}
auto wellDateKey = std::make_pair( well, date );
rftWellDateSegments[wellDateKey] = segmentsForWellDate;
}
}
for ( const auto& a : rftWellDateSegments )
{
auto [wellName, date] = a.first;
auto segmentData = a.second;
std::cout << "\nWell: " << wellName << "Date : " << std::get<0>( date ) << " " << std::get<1>( date ) << " "
<< std::get<2>( date ) << " \n";
for ( const auto& r : segmentData )
{
std::cout << "SEGNXT " << std::setw( 2 ) << r.segNext() << ", ";
std::cout << "SEGBRNO " << std::setw( 2 ) << r.segBrno() << ", ";
std::cout << "BNRST " << std::setw( 2 ) << r.segBrnst() << ", ";
std::cout << "BRNEN " << std::setw( 2 ) << r.segBrnen() << ", ";
std::cout << "SEGNO " << std::setw( 2 ) << r.segNo() << "\n";
}
}
}
}
TEST( OpmSummaryTests, OpmComputeSegmentTopology )
{
std::vector<std::string> esmryKeywords;
{
// QString filePath = "e:/gitroot/opm-tests/model1/opm-simulation-reference/flow/MSW_MODEL_1.RFT";
// QString filePath = "e:/gitroot/opm-tests/norne/ECL.2014.2/NORNE_ATW2013.RFT";
// QString filePath = "d:/Models/Statoil/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT";
// QString filePath = "e:/models/from_equinor_sftp/MSW-RFTfile/NORNE_ATW2013_RFTPLT_MSW.RFT";
QString filePath = "e:/models/from_equinor_sftp/MSWRFT_toCS/MSWLOOPED_UN_RFT.RFT";
RifReaderOpmRft reader( filePath );
auto addresses = reader.eclipseRftAddresses();
std::vector<float> segStartDepth;
std::vector<float> segEndDepth;
std::vector<float> segNumber;
std::set<RifEclipseRftAddress> segmentAdresses;
for ( const auto& adr : addresses )
{
if ( adr.wellLogChannel() == RifEclipseRftAddress::RftWellLogChannelType::SEGMENT_VALUES )
{
segmentAdresses.insert( adr );
}
}
for ( const auto& adr : segmentAdresses )
{
qDebug() << adr.timeStep().toString( "YYYY MM dd" ) << " " << adr.segmentResultName();
if ( adr.segmentResultName() == RiaDefines::segmentNumberResultName() )
{
std::vector<double> values;
reader.values( adr, &values );
}
}
}
}
TEST( OpmSummaryTests, OpenEmptySummaryFile )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/SummaryData/empty-file/" ).arg( TEST_DATA_DIR );
QString rootPath = SUMMARY_TEST_DATA_DIRECTORY + "BLASTO_PRED-19";
QString smspecFilePath = rootPath + ".SMSPEC";
Opm::EclIO::ESmry eSmry( smspecFilePath.toStdString() );
// Test to verify that is is possible to read an empty summary file
// eSmry.make_esmry_file() will fail if the summary file is empty
EXPECT_TRUE( eSmry.numberOfTimeSteps() == 0 );
}
//--------------------------------------------------------------------------------------------------
/// The low-level opm-common reader requires a data file. When the SMSPEC has no UNSMRY (or
/// non-unified) data file, the ESmry constructor throws. RifReaderEclipseSummary guards against this,
/// see ReadSmspecWithoutUnsmryEmptyReader.
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, ReadSmspecWithoutUnsmry )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/SummaryData/smspec-only/" ).arg( TEST_DATA_DIR );
QString filePath = SUMMARY_TEST_DATA_DIRECTORY + "3_R001_REEK-1.SMSPEC";
ASSERT_TRUE( QFile::exists( filePath ) );
// No UNSMRY data file is expected to be present for this case.
QString unsmryFilePath( filePath );
unsmryFilePath.replace( ".SMSPEC", ".UNSMRY" );
EXPECT_FALSE( QFile::exists( unsmryFilePath ) );
// The opm-common reader cannot open a SMSPEC without a data file, and throws.
EXPECT_ANY_THROW( Opm::EclIO::ESmry eSmry( filePath.toStdString() ) );
}
//--------------------------------------------------------------------------------------------------
/// Open the same SMSPEC (no UNSMRY data file) using the resdata reader for comparison.
/// resdata requires a data file, so openEclSum() returns a null reader, but must not throw.
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, ReadSmspecWithoutUnsmryResdata )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/SummaryData/smspec-only/" ).arg( TEST_DATA_DIR );
QString filePath = SUMMARY_TEST_DATA_DIRECTORY + "3_R001_REEK-1.SMSPEC";
ASSERT_TRUE( QFile::exists( filePath ) );
// No UNSMRY data file is expected to be present for this case.
QString unsmryFilePath( filePath );
unsmryFilePath.replace( ".SMSPEC", ".UNSMRY" );
EXPECT_FALSE( QFile::exists( unsmryFilePath ) );
ecl_sum_type* eclSum = RifEclipseSummaryTools::openEclSum( filePath, false );
// resdata needs a data file alongside the SMSPEC; without UNSMRY no reader is created.
EXPECT_EQ( eclSum, nullptr );
if ( eclSum )
{
auto timeSteps = RifEclipseSummaryTools::getTimeSteps( eclSum );
std::cout << "Number of time steps: " << timeSteps.size() << "\n";
RifEclipseSummaryTools::closeEclSum( eclSum );
}
}
//--------------------------------------------------------------------------------------------------
/// Open the SMSPEC (no UNSMRY data file) through RifReaderEclipseSummary. The reader must not crash
/// and must report empty data.
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, ReadSmspecWithoutUnsmryEmptyReader )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/SummaryData/smspec-only/" ).arg( TEST_DATA_DIR );
QString filePath = SUMMARY_TEST_DATA_DIRECTORY + "3_R001_REEK-1.SMSPEC";
ASSERT_TRUE( QFile::exists( filePath ) );
RifReaderEclipseSummary reader;
// No summary data file is present, but opening must succeed and create a valid, but empty, reader.
// This ensures the case is opened once and not re-read on every request.
EXPECT_TRUE( reader.open( filePath, nullptr ) );
reader.createAndSetAddresses();
// No data is available, so the reader reports empty content.
EXPECT_TRUE( reader.allResultAddresses().empty() );
auto [ok, values] = reader.values( RifEclipseSummaryAddress::fieldAddress( "FOPT" ) );
EXPECT_TRUE( values.empty() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, DISABLED_ReadOpmRadialGrid )
{
{
QString filePath = "e:/models/from_equinor_sftp/2021.10.1-Radial-testcase/global-radial/GLOBAL-RADIAL.EGRID";
Opm::EclIO::EGrid eGrid( filePath.toStdString() );
auto dims = eGrid.dimension();
size_t cellCount = dims[0] * dims[1] * dims[2];
std::array<double, 8> X{};
std::array<double, 8> Y{};
std::array<double, 8> Z{};
for ( size_t cidx = 0; cidx < cellCount; cidx++ )
{
eGrid.getCellCorners( cidx, X, Y, Z );
for ( size_t i = 0; i < 8; i++ )
{
std::cout << X[i] << " " << Y[i] << " " << Z[i] << "\n";
}
}
}
}
TEST( OpmSummaryHeaderSearch, NoEsmryRestart )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/summary-header-search/no-esmry-restart/" ).arg( TEST_DATA_DIR );
QString filename = SUMMARY_TEST_DATA_DIRECTORY + "/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY";
const bool useOpmReader = true;
std::vector<QString> warnings;
auto restartFilenames = RifEclipseSummaryTools::getRestartFileNames( filename, useOpmReader, warnings );
EXPECT_TRUE( restartFilenames.size() == 1 );
auto restartFileName = restartFilenames[0];
// search for text iter-3
EXPECT_TRUE( restartFileName.contains( "iter-3" ) );
// check that the file does not exist
QFile file( restartFileName );
EXPECT_FALSE( file.exists() );
}
TEST( OpmSummaryHeaderSearch, OnlyEsmryFiles )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/summary-header-search/only-esmry/" ).arg( TEST_DATA_DIR );
QString filename = SUMMARY_TEST_DATA_DIRECTORY + "/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY";
const bool useOpmReader = true;
std::vector<QString> warnings;
auto restartFilenames = RifEclipseSummaryTools::getRestartFileNames( filename, useOpmReader, warnings );
EXPECT_TRUE( restartFilenames.size() == 1 );
auto restartFileName = restartFilenames[0];
// search for text iter-3
EXPECT_TRUE( restartFileName.contains( "iter-3" ) );
// check that the file exists
QFile file( restartFileName );
EXPECT_TRUE( file.exists() );
}
TEST( OpmSummaryHeaderSearch, OnlySmspecFiles )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/summary-header-search/only-smspec/" ).arg( TEST_DATA_DIR );
QString filename = SUMMARY_TEST_DATA_DIRECTORY + "/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC";
const bool useOpmReader = true;
std::vector<QString> warnings;
auto restartFilenames = RifEclipseSummaryTools::getRestartFileNames( filename, useOpmReader, warnings );
EXPECT_TRUE( restartFilenames.size() == 1 );
auto restartFileName = restartFilenames[0];
// search for text iter-3
EXPECT_TRUE( restartFileName.contains( "iter-3" ) );
// check that the file exists
QFile file( restartFileName );
EXPECT_TRUE( file.exists() );
}
//--------------------------------------------------------------------------------------------------
/// Summary file names can contain multiple dots. The ESMRY data file must be found when opening the
/// SMSPEC file name, see https://github.com/OPM/ResInsight/issues/14761
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, OpenEsmryWithMultipleDotsInFileName )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/summary-header-search/only-esmry/" ).arg( TEST_DATA_DIR );
QString sourceFilePath = SUMMARY_TEST_DATA_DIRECTORY + "/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY";
QTemporaryDir tempDir;
ASSERT_TRUE( tempDir.isValid() );
const QString esmryFilePath = tempDir.path() + "/DROGON.V2.1-18.ESMRY";
ASSERT_TRUE( QFile::copy( sourceFilePath, esmryFilePath ) );
// Ensemble import opens the realization using the SMSPEC file name
const QString smspecFilePath = tempDir.path() + "/DROGON.V2.1-18.SMSPEC";
RifReaderEclipseSummary reader;
EXPECT_TRUE( reader.open( smspecFilePath, nullptr ) );
reader.createAndSetAddresses();
EXPECT_FALSE( reader.allResultAddresses().empty() );
}
//--------------------------------------------------------------------------------------------------
/// Open SMSPEC and UNSMRY files with multiple dots in the file name, see https://github.com/OPM/ResInsight/issues/14761
//--------------------------------------------------------------------------------------------------
TEST( OpmSummaryTests, OpenSmspecAndUnsmryWithMultipleDotsInFileName )
{
QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/SummaryData/Reek/" ).arg( TEST_DATA_DIR );
QTemporaryDir tempDir;
ASSERT_TRUE( tempDir.isValid() );
const QString rootPath = tempDir.path() + "/3_R001.V2.1_REEK-1";
ASSERT_TRUE( QFile::copy( SUMMARY_TEST_DATA_DIRECTORY + "3_R001_REEK-1.SMSPEC", rootPath + ".SMSPEC" ) );
ASSERT_TRUE( QFile::copy( SUMMARY_TEST_DATA_DIRECTORY + "3_R001_REEK-1.UNSMRY", rootPath + ".UNSMRY" ) );
RifReaderEclipseSummary reader;
EXPECT_TRUE( reader.open( rootPath + ".SMSPEC", nullptr ) );
reader.createAndSetAddresses();
EXPECT_FALSE( reader.allResultAddresses().empty() );
auto [ok, values] = reader.values( RifEclipseSummaryAddress::fieldAddress( "FOPT" ) );
EXPECT_TRUE( ok );
EXPECT_FALSE( values.empty() );
}