Merge pull request #414 from joakim-hove/welltest-state
Add WellTestState object to keep track of automatically closed wells
This commit is contained in:
@@ -94,6 +94,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellPolymerProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/WellTestState.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.cpp
|
||||
src/opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp
|
||||
@@ -459,6 +460,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Schedule/MSW/updatingCompletionsWithSegments.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellProductionProperties.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/CompletionSet.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/ThresholdPressure.hpp
|
||||
opm/parser/eclipse/EclipseState/SimulationConfig/SimulationConfig.hpp
|
||||
|
||||
82
opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp
Normal file
82
opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright 2018 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef WELLTEST_STATE_H
|
||||
#define WELLTEST_STATE_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class WellTestState {
|
||||
public:
|
||||
/*
|
||||
This class implements a small mutable state object which keeps track of
|
||||
which wells have been automatically closed by the simulator, and by
|
||||
checking with the WTEST configuration object the class can return a list
|
||||
(well_name,reason) pairs for wells which should be checked as candiates
|
||||
for opening.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct ClosedWell {
|
||||
std::string name;
|
||||
WellTestConfig::Reason reason;
|
||||
double last_test;
|
||||
int num_attempt;
|
||||
};
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
/*
|
||||
The update will consult the WellTestConfig object and return a list of
|
||||
wells which should be checked for possible reopening; observe that the
|
||||
update method will update the internal state of the object by counting up
|
||||
the openiing attempts, and also set the time for the last attempt to open.
|
||||
*/
|
||||
std::vector<std::pair<std::string, WellTestConfig::Reason>> update(const WellTestConfig& config, double sim_time);
|
||||
|
||||
/*
|
||||
If the simulator decides that a constraint is no longer met the drop()
|
||||
method should be called to indicate that this reason for keeping the well
|
||||
closed is no longer active.
|
||||
*/
|
||||
void drop(const std::string& well_name, WellTestConfig::Reason reason);
|
||||
|
||||
|
||||
bool has(const std::string well_name, WellTestConfig::Reason reason) const;
|
||||
void openWell(const std::string& well_name);
|
||||
size_t size() const;
|
||||
private:
|
||||
std::vector<ClosedWell> wells;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright 2018 Statoil ASA.
|
||||
|
||||
This file is part of the Open Porous Media project (OPM).
|
||||
|
||||
OPM is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OPM is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
void WellTestState::addClosedWell(const std::string& well_name, WellTestConfig::Reason reason, double sim_time) {
|
||||
if (this->has(well_name, reason))
|
||||
return;
|
||||
|
||||
this->wells.push_back({well_name, reason, 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::drop(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::has(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);
|
||||
});
|
||||
return (well_iter != wells.end());
|
||||
}
|
||||
|
||||
size_t WellTestState::size() const {
|
||||
return this->wells.size();
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::pair<std::string, WellTestConfig::Reason>> WellTestState::update(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;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define BOOST_TEST_MODULE WTEST
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellTestState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/WellTestConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
|
||||
@@ -61,10 +62,60 @@ BOOST_AUTO_TEST_CASE(CreateWellTestConfig) {
|
||||
BOOST_CHECK(!wc.has("NAMEX", WellTestConfig::Reason::ECONOMIC));
|
||||
BOOST_CHECK(!wc.has("NAME"));
|
||||
|
||||
|
||||
BOOST_CHECK_THROW(wc.get("NAMEX", WellTestConfig::Reason::ECONOMIC), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(wc.get("NO_NAME", WellTestConfig::Reason::ECONOMIC), std::invalid_argument);
|
||||
const auto& wt = wc.get("NAMEX", WellTestConfig::Reason::PHYSICAL);
|
||||
BOOST_CHECK_EQUAL(wt.name, "NAMEX");
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
BOOST_CHECK_EQUAL(st.size(), 1);
|
||||
|
||||
auto shut_wells = st.update(wc, 5000);
|
||||
BOOST_CHECK_EQUAL( shut_wells.size(), 1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WTEST_STATE) {
|
||||
WellTestConfig wc;
|
||||
WellTestState st;
|
||||
st.addClosedWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100);
|
||||
BOOST_CHECK_EQUAL(st.size(), 1);
|
||||
|
||||
st.addClosedWell("WELL_NAME", WellTestConfig::Reason::ECONOMIC, 100);
|
||||
BOOST_CHECK_EQUAL(st.size(), 1);
|
||||
|
||||
st.addClosedWell("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 100);
|
||||
BOOST_CHECK_EQUAL(st.size(), 2);
|
||||
|
||||
st.addClosedWell("WELLX", WellTestConfig::Reason::PHYSICAL, 100);
|
||||
BOOST_CHECK_EQUAL(st.size(), 3);
|
||||
|
||||
auto shut_wells = st.update(wc, 5000);
|
||||
BOOST_CHECK_EQUAL( shut_wells.size(), 0);
|
||||
|
||||
wc.add_well("WELL_NAME", WellTestConfig::Reason::PHYSICAL, 1000, 2, 0);
|
||||
// Not sufficient time has passed.
|
||||
BOOST_CHECK_EQUAL( st.update(wc, 200).size(), 0);
|
||||
|
||||
// We should test it:
|
||||
BOOST_CHECK_EQUAL( st.update(wc, 1200).size(), 1);
|
||||
|
||||
// Not sufficient time has passed.
|
||||
BOOST_CHECK_EQUAL( st.update(wc, 1700).size(), 0);
|
||||
|
||||
// We should test it:
|
||||
BOOST_CHECK_EQUAL( st.update(wc, 2400).size(), 1);
|
||||
|
||||
// Too many attempts:
|
||||
BOOST_CHECK_EQUAL( st.update(wc, 24000).size(), 0);
|
||||
|
||||
st.drop("WELL_NAME", WellTestConfig::Reason::ECONOMIC);
|
||||
|
||||
st.openWell("WELL_NAME");
|
||||
BOOST_CHECK_EQUAL(st.size(), 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user