diff --git a/opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp b/opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp index 804d485ba..a83adbad3 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp @@ -31,11 +31,12 @@ public: using storage = std::vector; WList() = default; - WList(const storage& wlist); + WList(const storage& wlist, std::string wlname); std::size_t size() const; void add(const std::string& well); void del(const std::string& well); bool has(const std::string& well) const; + std::string getName() const; std::vector wells() const; bool operator==(const WList& data) const; @@ -44,10 +45,12 @@ public: void serializeOp(Serializer& serializer) { serializer(well_list); + serializer(name); } private: storage well_list; + std::string name; }; diff --git a/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp b/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp index 5f26f6dc0..f753ecc8b 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp @@ -33,14 +33,16 @@ public: static WListManager serializeObject(); + //const std::vector wListInputSeq()const; std::size_t WListSize() const; bool hasList(const std::string&) const; WList& getList(const std::string& name); const WList& getList(const std::string& name) const; - WList& newList(const std::string& name); + WList& newList(const std::string& name, const std::vector& wname); //void delWell(const std::string& well); const std::vector& getWListNames(const std::string& wname) const; + std::size_t getNoWListsWell(std::string wname) const; bool hasWList(const std::string& wname) const; void addWListWell(const std::string& wname, const std::string& wlname); void delWell(const std::string& wname); @@ -53,11 +55,14 @@ public: { serializer.map(wlists); serializer.map(well_wlist_names); + //serializer.vector(wlist_input_seq); } private: std::map wlists; std::map> well_wlist_names; + std::map no_wlists_well; + //std::vector wlist_input_seq; }; } diff --git a/src/opm/output/eclipse/AggregateWListData.cpp b/src/opm/output/eclipse/AggregateWListData.cpp index ddc46aa5a..a6f6e83e4 100644 --- a/src/opm/output/eclipse/AggregateWListData.cpp +++ b/src/opm/output/eclipse/AggregateWListData.cpp @@ -112,6 +112,19 @@ std::vector> wellOrderInWList(const Opm::Schedule& sc throw std::logic_error(msg); } } + /*for (const auto& wlst_name : wlmngr.wListInputSeq()) { + if (std::count(wListNames.begin(), wListNames.end(), wlst_name) > 0) { + if (wlmngr.hasList(wlst_name)) { + wlist = wlmngr.getList(wlst_name); + auto well_no = findInVector(wlist.wells(), wname); + if (well_no) well_order[iwlst] = well_no.value() + 1; + iwlst += 1; + } else { + auto msg = fmt::format("Well List Manager does not contain WLIST: {} ", wlst_name); + throw std::logic_error(msg); + } + } + }*/ } //store vector in map - and reset vector values to zero curWelOrd.push_back(well_order); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp index 349130768..f515e8105 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/KeywordHandlers.cpp @@ -1595,7 +1595,7 @@ namespace { throw std::invalid_argument("The list name in WLIST must start with a '*'"); if (action == "NEW") { - new_wlm.newList(name); + new_wlm.newList(name, wells); } if (!new_wlm.hasList(name)) diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp index 853fb506c..998a9824a 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp @@ -22,8 +22,9 @@ namespace Opm { -WList::WList(const storage& wlist) : - well_list(wlist) +WList::WList(const storage& wlist, std::string wlname) : + well_list(wlist), + name(wlname) { } @@ -33,6 +34,10 @@ std::size_t WList::size() const { } +std::string WList::getName() const { + return this->name; +} + bool WList::has(const std::string& well) const { return (std::count(this->well_list.begin(), this->well_list.end(), well) > 0); } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp index 34b86047d..af159a49c 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp @@ -27,10 +27,20 @@ #include namespace Opm { + template + std::optional findInVector(const std::vector & vecOfElements, const T & element) + { + // Find given element in vector + auto it = std::find(vecOfElements.begin(), vecOfElements.end(), element); + + return (it != vecOfElements.end()) ? std::optional {std::distance(vecOfElements.begin(), it)} : + std::nullopt; +} + WListManager WListManager::serializeObject() { WListManager result; - result.wlists = {{"test1", WList({"test2", "test3"})}}; + result.wlists = {{"test1", WList({"test2", "test3"}, "test1")}}; return result; } @@ -44,12 +54,36 @@ namespace Opm { } - WList& WListManager::newList(const std::string& name) { + /*WList& WListManager::newList(const std::string& name) { this->wlists.erase(name); - this->wlists.insert( {name, WList() }); + this->wlists.insert({name, WList({}, name)}); + return this->getList(name); + }*/ + + WList& WListManager::newList(const std::string& name, const std::vector& new_well_names) { + if (this->hasList(name)) { + auto& wlist = getList(name); + std::vector replace_wellnames; + for (const auto& wname : wlist.wells()){ + if (std::count(new_well_names.begin(), new_well_names.end(), wname) == 0) { + this->delWListWell(wname, name); + } else { + replace_wellnames.push_back(wname); + } + } + for (const auto& rwname : replace_wellnames) { + wlist.del(rwname); + } + } else { + //this->wlist_input_seq.push_back(name); + this->wlists.insert( {name, WList({}, name)} ); + } return this->getList(name); } + //const std::vector WListManager::wListInputSeq() const { + // return this->wlist_input_seq; + //} WList& WListManager::getList(const std::string& name) { return this->wlists.at(name); @@ -78,20 +112,29 @@ namespace Opm { } } + std::size_t WListManager::getNoWListsWell(std::string wname) const { + return this->no_wlists_well.at(wname); + } + void WListManager::addWListWell(const std::string& wname, const std::string& wlname) { //add well to wlist if it is not already in the well list auto& wlist = this->getList(wlname); wlist.add(wname); //add well list to well if not in vector already if (this->well_wlist_names.count(wname) > 0) { + auto& no_wl = this->no_wlists_well.at(wname); auto& wlist_vec = this->well_wlist_names.at(wname); - if (std::count(wlist_vec.begin(), wlist_vec.end(), wlname) == 0) + if (std::count(wlist_vec.begin(), wlist_vec.end(), wlname) == 0) { wlist_vec.push_back(wlname); + no_wl += 1; + } } else { //make wlist vector for new well std::vector new_wlvec; + std::size_t sz = 1; new_wlvec.push_back(wlname); this->well_wlist_names.insert({wname, new_wlvec}); + this->no_wlists_well.insert({wname, sz}); } } @@ -99,21 +142,38 @@ namespace Opm { for (auto& pair: this->wlists) { auto& wlist = pair.second; wlist.del(wname); + if (this->well_wlist_names.count(wname) > 0) { + auto& wlist_vec = this->well_wlist_names.at(wname); + auto& no_wl = this->no_wlists_well.at(wname); + auto itwl = std::find(wlist_vec.begin(), wlist_vec.end(), wlist.getName()); + if (itwl != wlist_vec.end()) { + wlist_vec.erase(itwl); + no_wl -= 1; + if (no_wl == 0) { + wlist_vec.clear(); + } + } + } } - const auto& it = this->well_wlist_names.find(wname); - this->well_wlist_names.erase(it); } void WListManager::delWListWell(const std::string& wname, const std::string& wlname) { //delete well from well list auto& wlist = this->getList(wlname); wlist.del(wname); + if (this->well_wlist_names.count(wname) > 0) { auto& wlist_vec = this->well_wlist_names.at(wname); - // remove wlist element from vector of well lists for a well + auto& no_wl = this->no_wlists_well.at(wname); + // reduce the no of well lists associated with a well, delete whole list if no wlists is zero const auto& it = std::find(wlist_vec.begin(), wlist_vec.end(), wlname); if (it != wlist_vec.end()) { - wlist_vec.erase(it); + //wlist_vec.erase(it); + no_wl -= 1; + if (no_wl == 0) { + wlist_vec.clear(); + } + } } } diff --git a/tests/TEST_WLIST.DATA b/tests/TEST_WLIST.DATA index 0155ce9ff..91a6f22ff 100644 --- a/tests/TEST_WLIST.DATA +++ b/tests/TEST_WLIST.DATA @@ -2564,6 +2564,17 @@ WLIST --written by schedule script DATES 10 SEP 2020 / +/ + +WLIST --written by schedule script + '*PRD1' NEW 'P2' 'P3' / +/ + +WLIST --written by schedule script + '*PRD2' NEW 'P1' / +/ + +DATES 20 SEP 2020 / 1 OCT 2020 / 10 OCT 2020 / @@ -2572,9 +2583,6 @@ DATES 1 DEC 2020 / 1 JAN 2021 / / - --- 1.5 2 2 5 10 10 30 30 30 30 30 30 30 / - END diff --git a/tests/parser/ACTIONX.cpp b/tests/parser/ACTIONX.cpp index 523d7eecb..cb87bdda9 100644 --- a/tests/parser/ACTIONX.cpp +++ b/tests/parser/ACTIONX.cpp @@ -651,10 +651,11 @@ BOOST_AUTO_TEST_CASE(TestWLIST) { Action::Context context(st, wlm); - auto& wl = wlm.newList("*LIST1"); - wl.add("W1"); - wl.add("W3"); - wl.add("W5"); + //auto& wl = wlm.newList("*LIST1"); + auto& wl = wlm.newList("*LIST1", {"W1", "W3", "W5"}); + //wl.add("W1"); + //wl.add("W3"); + //wl.add("W5"); auto res = ast.eval(context); auto wells = res.wells(); BOOST_CHECK(res); diff --git a/tests/parser/WLIST.cpp b/tests/parser/WLIST.cpp index e5938f117..5e748d098 100644 --- a/tests/parser/WLIST.cpp +++ b/tests/parser/WLIST.cpp @@ -76,28 +76,28 @@ BOOST_AUTO_TEST_CASE(WLISTManager) { { - auto& wlist1 = wlm.newList("LIST1"); - wlist1.add("A"); - wlist1.add("B"); - wlist1.add("C"); + auto& wlist1 = wlm.newList("LIST1", {"A", "B", "C"}); + //wlist1.add("A"); + //wlist1.add("B"); + //wlist1.add("C"); } // If a new list is added with the same name as an existing list the old // list is dropped and a new list is created. { - auto& wlist1 = wlm.newList("LIST1"); + auto& wlist1 = wlm.newList("LIST1", {}); BOOST_CHECK_EQUAL(wlist1.size(), 0U); } - auto& wlist1 = wlm.newList("LIST1"); - auto& wlist2 = wlm.newList("LIST2"); + auto& wlist1 = wlm.newList("LIST1", {"W1", "W2", "W3"}); + auto& wlist2 = wlm.newList("LIST2", {"W1", "W2", "W3"}); - wlist1.add("W1"); + /*wlist1.add("W1"); wlist1.add("W2"); wlist1.add("W3"); wlist2.add("W1"); wlist2.add("W2"); - wlist2.add("W3"); + wlist2.add("W3"); */ // The delWell operation will work across all well lists. wlm.delWell("W1"); diff --git a/tests/test_AggregateWListData.cpp b/tests/test_AggregateWListData.cpp index 06b4c8cd2..35a0bc4ff 100644 --- a/tests/test_AggregateWListData.cpp +++ b/tests/test_AggregateWListData.cpp @@ -84,7 +84,7 @@ struct SimulationCase BOOST_AUTO_TEST_SUITE(Aggregate_WList) -// test dimensions of multisegment data +// test dimensions for IWLS and ZWLS plus the vectors for different cases BOOST_AUTO_TEST_CASE (Constructor) { namespace VI = ::Opm::RestartIO::Helpers::VectorItems; @@ -424,6 +424,70 @@ BOOST_AUTO_TEST_CASE (Constructor) BOOST_CHECK_EQUAL(zWLs[start + 3].c_str(), blank8); } + // Report Step 9 (10.09.20) + { + const auto simStep = std::size_t {8}; + double secs_elapsed = 3.1536E07; + const auto ih + = Opm::RestartIO::Helpers::createInteHead(es, grid, sched, secs_elapsed, simStep, simStep + 1, simStep); + + auto wListData = Opm::RestartIO::Helpers::AggregateWListData(ih); + wListData.captureDeclaredWListData(sched, simStep, ih); + + // IWls-parameters + auto iWLs = wListData.getIWls(); + auto start = 0 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(iWLs[start + 0], 1); + BOOST_CHECK_EQUAL(iWLs[start + 1], 0); + BOOST_CHECK_EQUAL(iWLs[start + 2], 0); + BOOST_CHECK_EQUAL(iWLs[start + 3], 0); + + start = 1 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(iWLs[start + 0], 0); + BOOST_CHECK_EQUAL(iWLs[start + 1], 1); + BOOST_CHECK_EQUAL(iWLs[start + 2], 0); + BOOST_CHECK_EQUAL(iWLs[start + 3], 0); + + start = 2 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(iWLs[start + 0], 0); + BOOST_CHECK_EQUAL(iWLs[start + 1], 2); + BOOST_CHECK_EQUAL(iWLs[start + 2], 0); + BOOST_CHECK_EQUAL(iWLs[start + 3], 0); + + start = 3 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(iWLs[start + 0], 1); + BOOST_CHECK_EQUAL(iWLs[start + 1], 0); + BOOST_CHECK_EQUAL(iWLs[start + 2], 0); + BOOST_CHECK_EQUAL(iWLs[start + 3], 0); + + // ZWLs-parameters + const std::string blank8 = " "; + + auto zWLs = wListData.getZWls(); + start = 0 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(zWLs[start + 0].c_str(), pad8("*PRD2")); + BOOST_CHECK_EQUAL(zWLs[start + 1].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 2].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 3].c_str(), blank8); + + start = 1 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(zWLs[start + 0].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 1].c_str(), pad8("*PRD1")); + BOOST_CHECK_EQUAL(zWLs[start + 2].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 3].c_str(), blank8); + + start = 2 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(zWLs[start + 0].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 1].c_str(), pad8("*PRD1")); + BOOST_CHECK_EQUAL(zWLs[start + 2].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 3].c_str(), blank8); + + start = 3 * ih[VI::intehead::MXWLSTPRWELL]; + BOOST_CHECK_EQUAL(zWLs[start + 0].c_str(), pad8("*INJ1")); + BOOST_CHECK_EQUAL(zWLs[start + 1].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 2].c_str(), blank8); + BOOST_CHECK_EQUAL(zWLs[start + 3].c_str(), blank8); + } } BOOST_AUTO_TEST_SUITE_END()