#7622 Summary Restart : Add summary restart reader

Move libecl reader into RifEclEclipseSummary
Add a summary file restart history reader
Simplify RifEclipseSummary
This commit is contained in:
Magne Sjaastad
2021-04-27 15:08:48 +02:00
parent 6ed6b17543
commit 2c91725365
16 changed files with 1039 additions and 648 deletions

View File

@@ -25,8 +25,14 @@
#include "cafAppEnum.h"
#include "ert/ecl/ecl_file.h"
#include "ert/ecl/ecl_kw.h"
#include "ert/ecl/ecl_kw_magic.h"
#include "ert/ecl/ecl_sum.h"
#include "ert/ecl/ecl_util.h"
#include "ert/ecl/smspec_node.hpp"
#include <QDateTime>
#include <QDir>
#include <QString>
#include <QStringList>
@@ -127,7 +133,7 @@ QString RifEclipseSummaryTools::findGridCaseFileFromSummaryHeaderFile( const QSt
//--------------------------------------------------------------------------------------------------
void RifEclipseSummaryTools::dumpMetaData( RifSummaryReaderInterface* readerEclipseSummary )
{
std::set<RifEclipseSummaryAddress> addresses = readerEclipseSummary->allResultAddresses();
const std::set<RifEclipseSummaryAddress>& addresses = readerEclipseSummary->allResultAddresses();
for ( int category = 0; category < RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR; category++ )
{
@@ -137,18 +143,18 @@ void RifEclipseSummaryTools::dumpMetaData( RifSummaryReaderInterface* readerEcli
std::vector<RifEclipseSummaryAddress> catAddresses =
RiaSummaryCurveAnalyzer::addressesForCategory( addresses, categoryEnum );
if ( catAddresses.size() > 0 )
if ( !catAddresses.empty() )
{
std::cout << caf::AppEnum<RifEclipseSummaryAddress::SummaryVarCategory>::uiText( categoryEnum ).toStdString()
<< " count : " << catAddresses.size() << std::endl;
for ( size_t i = 0; i < catAddresses.size(); i++ )
for ( const auto& catAddresse : catAddresses )
{
std::cout << catAddresses[i].quantityName() << " " << catAddresses[i].regionNumber() << " "
<< catAddresses[i].regionNumber2() << " " << catAddresses[i].wellGroupName() << " "
<< catAddresses[i].wellName() << " " << catAddresses[i].wellSegmentNumber() << " "
<< catAddresses[i].lgrName() << " " << catAddresses[i].cellI() << " "
<< catAddresses[i].cellJ() << " " << catAddresses[i].cellK() << std::endl;
std::cout << catAddresse.quantityName() << " " << catAddresse.regionNumber() << " "
<< catAddresse.regionNumber2() << " " << catAddresse.wellGroupName() << " "
<< catAddresse.wellName() << " " << catAddresse.wellSegmentNumber() << " "
<< catAddresse.lgrName() << " " << catAddresse.cellI() << " " << catAddresse.cellJ() << " "
<< catAddresse.cellK() << std::endl;
}
std::cout << std::endl;
@@ -156,6 +162,88 @@ void RifEclipseSummaryTools::dumpMetaData( RifSummaryReaderInterface* readerEcli
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RifRestartFileInfo> RifEclipseSummaryTools::getRestartFiles( const QString& headerFileName,
std::vector<QString>& warnings )
{
std::vector<RifRestartFileInfo> restartFiles;
std::set<QString> restartFilesOpened;
RifRestartFileInfo currFile;
currFile.fileName = headerFileName;
while ( !currFile.fileName.isEmpty() )
{
// Due to a weakness in libecl regarding restart summary header file selection,
// do some extra checking
{
QString formattedHeaderExtension = ".FSMSPEC";
QString nonformattedHeaderExtension = ".SMSPEC";
QString formattedDataFileExtension = ".FUNSMRY";
if ( currFile.fileName.endsWith( nonformattedHeaderExtension, Qt::CaseInsensitive ) )
{
QString formattedHeaderFile = currFile.fileName;
formattedHeaderFile.replace( nonformattedHeaderExtension, formattedHeaderExtension, Qt::CaseInsensitive );
QString formattedDateFile = currFile.fileName;
formattedDateFile.replace( nonformattedHeaderExtension, formattedDataFileExtension, Qt::CaseInsensitive );
QFileInfo nonformattedHeaderFileInfo = QFileInfo( currFile.fileName );
QFileInfo formattedHeaderFileInfo = QFileInfo( formattedHeaderFile );
QFileInfo formattedDateFileInfo = QFileInfo( formattedDateFile );
if ( formattedHeaderFileInfo.lastModified() < nonformattedHeaderFileInfo.lastModified() &&
formattedHeaderFileInfo.exists() && !formattedDateFileInfo.exists() )
{
warnings.push_back(
QString( "RifReaderEclipseSummary: Formatted summary header file without an\n" ) +
QString( "associated data file detected.\n" ) +
QString( "This may cause a failure reading summary origin data.\n" ) +
QString( "To avoid this problem, please delete or rename the.FSMSPEC file." ) );
break;
}
}
QString prevFile = currFile.fileName;
currFile = getRestartFile( currFile.fileName );
// Fix to stop potential infinite loop
if ( currFile.fileName == prevFile )
{
warnings.push_back( "RifReaderEclipseSummary: Restart file reference loop detected" );
break;
}
if ( restartFilesOpened.count( currFile.fileName ) != 0u )
{
warnings.push_back( "RifReaderEclipseSummary: Same restart file being opened multiple times" );
}
restartFilesOpened.insert( currFile.fileName );
}
if ( !currFile.fileName.isEmpty() ) restartFiles.push_back( currFile );
}
return restartFiles;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifRestartFileInfo RifEclipseSummaryTools::getFileInfo( const QString& headerFileName )
{
RifRestartFileInfo fileInfo;
ecl_sum_type* ecl_sum = openEclSum( headerFileName, false );
std::vector<time_t> timeSteps = getTimeSteps( ecl_sum );
if ( !timeSteps.empty() )
{
fileInfo.fileName = headerFileName;
fileInfo.startDate = timeSteps.front();
fileInfo.endDate = timeSteps.back();
}
closeEclSum( ecl_sum );
return fileInfo;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -193,3 +281,124 @@ void RifEclipseSummaryTools::findSummaryHeaderFileInfo( const QString& inputFile
free( myBase );
free( myPath );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifRestartFileInfo RifEclipseSummaryTools::getRestartFile( const QString& headerFileName )
{
ecl_sum_type* ecl_sum = openEclSum( headerFileName, true );
const ecl_smspec_type* smspec = ecl_sum ? ecl_sum_get_smspec( ecl_sum ) : nullptr;
const char* rstCase = smspec ? ecl_smspec_get_restart_case( smspec ) : nullptr;
QString restartCase =
rstCase ? RiaFilePathTools::canonicalPath( RiaStringEncodingTools::fromNativeEncoded( rstCase ) ) : "";
closeEclSum( ecl_sum );
if ( !restartCase.isEmpty() )
{
QString path = QFileInfo( restartCase ).dir().path();
QString restartBase = QDir( restartCase ).dirName();
char* smspec_header = ecl_util_alloc_exfilename( path.toStdString().data(),
restartBase.toStdString().data(),
ECL_SUMMARY_HEADER_FILE,
false /*unformatted*/,
0 );
QString restartFileName =
RiaFilePathTools::toInternalSeparator( RiaStringEncodingTools::fromNativeEncoded( smspec_header ) );
free( smspec_header );
return getFileInfo( restartFileName );
}
return RifRestartFileInfo();
}
std::vector<time_t> RifEclipseSummaryTools::getTimeSteps( ecl_sum_type* ecl_sum )
{
std::vector<time_t> timeSteps;
if ( ecl_sum )
{
time_t_vector_type* steps = ecl_sum_alloc_time_vector( ecl_sum, false );
if ( steps )
{
for ( int i = 0; i < time_t_vector_size( steps ); i++ )
{
timeSteps.push_back( time_t_vector_iget( steps, i ) );
}
time_t_vector_free( steps );
}
}
return timeSteps;
}
RiaDefines::EclipseUnitSystem RifEclipseSummaryTools::readUnitSystem( ecl_sum_type* ecl_sum )
{
ert_ecl_unit_enum eclUnitEnum = ecl_sum_get_unit_system( ecl_sum );
switch ( eclUnitEnum )
{
case ECL_METRIC_UNITS:
return RiaDefines::EclipseUnitSystem::UNITS_METRIC;
case ECL_FIELD_UNITS:
return RiaDefines::EclipseUnitSystem::UNITS_FIELD;
case ECL_LAB_UNITS:
return RiaDefines::EclipseUnitSystem::UNITS_LAB;
default:
return RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ecl_sum_type* RifEclipseSummaryTools::openEclSum( const QString& inHeaderFileName, bool includeRestartFiles )
{
QString headerFileName;
QStringList dataFileNames;
QString nativeHeaderFileName = QDir::toNativeSeparators( inHeaderFileName );
RifEclipseSummaryTools::findSummaryFiles( nativeHeaderFileName, &headerFileName, &dataFileNames );
if ( headerFileName.isEmpty() || dataFileNames.isEmpty() ) return nullptr;
assert( !headerFileName.isEmpty() );
assert( dataFileNames.size() > 0 );
stringlist_type* dataFiles = stringlist_alloc_new();
for ( int i = 0; i < dataFileNames.size(); i++ )
{
stringlist_append_copy( dataFiles, RiaStringEncodingTools::toNativeEncoded( dataFileNames[i] ).data() );
}
bool lazyLoad = true;
std::string itemSeparatorInVariableNames = ":";
ecl_sum_type* ecl_sum = nullptr;
try
{
ecl_sum = ecl_sum_fread_alloc( RiaStringEncodingTools::toNativeEncoded( headerFileName ).data(),
dataFiles,
itemSeparatorInVariableNames.data(),
includeRestartFiles,
lazyLoad,
ECL_FILE_CLOSE_STREAM );
}
catch ( ... )
{
ecl_sum = nullptr;
}
stringlist_free( dataFiles );
return ecl_sum;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseSummaryTools::closeEclSum( ecl_sum_type* ecl_sum )
{
if ( ecl_sum ) ecl_sum_free( ecl_sum );
}