Add serialization of SummaryState
This commit is contained in:
parent
cb106240bf
commit
ec20274fa3
@ -91,6 +91,8 @@ public:
|
||||
std::vector<std::string> wells(const std::string& var) const;
|
||||
std::vector<std::string> groups() const;
|
||||
std::vector<std::string> groups(const std::string& var) const;
|
||||
std::vector<char> serialize() const;
|
||||
void deserialize(const std::vector<char>& buffer);
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
std::size_t num_wells() const;
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <unordered_map>
|
||||
#include <cstring>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
@ -211,4 +212,134 @@ namespace {
|
||||
std::size_t SummaryState::size() const {
|
||||
return this->values.size();
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
class Serializer {
|
||||
public:
|
||||
Serializer() = default;
|
||||
Serializer(const std::vector<char>& buffer) :
|
||||
buffer(buffer)
|
||||
{}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void put(const T& value) {
|
||||
this->pack(std::addressof(value), sizeof(T));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
T get() {
|
||||
T value;
|
||||
std::memcpy(&value, &this->buffer[pos], sizeof(T));
|
||||
this->pos += sizeof(T);
|
||||
return value;
|
||||
}
|
||||
|
||||
std::vector<char> buffer;
|
||||
private:
|
||||
void pack(const void * ptr, std::size_t value_size) {
|
||||
std::size_t write_pos = this->buffer.size();
|
||||
std::size_t new_size = write_pos + value_size;
|
||||
this->buffer.resize( new_size );
|
||||
std::memcpy(&this->buffer[write_pos], ptr, value_size);
|
||||
}
|
||||
|
||||
std::size_t pos = 0;
|
||||
};
|
||||
|
||||
template <>
|
||||
void Serializer::put(const std::string& value) {
|
||||
this->put<std::string::size_type>(value.size());
|
||||
this->pack(value.c_str(), value.size());
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string Serializer::get() {
|
||||
std::string::size_type length = this->get<std::string::size_type>();
|
||||
this->pos += length;
|
||||
return {std::addressof(this->buffer[this->pos - length]), length};
|
||||
}
|
||||
|
||||
void put_map(Serializer& ser, const std::unordered_map<std::string, double>& values) {
|
||||
ser.put(values.size());
|
||||
for (const auto& value_pair : values) {
|
||||
ser.put(value_pair.first);
|
||||
ser.put(value_pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::vector<char> SummaryState::serialize() const {
|
||||
std::vector<char> buffer;
|
||||
Serializer ser;
|
||||
ser.put(this->elapsed);
|
||||
put_map(ser, values);
|
||||
|
||||
ser.put(this->well_values.size());
|
||||
for (const auto& well_var_pair : this->well_values) {
|
||||
ser.put(well_var_pair.first);
|
||||
put_map(ser, well_var_pair.second);
|
||||
}
|
||||
|
||||
ser.put(this->group_values.size());
|
||||
for (const auto& group_var_pair : this->group_values) {
|
||||
ser.put(group_var_pair.first);
|
||||
put_map(ser, group_var_pair.second);
|
||||
}
|
||||
|
||||
return std::move(ser.buffer);
|
||||
}
|
||||
|
||||
|
||||
void SummaryState::deserialize(const std::vector<char>& buffer) {
|
||||
this->values.clear();
|
||||
this->m_wells.clear();
|
||||
this->well_values.clear();
|
||||
this->m_groups.clear();
|
||||
this->group_values.clear();
|
||||
this->elapsed = 0;
|
||||
|
||||
Serializer ser(buffer);
|
||||
this->elapsed = ser.get<double>();
|
||||
{
|
||||
std::size_t num_values = ser.get<std::size_t>();
|
||||
for (std::size_t index = 0; index < num_values; index++) {
|
||||
std::string key = ser.get<std::string>();
|
||||
double value = ser.get<double>();
|
||||
this->update(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t num_well_var = ser.get<std::size_t>();
|
||||
for (std::size_t var_index = 0; var_index < num_well_var; var_index++) {
|
||||
std::string var = ser.get<std::string>();
|
||||
|
||||
std::size_t num_well = ser.get<std::size_t>();
|
||||
for (std::size_t well_index=0; well_index < num_well; well_index++) {
|
||||
std::string well = ser.get<std::string>();
|
||||
double value = ser.get<double>();
|
||||
this->update_well_var(well, var, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::size_t num_group_var = ser.get<std::size_t>();
|
||||
for (std::size_t var_index = 0; var_index < num_group_var; var_index++) {
|
||||
std::string var = ser.get<std::string>();
|
||||
|
||||
std::size_t num_group = ser.get<std::size_t>();
|
||||
for (std::size_t group_index=0; group_index < num_group; group_index++) {
|
||||
std::string group = ser.get<std::string>();
|
||||
double value = ser.get<double>();
|
||||
this->update_group_var(group, var, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3225,4 +3225,84 @@ BOOST_AUTO_TEST_CASE(SummaryState_TOTAL) {
|
||||
BOOST_CHECK_EQUAL(st.get_elapsed(), 200);
|
||||
}
|
||||
|
||||
bool equal(const SummaryState& st1 , const SummaryState& st2) {
|
||||
if (st1.size() != st2.size())
|
||||
return false;
|
||||
|
||||
{
|
||||
const auto& wells2 = st2.wells();
|
||||
if (wells2.size() != st1.wells().size())
|
||||
return false;
|
||||
|
||||
for (const auto& well : st1.wells()) {
|
||||
auto f = std::find(wells2.begin(), wells2.end(), well);
|
||||
if (f == wells2.end())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto& groups2 = st2.groups();
|
||||
if (groups2.size() != st1.groups().size())
|
||||
return false;
|
||||
|
||||
for (const auto& group : st1.groups()) {
|
||||
auto f = std::find(groups2.begin(), groups2.end(), group);
|
||||
if (f == groups2.end())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (const auto& value_pair : st1) {
|
||||
const std::string& key = value_pair.first;
|
||||
double value = value_pair.second;
|
||||
if (value != st2.get(key))
|
||||
return false;
|
||||
}
|
||||
|
||||
return st1.get_elapsed() == st2.get_elapsed();
|
||||
}
|
||||
|
||||
|
||||
void test_serialize(const SummaryState& st) {
|
||||
SummaryState st2;
|
||||
auto serial = st.serialize();
|
||||
st2.deserialize(serial);
|
||||
BOOST_CHECK( equal(st, st2));
|
||||
|
||||
st2.update_elapsed(1234567.09);
|
||||
st2.update("FOPT", 200);
|
||||
st2.deserialize(serial);
|
||||
BOOST_CHECK( equal(st, st2));
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(serialize_sumary_state) {
|
||||
SummaryState st;
|
||||
test_serialize(st);
|
||||
|
||||
st.update_elapsed(1000);
|
||||
test_serialize(st);
|
||||
|
||||
st.update("FOPT", 100);
|
||||
test_serialize(st);
|
||||
|
||||
st.update("FGPT", 100);
|
||||
test_serialize(st);
|
||||
|
||||
st.update_well_var("OP_1", "WOPR", 1000);
|
||||
test_serialize(st);
|
||||
|
||||
st.update_well_var("OP_2", "WGOR", 0.67);
|
||||
test_serialize(st);
|
||||
|
||||
st.update_group_var("G1", "GOPR", 1000);
|
||||
test_serialize(st);
|
||||
|
||||
st.update_group_var("G2", "GGOR", 0.67);
|
||||
test_serialize(st);
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
Reference in New Issue
Block a user