Integrate SummaryNode in ESmry (#1642)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user