///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2020- 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 "RiaOpmParserTools.h" #include "RiaLogging.h" #include "RiaTextStringTools.h" #include "RifEclipseInputFileTools.h" #include "cafPdmUiItem.h" #include "cafUtils.h" #include "opm/input/eclipse/Deck/Deck.hpp" #include "opm/input/eclipse/Parser/ParseContext.hpp" #include "opm/input/eclipse/Parser/Parser.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/I.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/P.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/V.hpp" #include "opm/input/eclipse/Parser/ParserKeywords/W.hpp" #include #include //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RiaOpmParserTools::extractVfpInjectionTables( const std::string& filename ) { std::vector tables; try { Opm::Parser parser( false ); const ::Opm::ParserKeywords::VFPINJ kw1; const ::Opm::ParserKeywords::VFPIDIMS kw2; parser.addParserKeyword( kw1 ); parser.addParserKeyword( kw2 ); auto deck = parser.parseFile( filename ); std::string myKeyword = "VFPINJ"; auto keywordList = deck.getKeywordList( myKeyword ); for ( auto kw : keywordList ) { auto name = kw->name(); Opm::UnitSystem unitSystem; { const auto& header = kw->getRecord( 0 ); if ( header.getItem().hasValue( 0 ) ) { std::string units_string; units_string = header.getItem().get( 0 ); unitSystem = Opm::UnitSystem( units_string ); } } Opm::VFPInjTable table( *kw, unitSystem ); tables.push_back( table ); } } catch ( ... ) { } return tables; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RiaOpmParserTools::extractVfpProductionTables( const std::string& filename ) { std::vector tables; try { Opm::Parser parser( false ); const ::Opm::ParserKeywords::VFPPROD kw1; parser.addParserKeyword( kw1 ); auto deck = parser.parseFile( filename ); std::string myKeyword = "VFPPROD"; auto keywordList = deck.getKeywordList( myKeyword ); for ( auto kw : keywordList ) { auto name = kw->name(); Opm::UnitSystem unitSystem; { const auto& header = kw->getRecord( 0 ); if ( header.getItem().hasValue( 0 ) ) { std::string units_string; units_string = header.getItem().get( 0 ); unitSystem = Opm::UnitSystem( units_string ); } } bool gaslift_opt_active = false; Opm::VFPProdTable table( *kw, gaslift_opt_active, unitSystem ); tables.push_back( table ); } } catch ( ... ) { } return tables; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::map>> RiaOpmParserTools::extractWseglink( const std::string& filename ) { if ( !std::filesystem::exists( filename ) ) return {}; Opm::Parser parser( false ); const Opm::ParserKeywords::WSEGLINK kw1; const Opm::ParserKeywords::INCLUDE kw2; const Opm::ParserKeywords::PATHS kw3; parser.addParserKeyword( kw1 ); parser.addParserKeyword( kw2 ); parser.addParserKeyword( kw3 ); std::stringstream ss; Opm::ParseContext parseContext( Opm::InputError::Action::WARN ); auto deck = parser.parseFile( filename, parseContext ); std::string keyword = "WSEGLINK"; auto keywordList = deck.getKeywordList( keyword ); if ( keywordList.empty() ) return {}; std::map>> wseglink; for ( auto kw : keywordList ) { auto name = kw->name(); for ( size_t i = 0; i < kw->size(); i++ ) { auto deckRecord = kw->getRecord( i ); std::string wellName; int segment1 = -1; int segment2 = -1; { auto itemName = ::Opm::ParserKeywords::WSEGLINK::WELL::itemName; if ( deckRecord.hasItem( itemName ) && deckRecord.getItem( itemName ).hasValue( 0 ) ) { wellName = deckRecord.getItem( itemName ).getTrimmedString( 0 ); } } { auto itemName = ::Opm::ParserKeywords::WSEGLINK::SEGMENT1::itemName; if ( deckRecord.hasItem( itemName ) && deckRecord.getItem( itemName ).hasValue( 0 ) ) { segment1 = deckRecord.getItem( itemName ).get( 0 ); } } { auto itemName = ::Opm::ParserKeywords::WSEGLINK::SEGMENT2::itemName; if ( deckRecord.hasItem( itemName ) && deckRecord.getItem( itemName ).hasValue( 0 ) ) { segment2 = deckRecord.getItem( itemName ).get( 0 ); } } if ( segment1 != -1 && segment2 != -1 ) { wseglink[wellName].push_back( std::make_pair( segment1, segment2 ) ); } } } return wseglink; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RiaOpmParserTools::extractWsegAicd( const std::string& filename ) { if ( !std::filesystem::exists( filename ) ) return {}; try { Opm::Parser parser( false ); const Opm::ParserKeywords::WSEGAICD kw1; const Opm::ParserKeywords::INCLUDE kw2; const Opm::ParserKeywords::PATHS kw3; parser.addParserKeyword( kw1 ); parser.addParserKeyword( kw2 ); parser.addParserKeyword( kw3 ); std::stringstream ss; Opm::ParseContext parseContext( Opm::InputError::Action::WARN ); auto deck = parser.parseFile( filename, parseContext ); const std::string keyword = "WSEGAICD"; auto keywordList = deck.getKeywordList( keyword ); if ( keywordList.empty() ) return {}; using namespace Opm::ParserKeywords; std::set keywordsToExtract = { WSEGAICD::STRENGTH::itemName, WSEGAICD::DENSITY_CALI::itemName, WSEGAICD::VISCOSITY_CALI::itemName, WSEGAICD::FLOW_RATE_EXPONENT::itemName, WSEGAICD::VISC_EXPONENT::itemName, WSEGAICD::CRITICAL_VALUE::itemName, WSEGAICD::MAX_ABS_RATE::itemName, WSEGAICD::OIL_FLOW_FRACTION::itemName, WSEGAICD::WATER_FLOW_FRACTION::itemName, WSEGAICD::GAS_FLOW_FRACTION::itemName, WSEGAICD::OIL_VISC_FRACTION::itemName, WSEGAICD::WATER_VISC_FRACTION::itemName, WSEGAICD::GAS_VISC_FRACTION::itemName }; std::vector aicdData; for ( const auto& kw : keywordList ) { auto name = kw->name(); for ( size_t kwIndex = 0; kwIndex < kw->size(); kwIndex++ ) { RiaOpmParserTools::AicdTemplateValues aicdTemplate; auto deckRecord = kw->getRecord( kwIndex ); auto numItems = deckRecord.size(); for ( size_t deckIndex = 0; deckIndex < numItems; deckIndex++ ) { auto deckItem = deckRecord.getItem( deckIndex ); if ( !deckItem.hasValue( 0 ) ) continue; if ( !keywordsToExtract.contains( deckItem.name() ) ) continue; auto typeTag = deckItem.getType(); if ( typeTag == Opm::type_tag::fdouble ) { // Only read out explicitly set values. If the value is defaulted, do not read out the value to make sure the string // "1*" is displayed in the GUI if ( !deckItem.defaultApplied( 0 ) ) { double doubleValue = deckItem.get( 0 ); aicdTemplate[deckItem.name()] = doubleValue; } } } aicdData.push_back( aicdTemplate ); } } return aicdData; } catch ( std::exception& e ) { RiaLogging::error( e.what() ); } return {}; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RiaOpmParserTools::extractWsegAicdCompletor( const std::string& filename ) { QFile file( QString::fromStdString( filename ) ); if ( !file.open( QFile::ReadOnly ) ) return {}; std::vector aicdTemplates; const QString keyword( "WSEGAICD" ); const QString keywordToStopParsing; auto keywordContent = RifEclipseInputFileTools::readKeywordContentFromFile( keyword, keywordToStopParsing, file ); for ( const auto& s : keywordContent ) { auto wordsInLine = RiaTextStringTools::splitSkipEmptyParts( s ); std::vector values; for ( const auto& word : wordsInLine ) { bool ok = false; auto doubleValue = word.toDouble( &ok ); if ( ok ) values.push_back( doubleValue ); } // Completor exports the values in the following format, 12 values per row // WSEGAICD // --Number Alpha x y a b c d e f rhocal viscal // 1 0.000017253 3.05 0.67 1 1 1 2.43 1.18 10.0 1000 1 // 2 0.000027253 5.05 0.53 1 1 1 2.43 1.28 7.02 1000 1 // if ( values.size() == 12 ) { RiaOpmParserTools::AicdTemplateValues aicdValues; aicdValues[aicdTemplateId()] = values[0]; aicdValues[Opm::ParserKeywords::WSEGAICD::STRENGTH::itemName] = values[1]; // Alpha aicdValues[Opm::ParserKeywords::WSEGAICD::FLOW_RATE_EXPONENT::itemName] = values[2]; // x aicdValues[Opm::ParserKeywords::WSEGAICD::VISC_EXPONENT::itemName] = values[3]; // y aicdValues[Opm::ParserKeywords::WSEGAICD::OIL_FLOW_FRACTION::itemName] = values[4]; // a aicdValues[Opm::ParserKeywords::WSEGAICD::WATER_FLOW_FRACTION::itemName] = values[5]; // b aicdValues[Opm::ParserKeywords::WSEGAICD::GAS_FLOW_FRACTION::itemName] = values[6]; // c aicdValues[Opm::ParserKeywords::WSEGAICD::OIL_VISC_FRACTION::itemName] = values[7]; // d aicdValues[Opm::ParserKeywords::WSEGAICD::WATER_VISC_FRACTION::itemName] = values[8]; // e aicdValues[Opm::ParserKeywords::WSEGAICD::GAS_VISC_FRACTION::itemName] = values[9]; // f aicdValues[Opm::ParserKeywords::WSEGAICD::DENSITY_CALI::itemName] = values[10]; // rhocal aicdValues[Opm::ParserKeywords::WSEGAICD::VISCOSITY_CALI::itemName] = values[11]; // viscal aicdTemplates.push_back( aicdValues ); } } return aicdTemplates; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::string RiaOpmParserTools::aicdTemplateId() { return "ID_NUMBER"; }