///////////////////////////////////////////////////////////////////////////////// // // 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RifProjectSummaryDataWriter.h" #include "RifSummaryReaderInterface.h" #include "cafAssert.h" #ifdef _MSC_VER // Disable warning from external library to make sure treat warnings as error works #pragma warning( disable : 4267 ) #endif #include "opm/common/utility/TimeService.hpp" #include "opm/io/eclipse/EclOutput.hpp" #include "opm/io/eclipse/ExtESmry.hpp" #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RifProjectSummaryDataWriter::RifProjectSummaryDataWriter() : m_timeStepCount( 0 ) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifProjectSummaryDataWriter::importFromSourceSummaryReader( const RifSummaryReaderInterface* reader ) { if ( !reader ) return; std::string keyword = "TIME"; auto summaryAddress = RifEclipseSummaryAddress::miscAddress( keyword ); if ( reader->hasAddress( summaryAddress ) ) { auto timeSteps = reader->timeSteps( summaryAddress ); if ( !timeSteps.empty() ) { Opm::TimeStampUTC ts( timeSteps.front() ); m_startTime = { ts.day(), ts.month(), ts.year(), ts.hour(), ts.minutes(), ts.seconds(), 0 }; } auto [isOk, values] = reader->values( summaryAddress ); const auto& unitString = reader->unitName( summaryAddress ); m_keywords.push_back( keyword ); m_units.push_back( unitString ); std::vector floatValues; floatValues.reserve( values.size() ); for ( const auto& v : values ) { floatValues.push_back( v ); } m_values.push_back( floatValues ); m_timeStepCount = values.size(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifProjectSummaryDataWriter::importFromProjectSummaryFile( const std::string& projectSummaryFileName ) { try { Opm::EclIO::ExtESmry sourceSummary( projectSummaryFileName ); Opm::TimeStampUTC ts( std::chrono::system_clock::to_time_t( sourceSummary.startdate() ) ); m_startTime = { ts.day(), ts.month(), ts.year(), ts.hour(), ts.minutes(), ts.seconds(), 0 }; auto keywords = sourceSummary.keywordList(); for ( const auto& keyword : keywords ) { const auto& values = sourceSummary.get( keyword ); const auto& unitString = sourceSummary.get_unit( keyword ); m_keywords.push_back( keyword ); m_units.push_back( unitString ); m_values.push_back( values ); if ( m_timeStepCount == 0 ) { m_timeStepCount = values.size(); } } } catch ( ... ) { std::string txt = "Error detected during import of data from " + projectSummaryFileName; m_errorMessages.push_back( txt ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifProjectSummaryDataWriter::setData( const std::vector& keywords, const std::vector& units, const std::vector>& values ) { if ( keywords.empty() ) return; CAF_ASSERT( keywords.size() == units.size() ); CAF_ASSERT( keywords.size() == values.size() ); for ( size_t i = 0; i < keywords.size(); i++ ) { auto existingIndex = indexForKeyword( keywords[i] ); if ( existingIndex == -1 ) { m_keywords.push_back( keywords[i] ); m_units.push_back( units[i] ); m_values.push_back( values[i] ); } else { // Overwrite existing data m_keywords[existingIndex] = keywords[i]; m_units[existingIndex] = units[i]; m_values[existingIndex] = values[i]; } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifProjectSummaryDataWriter::writeDataToFile( const std::string& fileName ) { // Reference to other locations writing to ESMRY files // ESmry::make_esmry_file() // ExtSmryOutput::write() try { // The ExtESmry reader supports only binary mode, set formatted to false bool formatted = false; Opm::EclIO::EclOutput outFile( fileName, formatted, std::ios::out ); outFile.write( "START", m_startTime ); outFile.write( "KEYCHECK", m_keywords ); outFile.write( "UNITS", m_units ); { // Bool array 1 means RSTEP, 0 means no RSTEP // Dummy values, but required by the reader std::vector intValues( m_timeStepCount, 1 ); outFile.write( "RSTEP", intValues ); } { // TSTEP represents time steps // Dummy values, but required by the reader std::vector intValues; intValues.resize( m_timeStepCount ); std::iota( intValues.begin(), intValues.end(), 0 ); outFile.write( "TSTEP", intValues ); } for ( size_t i = 0; i < static_cast( m_keywords.size() ); i++ ) { std::string vect_name = "V" + std::to_string( i ); outFile.write( vect_name, m_values[i] ); } } catch ( ... ) { std::string txt = "Error detected during export of data to " + fileName; m_errorMessages.push_back( txt ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RifProjectSummaryDataWriter::errorMessages() const { return m_errorMessages; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RifProjectSummaryDataWriter::clearErrorMessages() { m_errorMessages.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- int RifProjectSummaryDataWriter::indexForKeyword( const std::string& keyword ) const { for ( int i = 0; i < static_cast( m_keywords.size() ); i++ ) { if ( m_keywords[i] == keyword ) return i; } return -1; }