Add class WellMatcher and use it UDQ evaluation
This commit is contained in:
parent
279871df05
commit
7ef7e3017e
@ -134,6 +134,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/injection.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/Well.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WList.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.cpp
|
||||
@ -704,6 +705,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/InjectionControls.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Well/WellFoamProperties.hpp
|
||||
|
@ -121,7 +121,7 @@ void msim::run_step(const Schedule& schedule, Action::State& action_state, Summa
|
||||
group_nwrk_data,
|
||||
{});
|
||||
|
||||
schedule.getUDQConfig( report_step ).eval(report_step, st, udq_state);
|
||||
schedule.getUDQConfig( report_step ).eval(report_step, schedule.wellMatcher(report_step), st, udq_state);
|
||||
|
||||
this->output(action_state,
|
||||
st,
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
|
||||
|
||||
#include <opm/common/utility/ActiveGridCells.hpp>
|
||||
@ -193,6 +194,7 @@ namespace Opm
|
||||
bool hasWell(const std::string& wellName) const;
|
||||
bool hasWell(const std::string& wellName, std::size_t timeStep) const;
|
||||
|
||||
WellMatcher wellMatcher(std::size_t report_step) const;
|
||||
std::vector<std::string> wellNames(const std::string& pattern, std::size_t timeStep, const std::vector<std::string>& matching_wells = {}) const;
|
||||
std::vector<std::string> wellNames(const std::string& pattern) const;
|
||||
std::vector<std::string> wellNames(std::size_t timeStep) const;
|
||||
|
@ -43,6 +43,7 @@ namespace Opm {
|
||||
class SummaryState;
|
||||
class UDQState;
|
||||
class KeywordLocation;
|
||||
class WellMatcher;
|
||||
|
||||
class UDQConfig {
|
||||
public:
|
||||
@ -61,7 +62,7 @@ namespace Opm {
|
||||
void add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value, std::size_t report_step);
|
||||
void add_define(const std::string& quantity, const KeywordLocation& location, const std::vector<std::string>& expression);
|
||||
|
||||
void eval(std::size_t report_step, SummaryState& st, UDQState& udq_state) const;
|
||||
void eval(std::size_t report_step, const WellMatcher& wm, SummaryState& st, UDQState& udq_state) const;
|
||||
const UDQDefine& define(const std::string& key) const;
|
||||
std::vector<UDQDefine> definitions() const;
|
||||
std::vector<UDQDefine> definitions(UDQVarType var_type) const;
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
|
||||
|
||||
namespace Opm {
|
||||
class SummaryState;
|
||||
@ -37,7 +38,7 @@ namespace Opm {
|
||||
|
||||
class UDQContext{
|
||||
public:
|
||||
UDQContext(const UDQFunctionTable& udqft, SummaryState& summary_state, UDQState& udq_state);
|
||||
UDQContext(const UDQFunctionTable& udqft, const WellMatcher& wm, SummaryState& summary_state, UDQState& udq_state);
|
||||
std::optional<double> get(const std::string& key) const;
|
||||
std::optional<double> get_well_var(const std::string& well, const std::string& var) const;
|
||||
std::optional<double> get_group_var(const std::string& group, const std::string& var) const;
|
||||
@ -46,9 +47,11 @@ namespace Opm {
|
||||
void update_define(const std::string& keyword, const UDQSet& udq_result);
|
||||
const UDQFunctionTable& function_table() const;
|
||||
std::vector<std::string> wells() const;
|
||||
std::vector<std::string> wells(const std::string& pattern) const;
|
||||
std::vector<std::string> groups() const;
|
||||
private:
|
||||
const UDQFunctionTable& udqft;
|
||||
WellMatcher well_matcher;
|
||||
SummaryState& summary_state;
|
||||
UDQState& udq_state;
|
||||
//std::unordered_map<std::string, UDQSet> udq_results;
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2019 Equinor 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 WELL_MATCHER_HPP
|
||||
#define WELL_MATCHER_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class WellMatcher {
|
||||
public:
|
||||
WellMatcher() = default;
|
||||
explicit WellMatcher(const std::vector<std::string>& wells);
|
||||
WellMatcher(const std::vector<std::string>& wells, const WListManager& wlm);
|
||||
const std::vector<std::string>& wells() const;
|
||||
std::vector<std::string> wells(const std::string& pattern) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_wells;
|
||||
WListManager m_wlm;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -1086,6 +1086,18 @@ private:
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
WellMatcher Schedule::wellMatcher(std::size_t report_step) const {
|
||||
std::vector<std::string> wnames;
|
||||
for (const auto& well_pair : this->wells_static) {
|
||||
const auto& dynamic_state = well_pair.second;
|
||||
if (dynamic_state.get(report_step))
|
||||
wnames.push_back(well_pair.first);
|
||||
}
|
||||
return WellMatcher(wnames, this->getWListManager(report_step));
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> Schedule::wellNames(const std::string& pattern) const {
|
||||
return this->wellNames(pattern, this->size() - 1);
|
||||
}
|
||||
|
@ -145,28 +145,34 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
||||
const auto& string_value = std::get<std::string>( this->value );
|
||||
auto data_type = UDQ::targetType(string_value);
|
||||
if (data_type == UDQVarType::WELL_VAR) {
|
||||
const auto& wells = context.wells();
|
||||
const auto& all_wells = context.wells();
|
||||
auto res = UDQSet::wells(string_value, all_wells);
|
||||
|
||||
if (this->selector.size() > 0) {
|
||||
const std::string& well_pattern = this->selector[0];
|
||||
if (well_pattern.find("*") == std::string::npos)
|
||||
return this->sign * UDQSet::scalar(string_value, context.get_well_var(well_pattern, string_value));
|
||||
else {
|
||||
auto res = UDQSet::wells(string_value, wells);
|
||||
int fnmatch_flags = 0;
|
||||
for (const auto& well : wells) {
|
||||
if (fnmatch(well_pattern.c_str(), well.c_str(), fnmatch_flags) == 0)
|
||||
res.assign(well, context.get_well_var(well, string_value));
|
||||
}
|
||||
return this->sign * res;
|
||||
}
|
||||
} else {
|
||||
auto res = UDQSet::wells(string_value, wells);
|
||||
for (const auto& well : wells)
|
||||
if (this->selector.empty()) {
|
||||
for (const auto& well : all_wells)
|
||||
res.assign(well, context.get_well_var(well, string_value));
|
||||
|
||||
return this->sign * res;
|
||||
} else {
|
||||
const std::string& well_pattern = this->selector[0];
|
||||
if (well_pattern.find('*') == std::string::npos)
|
||||
/*
|
||||
The right hand side is a fully qualified well name without
|
||||
any '*', in this case the right hand side evaluates to a
|
||||
*scalar* - and that scalar value is distributed among all
|
||||
the wells in the result set.
|
||||
*/
|
||||
res.assign( context.get_well_var(well_pattern, string_value));
|
||||
else {
|
||||
/*
|
||||
The right hand side is a set of wells. The result set will
|
||||
be updated for all wells in the right hand set, wells
|
||||
missing in the right hand set will be undefined in the
|
||||
result set.
|
||||
*/
|
||||
for (const auto& wname : context.wells(well_pattern))
|
||||
res.assign(wname, context.get_well_var(wname, string_value));
|
||||
}
|
||||
}
|
||||
return this->sign * res;
|
||||
}
|
||||
|
||||
if (data_type == UDQVarType::GROUP_VAR) {
|
||||
|
@ -302,9 +302,9 @@ namespace Opm {
|
||||
this->type_count == data.type_count;
|
||||
}
|
||||
|
||||
void UDQConfig::eval(std::size_t report_step, SummaryState& st, UDQState& udq_state) const {
|
||||
void UDQConfig::eval(std::size_t report_step, const WellMatcher& wm, SummaryState& st, UDQState& udq_state) const {
|
||||
const auto& func_table = this->function_table();
|
||||
UDQContext context(func_table, st, udq_state);
|
||||
UDQContext context(func_table, wm, st, udq_state);
|
||||
|
||||
for (const auto& assign : this->assignments(UDQVarType::WELL_VAR)) {
|
||||
if (udq_state.assign(report_step, assign.keyword())) {
|
||||
|
@ -41,8 +41,9 @@ bool is_udq(const std::string& key) {
|
||||
}
|
||||
|
||||
|
||||
UDQContext::UDQContext(const UDQFunctionTable& udqft_arg, SummaryState& summary_state_arg, UDQState& udq_state_arg) :
|
||||
UDQContext::UDQContext(const UDQFunctionTable& udqft_arg, const WellMatcher& wm, SummaryState& summary_state_arg, UDQState& udq_state_arg) :
|
||||
udqft(udqft_arg),
|
||||
well_matcher(wm),
|
||||
summary_state(summary_state_arg),
|
||||
udq_state(udq_state_arg)
|
||||
{
|
||||
@ -117,7 +118,11 @@ bool is_udq(const std::string& key) {
|
||||
}
|
||||
|
||||
std::vector<std::string> UDQContext::wells() const {
|
||||
return this->summary_state.wells();
|
||||
return this->well_matcher.wells();
|
||||
}
|
||||
|
||||
std::vector<std::string> UDQContext::wells(const std::string& pattern) const {
|
||||
return this->well_matcher.wells(pattern);
|
||||
}
|
||||
|
||||
std::vector<std::string> UDQContext::groups() const {
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2019 Equinor 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 <algorithm>
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
WellMatcher::WellMatcher(const std::vector<std::string>& wells) :
|
||||
m_wells(wells)
|
||||
{}
|
||||
|
||||
WellMatcher::WellMatcher(const std::vector<std::string>& wells, const WListManager &wlm) :
|
||||
m_wells(wells),
|
||||
m_wlm(wlm)
|
||||
{}
|
||||
|
||||
const std::vector<std::string>& WellMatcher::wells() const {
|
||||
return this->m_wells;
|
||||
}
|
||||
|
||||
std::vector<std::string> WellMatcher::wells(const std::string& pattern) const {
|
||||
if (pattern.size() == 0)
|
||||
return {};
|
||||
|
||||
// WLIST
|
||||
if (pattern[0] == '*' && pattern.size() > 1)
|
||||
return this->m_wlm.wells(pattern);
|
||||
|
||||
// Normal pattern matching
|
||||
auto star_pos = pattern.find('*');
|
||||
if (star_pos != std::string::npos) {
|
||||
std::vector<std::string> names;
|
||||
for (const auto& wname : this->m_wells) {
|
||||
int flags = 0;
|
||||
if (fnmatch(pattern.c_str(), wname.c_str(), flags) == 0)
|
||||
names.push_back(wname);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
auto name_iter = std::find(this->m_wells.begin(), this->m_wells.end(), pattern);
|
||||
if (name_iter != this->m_wells.end())
|
||||
return { pattern };
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
@ -41,6 +41,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
|
||||
@ -3305,6 +3306,36 @@ BOOST_AUTO_TEST_CASE(WellNames) {
|
||||
|
||||
auto abs_all = schedule.wellNames();
|
||||
BOOST_CHECK_EQUAL(abs_all.size(), 9U);
|
||||
|
||||
|
||||
WellMatcher wm0( {}, WListManager{});
|
||||
const auto& wml0 = wm0.wells();
|
||||
BOOST_CHECK(wml0.empty());
|
||||
|
||||
WellMatcher wm1( {"W1", "W2", "W3", "P1", "P2", "P3"}, WListManager{});
|
||||
const std::vector<std::string> pwells = {"P1", "P2", "P3"};
|
||||
BOOST_CHECK( pwells == wm1.wells("P*"));
|
||||
|
||||
auto wm2 = schedule.wellMatcher(4);
|
||||
const auto& all_wells = wm2.wells();
|
||||
BOOST_CHECK_EQUAL(all_wells.size(), 9);
|
||||
for (const auto& w : std::vector<std::string>{"W1", "W2", "W3", "I1", "I2", "I3", "DEFAULT", "ALLOW", "BAN"})
|
||||
BOOST_CHECK(has(all_wells, w));
|
||||
|
||||
const std::vector<std::string> wwells = {"W1", "W2", "W3"};
|
||||
BOOST_CHECK( wwells == wm2.wells("W*"));
|
||||
BOOST_CHECK( wm2.wells("XYZ*").empty() );
|
||||
BOOST_CHECK( wm2.wells("XYZ").empty() );
|
||||
|
||||
auto def = wm2.wells("DEFAULT");
|
||||
BOOST_CHECK_EQUAL(def.size() , 1);
|
||||
BOOST_CHECK_EQUAL(def[0], "DEFAULT");
|
||||
|
||||
|
||||
auto l2 = wm2.wells("*ILIST");
|
||||
BOOST_CHECK_EQUAL( l2.size(), 2U);
|
||||
BOOST_CHECK( has(l2, "I1"));
|
||||
BOOST_CHECK( has(l2, "I2"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(GROUP_VARIABLES)
|
||||
UDQDefine def_group(udqp, "GUOPRL", location, {"(", "5000", "-", "GOPR", "LOWER", "*", "0.13", "-", "GOPR", "UPPER", "*", "0.15", ")" , "*", "0.89"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
double gopr_lower = 1234;
|
||||
double gopr_upper = 4321;
|
||||
|
||||
@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(SUBTRACT)
|
||||
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1"}), st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 4);
|
||||
auto res = def.eval(context);
|
||||
@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE(TEST)
|
||||
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2"}), st, udq_state);
|
||||
|
||||
st.update_group_var("MAU", "GOPR", 4);
|
||||
st.update_group_var("XXX", "GOPR", 5);
|
||||
@ -176,7 +176,7 @@ BOOST_AUTO_TEST_CASE(MIX_SCALAR) {
|
||||
UDQDefine def_add(udqp, "WU", location, {"WOPR", "+", "1"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1"}), st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
|
||||
@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(UDQFieldSetTest) {
|
||||
UDQFunctionTable udqft(udqp);
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2", "P3", "P4"}), st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1.0);
|
||||
st.update_well_var("P2", "WOPR", 2.0);
|
||||
@ -303,7 +303,7 @@ BOOST_AUTO_TEST_CASE(UDQ_GROUP_TEST) {
|
||||
UDQDefine def_fopr(udqp, "FUOPR", location, {"SUM", "(", "GOPR", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
|
||||
st.update_group_var("G1", "GOPR", 1.0);
|
||||
st.update_group_var("G2", "GOPR", 2.0);
|
||||
@ -326,7 +326,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQDefine def(udqp, "WUBHP", location, {"WBHP"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"W1", "W2", "W3"}), st, udq_state);
|
||||
|
||||
st.update_well_var("W1", "WBHP", 11);
|
||||
st.update_well_var("W2", "WBHP", 2);
|
||||
@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQDefine def(udqp, "WUBHP", location, {"WBHP" , "'P*'"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"I1", "I2", "P1", "P2"}), st, udq_state);
|
||||
|
||||
|
||||
st.update_well_var("P1", "WBHP", 1);
|
||||
@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQDefine def(udqp, "WUBHP", location, {"NINT" , "(", "WBHP", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2", "I1", "I2"}), st, udq_state);
|
||||
st.update_well_var("P1", "WBHP", 4);
|
||||
st.update_well_var("P2", "WBHP", 3);
|
||||
st.update_well_var("I1", "WBHP", 2);
|
||||
@ -579,7 +579,7 @@ BOOST_AUTO_TEST_CASE(UDQ_CONTEXT) {
|
||||
UDQFunctionTable func_table;
|
||||
UDQParams udqp;
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext ctx(func_table, st, udq_state);
|
||||
UDQContext ctx(func_table, {}, st, udq_state);
|
||||
BOOST_CHECK_EQUAL(*ctx.get("JAN"), 1.0);
|
||||
BOOST_CHECK_THROW(ctx.get("NO_SUCH_KEY"), std::out_of_range);
|
||||
|
||||
@ -990,7 +990,7 @@ BOOST_AUTO_TEST_CASE(UDQ_POW_TEST) {
|
||||
UDQDefine def_pow2(udqp, "WU", location, {"(", "WOPR", "+", "WWPR", ")", "^", "(", "WOPR", "+" , "WGOR", "*", "WWIR", "-", "WBHP", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1"}), st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
st.update_well_var("P1", "WWPR", 2);
|
||||
@ -1011,7 +1011,7 @@ BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) {
|
||||
UDQDefine def_cmp(udqp, "WU", location, {"WOPR", ">", "WWPR", "+", "WGOR", "*", "WWIR"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2"}), st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 0);
|
||||
st.update_well_var("P1", "WWPR", 10);
|
||||
@ -1040,61 +1040,61 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) {
|
||||
UDQFunctionTable udqft;
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"PA1", "PB2", "PC3", "PD4"}), st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
st.update_well_var("P2", "WOPR", 2);
|
||||
st.update_well_var("P3", "WOPR", 3);
|
||||
st.update_well_var("P4", "WOPR", 4);
|
||||
st.update_well_var("PA1", "WOPR", 1);
|
||||
st.update_well_var("PB2", "WOPR", 2);
|
||||
st.update_well_var("PC3", "WOPR", 3);
|
||||
st.update_well_var("PD4", "WOPR", 4);
|
||||
|
||||
st.update_well_var("P1", "WWPR", 1);
|
||||
st.update_well_var("P2", "WWPR", 2);
|
||||
st.update_well_var("P3", "WWPR", 3);
|
||||
st.update_well_var("P4", "WWPR", 4);
|
||||
st.update_well_var("PA1", "WWPR", 1);
|
||||
st.update_well_var("PB2", "WWPR", 2);
|
||||
st.update_well_var("PC3", "WWPR", 3);
|
||||
st.update_well_var("PD4", "WWPR", 4);
|
||||
|
||||
{
|
||||
UDQDefine def(udqp, "WUOPR", location, {"WOPR", "'*1'"});
|
||||
UDQDefine def(udqp, "WUOPR", location, {"WOPR", "'PA*'"});
|
||||
auto res = def.eval(context);
|
||||
BOOST_CHECK_EQUAL(4U, res.size());
|
||||
auto well1 = res["P1"];
|
||||
auto well1 = res["PA1"];
|
||||
BOOST_CHECK( well1.defined() );
|
||||
BOOST_CHECK_EQUAL(well1.get() , 1);
|
||||
|
||||
auto well2 = res["P2"];
|
||||
auto well2 = res["PB2"];
|
||||
BOOST_CHECK( !well2.defined() );
|
||||
|
||||
auto well4 = res["P4"];
|
||||
auto well4 = res["PD4"];
|
||||
BOOST_CHECK( !well4.defined() );
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqp, "WUOPR", location, {"1"});
|
||||
auto res = def.eval(context);
|
||||
BOOST_CHECK_EQUAL(4U, res.size());
|
||||
auto well1 = res["P1"];
|
||||
auto well1 = res["PA1"];
|
||||
BOOST_CHECK( well1.defined() );
|
||||
BOOST_CHECK_EQUAL(well1.get() , 1);
|
||||
|
||||
auto well2 = res["P2"];
|
||||
auto well2 = res["PB2"];
|
||||
BOOST_CHECK( well2.defined() );
|
||||
BOOST_CHECK_EQUAL(well2.get() , 1);
|
||||
|
||||
auto well4 = res["P4"];
|
||||
auto well4 = res["PD4"];
|
||||
BOOST_CHECK( well4.defined() );
|
||||
BOOST_CHECK_EQUAL(well4.get() , 1);
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqp, "WUOPR", location, {"WOPR", "'P1'"});
|
||||
UDQDefine def(udqp, "WUOPR", location, {"WOPR", "'PA1'"});
|
||||
auto res = def.eval(context);
|
||||
BOOST_CHECK_EQUAL(4U, res.size());
|
||||
auto well1 = res["P1"];
|
||||
auto well1 = res["PA1"];
|
||||
BOOST_CHECK( well1.defined() );
|
||||
BOOST_CHECK_EQUAL(well1.get() , 1);
|
||||
|
||||
auto well2 = res["P2"];
|
||||
auto well2 = res["PB2"];
|
||||
BOOST_CHECK( well2.defined() );
|
||||
BOOST_CHECK_EQUAL(well2.get() , 1);
|
||||
|
||||
auto well4 = res["P4"];
|
||||
auto well4 = res["PD4"];
|
||||
BOOST_CHECK( well4.defined() );
|
||||
BOOST_CHECK_EQUAL(well4.get() , 1);
|
||||
|
||||
@ -1110,7 +1110,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTD_NAN) {
|
||||
UDQDefine def_sort(udqp , "WUPR3", location, {"SORTD", "(", "WUPR1", ")" });
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"OP1", "OP2", "OP3", "OP4"}), st, udq_state);
|
||||
|
||||
st.update_well_var("OP1", "WWIR", 1.0);
|
||||
st.update_well_var("OP2", "WWIR", 2.0);
|
||||
@ -1156,7 +1156,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA) {
|
||||
UDQDefine def_sort(udqp , "WUPR3", location, {"SORTA", "(", "WUPR1", ")" });
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"OPL01", "OPL02", "OPU01", "OPU02"}), st, udq_state);
|
||||
|
||||
st.update_well_var("OPL01", "WWCT", 0.7);
|
||||
st.update_well_var("OPL02", "WWCT", 0.8);
|
||||
@ -1186,7 +1186,7 @@ BOOST_AUTO_TEST_CASE(UDQ_BASIC_MATH_TEST) {
|
||||
UDQDefine def_wuwct(udqp , "WUWCT", location, {"WWPR", "/", "(", "WOPR", "+", "WWPR", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2", "P3", "P4"}), st, udq_state);
|
||||
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
st.update_well_var("P2", "WOPR", 2);
|
||||
@ -1248,7 +1248,7 @@ BOOST_AUTO_TEST_CASE(DECK_TEST) {
|
||||
UDQDefine def(udqp, "WUOPRL", location, {"(", "WOPR", "OP1", "-", "150", ")", "*", "0.90"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"OP1", "OP2", "OP3"}), st, udq_state);
|
||||
|
||||
st.update_well_var("OP1", "WOPR", 300);
|
||||
st.update_well_var("OP2", "WOPR", 3000);
|
||||
@ -1284,7 +1284,7 @@ BOOST_AUTO_TEST_CASE(UDQ_PARSE_ERROR) {
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1"}), st, udq_state);
|
||||
st.update_well_var("P1", "WBHP", 1);
|
||||
|
||||
auto res = def1.eval(context);
|
||||
@ -1310,7 +1310,7 @@ BOOST_AUTO_TEST_CASE(UDQ_TYPE_ERROR) {
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2"}), st, udq_state);
|
||||
st.update_well_var("P1", "WBHP", 1);
|
||||
st.update_well_var("P2", "WBHP", 2);
|
||||
|
||||
@ -1693,7 +1693,7 @@ UDQ
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
|
||||
auto res0 = def0.eval(context);
|
||||
BOOST_CHECK_CLOSE( res0[0].get(), -0.00125*3, 1e-6);
|
||||
@ -1719,7 +1719,7 @@ UDQ
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
const double fwpr = 7;
|
||||
const double fopr = 4;
|
||||
const double fgpr = 7;
|
||||
@ -1761,7 +1761,7 @@ UDQ
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, WellMatcher({"W1", "W2", "W3"}), st, udq_state);
|
||||
st.update_well_var("W1", "WOPR", 1);
|
||||
st.update_well_var("W2", "WOPR", 2);
|
||||
st.update_well_var("W3", "WOPR", 3);
|
||||
@ -1800,7 +1800,7 @@ UDQ
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
auto undefined_value = udq.params().undefinedValue();
|
||||
UDQState udq_state(undefined_value);
|
||||
udq.eval(0, st, udq_state);
|
||||
udq.eval(0, {}, st, udq_state);
|
||||
|
||||
BOOST_CHECK_EQUAL( st.get("FU_UADD"), 12); // 10 + 2
|
||||
|
||||
@ -1827,7 +1827,7 @@ DEFINE FU_PAR2 FU_PAR3 /
|
||||
auto undefined_value = udq.params().undefinedValue();
|
||||
UDQState udq_state(undefined_value);
|
||||
st.update("FMWPR", 100);
|
||||
udq.eval(0, st, udq_state);
|
||||
udq.eval(0, {}, st, udq_state);
|
||||
|
||||
BOOST_CHECK_EQUAL(st.get("FU_PAR2"), 100);
|
||||
}
|
||||
@ -1845,7 +1845,7 @@ DEFINE FU_PAR3 FU_PAR2 + 1/
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
auto undefined_value = udq.params().undefinedValue();
|
||||
UDQState udq_state(undefined_value);
|
||||
udq.eval(0, st, udq_state);
|
||||
udq.eval(0, {}, st, udq_state);
|
||||
|
||||
BOOST_CHECK_EQUAL(st.get("FU_PAR2"), undefined_value);
|
||||
BOOST_CHECK_EQUAL(st.get("FU_PAR3"), undefined_value);
|
||||
@ -1963,7 +1963,7 @@ DEFINE WUGASRA 750000 - WGLIR '*' /
|
||||
st.update_well_var("W2", "WGLIR", 2);
|
||||
st.update_well_var("W3", "WGLIR", 3);
|
||||
|
||||
udq.eval(0, st, udq_state);
|
||||
udq.eval(0, WellMatcher({"W1", "W2", "W3"}), st, udq_state);
|
||||
{
|
||||
std::unordered_set<std::string> required_keys;
|
||||
udq.required_summary(required_keys);
|
||||
@ -2168,7 +2168,7 @@ DEFINE FU_VAR91 GOPR TEST /
|
||||
st.update_well_var("W3", "WGLIR", 3);
|
||||
st.update_group_var("TEST", "GOPR", 1);
|
||||
|
||||
udq.eval(0, st, udq_state);
|
||||
udq.eval(0, {}, st, udq_state);
|
||||
}
|
||||
|
||||
|
||||
@ -2189,7 +2189,7 @@ UDQ
|
||||
UDQState udq_state(undefined_value);
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
|
||||
BOOST_CHECK_THROW(udq.eval(0, st, udq_state), std::exception);
|
||||
BOOST_CHECK_THROW(udq.eval(0, {}, st, udq_state), std::exception);
|
||||
}
|
||||
|
||||
|
||||
@ -2215,7 +2215,7 @@ UDQ
|
||||
BOOST_CHECK(required_keys.empty());
|
||||
}
|
||||
|
||||
udq.eval(0, st, udq_state);
|
||||
udq.eval(0, {}, st, udq_state);
|
||||
BOOST_CHECK_EQUAL(st.get("FU_VAR1"), 10);
|
||||
}
|
||||
|
||||
@ -2256,7 +2256,7 @@ TSTEP
|
||||
// Counting: 1,2,3,4,5
|
||||
for (std::size_t report_step = 0; report_step < 5; report_step++) {
|
||||
const auto& udq = schedule.getUDQConfig(report_step);
|
||||
udq.eval(report_step, st, udq_state);
|
||||
udq.eval(report_step, schedule.wellMatcher(report_step), st, udq_state);
|
||||
auto fu_var1 = st.get("FU_VAR1");
|
||||
BOOST_CHECK_EQUAL(fu_var1, report_step + 1);
|
||||
}
|
||||
@ -2264,7 +2264,7 @@ TSTEP
|
||||
// Reset to zero and count: 1,2,3,4,5
|
||||
for (std::size_t report_step = 5; report_step < 10; report_step++) {
|
||||
const auto& udq = schedule.getUDQConfig(report_step);
|
||||
udq.eval(report_step, st, udq_state);
|
||||
udq.eval(report_step, schedule.wellMatcher(report_step), st, udq_state);
|
||||
auto fu_var1 = st.get("FU_VAR1");
|
||||
BOOST_CHECK_EQUAL(fu_var1, report_step - 4);
|
||||
}
|
||||
@ -2272,7 +2272,7 @@ TSTEP
|
||||
// Reset to zero and stay there.
|
||||
for (std::size_t report_step = 10; report_step < 15; report_step++) {
|
||||
const auto& udq = schedule.getUDQConfig(report_step);
|
||||
udq.eval(report_step, st, udq_state);
|
||||
udq.eval(report_step, schedule.wellMatcher(report_step),st, udq_state);
|
||||
auto fu_var1 = st.get("FU_VAR1");
|
||||
BOOST_CHECK_EQUAL(fu_var1, 0);
|
||||
}
|
||||
@ -2286,7 +2286,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DIV_TEST) {
|
||||
UDQDefine def_div(udqp, "FU", location, {"128", "/", "2", "/", "4", "/", "8"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, st, udq_state);
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
|
||||
auto res_div = def_div.eval(context);
|
||||
BOOST_CHECK_EQUAL( res_div[0].get() , 2.0);
|
||||
@ -2314,7 +2314,7 @@ UDQ
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
|
||||
const auto& udq = schedule.getUDQConfig(0);
|
||||
udq.eval(0, st, udq_state);
|
||||
udq.eval(0, {}, st, udq_state);
|
||||
auto fu_var1 = st.get("FU_VAR1");
|
||||
auto fu_var2 = st.get("FU_VAR2");
|
||||
auto fu_var3 = st.get("FU_VAR3");
|
||||
@ -2327,3 +2327,41 @@ UDQ
|
||||
BOOST_CHECK_CLOSE(fu_var5, -0.00000041232 * 4 + 0.0010395 * 3 + 0.16504, 1e-5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_WLIST) {
|
||||
std::string deck_string = R"(
|
||||
SCHEDULE
|
||||
|
||||
WELSPECS
|
||||
'P1' 'OP' 20 51 3.92 'OIL' 3* NO /
|
||||
'P2' 'OP' 20 51 3.92 'OIL' 3* NO /
|
||||
'P3' 'OP' 20 51 3.92 'OIL' 3* NO /
|
||||
'P4' 'OP' 20 51 3.92 'OIL' 3* NO /
|
||||
/
|
||||
|
||||
WLIST
|
||||
'*ILIST' 'NEW' P1 P2 P3 /
|
||||
/
|
||||
|
||||
UDQ
|
||||
DEFINE FU_VAR1 SUM(WOPR '*ILIST') /
|
||||
DEFINE FU_VAR2 SUM(WOPR '*') /
|
||||
/
|
||||
|
||||
)";
|
||||
|
||||
auto schedule = make_schedule(deck_string);
|
||||
UDQState udq_state(0);
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
const auto& udq = schedule.getUDQConfig(0);
|
||||
st.update_well_var("P1", "WOPR", 1);
|
||||
st.update_well_var("P2", "WOPR", 2);
|
||||
st.update_well_var("P3", "WOPR", 3);
|
||||
st.update_well_var("P4", "WOPR", 4);
|
||||
|
||||
udq.eval(0, schedule.wellMatcher(0), st, udq_state);
|
||||
auto fu_var1 = st.get("FU_VAR1");
|
||||
auto fu_var2 = st.get("FU_VAR2");
|
||||
BOOST_CHECK_EQUAL(fu_var1, 6);
|
||||
BOOST_CHECK_EQUAL(fu_var2, 10);
|
||||
}
|
||||
|
||||
|
@ -399,7 +399,7 @@ RestartValue first_sim(const Setup& setup, Action::State& action_state, SummaryS
|
||||
RestartValue restart_value(sol, wells, groups);
|
||||
|
||||
init_st(st);
|
||||
udq.eval(report_step, st, udq_state);
|
||||
udq.eval(report_step, setup.schedule.wellMatcher(report_step), st, udq_state);
|
||||
eclWriter.writeTimeStep( action_state,
|
||||
st,
|
||||
udq_state,
|
||||
|
Loading…
Reference in New Issue
Block a user