Merge pull request #677 from joakim-hove/well-names
Implement Schedule::wellNames()
This commit is contained in:
@@ -114,6 +114,7 @@ namespace Opm
|
||||
size_t numWells(size_t timestep) const;
|
||||
size_t getMaxNumConnectionsForWells(size_t timestep) const;
|
||||
bool hasWell(const std::string& wellName) const;
|
||||
std::vector<std::string> wellNames(const std::string& pattern, size_t timeStep, const std::vector<std::string>& matching_wells = {}) const;
|
||||
const Well* getWell(const std::string& wellName) const;
|
||||
std::vector< const Well* > getOpenWells(size_t timeStep) const;
|
||||
std::vector< const Well* > getWells() const;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
@@ -1897,6 +1898,64 @@ namespace Opm {
|
||||
return { tmp.begin(), tmp.end() };
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
There are many SCHEDULE keyword which take a wellname as argument. In
|
||||
addition to giving a fully qualified name like 'W1' you can also specify
|
||||
shell wildcard patterns like like 'W*', you can get all the wells in the
|
||||
well-list '*WL'[1] and the wellname '?' is used to get all the wells which
|
||||
already have matched a condition in a ACTIONX keyword. This function
|
||||
should be one-stop function to get all well names according to a input
|
||||
pattern. The timestep argument is used to check that the wells have
|
||||
indeewd been defined at the point in time we are considering.
|
||||
|
||||
[1]: The leading '*' in a WLIST name should not be interpreted as a shell
|
||||
wildcard!
|
||||
*/
|
||||
|
||||
|
||||
std::vector<std::string> Schedule::wellNames(const std::string& pattern, size_t timeStep, const std::vector<std::string>& matching_wells) const {
|
||||
std::vector<std::string> names;
|
||||
|
||||
// WLIST
|
||||
if (pattern[0] == '*') {
|
||||
const auto& wlm = this->getWListManager(timeStep);
|
||||
if (wlm.hasList(pattern)) {
|
||||
const auto& wlist = wlm.getList(pattern);
|
||||
return { wlist.begin(), wlist.end() };
|
||||
} else
|
||||
return {};
|
||||
}
|
||||
|
||||
// Normal pattern matching
|
||||
auto star_pos = pattern.find('*');
|
||||
if (star_pos != std::string::npos) {
|
||||
int flags = 0;
|
||||
std::vector<std::string> names;
|
||||
for (const auto& well_pair : this->m_wells) {
|
||||
if (fnmatch(pattern.c_str(), well_pair.first.c_str(), flags) == 0) {
|
||||
if (well_pair.second.firstTimeStep() <= timeStep)
|
||||
names.push_back(well_pair.first);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
// ACTIONX handler
|
||||
if (pattern == "?") {
|
||||
return { matching_wells.begin(), matching_wells.end() };
|
||||
}
|
||||
|
||||
// Normal well name without any special characters
|
||||
if (this->hasWell(pattern)) {
|
||||
auto well = this->getWell(pattern);
|
||||
if (well->firstTimeStep() <= timeStep)
|
||||
return { pattern };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
std::vector< Well* > Schedule::getWells(const std::string& wellNamePattern, const std::vector<std::string>& matching_wells) {
|
||||
// If we arrive here during the handling the body of a ACTIONX keyword
|
||||
// we can arrive with wellname '?' and a set of matching wells.
|
||||
|
||||
@@ -94,6 +94,9 @@ static Deck createDeckWTEST() {
|
||||
" \'DEFAULT\' \'OP\' 30 37 3.33 \'OIL\' 7*/ \n"
|
||||
" \'ALLOW\' \'OP\' 30 37 3.33 \'OIL\' 3* YES / \n"
|
||||
" \'BAN\' \'OP\' 20 51 3.92 \'OIL\' 3* NO / \n"
|
||||
" \'W1\' \'OP\' 20 51 3.92 \'OIL\' 3* NO / \n"
|
||||
" \'W2\' \'OP\' 20 51 3.92 \'OIL\' 3* NO / \n"
|
||||
" \'W3\' \'OP\' 20 51 3.92 \'OIL\' 3* NO / \n"
|
||||
"/\n"
|
||||
|
||||
"COMPDAT\n"
|
||||
@@ -125,6 +128,17 @@ static Deck createDeckWTEST() {
|
||||
" 10 JUL 2007 / \n"
|
||||
"/\n"
|
||||
|
||||
"WELSPECS\n"
|
||||
" \'I1\' \'OP\' 20 51 3.92 \'OIL\' 3* NO / \n"
|
||||
" \'I2\' \'OP\' 20 51 3.92 \'OIL\' 3* NO / \n"
|
||||
" \'I3\' \'OP\' 20 51 3.92 \'OIL\' 3* NO / \n"
|
||||
"/\n"
|
||||
|
||||
"WLIST\n"
|
||||
" \'*ILIST\' \'NEW\' I1 /\n"
|
||||
" \'*ILIST\' \'ADD\' I2 /\n"
|
||||
"/\n"
|
||||
|
||||
"WCONPROD\n"
|
||||
" 'BAN' 'OPEN' 'ORAT' 0.000 0.000 0.000 5* / \n"
|
||||
"/\n"
|
||||
@@ -2816,3 +2830,55 @@ BOOST_AUTO_TEST_CASE(WTEST_CONFIG) {
|
||||
BOOST_CHECK(wtest_config2.has("BAN", WellTestConfig::Reason::GROUP));
|
||||
BOOST_CHECK(!wtest_config2.has("BAN", WellTestConfig::Reason::PHYSICAL));
|
||||
}
|
||||
|
||||
|
||||
bool has(const std::vector<std::string>& l, const std::string& s) {
|
||||
auto f = std::find(l.begin(), l.end(), s);
|
||||
return (f != l.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(WellNames) {
|
||||
auto deck = createDeckWTEST();
|
||||
EclipseGrid grid1(10,10,10);
|
||||
TableManager table ( deck );
|
||||
Eclipse3DProperties eclipseProperties ( deck , table, grid1);
|
||||
Runspec runspec (deck);
|
||||
Schedule schedule(deck, grid1 , eclipseProperties, runspec);
|
||||
|
||||
auto names = schedule.wellNames("NO_SUCH_WELL", 0);
|
||||
BOOST_CHECK_EQUAL(names.size(), 0);
|
||||
|
||||
auto w1names = schedule.wellNames("W1", 0);
|
||||
BOOST_CHECK_EQUAL(w1names.size(), 1);
|
||||
BOOST_CHECK_EQUAL(w1names[0], "W1");
|
||||
|
||||
auto i1names = schedule.wellNames("11", 0);
|
||||
BOOST_CHECK_EQUAL(i1names.size(), 0);
|
||||
|
||||
auto listnamese = schedule.wellNames("*NO_LIST", 0);
|
||||
BOOST_CHECK_EQUAL( listnamese.size(), 0);
|
||||
|
||||
auto listnames0 = schedule.wellNames("*ILIST", 0);
|
||||
BOOST_CHECK_EQUAL( listnames0.size(), 0);
|
||||
|
||||
auto listnames1 = schedule.wellNames("*ILIST", 2);
|
||||
BOOST_CHECK_EQUAL( listnames1.size(), 2);
|
||||
BOOST_CHECK( has(listnames1, "I1"));
|
||||
BOOST_CHECK( has(listnames1, "I2"));
|
||||
|
||||
auto pnames1 = schedule.wellNames("I*", 0);
|
||||
BOOST_CHECK_EQUAL(pnames1.size(), 0);
|
||||
|
||||
auto pnames2 = schedule.wellNames("W*", 0);
|
||||
BOOST_CHECK_EQUAL(pnames2.size(), 3);
|
||||
BOOST_CHECK( has(pnames2, "W1"));
|
||||
BOOST_CHECK( has(pnames2, "W2"));
|
||||
BOOST_CHECK( has(pnames2, "W3"));
|
||||
|
||||
auto anames = schedule.wellNames("?", 0, {"W1", "W2"});
|
||||
BOOST_CHECK_EQUAL(anames.size(), 2);
|
||||
BOOST_CHECK(has(anames, "W1"));
|
||||
BOOST_CHECK(has(anames, "W2"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user