/*
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());
}
}
}