From c37e5f9503b11581a7f29f1d874cb1d4f6fb9e3a Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Fri, 6 Apr 2018 12:12:30 +0200 Subject: [PATCH 1/5] Move VFP tables to Schedule. --- CMakeLists_files.cmake | 8 +-- .../EclipseState/Schedule/Schedule.hpp | 13 ++++ .../{Tables => Schedule}/VFPInjTable.hpp | 0 .../{Tables => Schedule}/VFPProdTable.hpp | 0 .../EclipseState/Tables/TableManager.hpp | 15 ----- .../EclipseState/Schedule/Schedule.cpp | 64 ++++++++++++++++++ .../{Tables => Schedule}/VFPInjTable.cpp | 2 +- .../{Tables => Schedule}/VFPProdTable.cpp | 3 +- .../EclipseState/Tables/TableManager.cpp | 65 +------------------ tests/parser/PvtxTableTests.cpp | 4 +- tests/parser/TableManagerTests.cpp | 4 +- 11 files changed, 89 insertions(+), 89 deletions(-) rename opm/parser/eclipse/EclipseState/{Tables => Schedule}/VFPInjTable.hpp (100%) rename opm/parser/eclipse/EclipseState/{Tables => Schedule}/VFPProdTable.hpp (100%) rename src/opm/parser/eclipse/EclipseState/{Tables => Schedule}/VFPInjTable.cpp (99%) rename src/opm/parser/eclipse/EclipseState/{Tables => Schedule}/VFPProdTable.cpp (99%) diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 78c3de8d2..1388b5f61 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -106,11 +106,11 @@ if(ENABLE_ECL_INPUT) src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp src/opm/parser/eclipse/EclipseState/Tables/TableSchema.cpp src/opm/parser/eclipse/EclipseState/Tables/Tables.cpp - src/opm/parser/eclipse/EclipseState/Tables/VFPInjTable.cpp - src/opm/parser/eclipse/EclipseState/Tables/VFPProdTable.cpp src/opm/parser/eclipse/EclipseState/UDQConfig.cpp src/opm/parser/eclipse/EclipseState/Schedule/UDQ.cpp src/opm/parser/eclipse/EclipseState/Schedule/UDQExpression.cpp + src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp + src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp src/opm/parser/eclipse/Parser/ParseContext.cpp src/opm/parser/eclipse/Parser/Parser.cpp src/opm/parser/eclipse/Parser/ParserEnums.cpp @@ -362,7 +362,6 @@ if(ENABLE_ECL_INPUT) opm/parser/eclipse/EclipseState/Tables/PdvdTable.hpp opm/parser/eclipse/EclipseState/Tables/TlpmixpaTable.hpp opm/parser/eclipse/EclipseState/Tables/PvdgTable.hpp - opm/parser/eclipse/EclipseState/Tables/VFPProdTable.hpp opm/parser/eclipse/EclipseState/Tables/MsfnTable.hpp opm/parser/eclipse/EclipseState/Tables/GasvisctTable.hpp opm/parser/eclipse/EclipseState/Tables/Regdims.hpp @@ -371,7 +370,6 @@ if(ENABLE_ECL_INPUT) opm/parser/eclipse/EclipseState/Tables/PlydhflfTable.hpp opm/parser/eclipse/EclipseState/Tables/PlyshlogTable.hpp opm/parser/eclipse/EclipseState/Tables/RsvdTable.hpp - opm/parser/eclipse/EclipseState/Tables/VFPInjTable.hpp opm/parser/eclipse/EclipseState/Tables/SpecheatTable.hpp opm/parser/eclipse/EclipseState/Tables/SgcwmisTable.hpp opm/parser/eclipse/EclipseState/Tables/Sof2Table.hpp @@ -422,6 +420,8 @@ if(ENABLE_ECL_INPUT) opm/parser/eclipse/EclipseState/Aquancon.hpp opm/parser/eclipse/EclipseState/AquiferCT.hpp opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp + opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp + opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp opm/parser/eclipse/EclipseState/Schedule/Well.hpp opm/parser/eclipse/EclipseState/Schedule/WellInjectionProperties.hpp opm/parser/eclipse/EclipseState/Schedule/DynamicVector.hpp diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index 71ce7814d..fb32e963d 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -37,6 +37,8 @@ #include #include #include +#include +#include namespace Opm { @@ -107,6 +109,8 @@ namespace Opm const Events& getEvents() const; const Deck& getModifierDeck(size_t timeStep) const; bool hasOilVaporizationProperties() const; + const std::map& getVFPProdTables() const; + const std::map& getVFPInjTables() const; /* Will remove all completions which are connected to cell which is not @@ -125,9 +129,18 @@ namespace Opm Tuning m_tuning; MessageLimits m_messageLimits; Phases m_phases; + std::map m_vfpprodTables; + std::map m_vfpinjTables; WellProducer::ControlModeEnum m_controlModeWHISTCTL; + void initVFPProdTables(const Deck& deck, + std::map& tableMap); + + void initVFPInjTables(const Deck& deck, + std::map& tableMap); + + std::vector< Well* > getWells(const std::string& wellNamePattern); void updateWellStatus( Well& well, size_t reportStep , WellCommon::StatusEnum status); void addWellToGroup( Group& newGroup , Well& well , size_t timeStep); diff --git a/opm/parser/eclipse/EclipseState/Tables/VFPInjTable.hpp b/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp similarity index 100% rename from opm/parser/eclipse/EclipseState/Tables/VFPInjTable.hpp rename to opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp diff --git a/opm/parser/eclipse/EclipseState/Tables/VFPProdTable.hpp b/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp similarity index 100% rename from opm/parser/eclipse/EclipseState/Tables/VFPProdTable.hpp rename to opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp diff --git a/opm/parser/eclipse/EclipseState/Tables/TableManager.hpp b/opm/parser/eclipse/EclipseState/Tables/TableManager.hpp index 226ae59dd..cb1a2f586 100644 --- a/opm/parser/eclipse/EclipseState/Tables/TableManager.hpp +++ b/opm/parser/eclipse/EclipseState/Tables/TableManager.hpp @@ -35,8 +35,6 @@ #include #include -#include -#include #include #include #include @@ -46,8 +44,6 @@ #include #include -#include -#include #include namespace Opm { @@ -125,8 +121,6 @@ namespace Opm { const RockTable& getRockTable() const; const ViscrefTable& getViscrefTable() const; const WatdentTable& getWatdentTable() const; - const std::map& getVFPProdTables() const; - const std::map& getVFPInjTables() const; /// deck has keyword "IMPTVD" --- Imbition end-point versus depth tables bool useImptvd() const; @@ -153,13 +147,6 @@ namespace Opm { void initRocktabTables(const Deck& deck); void initGasvisctTables(const Deck& deck); - void initVFPProdTables(const Deck& deck, - std::map& tableMap); - - void initVFPInjTables(const Deck& deck, - std::map& tableMap); - - void initPlymaxTables(const Deck& deck); void initPlyrockTables(const Deck& deck); void initPlyshlogTables(const Deck& deck); @@ -292,8 +279,6 @@ namespace Opm { } std::map m_simpleTables; - std::map m_vfpprodTables; - std::map m_vfpinjTables; std::vector m_pvtgTables; std::vector m_pvtoTables; PvtwTable m_pvtwTable; diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index ac7f68f78..5bfe8c745 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -92,6 +93,8 @@ namespace Opm { if (Section::hasSCHEDULE(deck)) { iterateScheduleSection( parseContext, SCHEDULESection( deck ), grid, eclipseProperties ); } + initVFPProdTables(deck, m_vfpprodTables); + initVFPInjTables(deck, m_vfpinjTables); } @@ -103,6 +106,58 @@ namespace Opm { parse_context) {} + void Schedule::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; iposixStartTime( ); @@ -1684,5 +1739,14 @@ namespace Opm { for (auto& well : this->m_wells) well.filterCompletions(grid); } + + const std::map& Schedule::getVFPProdTables() const { + return m_vfpprodTables; + } + + const std::map& Schedule::getVFPInjTables() const { + return m_vfpinjTables; + } + } diff --git a/src/opm/parser/eclipse/EclipseState/Tables/VFPInjTable.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp similarity index 99% rename from src/opm/parser/eclipse/EclipseState/Tables/VFPInjTable.cpp rename to src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp index 3f89114f7..f5ffab6f2 100644 --- a/src/opm/parser/eclipse/EclipseState/Tables/VFPInjTable.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp @@ -22,11 +22,11 @@ #include #include #include -#include #include #include #include +#include //Anonymous namespace namespace { diff --git a/src/opm/parser/eclipse/EclipseState/Tables/VFPProdTable.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp similarity index 99% rename from src/opm/parser/eclipse/EclipseState/Tables/VFPProdTable.cpp rename to src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp index b07e94fca..bd961e19d 100644 --- a/src/opm/parser/eclipse/EclipseState/Tables/VFPProdTable.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp @@ -25,11 +25,12 @@ #include #include #include -#include #include #include #include +#include + namespace Opm { diff --git a/src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp b/src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp index b2ad4697d..fc3789208 100644 --- a/src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp +++ b/src/opm/parser/eclipse/EclipseState/Tables/TableManager.cpp @@ -121,9 +121,6 @@ namespace Opm { if( deck.hasKeyword( "WATDENT" ) ) this->m_watdentTable = WatdentTable( deck.getKeyword( "WATDENT" ) ); - initVFPProdTables(deck, m_vfpprodTables); - initVFPInjTables(deck, m_vfpinjTables); - if( deck.hasKeyword( "RTEMP" ) ) m_rtemp = deck.getKeyword("RTEMP").getRecord(0).getItem("TEMP").getSIDouble( 0 ); else if (deck.hasKeyword( "RTEMPA" ) ) @@ -495,59 +492,7 @@ namespace Opm { - 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; igetNTFIP( ) > ntfip) return m_regdims->getNTFIP( ); @@ -773,14 +718,6 @@ namespace Opm { 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; } diff --git a/tests/parser/PvtxTableTests.cpp b/tests/parser/PvtxTableTests.cpp index 82fbf4749..153ee42e2 100644 --- a/tests/parser/PvtxTableTests.cpp +++ b/tests/parser/PvtxTableTests.cpp @@ -37,8 +37,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/tests/parser/TableManagerTests.cpp b/tests/parser/TableManagerTests.cpp index 0cc7e803f..d224216eb 100644 --- a/tests/parser/TableManagerTests.cpp +++ b/tests/parser/TableManagerTests.cpp @@ -38,12 +38,12 @@ #include #include #include -#include -#include #include #include #include +#include +#include #include From b8cdeefaec86a9e38534a9692bd1d3ac5180a7bc Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Sun, 8 Apr 2018 13:16:23 +0200 Subject: [PATCH 2/5] Add missing header --- tests/parser/EclipseGridTests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parser/EclipseGridTests.cpp b/tests/parser/EclipseGridTests.cpp index 5557cb011..1abde12bc 100644 --- a/tests/parser/EclipseGridTests.cpp +++ b/tests/parser/EclipseGridTests.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #define BOOST_TEST_MODULE EclipseGridTests #include From 4d835fc759a490dae74aa898bd32fd63b49d2ce6 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Fri, 6 Apr 2018 16:17:04 +0200 Subject: [PATCH 3/5] Add events VFPINJ_UPDATE and VFPPROD_UPDATE --- opm/parser/eclipse/EclipseState/Schedule/Events.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Events.hpp b/opm/parser/eclipse/EclipseState/Schedule/Events.hpp index 170a96530..c9709e3b1 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Events.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Events.hpp @@ -89,7 +89,11 @@ namespace Opm /* TUNING has changed */ - TUNING_CHANGE = 2048 + TUNING_CHANGE = 2048, + + /* The VFP tables have changed */ + VFPINJ_UPDATE = 4096, + VFPPROD_UPDATE = 8192 }; } From 8d7e890967f55d7e73278aeeb18b9d18c3e9f1be Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 11 Apr 2018 06:23:28 +0200 Subject: [PATCH 4/5] Add argument timeStep to VFP access methods. --- opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp | 4 ++-- src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp index fb32e963d..c5f535d79 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp @@ -109,8 +109,8 @@ namespace Opm const Events& getEvents() const; const Deck& getModifierDeck(size_t timeStep) const; bool hasOilVaporizationProperties() const; - const std::map& getVFPProdTables() const; - const std::map& getVFPInjTables() const; + const std::map& getVFPProdTables(size_t timeStep) const; + const std::map& getVFPInjTables(size_t timeStep) const; /* Will remove all completions which are connected to cell which is not diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp index 5bfe8c745..e10349817 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Schedule.cpp @@ -1740,11 +1740,11 @@ namespace Opm { well.filterCompletions(grid); } - const std::map& Schedule::getVFPProdTables() const { + const std::map& Schedule::getVFPProdTables(size_t timeStep) const { return m_vfpprodTables; } - const std::map& Schedule::getVFPInjTables() const { + const std::map& Schedule::getVFPInjTables(size_t timeStep) const { return m_vfpinjTables; } From a119dadb45160b0090226882c1a4bd158bc4e0cd Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 11 Apr 2018 08:10:53 +0200 Subject: [PATCH 5/5] Add (unused) new constroctors --- .../EclipseState/Schedule/VFPInjTable.hpp | 9 + .../EclipseState/Schedule/VFPProdTable.hpp | 15 ++ .../EclipseState/Schedule/VFPInjTable.cpp | 141 +++++++++++++ .../EclipseState/Schedule/VFPProdTable.cpp | 189 ++++++++++++++++++ 4 files changed, 354 insertions(+) diff --git a/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp b/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp index e33628d43..44f0325d2 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp @@ -56,6 +56,15 @@ public: } + VFPInjTable(int table_num, + double datum_depth, + FLO_TYPE flo_type, + const std::vector& flo_data, + const std::vector& thp_data, + const array_type& data); + + VFPInjTable(const DeckKeyword& table, const UnitSystem& deck_unit_system); + /** * Initializes objects from raw data. NOTE: All raw data assumed to be in SI units * @param table_num VFP table number diff --git a/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp b/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp index 3631fd4f9..b3c678fb6 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp @@ -85,6 +85,21 @@ public: } + VFPProdTable(int table_num, + double datum_depth, + FLO_TYPE flo_type, + WFR_TYPE wfr_type, + GFR_TYPE gfr_type, + ALQ_TYPE alq_type, + const std::vector& flo_data, + const std::vector& thp_data, + const std::vector& wfr_data, + const std::vector& gfr_data, + const std::vector& alq_data, + const array_type& data); + + VFPProdTable( const DeckKeyword& table, const UnitSystem& deck_unit_system); + /** * Initializes objects from raw data. NOTE: All raw data assumed to be in SI units * @param table_num VFP table number diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp index f5ffab6f2..17d16e12f 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.cpp @@ -50,6 +50,147 @@ inline const Opm::DeckItem& getNonEmptyItem( const Opm::DeckRecord& record) { namespace Opm { +VFPInjTable::VFPInjTable(int table_num, + double datum_depth, + FLO_TYPE flo_type, + const std::vector& flo_data, + const std::vector& thp_data, + const array_type& data) { + m_table_num = table_num; + m_datum_depth = datum_depth; + m_flo_type = flo_type; + m_flo_data = flo_data; + m_thp_data = thp_data; + + extents shape; + shape[0] = data.shape()[0]; + shape[1] = data.shape()[1]; + m_data.resize(shape); + m_data = data; + + check(); +} + + + +VFPInjTable::VFPInjTable( const DeckKeyword& table, const UnitSystem& deck_unit_system) { + using ParserKeywords::VFPINJ; + + //Check that the table has enough records + if (table.size() < 4) { + throw std::invalid_argument("VFPINJ table does not appear to have enough records to be valid"); + } + + //Get record 1, the metadata for the table + const auto& header = table.getRecord(0); + + //Get the different header items + m_table_num = getNonEmptyItem(header).get< int >(0); + m_datum_depth = getNonEmptyItem(header).getSIDouble(0); + + m_flo_type = getFloType(getNonEmptyItem(header).get< std::string >(0)); + + //Not used, but check that PRESSURE_DEF is indeed THP + std::string quantity_string = getNonEmptyItem(header).get< std::string >(0); + if (quantity_string != "THP") { + throw std::invalid_argument("PRESSURE_DEF is required to be THP"); + } + + //Check units used for this table + std::string units_string = ""; + if (header.getItem().hasValue(0)) { + units_string = header.getItem().get< std::string >(0); + } + else { + //If units does not exist in record, the default value is the + //unit system of the deck itself: do nothing... + } + + if (units_string != "") { + UnitSystem::UnitType table_unit_type; + + //FIXME: Only metric and field supported at the moment. + //Need to change all of the convertToSI functions to support LAB/PVT-M + + if (units_string == "METRIC") { + table_unit_type = UnitSystem::UnitType::UNIT_TYPE_METRIC; + } + else if (units_string == "FIELD") { + table_unit_type = UnitSystem::UnitType::UNIT_TYPE_FIELD; + } + else if (units_string == "LAB") { + table_unit_type = UnitSystem::UnitType::UNIT_TYPE_FIELD; + } + else if (units_string == "PVT-M") { + throw std::invalid_argument("Unsupported UNITS string: 'PVT-M'"); + } + else { + throw std::invalid_argument("Invalid UNITS string"); + } + + //Sanity check + if(table_unit_type != deck_unit_system.getType()) { + throw std::invalid_argument("Deck units are not equal VFPINJ table units."); + } + } + + //Quantity in the body of the table + std::string body_string = getNonEmptyItem(header).get< std::string >(0); + if (body_string != "BHP") { + throw std::invalid_argument("Invalid BODY_DEF string"); + } + + + //Get actual rate / flow values + m_flo_data = getNonEmptyItem(table.getRecord(1)).getData< double >(); + convertFloToSI(m_flo_type, m_flo_data, deck_unit_system); + + //Get actual tubing head pressure values + m_thp_data = getNonEmptyItem(table.getRecord(2)).getData< double >(); + convertTHPToSI(m_thp_data, deck_unit_system); + + //Finally, read the actual table itself. + size_t nt = m_thp_data.size(); + size_t nf = m_flo_data.size(); + extents shape; + shape[0] = nt; + shape[1] = nf; + m_data.resize(shape); + std::fill_n(m_data.data(), m_data.num_elements(), std::nan("0")); + + //Check that size of table matches size of axis: + if (table.size() != nt + 3) { + throw std::invalid_argument("VFPINJ table does not contain enough records."); + } + + const double table_scaling_factor = deck_unit_system.parse("Pressure").getSIScaling(); + for (size_t i=3; i(record).get< int >(0) - 1; + + //Rest of values (bottom hole pressure or tubing head temperature) have index of flo value + const std::vector& bhp_tht = getNonEmptyItem(record).getData< double >(); + + if (bhp_tht.size() != nf) { + throw std::invalid_argument("VFPINJ table does not contain enough FLO values."); + } + + for (unsigned int f=0; f 1.0e10) { + //TODO: Replace with proper log message + std::cerr << "Too large value encountered in VFPINJ in [" + << t << "," << f << "]=" << value << std::endl; + } + m_data[t][f] = table_scaling_factor*value; + } + } + + check(); +} + + void VFPInjTable::init(int table_num, diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp index bd961e19d..648ec3c01 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.cpp @@ -124,6 +124,195 @@ VFPProdTable::ALQ_TYPE getALQType( const DeckItem& item) { } +VFPProdTable::VFPProdTable(int table_num, + double datum_depth, + FLO_TYPE flo_type, + WFR_TYPE wfr_type, + GFR_TYPE gfr_type, + ALQ_TYPE alq_type, + const std::vector& flo_data, + const std::vector& thp_data, + const std::vector& wfr_data, + const std::vector& gfr_data, + const std::vector& alq_data, + const array_type& data) { + + m_table_num = table_num; + m_datum_depth = datum_depth; + m_flo_type = flo_type; + m_wfr_type = wfr_type; + m_gfr_type = gfr_type; + m_alq_type = alq_type; + m_flo_data = flo_data; + m_thp_data = thp_data; + m_wfr_data = wfr_data; + m_gfr_data = gfr_data; + m_alq_data = alq_data; + + extents shape; + shape[0] = data.shape()[0]; + shape[1] = data.shape()[1]; + shape[2] = data.shape()[2]; + shape[3] = data.shape()[3]; + shape[4] = data.shape()[4]; + m_data.resize(shape); + m_data = data; + + //check(); +} + + +VFPProdTable::VFPProdTable( const DeckKeyword& table, const UnitSystem& deck_unit_system) { + using ParserKeywords::VFPPROD; + + //Check that the table has enough records + if (table.size() < 7) { + throw std::invalid_argument("VFPPROD table does not appear to have enough records to be valid"); + } + + //Get record 1, the metadata for the table + const auto& header = table.getRecord(0); + + //Get the different header items + m_table_num = header.getItem().get< int >(0); + m_datum_depth = header.getItem().getSIDouble(0); + + m_flo_type = Opm::getFloType(header.getItem()); + m_wfr_type = Opm::getWFRType(header.getItem()); + m_gfr_type = Opm::getGFRType(header.getItem()); + + //Not used, but check that PRESSURE_DEF is indeed THP + std::string quantity_string = header.getItem().get< std::string >(0); + if (quantity_string != "THP") { + throw std::invalid_argument("PRESSURE_DEF is required to be THP"); + } + + m_alq_type = Opm::getALQType(header.getItem()); + + //Check units used for this table + std::string units_string = ""; + if (header.getItem().hasValue(0)) { + units_string = header.getItem().get< std::string >(0); + } + else { + //If units does not exist in record, the default value is the + //unit system of the deck itself: do nothing... + } + + if (units_string != "") { + UnitSystem::UnitType table_unit_type; + + //FIXME: Only metric and field supported at the moment. + //Need to change all of the convertToSI functions to support LAB/PVT-M + + if (units_string == "METRIC") { + table_unit_type = UnitSystem::UnitType::UNIT_TYPE_METRIC; + } + else if (units_string == "FIELD") { + table_unit_type = UnitSystem::UnitType::UNIT_TYPE_FIELD; + } + else if (units_string == "LAB") { + table_unit_type = UnitSystem::UnitType::UNIT_TYPE_LAB; + } + else if (units_string == "PVT-M") { + throw std::invalid_argument("Unsupported UNITS string: 'PVT-M'"); + } + else { + throw std::invalid_argument("Invalid UNITS string"); + } + + //Sanity check + if(table_unit_type != deck_unit_system.getType()) { + throw std::invalid_argument("Deck units are not equal VFPPROD table units."); + } + } + + //Quantity in the body of the table + std::string body_string = header.getItem().get< std::string >(0); + if (body_string == "TEMP") { + throw std::invalid_argument("Invalid BODY_DEF string: TEMP not supported"); + } + else if (body_string == "BHP") { + + } + else { + throw std::invalid_argument("Invalid BODY_DEF string"); + } + + + //Get actual rate / flow values + m_flo_data = table.getRecord(1).getItem().getData< double >(); + convertFloToSI(m_flo_type, m_flo_data, deck_unit_system); + + //Get actual tubing head pressure values + m_thp_data = table.getRecord(2).getItem().getData< double >(); + convertTHPToSI(m_thp_data, deck_unit_system); + + //Get actual water fraction values + m_wfr_data = table.getRecord(3).getItem().getData< double >(); + convertWFRToSI(m_wfr_type, m_wfr_data, deck_unit_system); + + //Get actual gas fraction values + m_gfr_data = table.getRecord(4).getItem().getData< double >(); + convertGFRToSI(m_gfr_type, m_gfr_data, deck_unit_system); + + //Get actual gas fraction values + m_alq_data = table.getRecord(5).getItem().getData< double >(); + convertALQToSI(m_alq_type, m_alq_data, deck_unit_system); + + //Finally, read the actual table itself. + size_t nt = m_thp_data.size(); + size_t nw = m_wfr_data.size(); + size_t ng = m_gfr_data.size(); + size_t na = m_alq_data.size(); + size_t nf = m_flo_data.size(); + extents shape; + shape[0] = nt; + shape[1] = nw; + shape[2] = ng; + shape[3] = na; + shape[4] = nf; + m_data.resize(shape); + std::fill_n(m_data.data(), m_data.num_elements(), std::nan("0")); + + //Check that size of table matches size of axis: + if (table.size() != nt*nw*ng*na + 6) { + throw std::invalid_argument("VFPPROD table does not contain enough records."); + } + + //FIXME: Unit for TEMP=Tubing head temperature is not Pressure, see BODY_DEF + const double table_scaling_factor = deck_unit_system.parse("Pressure").getSIScaling(); + for (size_t i=6; i().get< int >(0) - 1; + int w = record.getItem().get< int >(0) - 1; + int g = record.getItem().get< int >(0) - 1; + int a = record.getItem().get< int >(0) - 1; + + //Rest of values (bottom hole pressure or tubing head temperature) have index of flo value + const std::vector& bhp_tht = record.getItem().getData< double >(); + + if (bhp_tht.size() != nf) { + throw std::invalid_argument("VFPPROD table does not contain enough FLO values."); + } + + for (size_t f=0; f 1.0e10) { + //TODO: Replace with proper log message + std::cerr << "VFPPROD element [" + << t << "," << w << "," << g << "," << a << "," << f + << "]=" << bhp_tht[f] << " too large" << std::endl; + } + m_data[t][w][g][a][f] = table_scaling_factor*bhp_tht[f]; + } + } + + check(table, table_scaling_factor); +} + + void VFPProdTable::init(int table_num, double datum_depth, FLO_TYPE flo_type,