Merge pull request #2069 from joakim-hove/udq-wlist

Udq wlist
This commit is contained in:
Joakim Hove 2020-11-03 11:22:02 +01:00 committed by GitHub
commit 6c449a48b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 293 additions and 108 deletions

View File

@ -134,6 +134,7 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/EclipseState/Schedule/Well/injection.cpp 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/Well.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.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/WList.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp src/opm/parser/eclipse/EclipseState/Schedule/Well/WListManager.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.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/InjectionControls.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/WList.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/WListManager.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.hpp opm/parser/eclipse/EclipseState/Schedule/Well/WellEconProductionLimits.hpp
opm/parser/eclipse/EclipseState/Schedule/Well/WellFoamProperties.hpp opm/parser/eclipse/EclipseState/Schedule/Well/WellFoamProperties.hpp

View File

@ -121,7 +121,7 @@ void msim::run_step(const Schedule& schedule, Action::State& action_state, Summa
group_nwrk_data, 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, this->output(action_state,
st, st,

View File

@ -44,6 +44,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp> #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/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellTestConfig.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/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
#include <opm/common/utility/ActiveGridCells.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) const;
bool hasWell(const std::string& wellName, std::size_t timeStep) 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, 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(const std::string& pattern) const;
std::vector<std::string> wellNames(std::size_t timeStep) const; std::vector<std::string> wellNames(std::size_t timeStep) const;

View File

@ -43,6 +43,7 @@ namespace Opm {
class SummaryState; class SummaryState;
class UDQState; class UDQState;
class KeywordLocation; class KeywordLocation;
class WellMatcher;
class UDQConfig { class UDQConfig {
public: 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_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 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; const UDQDefine& define(const std::string& key) const;
std::vector<UDQDefine> definitions() const; std::vector<UDQDefine> definitions() const;
std::vector<UDQDefine> definitions(UDQVarType var_type) const; std::vector<UDQDefine> definitions(UDQVarType var_type) const;

View File

@ -29,6 +29,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
namespace Opm { namespace Opm {
class SummaryState; class SummaryState;
@ -37,7 +38,7 @@ namespace Opm {
class UDQContext{ class UDQContext{
public: 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(const std::string& key) const;
std::optional<double> get_well_var(const std::string& well, const std::string& var) 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; 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); void update_define(const std::string& keyword, const UDQSet& udq_result);
const UDQFunctionTable& function_table() const; const UDQFunctionTable& function_table() const;
std::vector<std::string> wells() const; std::vector<std::string> wells() const;
std::vector<std::string> wells(const std::string& pattern) const;
std::vector<std::string> groups() const; std::vector<std::string> groups() const;
private: private:
const UDQFunctionTable& udqft; const UDQFunctionTable& udqft;
WellMatcher well_matcher;
SummaryState& summary_state; SummaryState& summary_state;
UDQState& udq_state; UDQState& udq_state;
//std::unordered_map<std::string, UDQSet> udq_results; //std::unordered_map<std::string, UDQSet> udq_results;

View File

@ -23,11 +23,10 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <string> #include <string>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WList.hpp>
namespace Opm { namespace Opm {
class WList;
class WListManager { class WListManager {
public: public:
WListManager() = default; WListManager() = default;

View File

@ -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

View File

@ -1050,42 +1050,26 @@ private:
std::vector<std::string> Schedule::wellNames(const std::string& pattern, std::size_t timeStep, const std::vector<std::string>& matching_wells) const { std::vector<std::string> Schedule::wellNames(const std::string& pattern, std::size_t timeStep, const std::vector<std::string>& matching_wells) const {
if (pattern.size() == 0)
return {};
// WLIST
if (pattern[0] == '*' && pattern.size() > 1) {
const auto& wlm = this->getWListManager(timeStep);
return 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& well_pair : this->wells_static) {
if (name_match(pattern, well_pair.first)) {
const auto& dynamic_state = well_pair.second;
if (dynamic_state.get(timeStep))
names.push_back(well_pair.first);
}
}
return names;
}
// ACTIONX handler // ACTIONX handler
if (pattern == "?") if (pattern == "?")
return { matching_wells.begin(), matching_wells.end() }; return { matching_wells.begin(), matching_wells.end() };
// Normal well name without any special characters auto wm = this->wellMatcher(timeStep);
if (this->hasWell(pattern)) { return wm.wells(pattern);
const auto& dynamic_state = this->wells_static.at(pattern);
if (dynamic_state.get(timeStep))
return { pattern };
}
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 { std::vector<std::string> Schedule::wellNames(const std::string& pattern) const {
return this->wellNames(pattern, this->size() - 1); return this->wellNames(pattern, this->size() - 1);
} }

View File

@ -145,27 +145,35 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
const auto& string_value = std::get<std::string>( this->value ); const auto& string_value = std::get<std::string>( this->value );
auto data_type = UDQ::targetType(string_value); auto data_type = UDQ::targetType(string_value);
if (data_type == UDQVarType::WELL_VAR) { if (data_type == UDQVarType::WELL_VAR) {
const auto& wells = context.wells(); const auto& all_wells = context.wells();
if (this->selector.size() > 0) { if (this->selector.empty()) {
auto res = UDQSet::wells(string_value, all_wells);
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]; const std::string& well_pattern = this->selector[0];
if (well_pattern.find("*") == std::string::npos) 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.
*/
return this->sign * UDQSet::scalar(string_value, context.get_well_var(well_pattern, string_value)); return this->sign * UDQSet::scalar(string_value, context.get_well_var(well_pattern, string_value));
else { else {
auto res = UDQSet::wells(string_value, wells); /*
int fnmatch_flags = 0; The right hand side is a set of wells. The result set will
for (const auto& well : wells) { be updated for all wells in the right hand set, wells
if (fnmatch(well_pattern.c_str(), well.c_str(), fnmatch_flags) == 0) missing in the right hand set will be undefined in the
res.assign(well, context.get_well_var(well, string_value)); result set.
} */
auto res = UDQSet::wells(string_value, all_wells);
for (const auto& wname : context.wells(well_pattern))
res.assign(wname, context.get_well_var(wname, string_value));
return this->sign * res; return this->sign * res;
} }
} else {
auto res = UDQSet::wells(string_value, wells);
for (const auto& well : wells)
res.assign(well, context.get_well_var(well, string_value));
return this->sign * res;
} }
} }

View File

@ -302,9 +302,9 @@ namespace Opm {
this->type_count == data.type_count; 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(); 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)) { for (const auto& assign : this->assignments(UDQVarType::WELL_VAR)) {
if (udq_state.assign(report_step, assign.keyword())) { if (udq_state.assign(report_step, assign.keyword())) {

View File

@ -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), udqft(udqft_arg),
well_matcher(wm),
summary_state(summary_state_arg), summary_state(summary_state_arg),
udq_state(udq_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 { 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 { std::vector<std::string> UDQContext::groups() const {

View File

@ -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 {};
}
}

View File

@ -41,6 +41,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.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/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp> #include <opm/parser/eclipse/Deck/DeckItem.hpp>
@ -3313,6 +3314,36 @@ BOOST_AUTO_TEST_CASE(WellNames) {
auto abs_all = schedule.wellNames(); auto abs_all = schedule.wellNames();
BOOST_CHECK_EQUAL(abs_all.size(), 9U); 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"));
} }

View File

@ -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"}); UDQDefine def_group(udqp, "GUOPRL", location, {"(", "5000", "-", "GOPR", "LOWER", "*", "0.13", "-", "GOPR", "UPPER", "*", "0.15", ")" , "*", "0.89"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); UDQState udq_state(udqp.undefinedValue());
UDQContext context(udqft, st, udq_state); UDQContext context(udqft, {}, st, udq_state);
double gopr_lower = 1234; double gopr_lower = 1234;
double gopr_upper = 4321; double gopr_upper = 4321;
@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(SUBTRACT)
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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); st.update_well_var("P1", "WOPR", 4);
auto res = def.eval(context); auto res = def.eval(context);
@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE(TEST)
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("MAU", "GOPR", 4);
st.update_group_var("XXX", "GOPR", 5); 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"}); UDQDefine def_add(udqp, "WU", location, {"WOPR", "+", "1"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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", "WOPR", 1);
@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(UDQFieldSetTest) {
UDQFunctionTable udqft(udqp); UDQFunctionTable udqft(udqp);
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("P1", "WOPR", 1.0);
st.update_well_var("P2", "WOPR", 2.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", ")"}); UDQDefine def_fopr(udqp, "FUOPR", location, {"SUM", "(", "GOPR", ")"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("G1", "GOPR", 1.0);
st.update_group_var("G2", "GOPR", 2.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"}); UDQDefine def(udqp, "WUBHP", location, {"WBHP"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("W1", "WBHP", 11);
st.update_well_var("W2", "WBHP", 2); st.update_well_var("W2", "WBHP", 2);
@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
UDQDefine def(udqp, "WUBHP", location, {"WBHP" , "'P*'"}); UDQDefine def(udqp, "WUBHP", location, {"WBHP" , "'P*'"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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); st.update_well_var("P1", "WBHP", 1);
@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
UDQDefine def(udqp, "WUBHP", location, {"NINT" , "(", "WBHP", ")"}); UDQDefine def(udqp, "WUBHP", location, {"NINT" , "(", "WBHP", ")"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("P1", "WBHP", 4);
st.update_well_var("P2", "WBHP", 3); st.update_well_var("P2", "WBHP", 3);
st.update_well_var("I1", "WBHP", 2); st.update_well_var("I1", "WBHP", 2);
@ -579,7 +579,7 @@ BOOST_AUTO_TEST_CASE(UDQ_CONTEXT) {
UDQFunctionTable func_table; UDQFunctionTable func_table;
UDQParams udqp; UDQParams udqp;
UDQState udq_state(udqp.undefinedValue()); 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_EQUAL(*ctx.get("JAN"), 1.0);
BOOST_CHECK_THROW(ctx.get("NO_SUCH_KEY"), std::out_of_range); 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", ")"}); UDQDefine def_pow2(udqp, "WU", location, {"(", "WOPR", "+", "WWPR", ")", "^", "(", "WOPR", "+" , "WGOR", "*", "WWIR", "-", "WBHP", ")"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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", "WOPR", 1);
st.update_well_var("P1", "WWPR", 2); 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"}); UDQDefine def_cmp(udqp, "WU", location, {"WOPR", ">", "WWPR", "+", "WGOR", "*", "WWIR"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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", "WOPR", 0);
st.update_well_var("P1", "WWPR", 10); st.update_well_var("P1", "WWPR", 10);
@ -1040,61 +1040,61 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) {
UDQFunctionTable udqft; UDQFunctionTable udqft;
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("PA1", "WOPR", 1);
st.update_well_var("P2", "WOPR", 2); st.update_well_var("PB2", "WOPR", 2);
st.update_well_var("P3", "WOPR", 3); st.update_well_var("PC3", "WOPR", 3);
st.update_well_var("P4", "WOPR", 4); st.update_well_var("PD4", "WOPR", 4);
st.update_well_var("P1", "WWPR", 1); st.update_well_var("PA1", "WWPR", 1);
st.update_well_var("P2", "WWPR", 2); st.update_well_var("PB2", "WWPR", 2);
st.update_well_var("P3", "WWPR", 3); st.update_well_var("PC3", "WWPR", 3);
st.update_well_var("P4", "WWPR", 4); 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); auto res = def.eval(context);
BOOST_CHECK_EQUAL(4U, res.size()); BOOST_CHECK_EQUAL(4U, res.size());
auto well1 = res["P1"]; auto well1 = res["PA1"];
BOOST_CHECK( well1.defined() ); BOOST_CHECK( well1.defined() );
BOOST_CHECK_EQUAL(well1.get() , 1); BOOST_CHECK_EQUAL(well1.get() , 1);
auto well2 = res["P2"]; auto well2 = res["PB2"];
BOOST_CHECK( !well2.defined() ); BOOST_CHECK( !well2.defined() );
auto well4 = res["P4"]; auto well4 = res["PD4"];
BOOST_CHECK( !well4.defined() ); BOOST_CHECK( !well4.defined() );
} }
{ {
UDQDefine def(udqp, "WUOPR", location, {"1"}); UDQDefine def(udqp, "WUOPR", location, {"1"});
auto res = def.eval(context); auto res = def.eval(context);
BOOST_CHECK_EQUAL(4U, res.size()); BOOST_CHECK_EQUAL(4U, res.size());
auto well1 = res["P1"]; auto well1 = res["PA1"];
BOOST_CHECK( well1.defined() ); BOOST_CHECK( well1.defined() );
BOOST_CHECK_EQUAL(well1.get() , 1); BOOST_CHECK_EQUAL(well1.get() , 1);
auto well2 = res["P2"]; auto well2 = res["PB2"];
BOOST_CHECK( well2.defined() ); BOOST_CHECK( well2.defined() );
BOOST_CHECK_EQUAL(well2.get() , 1); BOOST_CHECK_EQUAL(well2.get() , 1);
auto well4 = res["P4"]; auto well4 = res["PD4"];
BOOST_CHECK( well4.defined() ); BOOST_CHECK( well4.defined() );
BOOST_CHECK_EQUAL(well4.get() , 1); 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); auto res = def.eval(context);
BOOST_CHECK_EQUAL(4U, res.size()); BOOST_CHECK_EQUAL(4U, res.size());
auto well1 = res["P1"]; auto well1 = res["PA1"];
BOOST_CHECK( well1.defined() ); BOOST_CHECK( well1.defined() );
BOOST_CHECK_EQUAL(well1.get() , 1); BOOST_CHECK_EQUAL(well1.get() , 1);
auto well2 = res["P2"]; auto well2 = res["PB2"];
BOOST_CHECK( well2.defined() ); BOOST_CHECK( well2.defined() );
BOOST_CHECK_EQUAL(well2.get() , 1); BOOST_CHECK_EQUAL(well2.get() , 1);
auto well4 = res["P4"]; auto well4 = res["PD4"];
BOOST_CHECK( well4.defined() ); BOOST_CHECK( well4.defined() );
BOOST_CHECK_EQUAL(well4.get() , 1); 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", ")" }); UDQDefine def_sort(udqp , "WUPR3", location, {"SORTD", "(", "WUPR1", ")" });
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("OP1", "WWIR", 1.0);
st.update_well_var("OP2", "WWIR", 2.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", ")" }); UDQDefine def_sort(udqp , "WUPR3", location, {"SORTA", "(", "WUPR1", ")" });
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("OPL01", "WWCT", 0.7);
st.update_well_var("OPL02", "WWCT", 0.8); 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", ")"}); UDQDefine def_wuwct(udqp , "WUWCT", location, {"WWPR", "/", "(", "WOPR", "+", "WWPR", ")"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("P1", "WOPR", 1);
st.update_well_var("P2", "WOPR", 2); 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"}); UDQDefine def(udqp, "WUOPRL", location, {"(", "WOPR", "OP1", "-", "150", ")", "*", "0.90"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); 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("OP1", "WOPR", 300);
st.update_well_var("OP2", "WOPR", 3000); 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()); SummaryState st(std::chrono::system_clock::now());
UDQFunctionTable udqft(udqp); UDQFunctionTable udqft(udqp);
UDQState udq_state(udqp.undefinedValue()); 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); st.update_well_var("P1", "WBHP", 1);
auto res = def1.eval(context); auto res = def1.eval(context);
@ -1310,7 +1310,7 @@ BOOST_AUTO_TEST_CASE(UDQ_TYPE_ERROR) {
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQFunctionTable udqft(udqp); UDQFunctionTable udqft(udqp);
UDQState udq_state(udqp.undefinedValue()); 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("P1", "WBHP", 1);
st.update_well_var("P2", "WBHP", 2); st.update_well_var("P2", "WBHP", 2);
@ -1693,7 +1693,7 @@ UDQ
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQFunctionTable udqft(udqp); UDQFunctionTable udqft(udqp);
UDQState udq_state(udqp.undefinedValue()); UDQState udq_state(udqp.undefinedValue());
UDQContext context(udqft, st, udq_state); UDQContext context(udqft, {}, st, udq_state);
auto res0 = def0.eval(context); auto res0 = def0.eval(context);
BOOST_CHECK_CLOSE( res0[0].get(), -0.00125*3, 1e-6); BOOST_CHECK_CLOSE( res0[0].get(), -0.00125*3, 1e-6);
@ -1719,7 +1719,7 @@ UDQ
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQFunctionTable udqft(udqp); UDQFunctionTable udqft(udqp);
UDQState udq_state(udqp.undefinedValue()); UDQState udq_state(udqp.undefinedValue());
UDQContext context(udqft, st, udq_state); UDQContext context(udqft, {}, st, udq_state);
const double fwpr = 7; const double fwpr = 7;
const double fopr = 4; const double fopr = 4;
const double fgpr = 7; const double fgpr = 7;
@ -1761,7 +1761,7 @@ UDQ
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQFunctionTable udqft(udqp); UDQFunctionTable udqft(udqp);
UDQState udq_state(udqp.undefinedValue()); 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("W1", "WOPR", 1);
st.update_well_var("W2", "WOPR", 2); st.update_well_var("W2", "WOPR", 2);
st.update_well_var("W3", "WOPR", 3); st.update_well_var("W3", "WOPR", 3);
@ -1800,7 +1800,7 @@ UDQ
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
auto undefined_value = udq.params().undefinedValue(); auto undefined_value = udq.params().undefinedValue();
UDQState udq_state(undefined_value); 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 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(); auto undefined_value = udq.params().undefinedValue();
UDQState udq_state(undefined_value); UDQState udq_state(undefined_value);
st.update("FMWPR", 100); st.update("FMWPR", 100);
udq.eval(0, st, udq_state); udq.eval(0, {}, st, udq_state);
BOOST_CHECK_EQUAL(st.get("FU_PAR2"), 100); 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()); SummaryState st(std::chrono::system_clock::now());
auto undefined_value = udq.params().undefinedValue(); auto undefined_value = udq.params().undefinedValue();
UDQState udq_state(undefined_value); 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_PAR2"), undefined_value);
BOOST_CHECK_EQUAL(st.get("FU_PAR3"), 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("W2", "WGLIR", 2);
st.update_well_var("W3", "WGLIR", 3); 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; std::unordered_set<std::string> required_keys;
udq.required_summary(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_well_var("W3", "WGLIR", 3);
st.update_group_var("TEST", "GOPR", 1); 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); UDQState udq_state(undefined_value);
SummaryState st(std::chrono::system_clock::now()); 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()); 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); BOOST_CHECK_EQUAL(st.get("FU_VAR1"), 10);
} }
@ -2256,7 +2256,7 @@ TSTEP
// Counting: 1,2,3,4,5 // Counting: 1,2,3,4,5
for (std::size_t report_step = 0; report_step < 5; report_step++) { for (std::size_t report_step = 0; report_step < 5; report_step++) {
const auto& udq = schedule.getUDQConfig(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"); auto fu_var1 = st.get("FU_VAR1");
BOOST_CHECK_EQUAL(fu_var1, report_step + 1); BOOST_CHECK_EQUAL(fu_var1, report_step + 1);
} }
@ -2264,7 +2264,7 @@ TSTEP
// Reset to zero and count: 1,2,3,4,5 // Reset to zero and count: 1,2,3,4,5
for (std::size_t report_step = 5; report_step < 10; report_step++) { for (std::size_t report_step = 5; report_step < 10; report_step++) {
const auto& udq = schedule.getUDQConfig(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"); auto fu_var1 = st.get("FU_VAR1");
BOOST_CHECK_EQUAL(fu_var1, report_step - 4); BOOST_CHECK_EQUAL(fu_var1, report_step - 4);
} }
@ -2272,7 +2272,7 @@ TSTEP
// Reset to zero and stay there. // Reset to zero and stay there.
for (std::size_t report_step = 10; report_step < 15; report_step++) { for (std::size_t report_step = 10; report_step < 15; report_step++) {
const auto& udq = schedule.getUDQConfig(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"); auto fu_var1 = st.get("FU_VAR1");
BOOST_CHECK_EQUAL(fu_var1, 0); 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"}); UDQDefine def_div(udqp, "FU", location, {"128", "/", "2", "/", "4", "/", "8"});
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
UDQState udq_state(udqp.undefinedValue()); UDQState udq_state(udqp.undefinedValue());
UDQContext context(udqft, st, udq_state); UDQContext context(udqft, {}, st, udq_state);
auto res_div = def_div.eval(context); auto res_div = def_div.eval(context);
BOOST_CHECK_EQUAL( res_div[0].get() , 2.0); BOOST_CHECK_EQUAL( res_div[0].get() , 2.0);
@ -2314,7 +2314,7 @@ UDQ
SummaryState st(std::chrono::system_clock::now()); SummaryState st(std::chrono::system_clock::now());
const auto& udq = schedule.getUDQConfig(0); 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_var1 = st.get("FU_VAR1");
auto fu_var2 = st.get("FU_VAR2"); auto fu_var2 = st.get("FU_VAR2");
auto fu_var3 = st.get("FU_VAR3"); auto fu_var3 = st.get("FU_VAR3");
@ -2327,3 +2327,44 @@ UDQ
BOOST_CHECK_CLOSE(fu_var5, -0.00000041232 * 4 + 0.0010395 * 3 + 0.16504, 1e-5); 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 '*') /
DEFINE FU_VAR3 WOPR 'P4' /
/
)";
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");
auto fu_var3 = st.get("FU_VAR3");
BOOST_CHECK_EQUAL(fu_var1, 6);
BOOST_CHECK_EQUAL(fu_var2, 10);
BOOST_CHECK_EQUAL(fu_var3, 4);
}

View File

@ -399,7 +399,7 @@ RestartValue first_sim(const Setup& setup, Action::State& action_state, SummaryS
RestartValue restart_value(sol, wells, groups); RestartValue restart_value(sol, wells, groups);
init_st(st); 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, eclWriter.writeTimeStep( action_state,
st, st,
udq_state, udq_state,