/* Copyright 2015 Statoil ASA. This file is part of the Open Porous Media project (OPM). OPM 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. OPM 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 for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include // Phase::PhaseEnum #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Opm { TableManager::TableManager( const Deck& deck ) : m_tabdims( Tabdims(deck)), hasImptvd (deck.hasKeyword("IMPTVD")), hasEnptvd (deck.hasKeyword("ENPTVD")), hasEqlnum (deck.hasKeyword("EQLNUM")), m_jfunc( deck ) { initDims( deck ); initSimpleTables( deck ); initFullTables(deck, "PVTG", m_pvtgTables); initFullTables(deck, "PVTO", m_pvtoTables); if( deck.hasKeyword( "PVTW" ) ) this->m_pvtwTable = PvtwTable( deck.getKeyword( "PVTW" ) ); if( deck.hasKeyword( "DENSITY" ) ) this->m_densityTable = DensityTable( deck.getKeyword( "DENSITY" ) ); if( deck.hasKeyword( "ROCK" ) ) this->m_rockTable = RockTable( deck.getKeyword( "ROCK" ) ); initVFPProdTables(deck, m_vfpprodTables); initVFPInjTables(deck, m_vfpinjTables); } void TableManager::initDims(const Deck& deck) { using namespace Opm::ParserKeywords; if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); const auto& record = keyword.getRecord(0); int ntsequl = record.getItem().get< int >(0); int nodes_p = record.getItem().get< int >(0); int nodes_tab = record.getItem().get< int >(0); int nttrvd = record.getItem().get< int >(0); int ntsrvd = record.getItem().get< int >(0); m_eqldims = std::make_shared(ntsequl , nodes_p , nodes_tab , nttrvd , ntsrvd ); } else m_eqldims = std::make_shared(); if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); const auto& record = keyword.getRecord(0); int ntfip = record.getItem().get< int >(0); int nmfipr = record.getItem().get< int >(0); int nrfreg = record.getItem().get< int >(0); int ntfreg = record.getItem().get< int >(0); int nplmix = record.getItem().get< int >(0); m_regdims = std::make_shared( ntfip , nmfipr , nrfreg , ntfreg , nplmix ); } else m_regdims = std::make_shared(); } void TableManager::addTables( const std::string& tableName , size_t numTables) { m_simpleTables.emplace(std::make_pair(tableName , TableContainer( numTables ))); } bool TableManager::hasTables( const std::string& tableName ) const { auto pair = m_simpleTables.find( tableName ); if (pair == m_simpleTables.end()) return false; else { const auto& tables = pair->second; return !tables.empty(); } } const TableContainer& TableManager::getTables( const std::string& tableName ) const { auto pair = m_simpleTables.find( tableName ); if (pair == m_simpleTables.end()) throw std::invalid_argument("No such table collection: " + tableName); else return pair->second; } TableContainer& TableManager::forceGetTables( const std::string& tableName , size_t numTables ) { auto pair = m_simpleTables.find( tableName ); if (pair == m_simpleTables.end()) { addTables( tableName , numTables ); pair = m_simpleTables.find( tableName ); } return pair->second; } const TableContainer& TableManager::operator[](const std::string& tableName) const { return getTables(tableName); } void TableManager::initSimpleTables(const Deck& deck) { addTables( "SWOF" , m_tabdims.getNumSatTables() ); addTables( "SGWFN", m_tabdims.getNumSatTables() ); addTables( "SGOF", m_tabdims.getNumSatTables() ); addTables( "SLGOF", m_tabdims.getNumSatTables() ); addTables( "SOF2", m_tabdims.getNumSatTables() ); addTables( "SOF3", m_tabdims.getNumSatTables() ); addTables( "SWFN", m_tabdims.getNumSatTables() ); addTables( "SGFN", m_tabdims.getNumSatTables() ); addTables( "SSFN", m_tabdims.getNumSatTables() ); addTables( "MSFN", m_tabdims.getNumSatTables() ); addTables( "PLYADS", m_tabdims.getNumSatTables() ); addTables( "PLYROCK", m_tabdims.getNumSatTables()); addTables( "PLYVISC", m_tabdims.getNumPVTTables()); addTables( "PLYDHFLF", m_tabdims.getNumPVTTables()); addTables( "PVDG", m_tabdims.getNumPVTTables()); addTables( "PVDO", m_tabdims.getNumPVTTables()); addTables( "PVDS", m_tabdims.getNumPVTTables()); addTables( "OILVISCT", m_tabdims.getNumPVTTables()); addTables( "WATVISCT", m_tabdims.getNumPVTTables()); addTables( "GASVISCT", m_tabdims.getNumPVTTables()); addTables( "PLYMAX", m_regdims->getNPLMIX()); addTables( "RSVD", m_eqldims->getNumEquilRegions()); addTables( "RVVD", m_eqldims->getNumEquilRegions()); { size_t numMiscibleTables = ParserKeywords::MISCIBLE::NTMISC::defaultValue; if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); const auto& record = keyword.getRecord(0); numMiscibleTables = static_cast(record.getItem().get< int >(0)); } addTables( "SORWMIS", numMiscibleTables); addTables( "SGCWMIS", numMiscibleTables); addTables( "MISC", numMiscibleTables); addTables( "PMISC", numMiscibleTables); addTables( "TLPMIXPA",numMiscibleTables); } { size_t numEndScaleTables = ParserKeywords::ENDSCALE::NUM_TABLES::defaultValue; if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); const auto& record = keyword.getRecord(0); numEndScaleTables = static_cast(record.getItem().get< int >(0)); } addTables( "ENKRVD", numEndScaleTables); addTables( "ENPTVD", numEndScaleTables); addTables( "IMKRVD", numEndScaleTables); addTables( "IMPTVD", numEndScaleTables); } { size_t numRocktabTables = ParserKeywords::ROCKCOMP::NTROCC::defaultValue; if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); const auto& record = keyword.getRecord(0); numRocktabTables = static_cast(record.getItem().get< int >(0)); } addTables( "ROCKTAB", numRocktabTables); } initSimpleTableContainer(deck, "SGWFN", m_tabdims.getNumSatTables()); initSimpleTableContainer(deck, "SOF2" , m_tabdims.getNumSatTables()); initSimpleTableContainer(deck, "SOF3" , m_tabdims.getNumSatTables()); { initSimpleTableContainerWithJFunc(deck, "SWOF", m_tabdims.getNumSatTables()); initSimpleTableContainerWithJFunc(deck, "SGOF", m_tabdims.getNumSatTables()); initSimpleTableContainerWithJFunc(deck, "SWFN", m_tabdims.getNumSatTables()); initSimpleTableContainerWithJFunc(deck, "SGFN", m_tabdims.getNumSatTables()); initSimpleTableContainerWithJFunc(deck, "SLGOF", m_tabdims.getNumSatTables()); } initSimpleTableContainer(deck, "SSFN" , m_tabdims.getNumSatTables()); initSimpleTableContainer(deck, "MSFN" , m_tabdims.getNumSatTables()); initSimpleTableContainer(deck, "RSVD" , m_eqldims->getNumEquilRegions()); initSimpleTableContainer(deck, "RVVD" , m_eqldims->getNumEquilRegions()); { size_t numEndScaleTables = ParserKeywords::ENDSCALE::NUM_TABLES::defaultValue; if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); const auto& record = keyword.getRecord(0); numEndScaleTables = static_cast(record.getItem().get< int >(0)); } initSimpleTableContainer( deck , "ENKRVD", numEndScaleTables); initSimpleTableContainer( deck , "ENPTVD", numEndScaleTables); initSimpleTableContainer( deck , "IMKRVD", numEndScaleTables); initSimpleTableContainer( deck , "IMPTVD", numEndScaleTables); } { size_t numMiscibleTables = ParserKeywords::MISCIBLE::NTMISC::defaultValue; if (deck.hasKeyword()) { const auto& keyword = deck.getKeyword(); const auto& record = keyword.getRecord(0); numMiscibleTables = static_cast(record.getItem().get< int >(0)); } initSimpleTableContainer(deck, "SORWMIS", numMiscibleTables); initSimpleTableContainer(deck, "SGCWMIS", numMiscibleTables); initSimpleTableContainer(deck, "MISC", numMiscibleTables); initSimpleTableContainer(deck, "PMISC", numMiscibleTables); initSimpleTableContainer(deck, "TLPMIXPA", numMiscibleTables); } initSimpleTableContainer(deck, "PVDG", m_tabdims.getNumPVTTables()); initSimpleTableContainer(deck, "PVDO", m_tabdims.getNumPVTTables()); initSimpleTableContainer(deck, "PVDS", m_tabdims.getNumPVTTables()); initSimpleTableContainer(deck, "OILVISCT", m_tabdims.getNumPVTTables()); initSimpleTableContainer(deck, "WATVISCT", m_tabdims.getNumPVTTables()); initSimpleTableContainer(deck, "PLYADS", m_tabdims.getNumSatTables()); initSimpleTableContainer(deck, "PLYVISC", m_tabdims.getNumPVTTables()); initSimpleTableContainer(deck, "PLYDHFLF", m_tabdims.getNumPVTTables()); initPlyrockTables(deck); initPlymaxTables(deck); initGasvisctTables(deck); initRTempTables(deck); initRocktabTables(deck); initPlyshlogTables(deck); } void TableManager::initRTempTables(const Deck& deck) { // the temperature vs depth table. the problem here is that // the TEMPVD (E300) and RTEMPVD (E300 + E100) keywords are // synonymous, but we want to provide only a single cannonical // API here, so we jump through some small hoops... if (deck.hasKeyword("TEMPVD") && deck.hasKeyword("RTEMPVD")) throw std::invalid_argument("The TEMPVD and RTEMPVD tables are mutually exclusive!"); else if (deck.hasKeyword("TEMPVD")) initSimpleTableContainer(deck, "TEMPVD", "RTEMPVD", m_eqldims->getNumEquilRegions()); else if (deck.hasKeyword("RTEMPVD")) initSimpleTableContainer(deck, "RTEMPVD", "RTEMPVD" , m_eqldims->getNumEquilRegions()); } void TableManager::initGasvisctTables(const Deck& deck) { const std::string keywordName = "GASVISCT"; size_t numTables = m_tabdims.getNumPVTTables(); if (!deck.hasKeyword(keywordName)) return; // the table is not featured by the deck... auto& container = forceGetTables(keywordName , numTables); if (deck.count(keywordName) > 1) { complainAboutAmbiguousKeyword(deck, keywordName); return; } const auto& tableKeyword = deck.getKeyword(keywordName); for (size_t tableIdx = 0; tableIdx < tableKeyword.size(); ++tableIdx) { const auto& tableRecord = tableKeyword.getRecord( tableIdx ); const auto& dataItem = tableRecord.getItem( 0 ); if (dataItem.size() > 0) { std::shared_ptr table = std::make_shared( deck , dataItem ); container.addTable( tableIdx , table ); } } } void TableManager::initPlyshlogTables(const Deck& deck) { const std::string keywordName = "PLYSHLOG"; if (!deck.hasKeyword(keywordName)) { return; } if (!deck.count(keywordName)) { complainAboutAmbiguousKeyword(deck, keywordName); return; } size_t numTables = m_tabdims.getNumPVTTables(); auto& container = forceGetTables(keywordName , numTables); const auto& tableKeyword = deck.getKeyword(keywordName); if (tableKeyword.size() > 2) { std::string msg = "The Parser does currently NOT support the alternating record schema used in PLYSHLOG"; throw std::invalid_argument( msg ); } for (size_t tableIdx = 0; tableIdx < tableKeyword.size(); tableIdx += 2) { const auto& indexRecord = tableKeyword.getRecord( tableIdx ); const auto& dataRecord = tableKeyword.getRecord( tableIdx + 1); const auto& dataItem = dataRecord.getItem( 0 ); if (dataItem.size() > 0) { std::shared_ptr table = std::make_shared(indexRecord , dataRecord); container.addTable( tableIdx , table ); } } } void TableManager::initPlyrockTables(const Deck& deck) { size_t numTables = m_tabdims.getNumSatTables(); const std::string keywordName = "PLYROCK"; if (!deck.hasKeyword(keywordName)) { return; } if (!deck.count(keywordName)) { complainAboutAmbiguousKeyword(deck, keywordName); return; } const auto& keyword = deck.getKeyword(); auto& container = forceGetTables(keywordName , numTables); for (size_t tableIdx = 0; tableIdx < keyword.size(); ++tableIdx) { const auto& tableRecord = keyword.getRecord( tableIdx ); std::shared_ptr table = std::make_shared(tableRecord); container.addTable( tableIdx , table ); } } void TableManager::initPlymaxTables(const Deck& deck) { size_t numTables = m_regdims->getNPLMIX(); const std::string keywordName = "PLYMAX"; if (!deck.hasKeyword(keywordName)) { return; } if (!deck.count(keywordName)) { complainAboutAmbiguousKeyword(deck, keywordName); return; } const auto& keyword = deck.getKeyword(); auto& container = forceGetTables(keywordName , numTables); for (size_t tableIdx = 0; tableIdx < keyword.size(); ++tableIdx) { const auto& tableRecord = keyword.getRecord( tableIdx ); std::shared_ptr table = std::make_shared( tableRecord ); container.addTable( tableIdx , table ); } } void TableManager::initRocktabTables(const Deck& deck) { if (!deck.hasKeyword("ROCKTAB")) return; // ROCKTAB is not featured by the deck... if (deck.count("ROCKTAB") > 1) { complainAboutAmbiguousKeyword(deck, "ROCKTAB"); return; } const auto& rockcompKeyword = deck.getKeyword(); const auto& record = rockcompKeyword.getRecord( 0 ); size_t numTables = record.getItem().get< int >(0); auto& container = forceGetTables("ROCKTAB" , numTables); const auto rocktabKeyword = deck.getKeyword("ROCKTAB"); bool isDirectional = deck.hasKeyword(); bool useStressOption = false; if (deck.hasKeyword()) { const auto rockoptsKeyword = deck.getKeyword(); const auto& rockoptsRecord = rockoptsKeyword.getRecord(0); const auto& item = rockoptsRecord.getItem(); useStressOption = (item.getTrimmedString(0) == "STRESS"); } for (size_t tableIdx = 0; tableIdx < rocktabKeyword.size(); ++tableIdx) { const auto& tableRecord = rocktabKeyword.getRecord( tableIdx ); const auto& dataItem = tableRecord.getItem( 0 ); if (dataItem.size() > 0) { std::shared_ptr table = std::make_shared( dataItem , isDirectional, useStressOption ); container.addTable( tableIdx , table ); } } } void TableManager::initVFPProdTables(const Deck& deck, std::map& tableMap) { if (!deck.hasKeyword(ParserKeywords::VFPPROD::keywordName)) { return; } int num_tables = deck.count(ParserKeywords::VFPPROD::keywordName); const auto& keywords = deck.getKeywordList(); const auto& unit_system = deck.getActiveUnitSystem(); for (int i=0; i& tableMap) { if (!deck.hasKeyword(ParserKeywords::VFPINJ::keywordName)) { return; } int num_tables = deck.count(ParserKeywords::VFPINJ::keywordName); const auto& keywords = deck.getKeywordList(); const auto& unit_system = deck.getActiveUnitSystem(); for (int i=0; i& TableManager::getSwofTables() const { return m_swofTables; } */ const TableContainer& TableManager::getSwofTables() const { return getTables("SWOF"); } const TableContainer& TableManager::getSgwfnTables() const { return getTables("SGWFN"); } const TableContainer& TableManager::getSlgofTables() const { return getTables("SLGOF"); } const TableContainer& TableManager::getSgofTables() const { return getTables("SGOF"); } const TableContainer& TableManager::getSof2Tables() const { return getTables("SOF2"); } const TableContainer& TableManager::getSof3Tables() const { return getTables("SOF3"); } const TableContainer& TableManager::getSwfnTables() const { return getTables("SWFN"); } const TableContainer& TableManager::getSgfnTables() const { return getTables("SGFN"); } const TableContainer& TableManager::getSsfnTables() const { return getTables("SSFN"); } const TableContainer& TableManager::getRsvdTables() const { return getTables("RSVD"); } const TableContainer& TableManager::getRvvdTables() const { return getTables("RVVD"); } const TableContainer& TableManager::getEnkrvdTables() const { return getTables("ENKRVD"); } const TableContainer& TableManager::getEnptvdTables() const { return getTables("ENPTVD"); } const TableContainer& TableManager::getImkrvdTables() const { return getTables("IMKRVD"); } const TableContainer& TableManager::getImptvdTables() const { return getTables("IMPTVD"); } const TableContainer& TableManager::getPvdgTables() const { return getTables("PVDG"); } const TableContainer& TableManager::getPvdoTables() const { return getTables("PVDO"); } const TableContainer& TableManager::getPvdsTables() const { return getTables("PVDS"); } const TableContainer& TableManager::getOilvisctTables() const { return getTables("OILVISCT"); } const TableContainer& TableManager::getWatvisctTables() const { return getTables("WATVISCT"); } const TableContainer& TableManager::getGasvisctTables() const { return getTables("GASVISCT"); } const TableContainer& TableManager::getRtempvdTables() const { return getTables("RTEMPVD"); } const TableContainer& TableManager::getRocktabTables() const { return getTables("ROCKTAB"); } const TableContainer& TableManager::getPlyadsTables() const { return getTables("PLYADS"); } const TableContainer& TableManager::getPlyviscTables() const { return getTables("PLYVISC"); } const TableContainer& TableManager::getPlydhflfTables() const { return getTables("PLYDHFL"); } const TableContainer& TableManager::getPlymaxTables() const { return getTables("PLYMAX"); } const TableContainer& TableManager::getPlyrockTables() const { return getTables("PLYROCK"); } const TableContainer& TableManager::getPlyshlogTables() const { return getTables("PLYSHLOG"); } const std::vector& TableManager::getPvtgTables() const { return m_pvtgTables; } const std::vector& TableManager::getPvtoTables() const { return m_pvtoTables; } const PvtwTable& TableManager::getPvtwTable() const { return this->m_pvtwTable; } const DensityTable& TableManager::getDensityTable() const { return this->m_densityTable; } const RockTable& TableManager::getRockTable() const { return this->m_rockTable; } const TableContainer& TableManager::getMsfnTables() const { return getTables("MSFN"); } const TableContainer& TableManager::getPmiscTables() const { return getTables("PMISC"); } const TableContainer& TableManager::getMiscTables() const { return getTables("MISC"); } const TableContainer& TableManager::getSgcwmisTables() const { return getTables("SGCWMIS"); } const TableContainer& TableManager::getSorwmisTables() const { return getTables("SORWMIS"); } const TableContainer& TableManager::getTlpmixpaTables() const { return getTables("TLPMIXPA"); } const JFunc& TableManager::getJFunc() const { if (!useJFunc()) throw std::invalid_argument("Cannot get JFUNC table when JFUNC not in deck"); return m_jfunc; } const std::map& TableManager::getVFPProdTables() const { return m_vfpprodTables; } const std::map& TableManager::getVFPInjTables() const { return m_vfpinjTables; } bool TableManager::useImptvd() const { return hasImptvd; } bool TableManager::useEnptvd() const { return hasEnptvd; } bool TableManager::useEqlnum() const { return hasEqlnum; } bool TableManager::useJFunc() const { return m_jfunc; } const MessageContainer& TableManager::getMessageContainer() const { return m_messages; } MessageContainer& TableManager::getMessageContainer() { return m_messages; } void TableManager::complainAboutAmbiguousKeyword(const Deck& deck, const std::string& keywordName) { m_messages.error("The " + keywordName + " keyword must be unique in the deck. Ignoring all!"); const auto& keywords = deck.getKeywordList(keywordName); for (size_t i = 0; i < keywords.size(); ++i) { std::string msg = "Ambiguous keyword "+keywordName+" defined here"; m_messages.error(keywords[i]->getFileName(), msg, keywords[i]->getLineNumber()); } } }