Merge pull request #2720 from joakim-hove/wtest-overwrite

WTEST - consecutive keywords overwrite instead of updating
This commit is contained in:
Joakim Hove 2021-09-30 10:31:23 +02:00 committed by GitHub
commit 9a2a4036de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 103 deletions

View File

@ -21,14 +21,14 @@
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <vector> #include <unordered_map>
namespace Opm { namespace Opm {
class WellTestConfig { class WellTestConfig {
public: public:
enum Reason { enum class Reason {
PHYSICAL = 1, PHYSICAL = 1,
ECONOMIC = 2, ECONOMIC = 2,
GROUP = 4, GROUP = 4,
@ -38,7 +38,7 @@ public:
struct WTESTWell { struct WTESTWell {
std::string name; std::string name;
Reason shut_reason; int reasons;
double test_interval; double test_interval;
int num_test; int num_test;
double startup_time; double startup_time;
@ -48,7 +48,7 @@ public:
bool operator==(const WTESTWell& data) const { bool operator==(const WTESTWell& data) const {
return name == data.name && return name == data.name &&
shut_reason == data.shut_reason && reasons == data.reasons &&
test_interval == data.test_interval && test_interval == data.test_interval &&
num_test == data.num_test && num_test == data.num_test &&
startup_time == data.startup_time && startup_time == data.startup_time &&
@ -56,7 +56,7 @@ public:
} }
WTESTWell() = default; WTESTWell() = default;
WTESTWell(const std::string& name, Reason shut_reason, double test_interval, int num_test, double startup_time, int begin_report_step); WTESTWell(const std::string& name, int reasons, double test_interval, int num_test, double startup_time, int begin_report_step);
static WTESTWell serializeObject(); static WTESTWell serializeObject();
@ -64,7 +64,7 @@ public:
void serializeOp(Serializer& serializer) void serializeOp(Serializer& serializer)
{ {
serializer(name); serializer(name);
serializer(shut_reason); serializer(reasons);
serializer(test_interval); serializer(test_interval);
serializer(num_test); serializer(num_test);
serializer(startup_time); serializer(startup_time);
@ -72,36 +72,29 @@ public:
} }
}; };
WellTestConfig();
static WellTestConfig serializeObject(); static WellTestConfig serializeObject();
void add_well(const std::string& well, Reason reason, double test_interval, int num_test, double startup_time, int current_step);
void add_well(const std::string& well, const std::string& reasons, double test_interval, void add_well(const std::string& well, const std::string& reasons, double test_interval,
int num_test, double startup_time, int current_step); int num_test, double startup_time, int current_step);
void drop_well(const std::string& well); void drop_well(const std::string& well);
bool has(const std::string& well) const; bool has(const std::string& well) const;
bool has(const std::string& well, Reason reason) const; bool has(const std::string& well, Reason reason) const;
const WTESTWell& get(const std::string& well, Reason reason) const; const WTESTWell& get(const std::string& well, Reason reason) const;
size_t size() const;
static std::string reasonToString(const Reason reason); static std::string reasonToString(const Reason reason);
bool empty() const;
bool operator==(const WellTestConfig& data) const; bool operator==(const WellTestConfig& data) const;
template<class Serializer> template<class Serializer>
void serializeOp(Serializer& serializer) void serializeOp(Serializer& serializer)
{ {
serializer.vector(wells); serializer.map(wells);
} }
private: private:
std::vector<WTESTWell> wells; std::unordered_map<std::string, WTESTWell> wells;
WTESTWell* getWell(const std::string& well_name, const Reason reason);
}; };
} }
#endif #endif

View File

@ -23,9 +23,9 @@
namespace Opm { namespace Opm {
WellTestConfig::WTESTWell::WTESTWell(const std::string& name_arg, Reason shut_reason_arg, double test_interval_arg, int num_test_arg, double startup_time_arg, int begin_report_step_arg) : WellTestConfig::WTESTWell::WTESTWell(const std::string& name_arg, int shut_reason_arg, double test_interval_arg, int num_test_arg, double startup_time_arg, int begin_report_step_arg) :
name(name_arg), name(name_arg),
shut_reason(shut_reason_arg), reasons(shut_reason_arg),
test_interval(test_interval_arg), test_interval(test_interval_arg),
num_test(num_test_arg), num_test(num_test_arg),
startup_time(startup_time_arg), startup_time(startup_time_arg),
@ -33,116 +33,96 @@ WellTestConfig::WTESTWell::WTESTWell(const std::string& name_arg, Reason shut_re
{} {}
WellTestConfig::WTESTWell WellTestConfig::WTESTWell::serializeObject() { WellTestConfig::WTESTWell WellTestConfig::WTESTWell::serializeObject() {
return WellTestConfig::WTESTWell("name", Reason::THP_DESIGN, 100, 1, 674, 56); return WellTestConfig::WTESTWell("name", static_cast<int>(Reason::PHYSICAL), 100, 1, 674, 56);
} }
WellTestConfig::WellTestConfig() {
}
WellTestConfig WellTestConfig::serializeObject() WellTestConfig WellTestConfig::serializeObject()
{ {
WellTestConfig result; WellTestConfig result;
result.wells = { WellTestConfig::WTESTWell::serializeObject() }; result.wells.emplace( "W1", WellTestConfig::WTESTWell::serializeObject() );
return result; return result;
} }
void WellTestConfig::add_well(const std::string& well, Reason shut_reason, double test_interval,
void WellTestConfig::add_well(const std::string& well, const std::string& reasons_string, double test_interval,
int num_retries, double startup_time, const int current_step) { int num_retries, double startup_time, const int current_step) {
if (reasons_string.empty())
WTESTWell* well_ptr = getWell(well, shut_reason);
if (well_ptr) {
*well_ptr = WTESTWell{well, shut_reason, test_interval, num_retries, startup_time, current_step};
} else {
wells.emplace_back(well, shut_reason, test_interval, num_retries, startup_time, current_step);
}
}
void WellTestConfig::add_well(const std::string& well, const std::string& reasons, double test_interval,
int num_retries, double startup_time, const int current_step) {
if (reasons.empty())
throw std::invalid_argument("Can not pass empty string to stop testing to add_well() method."); throw std::invalid_argument("Can not pass empty string to stop testing to add_well() method.");
for (auto c : reasons) { int reasons{0};
for (auto c : reasons_string) {
switch(c) { switch(c) {
case 'P' : case 'P' :
add_well(well, Reason::PHYSICAL, test_interval, num_retries, startup_time, current_step); reasons += static_cast<int>(Reason::PHYSICAL);
break; break;
case 'E' : case 'E' :
add_well(well, Reason::ECONOMIC, test_interval, num_retries, startup_time, current_step); reasons += static_cast<int>(Reason::ECONOMIC);
break; break;
case 'G': case 'G':
add_well(well, Reason::GROUP, test_interval, num_retries, startup_time, current_step); reasons += static_cast<int>(Reason::GROUP);
break; break;
case 'D': case 'D':
add_well(well, Reason::THP_DESIGN, test_interval, num_retries, startup_time, current_step); reasons += static_cast<int>(Reason::THP_DESIGN);
break; break;
case 'C': case 'C':
add_well(well, Reason::COMPLETION, test_interval, num_retries, startup_time, current_step); reasons += static_cast<int>(Reason::COMPLETION);
break; break;
default: default:
throw std::invalid_argument("Invalid character in WTEST configuration"); throw std::invalid_argument("Invalid character in WTEST configuration");
} }
} }
this->wells.insert_or_assign(well, WTESTWell(well, reasons, test_interval, num_retries, startup_time, current_step));
} }
void WellTestConfig::drop_well(const std::string& well) { void WellTestConfig::drop_well(const std::string& well) {
wells.erase(std::remove_if(wells.begin(), this->wells.erase(well);
wells.end(),
[&well](const WTESTWell& wtest_well) { return (wtest_well.name == well); }),
wells.end());
} }
bool WellTestConfig::has(const std::string& well) const { bool WellTestConfig::has(const std::string& well) const {
const auto well_iter = std::find_if(wells.begin(), const auto well_iter = this->wells.find(well);
wells.end(),
[&well](const WTESTWell& wtest_well) { return (wtest_well.name == well); });
return (well_iter != wells.end()); return (well_iter != wells.end());
} }
bool WellTestConfig::has(const std::string& well, Reason reason) const { bool WellTestConfig::has(const std::string& well, Reason reason) const {
const auto well_iter = std::find_if(wells.begin(), const auto well_iter = this->wells.find(well);
wells.end(), if (well_iter == wells.end())
[&well, &reason](const WTESTWell& wtest_well) return false;
{
return (reason == wtest_well.shut_reason && wtest_well.name == well); return ((well_iter->second.reasons & static_cast<int>(reason)) != 0);
});
return (well_iter != wells.end());
} }
const WellTestConfig::WTESTWell& WellTestConfig::get(const std::string& well, Reason reason) const { const WellTestConfig::WTESTWell& WellTestConfig::get(const std::string& well, Reason reason) const {
const auto well_iter = std::find_if(wells.begin(), const auto well_iter = this->wells.find(well);
wells.end(),
[&well, &reason](const WTESTWell& wtest_well)
{
return (reason == wtest_well.shut_reason && wtest_well.name == well);
});
if (well_iter == wells.end()) if (well_iter == wells.end())
throw std::invalid_argument("No such WTEST object"); throw std::logic_error("No such WTEST well");
return *well_iter; if (well_iter->second.reasons & static_cast<int>(reason))
return well_iter->second;
throw std::logic_error("No such WTEST well");
} }
std::string WellTestConfig::reasonToString(const Reason reason) { std::string WellTestConfig::reasonToString(const Reason reason) {
switch(reason) { switch(reason) {
case PHYSICAL: case Reason::PHYSICAL:
return std::string("PHYSICAL"); return std::string("PHYSICAL");
case ECONOMIC: case Reason::ECONOMIC:
return std::string("ECONOMIC"); return std::string("ECONOMIC");
case GROUP: case Reason::GROUP:
return std::string("GROUP"); return std::string("GROUP");
case THP_DESIGN: case Reason::THP_DESIGN:
return std::string("THP_DESIGN"); return std::string("THP_DESIGN");
case COMPLETION: case Reason::COMPLETION:
return std::string("COMPLETION"); return std::string("COMPLETION");
default: default:
throw std::runtime_error("unknown closure reason"); throw std::runtime_error("unknown closure reason");
@ -150,19 +130,8 @@ std::string WellTestConfig::reasonToString(const Reason reason) {
} }
bool WellTestConfig::empty() const {
WellTestConfig::WTESTWell* WellTestConfig::getWell(const std::string& well_name, const Reason reason) { return this->wells.empty();
const auto well_iter = std::find_if(wells.begin(), wells.end(), [&well_name, &reason](const WTESTWell& well) {
return (reason == well.shut_reason && well.name == well_name);
});
return (well_iter == wells.end() ? nullptr : std::addressof(*well_iter) );
}
size_t WellTestConfig::size() const {
return wells.size();
} }
@ -175,3 +144,4 @@ bool WellTestConfig::operator==(const WellTestConfig& data) const {
} }

View File

@ -2861,12 +2861,12 @@ WCONINJH
{ {
const auto& wtest_config = schedule[0].wtest_config.get(); const auto& wtest_config = schedule[0].wtest_config.get();
BOOST_CHECK_EQUAL(wtest_config.size(), 0U); BOOST_CHECK(wtest_config.empty());
} }
{ {
const auto& wtest_config = schedule[1].wtest_config.get(); const auto& wtest_config = schedule[1].wtest_config.get();
BOOST_CHECK_EQUAL(wtest_config.size(), 0U); BOOST_CHECK(wtest_config.empty());
} }
} }
} }
@ -3158,12 +3158,12 @@ BOOST_AUTO_TEST_CASE(WTEST_CONFIG) {
const auto& schedule = make_schedule(createDeckWTEST()); const auto& schedule = make_schedule(createDeckWTEST());
const auto& wtest_config1 = schedule[0].wtest_config.get(); const auto& wtest_config1 = schedule[0].wtest_config.get();
BOOST_CHECK_EQUAL(wtest_config1.size(), 2U); BOOST_CHECK(!wtest_config1.empty());
BOOST_CHECK(wtest_config1.has("ALLOW")); BOOST_CHECK(wtest_config1.has("ALLOW"));
BOOST_CHECK(!wtest_config1.has("BAN")); BOOST_CHECK(!wtest_config1.has("BAN"));
const auto& wtest_config2 = schedule[1].wtest_config.get(); const auto& wtest_config2 = schedule[1].wtest_config.get();
BOOST_CHECK_EQUAL(wtest_config2.size(), 3U); BOOST_CHECK(!wtest_config2.empty());
BOOST_CHECK(!wtest_config2.has("ALLOW")); BOOST_CHECK(!wtest_config2.has("ALLOW"));
BOOST_CHECK(wtest_config2.has("BAN")); BOOST_CHECK(wtest_config2.has("BAN"));
BOOST_CHECK(wtest_config2.has("BAN", WellTestConfig::Reason::GROUP)); BOOST_CHECK(wtest_config2.has("BAN", WellTestConfig::Reason::GROUP));

View File

@ -40,27 +40,24 @@ using namespace Opm;
BOOST_AUTO_TEST_CASE(CreateWellTestConfig) { BOOST_AUTO_TEST_CASE(CreateWellTestConfig) {
WellTestConfig wc; WellTestConfig wc;
BOOST_CHECK_EQUAL(wc.size() , 0U); BOOST_CHECK(wc.empty());
wc.add_well("NAME", WellTestConfig::Reason::PHYSICAL, 10, 10, 10, 1); wc.add_well("NAME", "P", 10, 10, 10, 1);
BOOST_CHECK_EQUAL(wc.size(), 1U); BOOST_CHECK(!wc.empty());
BOOST_CHECK_THROW(wc.add_well("NAME2", "", 10.0,10,10.0, 1), std::invalid_argument); BOOST_CHECK_THROW(wc.add_well("NAME2", "", 10.0,10,10.0, 1), std::exception);
BOOST_CHECK_THROW(wc.add_well("NAME3", "X", 1,2,3, 1), std::invalid_argument); BOOST_CHECK_THROW(wc.add_well("NAME3", "X", 1,2,3, 1), std::exception);
wc.add_well("NAME", "PEGDC", 10, 10, 10, 1); wc.add_well("NAME", "PEGDC", 10, 10, 10, 1);
BOOST_CHECK_EQUAL(wc.size(), 5U);
wc.add_well("NAMEX", "PGDC", 10, 10, 10, 1); wc.add_well("NAMEX", "PGDC", 10, 10, 10, 1);
BOOST_CHECK_EQUAL(wc.size(), 9U);
wc.drop_well("NAME"); wc.drop_well("NAME");
BOOST_CHECK_EQUAL(wc.size(), 4U);
BOOST_CHECK(wc.has("NAMEX")); BOOST_CHECK(wc.has("NAMEX"));
BOOST_CHECK(wc.has("NAMEX", WellTestConfig::Reason::PHYSICAL)); BOOST_CHECK(wc.has("NAMEX", WellTestConfig::Reason::PHYSICAL));
BOOST_CHECK(!wc.has("NAMEX", WellTestConfig::Reason::ECONOMIC)); BOOST_CHECK(!wc.has("NAMEX", WellTestConfig::Reason::ECONOMIC));
BOOST_CHECK(!wc.has("NAME")); BOOST_CHECK(!wc.has("NAME"));
BOOST_CHECK_THROW(wc.get("NAMEX", WellTestConfig::Reason::ECONOMIC), std::invalid_argument); BOOST_CHECK_THROW(wc.get("NAMEX", WellTestConfig::Reason::ECONOMIC), std::exception);
BOOST_CHECK_THROW(wc.get("NO_NAME", WellTestConfig::Reason::ECONOMIC), std::invalid_argument); BOOST_CHECK_THROW(wc.get("NO_NAME", WellTestConfig::Reason::ECONOMIC), std::exception);
const auto& wt = wc.get("NAMEX", WellTestConfig::Reason::PHYSICAL); const auto& wt = wc.get("NAMEX", WellTestConfig::Reason::PHYSICAL);
BOOST_CHECK_EQUAL(wt.name, "NAMEX"); BOOST_CHECK_EQUAL(wt.name, "NAMEX");
} }
@ -69,7 +66,7 @@ BOOST_AUTO_TEST_CASE(CreateWellTestConfig) {
BOOST_AUTO_TEST_CASE(WTEST_STATE2) { BOOST_AUTO_TEST_CASE(WTEST_STATE2) {
WellTestConfig wc; WellTestConfig wc;
WellTestState st; WellTestState st;
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 0, 0, 0, 0); wc.add_well("WELL_NAME", "P", 0, 0, 0, 0);
st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100); st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100);
BOOST_CHECK_EQUAL(st.sizeWells(), 1U); BOOST_CHECK_EQUAL(st.sizeWells(), 1U);
@ -124,7 +121,7 @@ BOOST_AUTO_TEST_CASE(WTEST_STATE) {
BOOST_CHECK_EQUAL(shut_wells.size(), 0U); BOOST_CHECK_EQUAL(shut_wells.size(), 0U);
} }
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1000. * day, 2, 0, 1); wc.add_well("WELL_NAME", "P", 1000. * day, 2, 0, 1);
// Not sufficient time has passed. // Not sufficient time has passed.
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 200. * day).size(), 0U); BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 200. * day).size(), 0U);
@ -147,7 +144,7 @@ BOOST_AUTO_TEST_CASE(WTEST_STATE) {
// Too many attempts: // Too many attempts:
BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 4000. * day).size(), 0U); BOOST_CHECK_EQUAL( st.updateWells(wc, wells, 4000. * day).size(), 0U);
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1000. * day, 3, 0, 5); wc.add_well("WELL_NAME", "P", 1000. * day, 3, 0, 5);
wells[0].updateStatus(Well::Status::SHUT); wells[0].updateStatus(Well::Status::SHUT);
@ -188,7 +185,7 @@ BOOST_AUTO_TEST_CASE(WTEST_STATE_COMPLETIONS) {
auto closed_completions = st.updateWells(wc, wells, 5000); auto closed_completions = st.updateWells(wc, wells, 5000);
BOOST_CHECK_EQUAL( closed_completions.size(), 0U); BOOST_CHECK_EQUAL( closed_completions.size(), 0U);
wc.add_well("WELL_NAME", WellTestConfig::Reason::COMPLETION, 1000, 2, 0, 0); wc.add_well("WELL_NAME", "C", 1000, 2, 0, 0);
// Not sufficient time has passed. // Not sufficient time has passed.
BOOST_CHECK_EQUAL( st.updateCompletion(wc, 200).size(), 0U); BOOST_CHECK_EQUAL( st.updateCompletion(wc, 200).size(), 0U);