Integrate SummaryNode in ESmry (#1642)

This commit is contained in:
Williham Williham Totland
2020-03-27 08:07:52 +01:00
committed by GitHub
parent 3e2160af28
commit 3e29350e94
5 changed files with 151 additions and 4 deletions
+11 -1
View File
@@ -22,7 +22,9 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <opm/common/utility/FileSystem.hpp>
#include <opm/io/eclipse/SummaryNode.hpp>
namespace Opm { namespace EclIO {
@@ -38,18 +40,22 @@ public:
bool hasKey(const std::string& key) const;
const std::vector<float>& get(const std::string& name) const;
const std::vector<float>& get(const SummaryNode& node) const;
std::vector<float> get_at_rstep(const std::string& name) const;
std::vector<float> get_at_rstep(const SummaryNode& node) const;
const std::vector<int>& get_startdat() const { return startdat; }
const std::vector<std::string>& keywordList() const { return keyword; }
const std::vector<std::string>& keywordList() const;
const std::vector<SummaryNode>& summaryNodeList() const;
int timestepIdxAtReportstepStart(const int reportStep) const;
size_t numberOfTimeSteps() const { return param[0].size(); }
const std::string& get_unit(const std::string& name) const;
const std::string& get_unit(const SummaryNode& node) const;
private:
int nVect, nI, nJ, nK;
@@ -57,6 +63,7 @@ private:
void ijk_from_global_index(int glob, int &i, int &j, int &k) const;
std::vector<std::vector<float>> param;
std::vector<std::string> keyword;
std::vector<SummaryNode> summaryNodes;
std::unordered_map<std::string, std::string> kwunits;
std::vector<int> seqIndex;
@@ -74,6 +81,9 @@ private:
void updatePathAndRootName(Opm::filesystem::path& dir, Opm::filesystem::path& rootN) const;
std::string makeKeyString(const std::string& keyword, const std::string& wgname, int num) const;
std::string unpackNumber(const SummaryNode&) const;
std::string lookupKey(const SummaryNode&) const;
};
}} // namespace Opm::EclIO
+13
View File
@@ -17,7 +17,12 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_IO_SUMMARYNODE_HPP
#define OPM_IO_SUMMARYNODE_HPP
#include <functional>
#include <string>
#include <unordered_set>
namespace Opm::EclIO {
@@ -53,7 +58,15 @@ struct SummaryNode {
constexpr static int default_number { std::numeric_limits<int>::min() };
std::string unique_key() const;
using number_renderer = std::function<std::string(const SummaryNode&)>;
std::string unique_key(number_renderer) const;
bool is_user_defined() const;
static Category category_from_keyword(const std::string&, const std::unordered_set<std::string> &miscellaneous_keywords = {});
};
} // namespace Opm::EclIO
#endif // OPM_IO_SUMMARYNODE_HPP
+64 -1
View File
@@ -51,7 +51,8 @@
namespace Opm { namespace EclIO {
ESmry::ESmry(const std::string &filename, bool loadBaseRunData)
ESmry::ESmry(const std::string &filename, bool loadBaseRunData) :
summaryNodes { }
{
Opm::filesystem::path inputFileName(filename);
@@ -84,6 +85,12 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData)
std::set<std::string> keywList;
std::vector<std::pair<std::string,int>> smryArray;
const std::unordered_set<std::string> segmentExceptions {
"SEPARATE",
"STEPTYPE",
"SUMTHIN",
} ;
// Read data from the summary into local data members.
{
EclFile smspec(smspec_file.string());
@@ -107,6 +114,14 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData)
for (unsigned int i=0; i<keywords.size(); i++) {
const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[i]);
if (keyString.length() > 0) {
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];
}
@@ -150,6 +165,14 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData)
for (size_t i = 0; i < keywords.size(); i++) {
const std::string keyString = makeKeyString(keywords[i], wgnames[i], nums[i]);
if (keyString.length() > 0) {
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];
}
@@ -496,6 +519,38 @@ std::string ESmry::makeKeyString(const std::string& keywordArg, const std::strin
return keyStr;
}
std::string ESmry::unpackNumber(const SummaryNode& node) const {
if (node.category == SummaryNode::Category::Block ||
node.category == SummaryNode::Category::Connection) {
int _i,_j,_k;
ijk_from_global_index(node.number, _i, _j, _k);
return std::to_string(_i) + "," + std::to_string(_j) + "," + std::to_string(_k);
} else if (node.category == SummaryNode::Category::Region && node.keyword[2] == 'F') {
const auto r1 = node.number % (1 << 15);
const auto r2 = (node.number / (1 << 15)) - 10;
return std::to_string(r1) + "-" + std::to_string(r2);
} else {
return std::to_string(node.number);
}
}
std::string ESmry::lookupKey(const SummaryNode& node) const {
return node.unique_key(std::bind( &ESmry::unpackNumber, this, std::placeholders::_1 ));
}
const std::vector<float>& ESmry::get(const SummaryNode& node) const {
return get(lookupKey(node));
}
std::vector<float> ESmry::get_at_rstep(const SummaryNode& node) const {
return get_at_rstep(lookupKey(node));
}
const std::string& ESmry::get_unit(const SummaryNode& node) const {
return get_unit(lookupKey(node));
}
const std::vector<float>& ESmry::get(const std::string& name) const
{
@@ -543,4 +598,12 @@ const std::string& ESmry::get_unit(const std::string& name) const {
return kwunits.at(name);
}
const std::vector<std::string>& ESmry::keywordList() const {
return keyword;
}
const std::vector<SummaryNode>& ESmry::summaryNodeList() const {
return summaryNodes;
}
}} // namespace Opm::ecl
+35 -2
View File
@@ -65,16 +65,20 @@ constexpr bool use_name(Opm::EclIO::SummaryNode::Category category) {
return false; // Never reached, but quells compiler warning
}
std::string default_number_renderer(const Opm::EclIO::SummaryNode& node) {
return std::to_string(node.number);
}
};
std::string Opm::EclIO::SummaryNode::unique_key() const {
std::string Opm::EclIO::SummaryNode::unique_key(number_renderer render_number) const {
std::vector<std::string> key_parts { keyword } ;
if (use_name(category))
key_parts.emplace_back(wgname);
if (use_number(category))
key_parts.emplace_back(std::to_string(number));
key_parts.emplace_back(render_number(*this));
auto compose_key = [](std::string& key, const std::string& key_part) -> std::string {
constexpr auto delimiter { ':' } ;
@@ -84,6 +88,10 @@ std::string Opm::EclIO::SummaryNode::unique_key() const {
return std::accumulate(std::begin(key_parts), std::end(key_parts), std::string(), compose_key);
}
std::string Opm::EclIO::SummaryNode::unique_key() const {
return unique_key(default_number_renderer);
}
bool Opm::EclIO::SummaryNode::is_user_defined() const {
static const std::unordered_set<std::string> udq_blacklist {
"AUTOCOAR",
@@ -119,3 +127,28 @@ bool Opm::EclIO::SummaryNode::is_user_defined() const {
return matched && !blacklisted;
}
Opm::EclIO::SummaryNode::Category Opm::EclIO::SummaryNode::category_from_keyword(
const std::string& keyword,
const std::unordered_set<std::string>& miscellaneous_keywords
) {
if (keyword.length() == 0) {
return Category::Miscellaneous;
}
if (miscellaneous_keywords.find(keyword) != miscellaneous_keywords.end()) {
return Category::Miscellaneous;
}
switch (keyword[0]) {
case 'A': return Category::Aquifer;
case 'B': return Category::Block;
case 'C': return Category::Connection;
case 'F': return Category::Field;
case 'G': return Category::Group;
case 'R': return Category::Region;
case 'S': return Category::Segment;
case 'W': return Category::Well;
default: return Category::Miscellaneous;
}
}
+28
View File
@@ -45,4 +45,32 @@ BOOST_AUTO_TEST_CASE(UniqueKey) {
expect_key( { "KEYW", Category::Miscellaneous, Type::Rate, "NORA", 8 }, "KEYW" );
}
BOOST_AUTO_TEST_CASE(InjectedNumberRenderer) {
using Category = Opm::EclIO::SummaryNode::Category;
using Type = Opm::EclIO::SummaryNode::Type;
Opm::EclIO::SummaryNode positiveNode {
"SIGN",
Category::Region,
Type::Undefined,
"-",
2
};
Opm::EclIO::SummaryNode negativeNode {
"SIGN",
Category::Region,
Type::Undefined,
"-",
-2
};
auto chooseSign = [](const Opm::EclIO::SummaryNode& node) -> std::string {
return node.number > 0 ? "+" : "-";
};
BOOST_CHECK_EQUAL(positiveNode.unique_key(chooseSign), "SIGN:+");
BOOST_CHECK_EQUAL(negativeNode.unique_key(chooseSign), "SIGN:-");
}
BOOST_AUTO_TEST_SUITE_END() // UniqueKey