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;
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 lookupKey(const SummaryNode&) const;

View File

@ -24,9 +24,15 @@
#include <optional>
#include <string>
#include <unordered_set>
#include <array>
namespace Opm { namespace EclIO {
struct lgr_info {
std::string name;
std::array<int, 3> 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<std::string> fip_region;
std::optional<lgr_info> lgr;
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; }
operator Opm::EclIO::SummaryNode() const {
return { keyword_, category_, type_, name_, number_, fip_region_ };
return { keyword_, category_, type_, name_, number_, fip_region_, {}};
}
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,
wgnames[kw_index],
make_num(nums_list[kw_index]),
""};
"",
{}
};
block_data.emplace_back( node, vector_length );
}

View File

@ -166,24 +166,64 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspecList.back().get<int>("NUMS");
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;
combindKeyList.reserve(dimens[0]);
this->startdat = make_date(smspecList.back().get<int>("STARTDAT"));
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 ( have_lgr ) {
for (unsigned int i=0; i<keywords.size(); i++) {
if (! keyString.empty()) {
summaryNodes.push_back({
keywords[i],
SummaryNode::category_from_keyword(keywords[i], segmentExceptions),
SummaryNode::Type::Undefined,
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);
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 (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];
@ -193,7 +233,7 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
keywordListSpecFile.push_back(combindKeyList);
getRstString(restartArray, pathRstFile, rstRootN);
if ((rstRootN.string() != "") && (loadBaseRunData)){
if ((rstRootN.string() != "") && (loadBaseRunData)) {
if (! Opm::filesystem::exists(pathRstFile))
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, ...)
// std::set keywList is storing keywords from all runs involved
while ((rstRootN.string() != "") && (loadBaseRunData)) {
while ((rstRootN.string() != "") && (loadBaseRunData)){
Opm::filesystem::path rstFile = pathRstFile / rstRootN;
rstFile += ".SMSPEC";
@ -258,27 +298,69 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspecList.back().get<int>("NUMS");
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;
combindKeyList.reserve(dimens[0]);
this->startdat = make_date(smspecList.back().get<int>("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<int>(smryArray.size());
nParamsSpecFile.resize(nSpecFiles, 0);
@ -326,11 +409,33 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
const std::vector<int> nums = smspecList[specInd].get<int>("NUMS");
for (size_t i=0; i < keywords.size(); i++) {
const std::string keyw = makeKeyString(keywords[i], wgnames[i], nums[i]);
std::vector<std::string> lgrs;
std::vector<int> numlx;
std::vector<int> numly;
std::vector<int> numlz;
if (keywList.find(keyw) != keywList.end())
arrayPos[specInd][keyIndex[keyw]]=i;
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())
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<std::string> ESmry::checkForMultipleResultFiles(const Opm::filesystem::path& rootN, bool formatted) const {
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(":+:+:+:+");
@ -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;

View File

@ -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<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 (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, {}, {} });
}
}