diff --git a/opm/io/eclipse/ESmry.hpp b/opm/io/eclipse/ESmry.hpp index 31dd28203..041e2bcec 100644 --- a/opm/io/eclipse/ESmry.hpp +++ b/opm/io/eclipse/ESmry.hpp @@ -119,7 +119,9 @@ private: void updatePathAndRootName(filesystem::path& dir, filesystem::path& rootN) const; - std::string makeKeyString(const std::string& keyword, const std::string& wgname, int num) const; + + std::string makeKeyString(const std::string& keyword, const std::string& wgname, int num, + const std::optional lgr_info) const; std::string unpackNumber(const SummaryNode&) const; std::string lookupKey(const SummaryNode&) const; diff --git a/opm/io/eclipse/SummaryNode.hpp b/opm/io/eclipse/SummaryNode.hpp index 4690dadea..e1f659acb 100644 --- a/opm/io/eclipse/SummaryNode.hpp +++ b/opm/io/eclipse/SummaryNode.hpp @@ -24,9 +24,15 @@ #include #include #include +#include namespace Opm { namespace EclIO { + struct lgr_info { + std::string name; + std::array ijk; + }; + struct SummaryNode { enum class Category { Well, @@ -52,13 +58,14 @@ struct SummaryNode { Undefined, }; + std::string keyword; Category category; Type type; std::string wgname; int number; - std::optional fip_region; + std::optional lgr; constexpr static int default_number { std::numeric_limits::min() }; diff --git a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp index 2777ff0a4..29fd1da4a 100644 --- a/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp +++ b/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp @@ -68,7 +68,7 @@ namespace Opm { const KeywordLocation& location( ) const { return this->loc; } operator Opm::EclIO::SummaryNode() const { - return { keyword_, category_, type_, name_, number_, fip_region_ }; + return { keyword_, category_, type_, name_, number_, fip_region_, {}}; } template diff --git a/src/opm/io/eclipse/ERsm.cpp b/src/opm/io/eclipse/ERsm.cpp index 86e30ae71..31b22f0e2 100644 --- a/src/opm/io/eclipse/ERsm.cpp +++ b/src/opm/io/eclipse/ERsm.cpp @@ -177,7 +177,9 @@ void ERsm::load_block(std::deque& lines, std::size_t& vector_length SummaryNode::Type::Undefined, wgnames[kw_index], make_num(nums_list[kw_index]), - ""}; + "", + {} + }; block_data.emplace_back( node, vector_length ); } diff --git a/src/opm/io/eclipse/ESmry.cpp b/src/opm/io/eclipse/ESmry.cpp index 815607f10..e25dfaaaf 100644 --- a/src/opm/io/eclipse/ESmry.cpp +++ b/src/opm/io/eclipse/ESmry.cpp @@ -166,24 +166,64 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) : const std::vector nums = smspecList.back().get("NUMS"); const std::vector units = smspecList.back().get("UNITS"); + std::vector lgrs; + std::vector numlx; + std::vector numly; + std::vector numlz; + + if (smspecList.back().hasKey("LGRS")){ + lgrs = smspecList.back().get("LGRS"); + numlx = smspecList.back().get("NUMLX"); + numly = smspecList.back().get("NUMLY"); + numlz = smspecList.back().get("NUMLZ"); + } + + const bool have_lgr = !lgrs.empty(); + std::vector combindKeyList; combindKeyList.reserve(dimens[0]); this->startdat = make_date(smspecList.back().get("STARTDAT")); - for (unsigned int i=0; i nums = smspecList.back().get("NUMS"); const std::vector units = smspecList.back().get("UNITS"); + std::vector lgrs; + std::vector numlx; + std::vector numly; + std::vector numlz; + + if (smspecList.back().hasKey("LGRS")){ + lgrs = smspecList.back().get("LGRS"); + numlx = smspecList.back().get("NUMLX"); + numly = smspecList.back().get("NUMLY"); + numlz = smspecList.back().get("NUMLZ"); + } + + const bool have_lgr = !lgrs.empty(); + std::vector combindKeyList; combindKeyList.reserve(dimens[0]); this->startdat = make_date(smspecList.back().get("STARTDAT")); - for (size_t i = 0; i < keywords.size(); i++) { - const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[i]); - combindKeyList.push_back(keyString); + if (have_lgr) { + for (size_t i = 0; i < keywords.size(); i++) { + Opm::EclIO::lgr_info lgr { lgrs[i], {numlx[i], numly[i], numlz[i]}}; + const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[i], lgr); - if (! keyString.empty()) { - summaryNodes.push_back({ - keywords[i], - SummaryNode::category_from_keyword(keywords[i], segmentExceptions), - SummaryNode::Type::Undefined, - wgnames[i], - nums[i], - "" - }); + combindKeyList.push_back(keyString); - keywList.insert(keyString); - kwunits[keyString] = units[i]; + if (! keyString.empty()) { + summaryNodes.push_back( { + keywords[i], + SummaryNode::category_from_keyword(keywords[i], segmentExceptions), + SummaryNode::Type::Undefined, + wgnames[i], + nums[i], + "", + lgr + }); + + keywList.insert(keyString); + kwunits[keyString] = units[i]; + } + } + + } else { + + for (size_t i = 0; i < keywords.size(); i++) { + + const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[i], {}); + combindKeyList.push_back(keyString); + + if (! keyString.empty()) { + summaryNodes.push_back( { + keywords[i], + SummaryNode::category_from_keyword(keywords[i], segmentExceptions), + SummaryNode::Type::Undefined, + wgnames[i], + nums[i], + "", + {} + }); + + keywList.insert(keyString); + kwunits[keyString] = units[i]; + } } } @@ -288,6 +370,7 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) : getRstString(restartArray, pathRstFile, rstRootN); } + nSpecFiles = static_cast(smryArray.size()); nParamsSpecFile.resize(nSpecFiles, 0); @@ -326,11 +409,33 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) : const std::vector nums = smspecList[specInd].get("NUMS"); - for (size_t i=0; i < keywords.size(); i++) { - const std::string keyw = makeKeyString(keywords[i], wgnames[i], nums[i]); + std::vector lgrs; + std::vector numlx; + std::vector numly; + std::vector numlz; - if (keywList.find(keyw) != keywList.end()) - arrayPos[specInd][keyIndex[keyw]]=i; + if (smspecList[specInd].hasKey("LGRS")){ + lgrs = smspecList[specInd].get("LGRS"); + numlx = smspecList[specInd].get("NUMLX"); + numly = smspecList[specInd].get("NUMLY"); + numlz = smspecList[specInd].get("NUMLZ"); + } + + const bool have_lgr = !lgrs.empty(); + + if (have_lgr) { + for (size_t i=0; i < keywords.size(); i++) { + Opm::EclIO::lgr_info lgr { lgrs[i], {numlx[i], numly[i], numlz[i]}}; + const std::string keyw = makeKeyString(keywords[i], wgnames[i], nums[i], lgr); + if (keywList.find(keyw) != keywList.end()) + arrayPos[specInd][keyIndex[keyw]]=i; + } + } else { + for (size_t i=0; i < keywords.size(); i++) { + const std::string keyw = makeKeyString(keywords[i], wgnames[i], nums[i], {}); + if (keywList.find(keyw) != keywList.end()) + arrayPos[specInd][keyIndex[keyw]]=i; + } } specInd--; @@ -962,8 +1067,6 @@ bool ESmry::make_esmry_file() } } - - std::vector ESmry::checkForMultipleResultFiles(const Opm::filesystem::path& rootN, bool formatted) const { std::vector fileList; @@ -1028,7 +1131,8 @@ void ESmry::ijk_from_global_index(int glob, int &i, int &j, int &k) const } -std::string ESmry::makeKeyString(const std::string& keywordArg, const std::string& wgname, int num) const +std::string ESmry::makeKeyString(const std::string& keywordArg, const std::string& wgname, int num, + const std::optional lgr) const { const auto no_wgname = std::string_view(":+:+:+:+"); @@ -1072,12 +1176,38 @@ std::string ESmry::makeKeyString(const std::string& keywordArg, const std::strin return fmt::format("{}:{}", keywordArg, wgname); } + if (first == 'L') { + + if (!lgr.has_value()) + throw std::invalid_argument("need lgr info element for making L type vector strings"); + + auto lgr_ = lgr.value(); + + if (keywordArg[1] == 'B') + return fmt::format("{}:{}:{},{},{}", keywordArg, lgr_.name, lgr_.ijk[0], lgr_.ijk[1], lgr_.ijk[2]); + + if (keywordArg[1] == 'C') + return fmt::format("{}:{}:{}:{},{},{}", keywordArg, lgr_.name, wgname, lgr_.ijk[0], lgr_.ijk[1], lgr_.ijk[2]); + + if (keywordArg[1] == 'W') + return fmt::format("{}:{}:{}", keywordArg, lgr_.name, wgname); + + return fmt::format("{}", keywordArg); + } + if (first == 'R') { if (num <= 0) { return ""; } - if (keywordArg[1] == 'F') { + std::string str34 = keywordArg.substr(2,2); + std::string str45 = keywordArg.substr(3,2); + + if (keywordArg == "RORFR") // exception, standard region summary keyword + return fmt::format("{}:{}", keywordArg, num); + + if ((str34 == "FR") || (str34 == "FT") || (str45 == "FR") || (str45 == "FT")) { + // NUMS = R1 + 32768*(R2 + 10) const auto r1 = num % (1UL << 15); const auto r2 = (num / (1UL << 15)) - 10; diff --git a/src/opm/output/eclipse/Summary.cpp b/src/opm/output/eclipse/Summary.cpp index 2daa057d1..8ea1e85e2 100644 --- a/src/opm/output/eclipse/Summary.cpp +++ b/src/opm/output/eclipse/Summary.cpp @@ -197,12 +197,12 @@ namespace { // Recall: Cannot use emplace_back() for PODs. for (const auto& vector : vectors) { entities.push_back({ kwpref + vector.kw, cat, - vector.type, name, dflt_num, {} }); + vector.type, name, dflt_num, {}, {} }); } for (const auto& extra_vector : extra_vectors) { entities.push_back({ extra_vector.kw, cat, - extra_vector.type, name, dflt_num, {} }); + extra_vector.type, name, dflt_num, {}, {} }); } }; @@ -212,7 +212,7 @@ namespace { const auto& well = sched.getWellatEnd(well_name); for (const auto& conn : well.getConnections()) { for (const auto& conn_vector : extra_connection_vectors) - entities.push_back( {conn_vector.kw, Cat::Connection, conn_vector.type, well.name(), static_cast(conn.global_index() + 1), {}} ); + entities.push_back( {conn_vector.kw, Cat::Connection, conn_vector.type, well.name(), static_cast(conn.global_index() + 1), {}, {}} ); } } @@ -249,7 +249,7 @@ namespace { for (auto segID = 0*nSeg + 1; segID <= nSeg; ++segID) { for (const auto& vector : vectors) { entities.push_back({ vector.kw, Cat::Segment, - vector.type, wname, segID, {} }); + vector.type, wname, segID, {}, {} }); } } }; @@ -286,7 +286,7 @@ namespace { for (const auto& aquiferID : aquiferIDs) { for (const auto& vector : vectors) { entities.push_back({ vector.kw, Cat::Aquifer, - vector.type, "", aquiferID, {} }); + vector.type, "", aquiferID, {}, {} }); } } @@ -309,7 +309,7 @@ namespace { for (const auto& aquiferID : aquiferIDs) { for (const auto& vector : vectors) { entities.push_back({ vector.kw, Cat::Aquifer, - vector.type, "", aquiferID, {} }); + vector.type, "", aquiferID, {}, {} }); } }