Merge pull request #2671 from tskille/esmry_lgr

Adding support for LGR related summary vectors
This commit is contained in:
Joakim Hove 2021-09-13 14:06:21 +02:00 committed by GitHub
commit 6c9a756d9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 187 additions and 46 deletions

View File

@ -119,7 +119,9 @@ private:
void updatePathAndRootName(filesystem::path& dir, filesystem::path& rootN) const; 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<Opm::EclIO::lgr_info> lgr_info) const;
std::string unpackNumber(const SummaryNode&) const; std::string unpackNumber(const SummaryNode&) const;
std::string lookupKey(const SummaryNode&) const; std::string lookupKey(const SummaryNode&) const;

View File

@ -24,9 +24,15 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
#include <array>
namespace Opm { namespace EclIO { namespace Opm { namespace EclIO {
struct lgr_info {
std::string name;
std::array<int, 3> ijk;
};
struct SummaryNode { struct SummaryNode {
enum class Category { enum class Category {
Well, Well,
@ -52,13 +58,14 @@ struct SummaryNode {
Undefined, Undefined,
}; };
std::string keyword; std::string keyword;
Category category; Category category;
Type type; Type type;
std::string wgname; std::string wgname;
int number; int number;
std::optional<std::string> fip_region; std::optional<std::string> fip_region;
std::optional<lgr_info> lgr;
constexpr static int default_number { std::numeric_limits<int>::min() }; constexpr static int default_number { std::numeric_limits<int>::min() };

View File

@ -68,7 +68,7 @@ namespace Opm {
const KeywordLocation& location( ) const { return this->loc; } const KeywordLocation& location( ) const { return this->loc; }
operator Opm::EclIO::SummaryNode() const { operator Opm::EclIO::SummaryNode() const {
return { keyword_, category_, type_, name_, number_, fip_region_ }; return { keyword_, category_, type_, name_, number_, fip_region_, {}};
} }
template<class Serializer> template<class Serializer>

View File

@ -177,7 +177,9 @@ void ERsm::load_block(std::deque<std::string>& lines, std::size_t& vector_length
SummaryNode::Type::Undefined, SummaryNode::Type::Undefined,
wgnames[kw_index], wgnames[kw_index],
make_num(nums_list[kw_index]), make_num(nums_list[kw_index]),
""}; "",
{}
};
block_data.emplace_back( node, vector_length ); block_data.emplace_back( node, vector_length );
} }

View File

@ -166,34 +166,74 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspecList.back().get<int>("NUMS"); const std::vector<int> nums = smspecList.back().get<int>("NUMS");
const std::vector<std::string> units = smspecList.back().get<std::string>("UNITS"); const std::vector<std::string> units = smspecList.back().get<std::string>("UNITS");
std::vector<std::string> lgrs;
std::vector<int> numlx;
std::vector<int> numly;
std::vector<int> numlz;
if (smspecList.back().hasKey("LGRS")){
lgrs = smspecList.back().get<std::string>("LGRS");
numlx = smspecList.back().get<int>("NUMLX");
numly = smspecList.back().get<int>("NUMLY");
numlz = smspecList.back().get<int>("NUMLZ");
}
const bool have_lgr = !lgrs.empty();
std::vector<std::string> combindKeyList; std::vector<std::string> combindKeyList;
combindKeyList.reserve(dimens[0]); combindKeyList.reserve(dimens[0]);
this->startdat = make_date(smspecList.back().get<int>("STARTDAT")); this->startdat = make_date(smspecList.back().get<int>("STARTDAT"));
if ( have_lgr ) {
for (unsigned int i=0; i<keywords.size(); i++) { for (unsigned int i=0; i<keywords.size(); i++) {
const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[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);
combindKeyList.push_back(keyString); combindKeyList.push_back(keyString);
if (! keyString.empty()) { if (! keyString.empty()) {
summaryNodes.push_back({ summaryNodes.push_back( {
keywords[i], keywords[i],
SummaryNode::category_from_keyword(keywords[i], segmentExceptions), SummaryNode::category_from_keyword(keywords[i], segmentExceptions),
SummaryNode::Type::Undefined, SummaryNode::Type::Undefined,
wgnames[i], wgnames[i],
nums[i], nums[i],
"" "",
lgr
}); });
keywList.insert(keyString); keywList.insert(keyString);
kwunits[keyString] = units[i]; kwunits[keyString] = units[i];
} }
} }
} else {
for (unsigned int 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];
}
}
keywordListSpecFile.push_back(combindKeyList); keywordListSpecFile.push_back(combindKeyList);
getRstString(restartArray, pathRstFile, rstRootN); getRstString(restartArray, pathRstFile, rstRootN);
if ((rstRootN.string() != "") && (loadBaseRunData)){ if ((rstRootN.string() != "") && (loadBaseRunData)) {
if (! Opm::filesystem::exists(pathRstFile)) if (! Opm::filesystem::exists(pathRstFile))
OPM_THROW(std::runtime_error, "path to restart file not found, '" + pathRstFile.string() + "'"); OPM_THROW(std::runtime_error, "path to restart file not found, '" + pathRstFile.string() + "'");
@ -220,7 +260,7 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
// checking if this is a restart run. Supporting nested restarts (restart, from restart, ...) // checking if this is a restart run. Supporting nested restarts (restart, from restart, ...)
// std::set keywList is storing keywords from all runs involved // std::set keywList is storing keywords from all runs involved
while ((rstRootN.string() != "") && (loadBaseRunData)) { while ((rstRootN.string() != "") && (loadBaseRunData)){
Opm::filesystem::path rstFile = pathRstFile / rstRootN; Opm::filesystem::path rstFile = pathRstFile / rstRootN;
rstFile += ".SMSPEC"; rstFile += ".SMSPEC";
@ -258,23 +298,41 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspecList.back().get<int>("NUMS"); const std::vector<int> nums = smspecList.back().get<int>("NUMS");
const std::vector<std::string> units = smspecList.back().get<std::string>("UNITS"); const std::vector<std::string> units = smspecList.back().get<std::string>("UNITS");
std::vector<std::string> lgrs;
std::vector<int> numlx;
std::vector<int> numly;
std::vector<int> numlz;
if (smspecList.back().hasKey("LGRS")){
lgrs = smspecList.back().get<std::string>("LGRS");
numlx = smspecList.back().get<int>("NUMLX");
numly = smspecList.back().get<int>("NUMLY");
numlz = smspecList.back().get<int>("NUMLZ");
}
const bool have_lgr = !lgrs.empty();
std::vector<std::string> combindKeyList; std::vector<std::string> combindKeyList;
combindKeyList.reserve(dimens[0]); combindKeyList.reserve(dimens[0]);
this->startdat = make_date(smspecList.back().get<int>("STARTDAT")); this->startdat = make_date(smspecList.back().get<int>("STARTDAT"));
if (have_lgr) {
for (size_t i = 0; i < keywords.size(); i++) { for (size_t i = 0; i < keywords.size(); i++) {
const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[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);
combindKeyList.push_back(keyString); combindKeyList.push_back(keyString);
if (! keyString.empty()) { if (! keyString.empty()) {
summaryNodes.push_back({ summaryNodes.push_back( {
keywords[i], keywords[i],
SummaryNode::category_from_keyword(keywords[i], segmentExceptions), SummaryNode::category_from_keyword(keywords[i], segmentExceptions),
SummaryNode::Type::Undefined, SummaryNode::Type::Undefined,
wgnames[i], wgnames[i],
nums[i], nums[i],
"" "",
lgr
}); });
keywList.insert(keyString); keywList.insert(keyString);
@ -282,12 +340,37 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
} }
} }
} 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];
}
}
}
smryArray.push_back({rstFile.string(),dimens[5]}); smryArray.push_back({rstFile.string(),dimens[5]});
keywordListSpecFile.push_back(combindKeyList); keywordListSpecFile.push_back(combindKeyList);
formattedFiles.push_back(baseRunFmt); formattedFiles.push_back(baseRunFmt);
getRstString(restartArray, pathRstFile, rstRootN); getRstString(restartArray, pathRstFile, rstRootN);
} }
nSpecFiles = static_cast<int>(smryArray.size()); nSpecFiles = static_cast<int>(smryArray.size());
nParamsSpecFile.resize(nSpecFiles, 0); nParamsSpecFile.resize(nSpecFiles, 0);
@ -326,12 +409,34 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspecList[specInd].get<int>("NUMS"); const std::vector<int> nums = smspecList[specInd].get<int>("NUMS");
for (size_t i=0; i < keywords.size(); i++) { std::vector<std::string> lgrs;
const std::string keyw = makeKeyString(keywords[i], wgnames[i], nums[i]); std::vector<int> numlx;
std::vector<int> numly;
std::vector<int> numlz;
if (smspecList[specInd].hasKey("LGRS")){
lgrs = smspecList[specInd].get<std::string>("LGRS");
numlx = smspecList[specInd].get<int>("NUMLX");
numly = smspecList[specInd].get<int>("NUMLY");
numlz = smspecList[specInd].get<int>("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()) if (keywList.find(keyw) != keywList.end())
arrayPos[specInd][keyIndex[keyw]]=i; 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--; specInd--;
} }
@ -962,8 +1067,6 @@ bool ESmry::make_esmry_file()
} }
} }
std::vector<std::string> ESmry::checkForMultipleResultFiles(const Opm::filesystem::path& rootN, bool formatted) const { std::vector<std::string> ESmry::checkForMultipleResultFiles(const Opm::filesystem::path& rootN, bool formatted) const {
std::vector<std::string> fileList; std::vector<std::string> 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<Opm::EclIO::lgr_info> lgr) const
{ {
const auto no_wgname = std::string_view(":+:+:+:+"); 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); 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 (first == 'R') {
if (num <= 0) { if (num <= 0) {
return ""; 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) // NUMS = R1 + 32768*(R2 + 10)
const auto r1 = num % (1UL << 15); const auto r1 = num % (1UL << 15);
const auto r2 = (num / (1UL << 15)) - 10; const auto r2 = (num / (1UL << 15)) - 10;

View File

@ -197,12 +197,12 @@ namespace {
// Recall: Cannot use emplace_back() for PODs. // Recall: Cannot use emplace_back() for PODs.
for (const auto& vector : vectors) { for (const auto& vector : vectors) {
entities.push_back({ kwpref + vector.kw, cat, entities.push_back({ kwpref + vector.kw, cat,
vector.type, name, dflt_num, {} }); vector.type, name, dflt_num, {}, {} });
} }
for (const auto& extra_vector : extra_vectors) { for (const auto& extra_vector : extra_vectors) {
entities.push_back({ extra_vector.kw, cat, 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); const auto& well = sched.getWellatEnd(well_name);
for (const auto& conn : well.getConnections()) { for (const auto& conn : well.getConnections()) {
for (const auto& conn_vector : extra_connection_vectors) for (const auto& conn_vector : extra_connection_vectors)
entities.push_back( {conn_vector.kw, Cat::Connection, conn_vector.type, well.name(), static_cast<int>(conn.global_index() + 1), {}} ); entities.push_back( {conn_vector.kw, Cat::Connection, conn_vector.type, well.name(), static_cast<int>(conn.global_index() + 1), {}, {}} );
} }
} }
@ -249,7 +249,7 @@ namespace {
for (auto segID = 0*nSeg + 1; segID <= nSeg; ++segID) { for (auto segID = 0*nSeg + 1; segID <= nSeg; ++segID) {
for (const auto& vector : vectors) { for (const auto& vector : vectors) {
entities.push_back({ vector.kw, Cat::Segment, 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& aquiferID : aquiferIDs) {
for (const auto& vector : vectors) { for (const auto& vector : vectors) {
entities.push_back({ vector.kw, Cat::Aquifer, 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& aquiferID : aquiferIDs) {
for (const auto& vector : vectors) { for (const auto& vector : vectors) {
entities.push_back({ vector.kw, Cat::Aquifer, entities.push_back({ vector.kw, Cat::Aquifer,
vector.type, "", aquiferID, {} }); vector.type, "", aquiferID, {}, {} });
} }
} }