Merge pull request #854 from GitPaean/fixing_maximum_wtest_attempt
not removing the well from WellTestState when testing is successful
This commit is contained in:
@@ -53,6 +53,8 @@ public:
|
||||
const WTESTWell& get(const std::string& well, Reason reason) const;
|
||||
size_t size() const;
|
||||
|
||||
static std::string reasonToString(const Reason reason);
|
||||
|
||||
private:
|
||||
std::vector<WTESTWell> wells;
|
||||
};
|
||||
|
||||
@@ -39,9 +39,13 @@ public:
|
||||
|
||||
|
||||
|
||||
struct ClosedWell {
|
||||
struct WTestWell {
|
||||
std::string name;
|
||||
WellTestConfig::Reason reason;
|
||||
// the well can be re-opened if the well testing is successful. We only test when it is closed.
|
||||
bool closed;
|
||||
// it can be the time of last test,
|
||||
// or the time that the well is closed if not test has not been performed after
|
||||
double last_test;
|
||||
int num_attempt;
|
||||
};
|
||||
@@ -58,7 +62,7 @@ public:
|
||||
The simulator has decided to close a particular well; we then add it here
|
||||
as a closed well with a particualar reason.
|
||||
*/
|
||||
void addClosedWell(const std::string& well_name, WellTestConfig::Reason reason, double sim_time);
|
||||
void closeWell(const std::string& well_name, WellTestConfig::Reason reason, double sim_time);
|
||||
|
||||
/*
|
||||
The simulator has decided to close a particular completion in a well; we then add it here
|
||||
@@ -82,14 +86,6 @@ public:
|
||||
*/
|
||||
std::vector<std::pair<std::string, int>> updateCompletion(const WellTestConfig& config, double sim_time);
|
||||
|
||||
|
||||
/*
|
||||
If the simulator decides that a constraint is no longer met the dropWell()
|
||||
method should be called to indicate that this reason for keeping the well
|
||||
closed is no longer active.
|
||||
*/
|
||||
void dropWell(const std::string& well_name, WellTestConfig::Reason reason);
|
||||
|
||||
/*
|
||||
If the simulator decides that a constraint is no longer met the dropCompletion()
|
||||
method should be called to indicate that this reason for keeping the well
|
||||
@@ -97,8 +93,9 @@ public:
|
||||
*/
|
||||
void dropCompletion(const std::string& well_name, int complnum);
|
||||
|
||||
bool hasWell(const std::string& well_name, WellTestConfig::Reason reason) const;
|
||||
void openWell(const std::string& well_name);
|
||||
bool hasWellClosed(const std::string& well_name, WellTestConfig::Reason reason) const;
|
||||
|
||||
void openWell(const std::string& well_name, WellTestConfig::Reason reason);
|
||||
|
||||
bool hasCompletion(const std::string& well_name, const int complnum) const;
|
||||
|
||||
@@ -111,8 +108,11 @@ public:
|
||||
double lastTestTime(const std::string& well_name) const;
|
||||
|
||||
private:
|
||||
std::vector<ClosedWell> wells;
|
||||
std::vector<WTestWell> wells;
|
||||
std::vector<ClosedCompletion> completions;
|
||||
|
||||
|
||||
WTestWell* getWell(const std::string& well_name, WellTestConfig::Reason reason);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -102,6 +102,23 @@ const WellTestConfig::WTESTWell& WellTestConfig::get(const std::string& well, Re
|
||||
|
||||
|
||||
|
||||
std::string WellTestConfig::reasonToString(const Reason reason) {
|
||||
switch(reason) {
|
||||
case PHYSICAL:
|
||||
return std::string("PHYSICAL");
|
||||
case ECONOMIC:
|
||||
return std::string("ECONOMIC");
|
||||
case GROUP:
|
||||
return std::string("GROUP");
|
||||
case THP_DESIGN:
|
||||
return std::string("THP_DESIGN");
|
||||
case COMPLETION:
|
||||
return std::string("COMPLETION");
|
||||
default:
|
||||
throw std::runtime_error("unknown closure reason");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t WellTestConfig::size() const {
|
||||
|
||||
@@ -19,72 +19,87 @@
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include <cassert>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestState.hpp>
|
||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
void WellTestState::addClosedWell(const std::string& well_name, WellTestConfig::Reason reason, double sim_time) {
|
||||
if (this->hasWell(well_name, reason))
|
||||
return;
|
||||
void WellTestState::closeWell(const std::string& well_name, WellTestConfig::Reason reason, double sim_time) {
|
||||
|
||||
this->wells.push_back({well_name, reason, sim_time, 0});
|
||||
WTestWell* well_ptr = getWell(well_name, reason);
|
||||
|
||||
if (well_ptr) {
|
||||
// the well exists already, we just update it with action of closing
|
||||
well_ptr->closed = true;
|
||||
well_ptr->last_test = sim_time;
|
||||
} else
|
||||
this->wells.push_back({well_name, reason, true, sim_time, 0});
|
||||
}
|
||||
|
||||
|
||||
void WellTestState::openWell(const std::string& well_name) {
|
||||
wells.erase(std::remove_if(wells.begin(),
|
||||
wells.end(),
|
||||
[&well_name](const ClosedWell& well) { return (well.name == well_name); }),
|
||||
wells.end());
|
||||
void WellTestState::openWell(const std::string& well_name, WellTestConfig::Reason reason) {
|
||||
|
||||
WTestWell* well_ptr = getWell(well_name, reason);
|
||||
|
||||
if (well_ptr)
|
||||
well_ptr->closed = false;
|
||||
else
|
||||
throw std::runtime_error("No well named " + well_name + " with close reason "
|
||||
+ WellTestConfig::reasonToString(reason)
|
||||
+ " found in WellTestState.");
|
||||
}
|
||||
|
||||
|
||||
void WellTestState::dropWell(const std::string& well_name, WellTestConfig::Reason reason) {
|
||||
wells.erase(std::remove_if(wells.begin(),
|
||||
wells.end(),
|
||||
[&well_name, reason](const ClosedWell& well) { return (well.name == well_name && well.reason == reason); }),
|
||||
wells.end());
|
||||
}
|
||||
|
||||
|
||||
bool WellTestState::hasWell(const std::string& well_name, WellTestConfig::Reason reason) const {
|
||||
bool WellTestState::hasWellClosed(const std::string& well_name, WellTestConfig::Reason reason) const {
|
||||
const auto well_iter = std::find_if(wells.begin(),
|
||||
wells.end(),
|
||||
[&well_name, &reason](const ClosedWell& well)
|
||||
{
|
||||
return (reason == well.reason && well.name == well_name);
|
||||
[&well_name, &reason](const WTestWell& well)
|
||||
{
|
||||
return (reason == well.reason && well.name == well_name && well.closed);
|
||||
});
|
||||
return (well_iter != wells.end());
|
||||
}
|
||||
|
||||
|
||||
WellTestState::WTestWell* WellTestState::getWell(const std::string& well_name, WellTestConfig::Reason reason)
|
||||
{
|
||||
const auto well_iter = std::find_if(wells.begin(), wells.end(), [&well_name, &reason](const WTestWell& well) {
|
||||
return (reason == well.reason && well.name == well_name);
|
||||
});
|
||||
|
||||
return (well_iter == wells.end() ? nullptr : &(*well_iter) );
|
||||
}
|
||||
|
||||
|
||||
size_t WellTestState::sizeWells() const {
|
||||
return this->wells.size();
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, WellTestConfig::Reason>> WellTestState::updateWell(const WellTestConfig& config, double sim_time) {
|
||||
std::vector<std::pair<std::string, WellTestConfig::Reason>> output;
|
||||
for (auto& closed_well : this->wells) {
|
||||
if (config.has(closed_well.name, closed_well.reason)) {
|
||||
const auto& well_config = config.get(closed_well.name, closed_well.reason);
|
||||
double elapsed = sim_time - closed_well.last_test;
|
||||
for (auto& well : this->wells) {
|
||||
if (well.closed && config.has(well.name, well.reason)) {
|
||||
const auto& well_config = config.get(well.name, well.reason);
|
||||
double elapsed = sim_time - well.last_test;
|
||||
|
||||
if (elapsed >= well_config.test_interval)
|
||||
if (well_config.num_test == 0 || (closed_well.num_attempt < well_config.num_test)) {
|
||||
closed_well.last_test = sim_time;
|
||||
closed_well.num_attempt += 1;
|
||||
output.push_back(std::make_pair(closed_well.name, closed_well.reason));
|
||||
if (well_config.num_test == 0 || (well.num_attempt < well_config.num_test)) {
|
||||
well.last_test = sim_time;
|
||||
well.num_attempt ++;
|
||||
output.emplace_back(std::make_pair(well.name, well.reason));
|
||||
if ( (well_config.num_test != 0) && (well.num_attempt >= well_config.num_test) ) {
|
||||
OpmLog::info(well.name + " will be tested for " + WellTestConfig::reasonToString(well.reason)
|
||||
+ " reason for the last time! " );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void WellTestState::addClosedCompletion(const std::string& well_name, int complnum, double sim_time) {
|
||||
if (this->hasCompletion(well_name, complnum))
|
||||
return;
|
||||
@@ -136,7 +151,7 @@ namespace Opm {
|
||||
double WellTestState::lastTestTime(const std::string& well_name) const {
|
||||
const auto well_iter = std::find_if(wells.begin(),
|
||||
wells.end(),
|
||||
[&well_name](const ClosedWell& well)
|
||||
[&well_name](const WTestWell& well)
|
||||
{
|
||||
return (well.name == well_name);
|
||||
});
|
||||
|
||||
@@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(WTEST_STATE2) {
|
||||
WellTestConfig wc;
|
||||
WellTestState st;
|
||||
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 0, 0, 0);
|
||||
st.addClosedWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100);
|
||||
st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100);
|
||||
BOOST_CHECK_EQUAL(st.sizeWells(), 1);
|
||||
|
||||
auto shut_wells = st.updateWell(wc, 5000);
|
||||
@@ -80,43 +80,49 @@ BOOST_AUTO_TEST_CASE(WTEST_STATE2) {
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WTEST_STATE) {
|
||||
const double day = 86400.;
|
||||
WellTestConfig wc;
|
||||
WellTestState st;
|
||||
st.addClosedWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100);
|
||||
st.closeWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100. * day);
|
||||
BOOST_CHECK_EQUAL(st.sizeWells(), 1);
|
||||
|
||||
st.addClosedWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100);
|
||||
st.openWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC);
|
||||
BOOST_CHECK_EQUAL(st.sizeWells(), 1);
|
||||
|
||||
st.addClosedWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100);
|
||||
st.closeWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100. * day);
|
||||
BOOST_CHECK_EQUAL(st.sizeWells(), 1);
|
||||
|
||||
st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100. * day);
|
||||
BOOST_CHECK_EQUAL(st.sizeWells(), 2);
|
||||
|
||||
st.addClosedWell("WELLX", WellTestConfig::Reason::PHYSICAL, 100);
|
||||
st.closeWell("WELLX", WellTestConfig::Reason::PHYSICAL, 100. * day);
|
||||
BOOST_CHECK_EQUAL(st.sizeWells(), 3);
|
||||
|
||||
auto shut_wells = st.updateWell(wc, 5000);
|
||||
BOOST_CHECK_EQUAL( shut_wells.size(), 0);
|
||||
|
||||
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1000, 2, 0);
|
||||
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1000. * day, 2, 0);
|
||||
// Not sufficient time has passed.
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 200).size(), 0);
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 200. * day).size(), 0);
|
||||
|
||||
// We should test it:
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 1200).size(), 1);
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 1200. * day).size(), 1);
|
||||
|
||||
// Not sufficient time has passed.
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 1700).size(), 0);
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 1700. * day).size(), 0);
|
||||
|
||||
// We should test it:
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 2400).size(), 1);
|
||||
st.openWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL);
|
||||
|
||||
st.closeWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1900. * day);
|
||||
|
||||
// We should not test it:
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 2400. * day).size(), 0);
|
||||
|
||||
// We should test it now:
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 3000. * day).size(), 1);
|
||||
|
||||
// Too many attempts:
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 24000).size(), 0);
|
||||
|
||||
st.dropWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC);
|
||||
|
||||
st.openWell("WELL_NAME");
|
||||
BOOST_CHECK_EQUAL(st.sizeWells(), 1);
|
||||
BOOST_CHECK_EQUAL( st.updateWell(wc, 24000. * day).size(), 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user