#7527 HDF Summary Reader : Add first working prototype

HDF5 must be compiled with special options to support multithreading. Disable file object multithreading for HDF5. Some vector types are not supported, as the support in opm-common reader is not complete (region, region_to_region, ...).
This commit is contained in:
Magne Sjaastad 2021-04-08 15:53:38 +02:00
parent d082ce7eb1
commit dd97e7741a
22 changed files with 990 additions and 147 deletions

View File

@ -81,6 +81,15 @@ void RiaPreferences::PageOrientationEnum::setUp()
addItem( QPageLayout::Landscape, "LANDSCAPE", "Landscape" );
setDefault( QPageLayout::Portrait );
}
template <>
void RiaPreferences::SummaryReaderModeType::setUp()
{
addItem( RiaPreferences::SummaryReaderMode::LIBECL, "LIBECL", "Default Reader (ecl)" );
addItem( RiaPreferences::SummaryReaderMode::HDF5_OPM_COMMON, "HDF5_OPM_COMMON", "[BETA] H5 Reader (HDF5 Eclipse)" );
addItem( RiaPreferences::SummaryReaderMode::OPM_COMMON, "OPM_COMMON", "[BETA] Performance Reader (omp-common)" );
setDefault( RiaPreferences::SummaryReaderMode::LIBECL );
}
} // namespace caf
CAF_PDM_SOURCE_INIT( RiaPreferences, "RiaPreferences" );
@ -88,7 +97,7 @@ CAF_PDM_SOURCE_INIT( RiaPreferences, "RiaPreferences" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPreferences::RiaPreferences( void )
RiaPreferences::RiaPreferences()
{
CAF_PDM_InitField( &m_navigationPolicy,
"navigationPolicy",
@ -404,15 +413,6 @@ RiaPreferences::RiaPreferences( void )
CAF_PDM_InitFieldNoDefault( &m_guiTheme, "guiTheme", "GUI theme", "", "", "" );
CAF_PDM_InitField( &m_useOptimizedSummaryDataFileReader,
"useOptimizedSummaryDataFileReader",
false,
"Use Optimized Summary Data Reader [BETA]",
"",
"",
"" );
m_useOptimizedSummaryDataFileReader.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitField( &m_createOptimizedSummaryDataFile,
"createOptimizedSummaryDataFile",
true,
@ -430,12 +430,14 @@ RiaPreferences::RiaPreferences( void )
"If not present, read optimized file with extension '*.LODSMRY'",
"" );
m_useOptimizedSummaryDataFile.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
CAF_PDM_InitFieldNoDefault( &m_summaryReader, "summaryReaderType", "Summary Data File Reader", "", "", "" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaPreferences::~RiaPreferences( void )
RiaPreferences::~RiaPreferences()
{
delete m_readerSettings;
}
@ -471,14 +473,14 @@ void RiaPreferences::defineEditorAttribute( const caf::PdmFieldHandle* field,
if ( field == &octaveShowHeaderInfoWhenExecutingScripts || field == &autocomputeDepthRelatedProperties ||
field == &loadAndShowSoil || field == &m_useShaders || field == &m_showHud ||
field == &m_appendClassNameToUiText || field == &m_appendFieldKeywordToToolTipText || field == &m_showTestToolbar ||
field == &m_includeFractureDebugInfoFile || field == &showLasCurveWithoutTvdWarning ||
field == &holoLensDisableCertificateVerification || field == &m_showProjectChangedDialog ||
field == &m_searchPlotTemplateFoldersRecursively || field == &m_showLegendBackground ||
field == &m_showSummaryTimeAsLongString || field == &m_showViewIdInProjectTree ||
field == &m_useMultipleThreadsWhenLoadingSummaryData || field == &m_enableFaultsByDefault ||
field == &m_showProgressBar || field == &m_openExportedPdfInViewer || field == &m_showInfoBox ||
field == &m_showGridBox || field == &m_useUndoRedo || field == &m_useOptimizedSummaryDataFileReader ||
field == &m_appendClassNameToUiText || field == &m_appendFieldKeywordToToolTipText ||
field == &m_showTestToolbar || field == &m_includeFractureDebugInfoFile ||
field == &showLasCurveWithoutTvdWarning || field == &holoLensDisableCertificateVerification ||
field == &m_showProjectChangedDialog || field == &m_searchPlotTemplateFoldersRecursively ||
field == &m_showLegendBackground || field == &m_showSummaryTimeAsLongString ||
field == &m_showViewIdInProjectTree || field == &m_useMultipleThreadsWhenLoadingSummaryData ||
field == &m_enableFaultsByDefault || field == &m_showProgressBar || field == &m_openExportedPdfInViewer ||
field == &m_showInfoBox || field == &m_showGridBox || field == &m_useUndoRedo ||
field == &m_createOptimizedSummaryDataFile || field == &m_useOptimizedSummaryDataFile )
{
caf::PdmUiCheckBoxEditorAttribute* myAttr = dynamic_cast<caf::PdmUiCheckBoxEditorAttribute*>( attribute );
@ -608,13 +610,13 @@ void RiaPreferences::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering&
{
caf::PdmUiGroup* group = uiOrdering.addNewGroup( "[BETA] Optimized Summary Reader" );
group->setCollapsedByDefault( true );
group->add( &m_useOptimizedSummaryDataFileReader );
group->add( &m_summaryReader );
if ( m_summaryReader == SummaryReaderMode::OPM_COMMON )
{
group->add( &m_createOptimizedSummaryDataFile );
group->add( &m_useOptimizedSummaryDataFile );
m_createOptimizedSummaryDataFile.uiCapability()->setUiReadOnly( !m_useOptimizedSummaryDataFileReader );
m_useOptimizedSummaryDataFile.uiCapability()->setUiReadOnly( !m_useOptimizedSummaryDataFileReader );
}
}
}
@ -727,7 +729,21 @@ QList<caf::PdmOptionItemInfo> RiaPreferences::calculateValueOptions( const caf::
options.push_back( caf::PdmOptionItemInfo( uiText, QVariant::fromValue( timeFormat ) ) );
}
}
else if ( fieldNeedingOptions == &m_summaryReader )
{
std::vector<SummaryReaderMode> availableModes;
availableModes.push_back( SummaryReaderMode::LIBECL );
#ifdef USE_HDF5
availableModes.push_back( SummaryReaderMode::HDF5_OPM_COMMON );
#endif // USE_HDF5
availableModes.push_back( SummaryReaderMode::OPM_COMMON );
for ( auto enumValue : availableModes )
{
options.push_back( caf::PdmOptionItemInfo( SummaryReaderModeType::uiText( enumValue ), enumValue ) );
}
}
return options;
}
@ -1214,9 +1230,9 @@ QString RiaPreferences::octaveExecutable() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaPreferences::useOptimizedSummaryDataReader() const
RiaPreferences::SummaryReaderMode RiaPreferences::summaryDataReader() const
{
return m_useOptimizedSummaryDataFileReader();
return m_summaryReader();
}
//--------------------------------------------------------------------------------------------------
@ -1224,7 +1240,7 @@ bool RiaPreferences::useOptimizedSummaryDataReader() const
//--------------------------------------------------------------------------------------------------
bool RiaPreferences::useOptimizedSummaryDataFiles() const
{
return m_useOptimizedSummaryDataFileReader();
return m_useOptimizedSummaryDataFile();
}
//--------------------------------------------------------------------------------------------------

View File

@ -70,6 +70,14 @@ public:
};
typedef caf::AppEnum<SummaryHistoryCurveStyleMode> SummaryHistoryCurveStyleModeType;
enum class SummaryReaderMode
{
LIBECL,
OPM_COMMON,
HDF5_OPM_COMMON
};
typedef caf::AppEnum<SummaryReaderMode> SummaryReaderModeType;
typedef caf::AppEnum<QPageSize::PageSizeId> PageSizeEnum;
typedef caf::AppEnum<QPageLayout::Orientation> PageOrientationEnum;
@ -139,7 +147,7 @@ public:
QString octaveExecutable() const;
// Summary readers
bool useOptimizedSummaryDataReader() const;
SummaryReaderMode summaryDataReader() const;
bool useOptimizedSummaryDataFiles() const;
bool createOptimizedSummaryDataFiles() const;
@ -249,10 +257,11 @@ private:
caf::PdmField<QString> m_multiLateralWellPattern;
// Summary data
caf::PdmField<bool> m_useOptimizedSummaryDataFileReader;
caf::PdmField<bool> m_createOptimizedSummaryDataFile;
caf::PdmField<bool> m_useOptimizedSummaryDataFile;
caf::PdmField<SummaryReaderModeType> m_summaryReader;
// 3d view
caf::PdmField<caf::AppEnum<RiaDefines::MeshModeType>> m_defaultMeshModeType;
caf::PdmField<caf::AppEnum<RiaGuiApplication::RINavigationPolicy>> m_navigationPolicy;

View File

@ -231,8 +231,15 @@ list(APPEND RI_LIBRARIES RigGeoMechDataModel)
# HDF5
#
if(RESINSIGHT_FOUND_HDF5)
list(APPEND CPP_SOURCES FileInterface/RifHdf5Reader.h
FileInterface/RifHdf5Reader.cpp)
list(
APPEND
CPP_SOURCES
FileInterface/RifHdf5Reader.h
FileInterface/RifHdf5Reader.cpp
FileInterface/RifHdf5SummaryReader.h
FileInterface/RifHdf5SummaryReader.cpp
FileInterface/RifOpmHdf5Summary.h
FileInterface/RifOpmHdf5Summary.cpp)
add_definitions(-DUSE_HDF5)
@ -247,8 +254,15 @@ if(RESINSIGHT_FOUND_HDF5)
include_directories(${HDF5_INCLUDE_DIRS})
endif() # MSVC
source_group("FileInterface" FILES FileInterface/RifHdf5Reader.h
FileInterface/RifHdf5Reader.cpp)
source_group(
"FileInterface"
FILES FileInterface/RifHdf5Reader.h
FileInterface/RifHdf5Reader.cpp
FileInterface/RifHdf5SummaryReader.h
FileInterface/RifHdf5SummaryReader.cpp
FileInterface/RifOpmHdf5Summary.h
FileInterface/RifOpmHdf5Summary.cpp)
endif()
# ##############################################################################

View File

@ -356,24 +356,7 @@ std::string RifHdf5Reader::getStringAttribute( H5::H5File file, std::string grou
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifHdf5Reader::getSubGroupNames( H5::H5File file, std::string baseGroupName ) const
{
H5::Group baseGroup = file.openGroup( baseGroupName.c_str() );
std::vector<std::string> subGroupNames;
hsize_t groupSize = baseGroup.getNumObjs();
for ( hsize_t i = 0; i < groupSize; i++ )
{
std::string nodeName( 1024, '\0' );
ssize_t slen = baseGroup.getObjnameByIdx( i, &nodeName[0], 1023 );
nodeName.resize( slen + 1 );
subGroupNames.push_back( nodeName );
}
return subGroupNames;
return RifHdf5ReaderTools::getSubGroupNames( &file, baseGroupName );
}
//--------------------------------------------------------------------------------------------------
@ -412,3 +395,33 @@ void RifHdf5Reader::getElementResultValues( H5::H5File file, std::string groupNa
( *resultValues ).resize( dims[0] );
dataset.read( resultValues->data(), H5::PredType::NATIVE_DOUBLE );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifHdf5ReaderTools::getSubGroupNames( H5::H5File* file, const std::string& baseGroupName )
{
if ( file )
{
H5::Group baseGroup = file->openGroup( baseGroupName.c_str() );
std::vector<std::string> subGroupNames;
hsize_t groupSize = baseGroup.getNumObjs();
for ( hsize_t i = 0; i < groupSize; i++ )
{
std::string nodeName( 1024, '\0' );
ssize_t slen = baseGroup.getObjnameByIdx( i, &nodeName[0], 1023 );
nodeName.resize( slen + 1 );
subGroupNames.push_back( nodeName );
}
return subGroupNames;
}
return {};
}

View File

@ -24,6 +24,12 @@
#include "H5Cpp.h"
class RifHdf5ReaderTools
{
public:
static std::vector<std::string> getSubGroupNames( H5::H5File* file, const std::string& baseGroupName );
};
//==================================================================================================
//
//

View File

@ -0,0 +1,249 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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 "RifHdf5SummaryReader.h"
#include "RiaLogging.h"
#include "RiaQDateTimeTools.h"
#include "RiaTimeTTools.h"
#include "RifHdf5Reader.h"
#include "H5Cpp.h"
#include <QDateTime>
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifHdf5SummaryReader::RifHdf5SummaryReader( const QString& fileName )
{
try
{
m_hdfFile = new H5::H5File( fileName.toStdString().c_str(), H5F_ACC_RDONLY );
}
catch ( ... )
{
RiaLogging::error( "Failed to open HDF file " + fileName );
delete m_hdfFile;
m_hdfFile = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifHdf5SummaryReader::~RifHdf5SummaryReader()
{
if ( m_hdfFile )
{
m_hdfFile->close();
delete m_hdfFile;
m_hdfFile = nullptr;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifHdf5SummaryReader::isValid() const
{
return ( m_hdfFile != nullptr );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::string> RifHdf5SummaryReader::vectorNames()
{
if ( m_hdfFile )
{
std::vector<std::string> names;
auto groupNames = RifHdf5ReaderTools::getSubGroupNames( m_hdfFile, "summary_vectors" );
names.reserve( groupNames.size() );
for ( const auto& name : groupNames )
{
names.push_back( name );
}
return names;
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<time_t> RifHdf5SummaryReader::timeSteps() const
{
std::vector<time_t> times;
// TODO: This function uses code taken from ESmry::dates(). There is conversion from time_t to
// chrono::system_clock::time_points, and then back to time_t again. Consider using one representation
double time_unit = 24 * 3600;
using namespace std::chrono;
using TP = time_point<system_clock>;
using DoubSec = duration<double, seconds::period>;
auto timeDeltasInDays = values( "TIME" );
std::vector<std::chrono::system_clock::time_point> timePoints;
TP startDat = std::chrono::system_clock::from_time_t( startDate() );
timePoints.reserve( timeDeltasInDays.size() );
for ( const auto& t : timeDeltasInDays )
{
timePoints.push_back( startDat + duration_cast<TP::duration>( DoubSec( t * time_unit ) ) );
}
for ( const auto& d : timePoints )
{
auto timeAsTimeT = std::chrono::system_clock::to_time_t( d );
times.push_back( timeAsTimeT );
}
return times;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RifHdf5SummaryReader::values( const std::string& vectorName, int smspecKeywordIndex ) const
{
if ( m_hdfFile )
{
try
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
std::string idText = std::to_string( smspecKeywordIndex );
std::string groupPath = "summary_vectors/" + vectorName + "/" + idText;
{
H5::Group generalGroup = m_hdfFile->openGroup( groupPath.c_str() );
H5::DataSet dataset = H5::DataSet( generalGroup.openDataSet( "values" ) );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
std::vector<double> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_DOUBLE );
return values;
}
}
catch ( ... )
{
}
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RifHdf5SummaryReader::values( const std::string& vectorName ) const
{
if ( m_hdfFile )
{
try
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
std::string groupPath = "summary_vectors/" + vectorName;
auto groupNames = RifHdf5ReaderTools::getSubGroupNames( m_hdfFile, groupPath );
if ( !groupNames.empty() )
{
groupPath = groupPath + "/" + groupNames[0];
H5::Group generalGroup = m_hdfFile->openGroup( groupPath.c_str() );
H5::DataSet dataset = H5::DataSet( generalGroup.openDataSet( "values" ) );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
std::vector<double> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_DOUBLE );
return values;
}
}
catch ( ... )
{
}
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
time_t RifHdf5SummaryReader::startDate() const
{
if ( m_hdfFile )
{
try
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
QString groupPath = QString( "general" );
H5::Group GridFunction_00002 = m_hdfFile->openGroup( groupPath.toStdString().c_str() );
H5::DataSet dataset = H5::DataSet( GridFunction_00002.openDataSet( "start_date" ) );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
std::vector<int> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_INT );
int day = values[0];
int month = values[1];
int year = values[2];
QDateTime reportDateTime = RiaQDateTimeTools::createUtcDateTime( QDate( year, month, day ) );
time_t myTime = RiaTimeTTools::fromQDateTime( reportDateTime );
return myTime;
}
catch ( ... )
{
}
RiaLogging::error( "Not able to read start_date from HDF5 " );
}
return {};
}

View File

@ -0,0 +1,51 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "H5Cpp.h"
#include <string>
#include <vector>
class QString;
//==================================================================================================
//
//
//==================================================================================================
class RifHdf5SummaryReader
{
public:
explicit RifHdf5SummaryReader( const QString& fileName );
~RifHdf5SummaryReader();
bool isValid() const;
std::vector<std::string> vectorNames();
std::vector<time_t> timeSteps() const;
std::vector<double> values( const std::string& vectorName, int smspecKeywordIndex ) const;
std::vector<double> values( const std::string& vectorName ) const;
private:
time_t startDate() const;
private:
H5::H5File* m_hdfFile;
};

View File

@ -79,9 +79,11 @@ size_t RifOpmCommonEclipseSummary::numberOfLodFilesCreated()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifOpmCommonEclipseSummary::open( const QString& headerFileName, bool includeRestartFiles )
bool RifOpmCommonEclipseSummary::open( const QString& headerFileName,
bool includeRestartFiles,
RiaThreadSafeLogger* threadSafeLogger )
{
if ( !openESmryFile( headerFileName, includeRestartFiles ) ) return false;
if ( !openESmryFile( headerFileName, includeRestartFiles, threadSafeLogger ) ) return false;
if ( m_createLodsmryFiles && !includeRestartFiles )
{
@ -96,7 +98,7 @@ bool RifOpmCommonEclipseSummary::open( const QString& headerFileName, bool inclu
// object. Close the file object to make sure allocated data is released, and create a new file object
// that will import only the meta data and no curve data. This is a relatively fast operation.
if ( !openESmryFile( headerFileName, includeRestartFiles ) ) return false;
if ( !openESmryFile( headerFileName, includeRestartFiles, threadSafeLogger ) ) return false;
}
}
@ -179,25 +181,19 @@ void RifOpmCommonEclipseSummary::buildMetaData()
m_timeSteps.push_back( timeAsTimeT );
}
auto nodes = m_eSmry->summaryNodeList();
for ( size_t i = 0; i < nodes.size(); i++ )
{
auto summaryNode = nodes[i];
auto eclAdr = createAddressFromSummaryNode( summaryNode, m_eSmry.get() );
auto [addresses, addressMap] = RifOpmCommonSummaryTools::buildMetaData( m_eSmry.get() );
if ( eclAdr.isValid() )
{
m_allResultAddresses.insert( eclAdr );
m_adrToSummaryNodeIndex[eclAdr] = i;
}
}
m_allResultAddresses = addresses;
m_adrToSummaryNodeIndex = addressMap;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifOpmCommonEclipseSummary::openESmryFile( const QString& headerFileName, bool includeRestartFiles )
bool RifOpmCommonEclipseSummary::openESmryFile( const QString& headerFileName,
bool includeRestartFiles,
RiaThreadSafeLogger* threadSafeLogger )
{
try
{
@ -207,7 +203,8 @@ bool RifOpmCommonEclipseSummary::openESmryFile( const QString& headerFileName, b
catch ( std::exception& e )
{
QString txt = QString( "Optimized Summary Reader error : %1" ).arg( e.what() );
RiaLogging::error( txt );
if ( threadSafeLogger ) threadSafeLogger->error( txt );
return false;
}
@ -228,43 +225,43 @@ void RifOpmCommonEclipseSummary::increaseLodFileCount()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifEclipseSummaryAddress RifOpmCommonEclipseSummary::createAddressFromSummaryNode( const Opm::EclIO::SummaryNode& node,
Opm::EclIO::ESmry* summaryFile )
RifEclipseSummaryAddress RifOpmCommonSummaryTools::createAddressFromSummaryNode( const Opm::EclIO::SummaryNode& summaryNode,
const Opm::EclIO::ESmry* summaryFile )
{
int i = -1;
int j = -1;
int k = -1;
switch ( node.category )
switch ( summaryNode.category )
{
case Opm::EclIO::SummaryNode::Category::Aquifer:
return RifEclipseSummaryAddress::aquiferAddress( node.keyword, node.number );
return RifEclipseSummaryAddress::aquiferAddress( summaryNode.keyword, summaryNode.number );
break;
case Opm::EclIO::SummaryNode::Category::Well:
return RifEclipseSummaryAddress::wellAddress( node.keyword, node.wgname );
return RifEclipseSummaryAddress::wellAddress( summaryNode.keyword, summaryNode.wgname );
break;
case Opm::EclIO::SummaryNode::Category::Group:
return RifEclipseSummaryAddress::wellGroupAddress( node.keyword, node.wgname );
return RifEclipseSummaryAddress::wellGroupAddress( summaryNode.keyword, summaryNode.wgname );
break;
case Opm::EclIO::SummaryNode::Category::Field:
return RifEclipseSummaryAddress::fieldAddress( node.keyword );
return RifEclipseSummaryAddress::fieldAddress( summaryNode.keyword );
break;
case Opm::EclIO::SummaryNode::Category::Region:
return RifEclipseSummaryAddress::regionAddress( node.keyword, node.number );
return RifEclipseSummaryAddress::regionAddress( summaryNode.keyword, summaryNode.number );
break;
case Opm::EclIO::SummaryNode::Category::Block:
summaryFile->ijk_from_global_index( node.number, i, j, k );
return RifEclipseSummaryAddress::blockAddress( node.keyword, i, j, k );
summaryFile->ijk_from_global_index( summaryNode.number, i, j, k );
return RifEclipseSummaryAddress::blockAddress( summaryNode.keyword, i, j, k );
break;
case Opm::EclIO::SummaryNode::Category::Connection:
summaryFile->ijk_from_global_index( node.number, i, j, k );
return RifEclipseSummaryAddress::wellCompletionAddress( node.keyword, node.wgname, i, j, k );
summaryFile->ijk_from_global_index( summaryNode.number, i, j, k );
return RifEclipseSummaryAddress::wellCompletionAddress( summaryNode.keyword, summaryNode.wgname, i, j, k );
break;
case Opm::EclIO::SummaryNode::Category::Segment:
return RifEclipseSummaryAddress::wellSegmentAddress( node.keyword, node.wgname, node.number );
return RifEclipseSummaryAddress::wellSegmentAddress( summaryNode.keyword, summaryNode.wgname, summaryNode.number );
break;
case Opm::EclIO::SummaryNode::Category::Miscellaneous:
return RifEclipseSummaryAddress::miscAddress( node.keyword );
return RifEclipseSummaryAddress::miscAddress( summaryNode.keyword );
break;
default:
break;
@ -272,3 +269,31 @@ RifEclipseSummaryAddress RifOpmCommonEclipseSummary::createAddressFromSummaryNod
return RifEclipseSummaryAddress();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<std::set<RifEclipseSummaryAddress>, std::map<RifEclipseSummaryAddress, size_t>>
RifOpmCommonSummaryTools::buildMetaData( const Opm::EclIO::ESmry* summaryFile )
{
std::set<RifEclipseSummaryAddress> addresses;
std::map<RifEclipseSummaryAddress, size_t> addressToNodeIndexMap;
if ( summaryFile )
{
auto nodes = summaryFile->summaryNodeList();
for ( size_t i = 0; i < nodes.size(); i++ )
{
auto summaryNode = nodes[i];
auto eclAdr = createAddressFromSummaryNode( summaryNode, summaryFile );
if ( eclAdr.isValid() )
{
addresses.insert( eclAdr );
addressToNodeIndexMap[eclAdr] = i;
}
}
}
return { addresses, addressToNodeIndexMap };
}

View File

@ -41,6 +41,18 @@ namespace EclIO
} // namespace EclIO
} // namespace Opm
class RiaThreadSafeLogger;
class RifOpmCommonSummaryTools
{
public:
static RifEclipseSummaryAddress createAddressFromSummaryNode( const Opm::EclIO::SummaryNode& summaryNode,
const Opm::EclIO::ESmry* summaryFile );
static std::pair<std::set<RifEclipseSummaryAddress>, std::map<RifEclipseSummaryAddress, size_t>>
buildMetaData( const Opm::EclIO::ESmry* summaryFile );
};
//==================================================================================================
//
//
@ -57,7 +69,7 @@ public:
static void resetLodCount();
static size_t numberOfLodFilesCreated();
bool open( const QString& headerFileName, bool includeRestartFiles );
bool open( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
const std::vector<time_t>& timeSteps( const RifEclipseSummaryAddress& resultAddress ) const override;
bool values( const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values ) const override;
@ -66,13 +78,10 @@ public:
private:
void buildMetaData();
bool openESmryFile( const QString& headerFileName, bool includeRestartFiles );
bool openESmryFile( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
static void increaseLodFileCount();
static RifEclipseSummaryAddress createAddressFromSummaryNode( const Opm::EclIO::SummaryNode& summaryNode,
Opm::EclIO::ESmry* summaryFile );
private:
std::unique_ptr<Opm::EclIO::ESmry> m_eSmry;
std::vector<std::string> m_eSmryKeywords;

View File

@ -0,0 +1,196 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RifOpmHdf5Summary.h"
#include "RiaLogging.h"
#include "RifHdf5SummaryReader.h"
#include "RifOpmCommonSummary.h"
#include "opm/io/eclipse/ESmry.hpp"
#include <QFileInfo>
#ifdef USE_OPENMP
#include <omp.h>
#endif
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifOpmHdf5Summary::RifOpmHdf5Summary()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifOpmHdf5Summary::~RifOpmHdf5Summary()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifOpmHdf5Summary::open( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger )
{
if ( !openESmryFile( headerFileName, includeRestartFiles, threadSafeLogger ) )
{
QString errorTxt = "Failed to open " + headerFileName;
if ( threadSafeLogger ) threadSafeLogger->error( errorTxt );
return false;
}
QFileInfo fi( headerFileName );
QString hdfFileName = fi.absolutePath() + "/" + fi.baseName() + ".h5";
if ( !QFile::exists( hdfFileName ) )
{
QString errorTxt = "Failed to open H5 file " + hdfFileName;
if ( threadSafeLogger ) threadSafeLogger->error( errorTxt );
return false;
}
m_hdf5Reader = std::make_unique<RifHdf5SummaryReader>( hdfFileName );
if ( !m_eSmry || !m_hdf5Reader ) return false;
buildMetaData();
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RifOpmHdf5Summary::timeSteps( const RifEclipseSummaryAddress& resultAddress ) const
{
return m_timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifOpmHdf5Summary::values( const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values ) const
{
if ( m_eSmry && m_hdf5Reader )
{
auto it = m_adrToSummaryNodeIndex.find( resultAddress );
if ( it != m_adrToSummaryNodeIndex.end() )
{
size_t index = it->second;
auto node = m_eSmry->summaryNodeList()[index];
int smspecIndex = static_cast<int>( node.smspecKeywordIndex );
const auto& vectorName = resultAddress.quantityName();
*values = m_hdf5Reader->values( vectorName, smspecIndex );
return true;
}
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifOpmHdf5Summary::unitName( const RifEclipseSummaryAddress& resultAddress ) const
{
if ( m_eSmry )
{
auto it = m_adrToSummaryNodeIndex.find( resultAddress );
if ( it != m_adrToSummaryNodeIndex.end() )
{
auto index = it->second;
auto node = m_eSmry->summaryNodeList()[index];
return m_eSmry->get_unit( node );
}
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::EclipseUnitSystem RifOpmHdf5Summary::unitSystem() const
{
// TODO: Not implemented
return RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifOpmHdf5Summary::buildMetaData()
{
if ( m_eSmry )
{
// Get time step data from HDF
if ( m_hdf5Reader )
{
m_timeSteps = m_hdf5Reader->timeSteps();
}
else
{
// Fallback to using opm-reader for time step data
std::vector<std::chrono::system_clock::time_point> timePoints;
timePoints = m_eSmry->dates();
for ( const auto& d : timePoints )
{
auto timeAsTimeT = std::chrono::system_clock::to_time_t( d );
m_timeSteps.push_back( timeAsTimeT );
}
}
auto [addresses, addressMap] = RifOpmCommonSummaryTools::buildMetaData( m_eSmry.get() );
m_allResultAddresses = addresses;
m_adrToSummaryNodeIndex = addressMap;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifOpmHdf5Summary::openESmryFile( const QString& headerFileName,
bool includeRestartFiles,
RiaThreadSafeLogger* threadSafeLogger )
{
try
{
m_eSmry = std::make_unique<Opm::EclIO::ESmry>( headerFileName.toStdString(), includeRestartFiles, false );
}
catch ( std::exception& e )
{
QString txt = QString( "Optimized Summary Reader error : %1" ).arg( e.what() );
if ( threadSafeLogger ) threadSafeLogger->error( txt );
return false;
}
return true;
}

View File

@ -0,0 +1,75 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RiaDefines.h"
#include "RifEclipseSummaryAddress.h"
#include "RifSummaryReaderInterface.h"
#include <QString>
#include <QStringList>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
class RifHdf5SummaryReader;
class RiaThreadSafeLogger;
namespace Opm
{
namespace EclIO
{
class ESmry;
struct SummaryNode;
} // namespace EclIO
} // namespace Opm
//==================================================================================================
//
//
//==================================================================================================
class RifOpmHdf5Summary : public RifSummaryReaderInterface
{
public:
RifOpmHdf5Summary();
~RifOpmHdf5Summary();
bool open( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
const std::vector<time_t>& timeSteps( const RifEclipseSummaryAddress& resultAddress ) const override;
bool values( const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values ) const override;
std::string unitName( const RifEclipseSummaryAddress& resultAddress ) const override;
RiaDefines::EclipseUnitSystem unitSystem() const override;
private:
void buildMetaData();
bool openESmryFile( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
private:
std::unique_ptr<Opm::EclIO::ESmry> m_eSmry;
std::vector<std::string> m_eSmryKeywords;
std::map<RifEclipseSummaryAddress, size_t> m_adrToSummaryNodeIndex;
std::vector<time_t> m_timeSteps;
std::unique_ptr<RifHdf5SummaryReader> m_hdf5Reader;
};

View File

@ -28,6 +28,10 @@
#include "RifOpmCommonSummary.h"
#include "RifReaderEclipseOutput.h"
#ifdef USE_HDF5
#include "RifOpmHdf5Summary.h"
#endif
#include <cassert>
#include <string>
@ -147,17 +151,33 @@ RifReaderEclipseSummary::~RifReaderEclipseSummary()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseSummary::open( const QString& headerFileName, bool includeRestartFiles )
bool RifReaderEclipseSummary::open( const QString& headerFileName,
bool includeRestartFiles,
RiaThreadSafeLogger* threadSafeLogger )
{
bool useOpmCommonReader = RiaPreferences::current()->useOptimizedSummaryDataReader();
bool isValid = false;
if ( useOpmCommonReader )
// Try to create readers. If HDF5 or Opm readers fails to create, use ecllib reader
if ( RiaPreferences::current()->summaryDataReader() == RiaPreferences::SummaryReaderMode::HDF5_OPM_COMMON )
{
#ifdef USE_HDF5
auto hdfReader = std::make_unique<RifOpmHdf5Summary>();
isValid = hdfReader->open( headerFileName, false, threadSafeLogger );
if ( isValid )
{
m_hdf5OpmReader = std::move( hdfReader );
}
#endif
}
else if ( RiaPreferences::current()->summaryDataReader() == RiaPreferences::SummaryReaderMode::OPM_COMMON )
{
bool useLodsmryFiles = RiaPreferences::current()->useOptimizedSummaryDataFiles();
if ( useLodsmryFiles && includeRestartFiles )
{
RiaLogging::error(
"LODSMRY file loading for summary restart files is not supported. Disable one of the options" );
QString txt = "LODSMRY file loading for summary restart files is not supported. Disable one of the options";
if ( threadSafeLogger ) threadSafeLogger->error( txt );
return false;
}
@ -166,13 +186,12 @@ bool RifReaderEclipseSummary::open( const QString& headerFileName, bool includeR
m_opmCommonReader->useLodsmaryFiles( RiaPreferences::current()->useOptimizedSummaryDataFiles() );
m_opmCommonReader->createLodsmaryFiles( RiaPreferences::current()->createOptimizedSummaryDataFiles() );
m_opmCommonReader->open( headerFileName, includeRestartFiles );
buildMetaData();
return true;
isValid = m_opmCommonReader->open( headerFileName, includeRestartFiles, threadSafeLogger );
if ( !isValid ) m_opmCommonReader.reset();
}
if ( !isValid || RiaPreferences::current()->summaryDataReader() == RiaPreferences::SummaryReaderMode::LIBECL )
{
assert( m_ecl_sum == nullptr );
m_ecl_sum = openEclSum( headerFileName, includeRestartFiles );
@ -183,12 +202,17 @@ bool RifReaderEclipseSummary::open( const QString& headerFileName, bool includeR
m_ecl_SmSpec = ecl_sum_get_smspec( m_ecl_sum );
m_timeSteps = getTimeSteps( m_ecl_sum );
m_unitSystem = readUnitSystem( m_ecl_sum );
buildMetaData();
return true;
isValid = true;
}
}
return false;
if ( isValid )
{
buildMetaData();
}
return isValid;
}
//--------------------------------------------------------------------------------------------------
@ -455,11 +479,11 @@ RifEclipseSummaryAddress addressFromErtSmSpecNode( const ecl::smspec_node& ertSu
//--------------------------------------------------------------------------------------------------
bool RifReaderEclipseSummary::values( const RifEclipseSummaryAddress& resultAddress, std::vector<double>* values ) const
{
CVF_ASSERT( values );
values->clear();
values->reserve( timeStepCount() );
// assert( m_ecl_sum != nullptr );
const std::vector<double>& cachedValues = m_valuesCache->getValues( resultAddress );
if ( !cachedValues.empty() )
{
@ -468,12 +492,21 @@ bool RifReaderEclipseSummary::values( const RifEclipseSummaryAddress& resultAddr
return true;
}
if ( m_hdf5OpmReader )
{
auto status = m_hdf5OpmReader->values( resultAddress, values );
if ( status ) m_valuesCache->insertValues( resultAddress, *values );
return status;
}
if ( m_opmCommonReader )
{
m_opmCommonReader->values( resultAddress, values );
m_valuesCache->insertValues( resultAddress, *values );
auto status = m_opmCommonReader->values( resultAddress, values );
if ( status ) m_valuesCache->insertValues( resultAddress, *values );
return true;
return status;
}
if ( m_ecl_SmSpec )
@ -536,16 +569,7 @@ bool RifReaderEclipseSummary::values( const RifEclipseSummaryAddress& resultAddr
//--------------------------------------------------------------------------------------------------
size_t RifReaderEclipseSummary::timeStepCount() const
{
if ( m_opmCommonReader )
{
return m_timeSteps.size();
}
assert( m_ecl_sum != nullptr );
if ( m_ecl_SmSpec == nullptr ) return 0;
return static_cast<size_t>( ecl_sum_get_data_length( m_ecl_sum ) );
}
//--------------------------------------------------------------------------------------------------
@ -553,8 +577,6 @@ size_t RifReaderEclipseSummary::timeStepCount() const
//--------------------------------------------------------------------------------------------------
const std::vector<time_t>& RifReaderEclipseSummary::timeSteps( const RifEclipseSummaryAddress& resultAddress ) const
{
// assert( m_ecl_sum != nullptr );
return m_timeSteps;
}
@ -580,6 +602,15 @@ void RifReaderEclipseSummary::buildMetaData()
m_allResultAddresses.clear();
m_resultAddressToErtNodeIdx.clear();
if ( m_hdf5OpmReader )
{
m_allResultAddresses = m_hdf5OpmReader->allResultAddresses();
m_allErrorAddresses = m_hdf5OpmReader->allErrorAddresses();
m_timeSteps = m_hdf5OpmReader->timeSteps( RifEclipseSummaryAddress() );
return;
}
if ( m_opmCommonReader )
{
m_allResultAddresses = m_opmCommonReader->allResultAddresses();

View File

@ -32,6 +32,8 @@
#include <vector>
class RifOpmCommonEclipseSummary;
class RifOpmHdf5Summary;
class RiaThreadSafeLogger;
//==================================================================================================
//
@ -68,7 +70,7 @@ public:
RifReaderEclipseSummary();
~RifReaderEclipseSummary() override;
bool open( const QString& headerFileName, bool includeRestartFiles );
bool open( const QString& headerFileName, bool includeRestartFiles, RiaThreadSafeLogger* threadSafeLogger );
std::vector<RifRestartFileInfo> getRestartFiles( const QString& headerFileName, bool* hasWarnings );
RifRestartFileInfo getFileInfo( const QString& headerFileName );
@ -107,6 +109,7 @@ private:
std::set<RifEclipseSummaryAddress> m_differenceAddresses;
std::unique_ptr<RifOpmCommonEclipseSummary> m_opmCommonReader;
std::unique_ptr<RifSummaryReaderInterface> m_hdf5OpmReader;
//==================================================================================================
//

View File

@ -85,13 +85,24 @@ void RimFileSummaryCase::updateFilePathsFromProjectPath( const QString& newProje
// RimTools::relocateFile( m_summaryHeaderFilename().path(), newProjectPath, oldProjectPath, nullptr, nullptr );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFileSummaryCase::createSummaryReaderInterfaceThreadSafe( RiaThreadSafeLogger* threadSafeLogger )
{
m_summaryFileReader = RimFileSummaryCase::findRelatedFilesAndCreateReader( this->summaryHeaderFilename(),
m_includeRestartFiles,
threadSafeLogger );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimFileSummaryCase::createSummaryReaderInterface()
{
m_summaryFileReader =
RimFileSummaryCase::findRelatedFilesAndCreateReader( this->summaryHeaderFilename(), m_includeRestartFiles );
m_summaryFileReader = RimFileSummaryCase::findRelatedFilesAndCreateReader( this->summaryHeaderFilename(),
m_includeRestartFiles,
nullptr );
}
//--------------------------------------------------------------------------------------------------
@ -110,16 +121,15 @@ void RimFileSummaryCase::createRftReaderInterface()
///
//--------------------------------------------------------------------------------------------------
RifReaderEclipseSummary* RimFileSummaryCase::findRelatedFilesAndCreateReader( const QString& headerFileName,
bool includeRestartFiles )
bool includeRestartFiles,
RiaThreadSafeLogger* threadSafeLogger )
{
RifReaderEclipseSummary* summaryFileReader = new RifReaderEclipseSummary;
if ( !summaryFileReader->open( headerFileName, includeRestartFiles ) )
if ( !summaryFileReader->open( headerFileName, includeRestartFiles, threadSafeLogger ) )
{
RiaLogging::warning( QString( "Failed to open summary file %1" ).arg( headerFileName ) );
delete summaryFileReader;
summaryFileReader = nullptr;
return nullptr;
}
return summaryFileReader;

View File

@ -25,6 +25,7 @@
class RifReaderRftInterface;
class RifReaderEclipseRft;
class RifReaderEclipseSummary;
class RiaThreadSafeLogger;
//==================================================================================================
//
@ -43,6 +44,7 @@ public:
QString caseName() const override;
void updateFilePathsFromProjectPath( const QString& newProjectPath, const QString& oldProjectPath ) override;
void createSummaryReaderInterfaceThreadSafe( RiaThreadSafeLogger* threadSafeLogger );
void createSummaryReaderInterface() override;
void createRftReaderInterface() override;
RifSummaryReaderInterface* summaryReader() override;
@ -51,7 +53,9 @@ public:
void setIncludeRestartFiles( bool includeRestartFiles );
static RifReaderEclipseSummary* findRelatedFilesAndCreateReader( const QString& headerFileName,
bool includeRestartFiles );
bool includeRestartFiles,
RiaThreadSafeLogger* threadSafeLogger );
static RifReaderEclipseRft* findRftDataAndCreateReader( const QString& headerFileName );
private:

View File

@ -182,8 +182,9 @@ void RimGridSummaryCase::updateFilePathsFromProjectPath( const QString& newProje
//--------------------------------------------------------------------------------------------------
void RimGridSummaryCase::createSummaryReaderInterface()
{
m_summaryFileReader =
RimFileSummaryCase::findRelatedFilesAndCreateReader( this->summaryHeaderFilename(), m_includeRestartFiles );
m_summaryFileReader = RimFileSummaryCase::findRelatedFilesAndCreateReader( this->summaryHeaderFilename(),
m_includeRestartFiles,
nullptr );
}
//--------------------------------------------------------------------------------------------------

View File

@ -441,18 +441,29 @@ void RimSummaryCaseMainCollection::loadFileSummaryCaseData( std::vector<RimFileS
RifOpmCommonEclipseSummary::resetLodCount();
#pragma omp parallel for schedule( dynamic )
RiaThreadSafeLogger threadSafeLogger;
// The HDF5 reader requires a special configuration to be thread safe. Disable threading for HDF reader creation.
bool canUseMultipleTreads =
( RiaPreferences::current()->summaryDataReader() != RiaPreferences::SummaryReaderMode::HDF5_OPM_COMMON );
#pragma omp parallel for schedule( dynamic ) if ( canUseMultipleTreads )
for ( int cIdx = 0; cIdx < static_cast<int>( fileSummaryCases.size() ); ++cIdx )
{
RimFileSummaryCase* fileSummaryCase = fileSummaryCases[cIdx];
if ( fileSummaryCase )
{
fileSummaryCase->createSummaryReaderInterface();
fileSummaryCase->createSummaryReaderInterfaceThreadSafe( &threadSafeLogger );
}
progInfo.setProgress( cIdx );
}
for ( const auto& txt : threadSafeLogger.messages() )
{
RiaLogging::info( txt );
}
auto numberOfLodFilesCreated = RifOpmCommonEclipseSummary::numberOfLodFilesCreated();
if ( numberOfLodFilesCreated > 0 )
{

View File

@ -2,10 +2,130 @@
#include "gtest/gtest.h"
#include "RiaTestDataDirectory.h"
#include "RifHdf5SummaryReader.h"
#include "RifOpmHdf5Summary.h"
#include "H5Cpp.h"
#include <iostream>
#include <H5Exception.h>
#include "opm/io/eclipse/ESmry.hpp"
static const QString H5_TEST_DATA_DIRECTORY = QString( "%1/h5-file/" ).arg( TEST_DATA_DIR );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( HDFTests, InspectSummaryData )
{
std::string file_path = H5_TEST_DATA_DIRECTORY.toStdString() + "NORNE_ATW2013_RFTPLT_V2.h5";
try
{
H5::Exception::dontPrint(); // Turn off auto-printing of failures to handle the errors appropriately
H5::H5File file( file_path.c_str(), H5F_ACC_RDONLY );
{
H5::Group GridFunction_00002 = file.openGroup( "summary_vectors/BPR/66" );
H5::DataSet dataset = H5::DataSet( GridFunction_00002.openDataSet( "values" ) );
hsize_t dims[2];
H5::DataSpace dataspace = dataset.getSpace();
dataspace.getSimpleExtentDims( dims, nullptr );
std::vector<double> values;
values.resize( dims[0] );
dataset.read( values.data(), H5::PredType::NATIVE_DOUBLE );
EXPECT_EQ( size_t( 894 ), values.size() );
}
}
catch ( H5::FileIException& error ) // catch failure caused by the H5File operations
{
std::cout << error.getCDetailMsg();
}
catch ( H5::DataSetIException& error ) // catch failure caused by the DataSet operations
{
std::cout << error.getCDetailMsg();
}
catch ( H5::DataSpaceIException& error ) // catch failure caused by the DataSpace operations
{
std::cout << error.getCDetailMsg();
}
catch ( H5::DataTypeIException& error ) // catch failure caused by the DataSpace operations
{
std::cout << error.getCDetailMsg();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( HDFTests, ReadSummaryData )
{
QString filePath = H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.h5";
RifHdf5SummaryReader hdf5SummaryReader( filePath );
auto vectorNames = hdf5SummaryReader.vectorNames();
EXPECT_EQ( size_t( 211 ), vectorNames.size() );
auto timeSteps = hdf5SummaryReader.timeSteps();
EXPECT_EQ( size_t( 894 ), timeSteps.size() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( HDFTests, ReadOpmSummaryData )
{
QString filePath = H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.SMSPEC";
RifOpmHdf5Summary hdf5SummaryReader;
hdf5SummaryReader.open( filePath, false, nullptr );
auto addresses = hdf5SummaryReader.allResultAddresses();
EXPECT_EQ( size_t( 2770 ), addresses.size() );
int itemCount = 0;
size_t totalValueCount = 0;
for ( const auto& adr : addresses )
{
if ( itemCount++ < 10 )
{
std::vector<double> values;
hdf5SummaryReader.values( adr, &values );
totalValueCount += values.size();
}
}
EXPECT_EQ( size_t( 8940 ), totalValueCount );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TEST( DISABLED_HDFTests, ReadOpmSummaryDataListContent )
{
QString filePath = H5_TEST_DATA_DIRECTORY + "NORNE_ATW2013_RFTPLT_V2.SMSPEC";
Opm::EclIO::ESmry eSmry( filePath.toStdString() );
auto nodes = eSmry.summaryNodeList();
for ( size_t i = 0; i < nodes.size(); i++ )
{
Opm::EclIO::SummaryNode n = nodes[i];
std::cout << n.keyword << " number: " << n.number << " msjNumber: " << n.smspecKeywordIndex << " "
<< n.unique_key() << "\n";
}
}
//--------------------------------------------------------------------------------------------------
///

View File

@ -23,7 +23,7 @@ TEST( DISABLED_RifSummaryDataTest, OpmCommonAllData )
{
auto start = std::chrono::high_resolution_clock::now();
reader.open( filename, true );
reader.open( filename, true, nullptr );
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
@ -74,7 +74,7 @@ TEST( DISABLED_RifSummaryDataTest, LibEclAllData )
{
auto start = std::chrono::high_resolution_clock::now();
reader.open( filename, true );
reader.open( filename, true, nullptr );
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;