diff --git a/msim/src/msim.cpp b/msim/src/msim.cpp index eaf353450..95dd81f7a 100644 --- a/msim/src/msim.cpp +++ b/msim/src/msim.cpp @@ -121,7 +121,7 @@ void msim::run_step(const Schedule& schedule, Action::State& action_state, Summa group_data, {}); - schedule.getUDQConfig( report_step ).eval(st); + schedule.getUDQConfig( report_step ).eval(st, udq_state); this->output(action_state, st, diff --git a/opm/output/eclipse/AggregateUDQData.hpp b/opm/output/eclipse/AggregateUDQData.hpp index 8e0c6999c..424038c34 100644 --- a/opm/output/eclipse/AggregateUDQData.hpp +++ b/opm/output/eclipse/AggregateUDQData.hpp @@ -41,6 +41,7 @@ namespace Opm { class Schedule; class UDQInput; class UDQActive; + class UDQState; } // Opm namespace Opm { namespace RestartIO { namespace Helpers { @@ -57,7 +58,7 @@ public: void captureDeclaredUDQData(const Opm::Schedule& sched, const std::size_t simStep, - const Opm::SummaryState& st, + const Opm::UDQState& udqState, const std::vector& inteHead); const std::vector& getIUDQ() const diff --git a/opm/output/eclipse/RestartIO.hpp b/opm/output/eclipse/RestartIO.hpp index 6653f6d7f..03b3dbdb4 100644 --- a/opm/output/eclipse/RestartIO.hpp +++ b/opm/output/eclipse/RestartIO.hpp @@ -26,7 +26,6 @@ #include -#include #include #include @@ -37,6 +36,8 @@ namespace Opm { class EclipseGrid; class EclipseState; class Schedule; + class UDQState; + class SummaryState; } // namespace Opm @@ -84,6 +85,7 @@ namespace Opm { namespace RestartIO { const Schedule& schedule, const Action::State& action_state, const SummaryState& sumState, + const UDQState& udqState, bool write_double = false); diff --git a/opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp b/opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp index 1b53f488e..3b602803f 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp @@ -88,7 +88,7 @@ public: void update_well_var(const std::string& well, const std::string& var, double value); void update_group_var(const std::string& group, const std::string& var, double value); void update_elapsed(double delta); - void update_udq(const UDQSet& udq_set); + void update_udq(const UDQSet& udq_set, double undefined_value); double get(const std::string&) const; double get(const std::string&, double) const; diff --git a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp index 9b63a3c27..795499dba 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp @@ -40,6 +40,8 @@ namespace Opm { class DeckRecord; class Deck; class SummaryState; + class UDQState; + class UDQConfig { public: UDQConfig() = default; @@ -57,7 +59,7 @@ namespace Opm { void add_assign(const std::string& quantity, const std::vector& selector, double value); void add_define(const std::string& quantity, const std::vector& expression); - void eval(SummaryState& st) const; + void eval(SummaryState& st, UDQState& udq_state) const; const UDQDefine& define(const std::string& key) const; std::vector definitions() const; std::vector definitions(UDQVarType var_type) const; diff --git a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp index 35cf9a3d4..fbc3e4889 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp @@ -21,32 +21,36 @@ #ifndef UDQ_CONTEXT_HPP #define UDQ_CONTEXT_HPP -#include +#include #include #include +#include #include +#include namespace Opm { class SummaryState; class UDQFunctionTable; + class UDQState; class UDQContext{ public: - UDQContext(const UDQFunctionTable& udqft, const SummaryState& summary_state); - double get(const std::string& key) const; - bool has_well_var(const std::string& well, const std::string& var) const; - double get_well_var(const std::string& well, const std::string& var) const; - bool has_group_var(const std::string& group, const std::string& var) const; - double get_group_var(const std::string& group, const std::string& var) const; + UDQContext(const UDQFunctionTable& udqft, SummaryState& summary_state, UDQState& udq_state); + std::optional get(const std::string& key) const; + std::optional get_well_var(const std::string& well, const std::string& var) const; + std::optional get_group_var(const std::string& group, const std::string& var) const; void add(const std::string& key, double value); + void update(const std::string& keyword, const UDQSet& udq_result); const UDQFunctionTable& function_table() const; std::vector wells() const; std::vector groups() const; private: const UDQFunctionTable& udqft; - const SummaryState& summary_state; + SummaryState& summary_state; + UDQState& udq_state; + //std::unordered_map udq_results; std::unordered_map values; }; } diff --git a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp index 3e9c22aee..e7d5223a3 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.hpp @@ -64,7 +64,7 @@ public: static UDQDefine serializeObject(); - UDQSet eval(const UDQContext& context) const; + UDQSet eval(UDQContext& context) const; const std::string& keyword() const; const std::string& input_string() const; UDQVarType var_type() const; diff --git a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp index 9b753c500..60438f7ce 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp @@ -47,9 +47,11 @@ public: void operator-=(double rhs); operator bool() const; + void assign(const std::optional& value); void assign(double value); bool defined() const; - double value() const; + double get() const; + const std::optional& value() const; const std::string& wgname() const; bool operator==(const UDQScalar& other) const; static UDQScalar deserialize(Serializer& ser); @@ -69,6 +71,7 @@ public: UDQSet(const std::string& name, std::size_t size); void serialize(Serializer& ser) const; static UDQSet deserialize(Serializer& ser); + static UDQSet scalar(const std::string& name, const std::optional& scalar_value); static UDQSet scalar(const std::string& name, double value); static UDQSet empty(const std::string& name); static UDQSet wells(const std::string& name, const std::vector& wells); @@ -77,6 +80,9 @@ public: static UDQSet groups(const std::string& name, const std::vector& groups, double scalar_value); static UDQSet field(const std::string& name, double scalar_value); + void assign(const std::optional& value); + void assign(const std::string& wgname, const std::optional& value); + void assign(double value); void assign(std::size_t index, double value); void assign(const std::string& wgname, double value); diff --git a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp index 8b59463b5..30bc01052 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp @@ -39,7 +39,7 @@ public: double get(const std::string& key) const; double get_group_var(const std::string& well, const std::string& var) const; double get_well_var(const std::string& well, const std::string& var) const; - void add(const UDQSet& result); + void add(const std::string& udq_key, const UDQSet& result); std::vector serialize() const; void deserialize(const std::vector& buffer); diff --git a/src/opm/output/eclipse/AggregateUDQData.cpp b/src/opm/output/eclipse/AggregateUDQData.cpp index 921c682d9..2066a028e 100644 --- a/src/opm/output/eclipse/AggregateUDQData.cpp +++ b/src/opm/output/eclipse/AggregateUDQData.cpp @@ -26,9 +26,9 @@ #include #include -//#include #include +#include #include #include #include @@ -269,7 +269,7 @@ namespace { } template - void staticContrib(const Opm::SummaryState& st, + void staticContrib(const Opm::UDQState& udq_state, const std::vector& wnames, const std::string udq, const std::size_t nwmaxz, @@ -280,8 +280,8 @@ namespace { dUdw[ind] = Opm::UDQ::restart_default; } for (std::size_t ind = 0; ind < wnames.size(); ind++) { - if (st.has_well_var(wnames[ind], udq)) { - dUdw[ind] = st.get_well_var(wnames[ind], udq); + if (udq_state.has_well_var(wnames[ind], udq)) { + dUdw[ind] = udq_state.get_well_var(wnames[ind], udq); } } } @@ -301,7 +301,7 @@ namespace { } template - void staticContrib(const Opm::SummaryState& st, + void staticContrib(const Opm::UDQState& udq_state, const std::vector groups, const std::string udq, const std::size_t ngmaxz, @@ -313,8 +313,8 @@ namespace { dUdg[ind] = Opm::UDQ::restart_default; } else { - if (st.has_group_var((*groups[ind]).name(), udq)) { - dUdg[ind] = st.get_group_var((*groups[ind]).name(), udq); + if (udq_state.has_group_var((*groups[ind]).name(), udq)) { + dUdg[ind] = udq_state.get_group_var((*groups[ind]).name(), udq); } else { dUdg[ind] = Opm::UDQ::restart_default; @@ -338,13 +338,13 @@ namespace { } template - void staticContrib(const Opm::SummaryState& st, + void staticContrib(const Opm::UDQState& udq_state, const std::string udq, DUDFArray& dUdf) { //set value for group name "FIELD" - if (st.has(udq)) { - dUdf[0] = st.get(udq); + if (udq_state.has(udq)) { + dUdf[0] = udq_state.get(udq); } else { dUdf[0] = Opm::UDQ::restart_default; @@ -458,7 +458,7 @@ void Opm::RestartIO::Helpers::AggregateUDQData:: captureDeclaredUDQData(const Opm::Schedule& sched, const std::size_t simStep, - const Opm::SummaryState& st, + const Opm::UDQState& udq_state, const std::vector& inteHead) { const auto& udqCfg = sched.getUDQConfig(simStep); @@ -549,7 +549,7 @@ captureDeclaredUDQData(const Opm::Schedule& sched, if (udq_input.var_type() == UDQVarType::WELL_VAR) { const std::string& udq = udq_input.keyword(); auto i_dudw = this->dUDW_[i_wudq]; - dUdw::staticContrib(st, wnames, udq, nwmax, i_dudw); + dUdw::staticContrib(udq_state, wnames, udq, nwmax, i_dudw); i_wudq++; cnt_dudw += 1; } @@ -568,7 +568,7 @@ captureDeclaredUDQData(const Opm::Schedule& sched, if (udq_input.var_type() == UDQVarType::GROUP_VAR) { const std::string& udq = udq_input.keyword(); auto i_dudg = this->dUDG_[i_gudq]; - dUdg::staticContrib(st, curGroups, udq, ngmax, i_dudg); + dUdg::staticContrib(udq_state, curGroups, udq, ngmax, i_dudg); i_gudq++; cnt_dudg += 1; } @@ -585,7 +585,7 @@ captureDeclaredUDQData(const Opm::Schedule& sched, if (udq_input.var_type() == UDQVarType::FIELD_VAR) { const std::string& udq = udq_input.keyword(); auto i_dudf = this->dUDF_[i_fudq]; - dUdf::staticContrib(st, udq, i_dudf); + dUdf::staticContrib(udq_state, udq, i_dudf); i_fudq++; cnt_dudf += 1; } diff --git a/src/opm/output/eclipse/EclipseIO.cpp b/src/opm/output/eclipse/EclipseIO.cpp index 48bd66ef3..4f55ad5e4 100644 --- a/src/opm/output/eclipse/EclipseIO.cpp +++ b/src/opm/output/eclipse/EclipseIO.cpp @@ -189,7 +189,7 @@ void EclipseIO::writeInitial( data::Solution simProps, std::map& ih, EclIO::OutputStream::Restart& rstFile) { @@ -300,7 +300,7 @@ namespace { const auto udqDims = Helpers::createUdqDims(schedule, simStep, ih); auto udqData = Helpers::AggregateUDQData(udqDims); - udqData.captureDeclaredUDQData(schedule, simStep, sum_state, ih); + udqData.captureDeclaredUDQData(schedule, simStep, udq_state, ih); if (udqDims[0] >= 1) { rstFile.write("ZUDN", udqData.getZUDN()); @@ -567,7 +567,7 @@ namespace { void writeSolution(const RestartValue& value, const Schedule& schedule, - const SummaryState& sum_state, + const UDQState& udq_state, int report_step, int sim_step, const bool ecl_compatible_rst, @@ -594,7 +594,7 @@ namespace { writeRegularSolutionVectors(value, write_double_arg, write); - writeUDQ(report_step, sim_step, schedule, sum_state, inteHD, rstFile); + writeUDQ(report_step, sim_step, schedule, udq_state, inteHD, rstFile); writeExtraVectors(value, write); @@ -656,6 +656,7 @@ void save(EclIO::OutputStream::Restart& rstFile, const Schedule& schedule, const Action::State& action_state, const SummaryState& sumState, + const UDQState& udqState, bool write_double) { ::Opm::RestartIO::checkSaveArguments(es, value, grid); @@ -685,7 +686,7 @@ void save(EclIO::OutputStream::Restart& rstFile, writeActionx(report_step, sim_step, es, schedule, action_state, sumState, rstFile); - writeSolution(value, schedule, sumState, report_step, sim_step, + writeSolution(value, schedule, udqState, report_step, sim_step, ecl_compatible_rst, write_double, inteHD, rstFile); if (! ecl_compatible_rst) { diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp index 706d229c9..943b853ab 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/SummaryState.cpp @@ -154,30 +154,24 @@ namespace { } } - void SummaryState::update_udq(const UDQSet& udq_set) { + + void SummaryState::update_udq(const UDQSet& udq_set, double undefined_value) { auto var_type = udq_set.var_type(); if (var_type == UDQVarType::WELL_VAR) { const std::vector wells = this->wells(); for (const auto& well : wells) { - const auto& udq_value = udq_set[well]; - if (udq_value) - this->update_well_var(well, udq_set.name(), udq_value.value()); - else - this->erase_well_var(well, udq_set.name()); + const auto& udq_value = udq_set[well].value(); + this->update_well_var(well, udq_set.name(), udq_value.value_or(undefined_value)); } } else if (var_type == UDQVarType::GROUP_VAR) { const std::vector groups = this->groups(); for (const auto& group : groups) { - const auto& udq_value = udq_set[group]; - if (udq_value) - this->update_group_var(group, udq_set.name(), udq_value.value()); - else - this->erase_group_var(group, udq_set.name()); + const auto& udq_value = udq_set[group].value(); + this->update_group_var(group, udq_set.name(), udq_value.value_or(undefined_value)); } } else { - const auto& udq_var = udq_set[0]; - if (udq_var) - this->update(udq_set.name(), udq_var.value()); + const auto& udq_var = udq_set[0].value(); + this->update(udq_set.name(), udq_var.value_or(undefined_value)); } } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQASTNode.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQASTNode.cpp index 9f8bdfdf3..cdd1a8e69 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQASTNode.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQASTNode.cpp @@ -154,19 +154,16 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const 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) { - if (context.has_well_var(well, string_value)) - res.assign(well, context.get_well_var(well, string_value)); - } + if (fnmatch(well_pattern.c_str(), well.c_str(), fnmatch_flags) == 0) + res.assign(well, context.get_well_var(well, string_value)); } return res; } } else { auto res = UDQSet::wells(string_value, wells); - for (const auto& well : wells) { - if (context.has_well_var(well, string_value)) - res.assign(well, context.get_well_var(well, string_value)); - } + for (const auto& well : wells) + res.assign(well, context.get_well_var(well, string_value)); + return res; } } @@ -181,10 +178,8 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const } else { const auto& groups = context.groups(); auto res = UDQSet::groups(string_value, groups); - for (const auto& group : groups) { - if (context.has_group_var(group, string_value)) - res.assign(group, context.get_group_var(group, string_value)); - } + for (const auto& group : groups) + res.assign(group, context.get_group_var(group, string_value)); return res; } } @@ -192,7 +187,11 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const if (data_type == UDQVarType::FIELD_VAR) return UDQSet::scalar(string_value, context.get(string_value)); - throw std::logic_error("Should not be here: var_type: " + UDQ::typeName(data_type)); + auto scalar = context.get(string_value); + if (scalar.has_value()) + return UDQSet::scalar(string_value, scalar.value()); + + throw std::logic_error("Should not be here: var_type: " + UDQ::typeName(data_type) + " stringvalue:" + string_value); } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp index f9e766fdb..c76ab5096 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.cpp @@ -289,37 +289,45 @@ namespace Opm { this->type_count == data.type_count; } - void UDQConfig::eval(SummaryState& st) const { + void UDQConfig::eval(SummaryState& st, UDQState& udq_state) const { const auto& func_table = this->function_table(); - UDQContext context(func_table, st); + auto undefined_value = this->params().undefinedValue(); + UDQContext context(func_table, st, udq_state); + for (const auto& assign : this->assignments(UDQVarType::WELL_VAR)) { auto ws = assign.eval(st.wells()); - st.update_udq(ws); + context.update(assign.keyword(), ws); + st.update_udq(ws, undefined_value); } for (const auto& def : this->definitions(UDQVarType::WELL_VAR)) { auto ws = def.eval(context); - st.update_udq(ws); + context.update(def.keyword(), ws); + st.update_udq(ws, undefined_value); } for (const auto& assign : this->assignments(UDQVarType::GROUP_VAR)) { auto ws = assign.eval(st.groups()); - st.update_udq(ws); + context.update(assign.keyword(), ws); + st.update_udq(ws, undefined_value); } for (const auto& def : this->definitions(UDQVarType::GROUP_VAR)) { auto ws = def.eval(context); - st.update_udq(ws); + context.update(def.keyword(), ws); + st.update_udq(ws, undefined_value); } for (const auto& assign : this->assignments(UDQVarType::FIELD_VAR)) { auto ws = assign.eval(); - st.update_udq(ws); + context.update(assign.keyword(), ws); + st.update_udq(ws, undefined_value); } for (const auto& def : this->definitions(UDQVarType::FIELD_VAR)) { auto field_udq = def.eval(context); - st.update_udq(field_udq); + context.update(def.keyword(), field_udq); + st.update_udq(field_udq, undefined_value); } } } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.cpp index 6485ff80f..af06b83e9 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.cpp @@ -20,13 +20,30 @@ #include #include #include +#include namespace Opm { - UDQContext::UDQContext(const UDQFunctionTable& udqft_arg, const SummaryState& summary_state_arg) : +namespace { + +bool is_udq(const std::string& key) { + if (key.size() < 2) + return false; + + if (key[1] != 'U') + return false; + + return true; +} + +} + + + UDQContext::UDQContext(const UDQFunctionTable& udqft_arg, SummaryState& summary_state_arg, UDQState& udq_state_arg) : udqft(udqft_arg), - summary_state(summary_state_arg) + summary_state(summary_state_arg), + udq_state(udq_state_arg) { for (const auto& pair : TimeMap::eclipseMonthIndices()) this->add(pair.first, pair.second); @@ -46,33 +63,56 @@ namespace Opm { this->add("TIMESTEP", 0.0); } + void UDQContext::update(const std::string& keyword, const UDQSet& udq_result) { + this->udq_state.add(keyword, udq_result); + } void UDQContext::add(const std::string& key, double value) { this->values[key] = value; } - double UDQContext::get(const std::string& key) const { + std::optional UDQContext::get(const std::string& key) const { + if (is_udq(key)) { + if (this->udq_state.has(key)) + return this->udq_state.get(key); + + return std::nullopt; + } + const auto& pair_ptr = this->values.find(key); - if (pair_ptr == this->values.end()) + if (pair_ptr != this->values.end()) + return pair_ptr->second; + + if (this->summary_state.has(key)) return this->summary_state.get(key); - return pair_ptr->second; + return std::nullopt; } - double UDQContext::get_well_var(const std::string& well, const std::string& var) const { - return this->summary_state.get_well_var(well, var); + std::optional UDQContext::get_well_var(const std::string& well, const std::string& var) const { + if (is_udq(var)) { + if (this->udq_state.has_well_var(well, var)) + return this->udq_state.get_well_var(well, var); + + return std::nullopt; + } + if (this->summary_state.has_well_var(well, var)) + return this->summary_state.get_well_var(well, var); + + return std::nullopt; } - bool UDQContext::has_well_var(const std::string& well, const std::string& var) const { - return this->summary_state.has_well_var(well, var); - } + std::optional UDQContext::get_group_var(const std::string& group, const std::string& var) const { + if (is_udq(var)) { + if (this->udq_state.has_group_var(group, var)) + return this->udq_state.get_group_var(group, var); - double UDQContext::get_group_var(const std::string& group, const std::string& var) const { - return this->summary_state.get_group_var(group, var); - } + return std::nullopt; + } + if (this->summary_state.has_group_var(group, var)) + return this->summary_state.get_group_var(group, var); - bool UDQContext::has_group_var(const std::string& group, const std::string& var) const { - return this->summary_state.has_group_var(group, var); + return std::nullopt; } std::vector UDQContext::wells() const { diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.cpp index d46a7e1f3..94d17ee89 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQDefine.cpp @@ -248,12 +248,13 @@ bool dynamic_type_check(UDQVarType lhs, UDQVarType rhs) { } -UDQSet UDQDefine::eval(const UDQContext& context) const { +UDQSet UDQDefine::eval(UDQContext& context) const { UDQSet res = this->ast->eval(this->m_var_type, context); if (!dynamic_type_check(this->var_type(), res.var_type())) { std::string msg = "Invalid runtime type conversion detected when evaluating UDQ"; throw std::invalid_argument(msg); } + context.update(this->keyword(), res); if (res.var_type() == UDQVarType::SCALAR) { /* @@ -272,7 +273,7 @@ UDQSet UDQDefine::eval(const UDQContext& context) const { regarding the semantics of group sets. */ - double scalar_value = res[0].value(); + const auto& scalar_value = res[0].value(); if (this->var_type() == UDQVarType::WELL_VAR) { const std::vector wells = context.wells(); UDQSet well_res = UDQSet::wells(this->m_keyword, wells); diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.cpp index e1a89afd1..63a39a8a4 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunction.cpp @@ -167,7 +167,7 @@ UDQSet UDQUnaryElementalFunction::ABS(const UDQSet& arg) { for (std::size_t index=0; index < result.size(); index++) { auto& udq_value = result[index]; if (udq_value) - result.assign( index, std::fabs(udq_value.value())); + result.assign( index, std::fabs(udq_value.get())); } return result; } @@ -211,7 +211,7 @@ UDQSet UDQUnaryElementalFunction::EXP(const UDQSet& arg) { for (std::size_t index=0; index < result.size(); index++) { auto& udq_value = result[index]; if (udq_value) - result.assign( index, std::exp(udq_value.value()) ); + result.assign( index, std::exp(udq_value.get()) ); } return result; } @@ -221,7 +221,7 @@ UDQSet UDQUnaryElementalFunction::NINT(const UDQSet& arg) { for (std::size_t index=0; index < result.size(); index++) { auto& udq_value = result[index]; if (udq_value) - result.assign( index, std::nearbyint(udq_value.value()) ); + result.assign( index, std::nearbyint(udq_value.get()) ); } return result; } @@ -259,7 +259,7 @@ UDQSet UDQUnaryElementalFunction::LN(const UDQSet& arg) { for (std::size_t index=0; index < result.size(); index++) { auto& udq_value = result[index]; if (udq_value) { - double elm = udq_value.value(); + double elm = udq_value.get(); if (elm > 0) result.assign(index, std::log(elm)); else @@ -275,7 +275,7 @@ UDQSet UDQUnaryElementalFunction::LOG(const UDQSet& arg) { for (std::size_t index=0; index < result.size(); index++) { auto& udq_value = result[index]; if (udq_value) { - double elm = udq_value.value(); + double elm = udq_value.get(); if (elm > 0) result.assign(index, std::log10(elm)); else @@ -297,10 +297,10 @@ namespace { const auto& elm2 = arg2[index]; if (elm1.defined() != elm2.defined()) { if (elm1) - result.assign(index, elm1.value()); + result.assign(index, elm1.get()); if (elm2) - result.assign(index, elm2.value()); + result.assign(index, elm2.get()); } } return result; @@ -316,9 +316,9 @@ UDQSet UDQUnaryElementalFunction::SORT(const UDQSet& arg, bool ascending) { const auto& value = arg[index]; if (value.defined()) { if (ascending) - sort_nodes.emplace_back(index, value.value() ); + sort_nodes.emplace_back(index, value.get() ); else - sort_nodes.emplace_back(index, -value.value() ); + sort_nodes.emplace_back(index, -value.get() ); } } @@ -365,11 +365,16 @@ UDQSet UDQBinaryFunction::LE(double eps, const UDQSet& lhs, const UDQSet& rhs) { for (std::size_t index=0; index < result.size(); index++) { auto elm = result[index]; if (elm) { - double diff = rel_diff[index].value(); - if (diff <= eps) + const double abs_diff = elm.get(); + if (abs_diff == 0) result.assign(index, 1); - else - result.assign(index, 0); + else { + double diff = rel_diff[index].get(); + if (diff <= eps) + result.assign(index, 1); + else + result.assign(index, 0); + } } } return result; @@ -382,15 +387,19 @@ UDQSet UDQBinaryFunction::GE(double eps, const UDQSet& lhs, const UDQSet& rhs) { for (std::size_t index=0; index < result.size(); index++) { auto elm = result[index]; if (elm) { - double diff = rel_diff[index].value(); - if (diff >= -eps) + const double abs_diff = elm.get(); + if (abs_diff == 0) result.assign(index, 1); - else - result.assign(index, 0); + else { + double diff = rel_diff[index].get(); + if (diff >= -eps) + result.assign(index, 1); + else + result.assign(index, 0); + } } } return result; - } @@ -401,23 +410,28 @@ UDQSet UDQBinaryFunction::EQ(double eps, const UDQSet& lhs, const UDQSet& rhs) { for (std::size_t index=0; index < result.size(); index++) { auto elm = result[index]; if (elm) { - double diff = std::fabs(rel_diff[index].value()); - if (diff <= eps) + const double abs_diff = elm.get(); + if (abs_diff == 0) result.assign(index, 1); - else - result.assign(index, 0); + else { + const double diff = std::fabs(rel_diff[index].get()); + if (diff <= eps) + result.assign(index, 1); + else + result.assign(index, 0); + } } } return result; - } + UDQSet UDQBinaryFunction::NE(double eps, const UDQSet& lhs, const UDQSet& rhs) { auto result = UDQBinaryFunction::EQ(eps, lhs, rhs); for (std::size_t index=0; index < result.size(); index++) { auto elm = result[index]; if (elm) - result.assign(index, 1 - elm.value()); + result.assign(index, 1 - elm.get()); } return result; } @@ -429,7 +443,7 @@ UDQSet UDQBinaryFunction::GT(const UDQSet& lhs, const UDQSet& rhs) { for (std::size_t index=0; index < result.size(); index++) { auto elm = result[index]; if (elm) { - double diff = elm.value(); + double diff = elm.get(); if (diff > 0) result.assign(index, 1); else @@ -445,7 +459,7 @@ UDQSet UDQBinaryFunction::LT(const UDQSet& lhs, const UDQSet& rhs) { for (std::size_t index=0; index < result.size(); index++) { auto elm = result[index]; if (elm) { - double diff = elm.value(); + double diff = elm.get(); if (diff < 0) result.assign(index, 1); else @@ -468,7 +482,7 @@ UDQSet UDQBinaryFunction::UADD(const UDQSet& lhs, const UDQSet& rhs) { const auto& rhs_elm = rhs[index]; if (lhs_elm && rhs_elm) - result.assign(index, rhs_elm.value() + lhs_elm.value()); + result.assign(index, rhs_elm.get() + lhs_elm.get()); } return result; } @@ -480,7 +494,7 @@ UDQSet UDQBinaryFunction::UMUL(const UDQSet& lhs, const UDQSet& rhs) { const auto& rhs_elm = rhs[index]; if (lhs_elm && rhs_elm) - result.assign(index, rhs_elm.value() * lhs_elm.value()); + result.assign(index, rhs_elm.get() * lhs_elm.get()); } return result; } @@ -492,7 +506,7 @@ UDQSet UDQBinaryFunction::UMIN(const UDQSet& lhs, const UDQSet& rhs) { const auto& rhs_elm = rhs[index]; if (lhs_elm && rhs_elm) - result.assign(index, std::min(rhs_elm.value(), lhs_elm.value())); + result.assign(index, std::min(rhs_elm.get(), lhs_elm.get())); } return result; } @@ -505,7 +519,7 @@ UDQSet UDQBinaryFunction::UMAX(const UDQSet& lhs, const UDQSet& rhs) { const auto& rhs_elm = rhs[index]; if (lhs_elm && rhs_elm) - result.assign(index, std::max(rhs_elm.value(), lhs_elm.value())); + result.assign(index, std::max(rhs_elm.get(), lhs_elm.get())); } return result; } @@ -533,7 +547,7 @@ UDQSet UDQBinaryFunction::POW(const UDQSet& lhs, const UDQSet& rhs) { auto& rhs_elm = rhs[index]; if (lhs_elm && rhs_elm) - result.assign(index, std::pow(lhs_elm.value(), rhs_elm.value())); + result.assign(index, std::pow(lhs_elm.get(), rhs_elm.get())); } return result; } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.cpp index e2355bf2b..5a2827293 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.cpp @@ -60,7 +60,11 @@ bool UDQScalar::defined() const { return this->m_value.has_value(); } -double UDQScalar::value() const { +const std::optional& UDQScalar::value() const { + return this->m_value; +} + +double UDQScalar::get() const { if (!this->m_value.has_value()) throw std::invalid_argument("UDQSCalar: Value not defined wgname: " + this->m_wgname); @@ -71,6 +75,16 @@ const std::string& UDQScalar::wgname() const { return this->m_wgname; } +void UDQScalar::assign(const std::optional& value) { + if (value.has_value()) { + if (std::isfinite(*value)) + this->m_value = value; + else + this->m_value = std::nullopt; + } else + this->m_value = std::nullopt; +} + void UDQScalar::assign(double value) { if (std::isfinite(value)) this->m_value = value; @@ -180,6 +194,13 @@ UDQSet UDQSet::scalar(const std::string& name, double scalar_value) return us; } +UDQSet UDQSet::scalar(const std::string& name, const std::optional& scalar_value) +{ + UDQSet us(name, UDQVarType::SCALAR); + us.assign(scalar_value); + return us; +} + UDQSet UDQSet::empty(const std::string& name) { return UDQSet(name, 0); @@ -243,11 +264,29 @@ void UDQSet::assign(const std::string& wgname, double value) { throw std::out_of_range("No well/group matching: " + wgname); } +void UDQSet::assign(const std::string& wgname, const std::optional& value) { + bool assigned = false; + for (auto& udq_value : this->values) { + int flags = 0; + if (fnmatch(wgname.c_str(), udq_value.wgname().c_str(), flags) == 0) { + udq_value.assign( value ); + assigned = true; + } + } + if (!assigned) + throw std::out_of_range("No well/group matching: " + wgname); +} + void UDQSet::assign(double value) { for (auto& v : this->values) v.assign(value); } +void UDQSet::assign(const std::optional& value) { + for (auto& v : this->values) + v.assign(value); +} + void UDQSet::assign(std::size_t index, double value) { auto& scalar = this->values[index]; scalar.assign(value); @@ -321,7 +360,7 @@ std::vector UDQSet::defined_values() const { std::vector dv; for (const auto& v : this->values) { if (v) - dv.push_back(v.value()); + dv.push_back(v.get()); } return dv; } @@ -429,7 +468,7 @@ UDQScalar operator/(const UDQScalar&lhs, double rhs) { UDQScalar operator/(double lhs, const UDQScalar& rhs) { UDQScalar result = rhs; if (result) - result.assign(lhs / result.value()); + result.assign(lhs / result.get()); return result; } @@ -451,10 +490,10 @@ UDQSet udq_cast(const UDQSet& lhs, const UDQSet& rhs) } if (rhs.var_type() == UDQVarType::WELL_VAR) - return UDQSet::wells(lhs.name(), rhs.wgnames(), lhs[0].value()); + return UDQSet::wells(lhs.name(), rhs.wgnames(), lhs[0].get()); if (rhs.var_type() == UDQVarType::GROUP_VAR) - return UDQSet::groups(lhs.name(), rhs.wgnames(), lhs[0].value()); + return UDQSet::groups(lhs.name(), rhs.wgnames(), lhs[0].get()); throw std::logic_error("Don't have a clue"); } else @@ -534,7 +573,7 @@ UDQSet operator/(double lhs, const UDQSet&rhs) { for (std::size_t index = 0; index < rhs.size(); index++) { const auto& elm = rhs[index]; if (elm) - result.assign(index, lhs / elm.value()); + result.assign(index, lhs / elm.get()); } return result; } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.cpp index da4f4a43c..adc4ef45f 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.cpp @@ -71,13 +71,13 @@ bool UDQState::has_group_var(const std::string& group, const std::string& key) c } -void UDQState::add(const UDQSet& result) { - if (!is_udq(result.name())) - throw std::logic_error("Key is not a UDQ variable:" + result.name()); +void UDQState::add(const std::string& udq_key, const UDQSet& result) { + if (!is_udq(udq_key)) + throw std::logic_error("Key is not a UDQ variable:" + udq_key); - auto res_iter = this->values.find(result.name()); + auto res_iter = this->values.find(udq_key); if (res_iter == this->values.end()) - this->values.insert( std::make_pair( result.name(), result )); + this->values.insert( std::make_pair( udq_key, result )); else res_iter->second = result; } @@ -88,7 +88,7 @@ double UDQState::get(const std::string& key) const { const auto& result = this->values.at(key)[0]; if (result.defined()) - return result.value(); + return result.get(); else return this->undefined_value; } @@ -107,7 +107,7 @@ double UDQState::get_wg_var(const std::string& wgname, const std::string& key, U const auto& result = result_set[wgname]; if (result.defined()) - return result.value(); + return result.get(); else return this->undefined_value; } diff --git a/tests/parser/UDQTests.cpp b/tests/parser/UDQTests.cpp index f94075daa..5bbde607e 100644 --- a/tests/parser/UDQTests.cpp +++ b/tests/parser/UDQTests.cpp @@ -58,51 +58,6 @@ Schedule make_schedule(const std::string& input) { } } -BOOST_AUTO_TEST_CASE(UDQSTATE) { - double undefined_value = 1234; - UDQState st(undefined_value); - BOOST_CHECK(!st.has("FUXX")); - BOOST_CHECK(!st.has_well_var("OP1", "WUXX")); - BOOST_CHECK(!st.has_group_var("G1", "GUXX")); - - // Try to get from symbol which is not UDQ -> logic_error - BOOST_CHECK_THROW(st.get("FOPR"), std::logic_error); - - // Try to get from a UDQ which has not registered -> out_of_range - BOOST_CHECK_THROW(st.get("FUPR"), std::out_of_range); - - auto fxpr = UDQSet::scalar("FXPR", 100); - BOOST_CHECK_THROW(st.add(fxpr), std::logic_error); - - BOOST_CHECK_THROW(st.get_well_var("OP1", "WUPR"), std::out_of_range); - - auto fupr = UDQSet::scalar("FUPR", 100); - st.add(fupr); - - // This is not a well quantity - BOOST_CHECK_THROW(st.get_well_var("OP1", "FUPR"), std::logic_error); - BOOST_CHECK_EQUAL(100, st.get("FUPR")); - - - auto wupr = UDQSet::wells("WUPR", {"P1", "P2"}); - wupr.assign("P1", 75); - st.add(wupr); - - BOOST_CHECK(st.has_well_var("P1", "WUPR")); - // We have a well P2 - but we have not assigned a value to it! - BOOST_CHECK(!st.has_well_var("P2", "WUPR")); - - BOOST_CHECK_EQUAL(st.get_well_var("P1", "WUPR"), 75); - BOOST_CHECK_EQUAL(st.get_well_var("P2", "WUPR"), undefined_value); - - - const auto buffer = st.serialize(); - UDQState st2(1067); - st2.deserialize( buffer ); - BOOST_CHECK(st == st2); -} - - BOOST_AUTO_TEST_CASE(TYPE_COERCION) { BOOST_CHECK( UDQVarType::SCALAR == UDQ::coerce(UDQVarType::SCALAR, UDQVarType::SCALAR) ); @@ -123,7 +78,8 @@ BOOST_AUTO_TEST_CASE(GROUP_VARIABLES) UDQFunctionTable udqft; UDQDefine def_group(udqp, "GUOPRL",{"(", "5000", "-", "GOPR", "LOWER", "*", "0.13", "-", "GOPR", "UPPER", "*", "0.15", ")" , "*", "0.89"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); double gopr_lower = 1234; double gopr_upper = 4321; @@ -131,8 +87,8 @@ BOOST_AUTO_TEST_CASE(GROUP_VARIABLES) st.update_group_var("UPPER", "GOPR", gopr_upper); auto res_group = def_group.eval(context); - BOOST_CHECK_EQUAL( res_group["UPPER"].value(), (5000 - gopr_lower*0.13 - gopr_upper*0.15)*0.89); - BOOST_CHECK_EQUAL( res_group["UPPER"].value(), (5000 - gopr_lower*0.13 - gopr_upper*0.15)*0.89); + BOOST_CHECK_EQUAL( res_group["UPPER"].get(), (5000 - gopr_lower*0.13 - gopr_upper*0.15)*0.89); + BOOST_CHECK_EQUAL( res_group["UPPER"].get(), (5000 - gopr_lower*0.13 - gopr_upper*0.15)*0.89); } @@ -145,14 +101,15 @@ BOOST_AUTO_TEST_CASE(SUBTRACT) UDQDefine scalar(udqp, "WU", {"16"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WOPR", 4); auto res = def.eval(context); - BOOST_CHECK_EQUAL( res[0].value(), 1.0); + BOOST_CHECK_EQUAL( res[0].get(), 1.0); auto res2 = scalar.eval(context); - BOOST_CHECK_EQUAL( res2[0].value(), 16.0); + BOOST_CHECK_EQUAL( res2[0].get(), 16.0); } BOOST_AUTO_TEST_CASE(TEST) @@ -165,7 +122,8 @@ BOOST_AUTO_TEST_CASE(TEST) UDQDefine def4(udqp, "WUWI3", {"FOPR" , "/", "2"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_group_var("MAU", "GOPR", 4); st.update_group_var("XXX", "GOPR", 5); @@ -175,20 +133,20 @@ BOOST_AUTO_TEST_CASE(TEST) st.update("FOPR", 2); auto res1 = def1.eval(context); - BOOST_CHECK_EQUAL( res1["P1"].value(), 20 ); - BOOST_CHECK_EQUAL( res1["P2"].value(), 20 ); + BOOST_CHECK_EQUAL( res1["P1"].get(), 20 ); + BOOST_CHECK_EQUAL( res1["P2"].get(), 20 ); auto res2 = def2.eval(context); - BOOST_CHECK_EQUAL( res2["P1"].value(), 1.50 ); - BOOST_CHECK_EQUAL( res2["P2"].value(), 1.50 ); + BOOST_CHECK_EQUAL( res2["P1"].get(), 1.50 ); + BOOST_CHECK_EQUAL( res2["P2"].get(), 1.50 ); auto res3 = def3.eval(context); - BOOST_CHECK_EQUAL( res3["P1"].value(), 0.00 ); - BOOST_CHECK_EQUAL( res3["P2"].value(), 0.00 ); + BOOST_CHECK_EQUAL( res3["P1"].get(), 0.00 ); + BOOST_CHECK_EQUAL( res3["P2"].get(), 0.00 ); auto res4 = def4.eval(context); - BOOST_CHECK_EQUAL( res4["P1"].value(), 1.00 ); - BOOST_CHECK_EQUAL( res4["P2"].value(), 1.00 ); + BOOST_CHECK_EQUAL( res4["P1"].get(), 1.00 ); + BOOST_CHECK_EQUAL( res4["P2"].get(), 1.00 ); /* This expression has a well set as target type, and involves group with @@ -208,12 +166,13 @@ BOOST_AUTO_TEST_CASE(MIX_SCALAR) { UDQParams udqp; UDQDefine def_add(udqp, "WU", {"WOPR", "+", "1"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WOPR", 1); auto res_add = def_add.eval(context); - BOOST_CHECK_EQUAL( res_add["P1"].value() , 2); + BOOST_CHECK_EQUAL( res_add["P1"].get() , 2); } @@ -229,7 +188,8 @@ BOOST_AUTO_TEST_CASE(UDQFieldSetTest) { UDQParams udqp; UDQFunctionTable udqft(udqp); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WOPR", 1.0); st.update_well_var("P2", "WOPR", 2.0); @@ -239,7 +199,7 @@ BOOST_AUTO_TEST_CASE(UDQFieldSetTest) { /*{ UDQDefine def_fxxx(udqp, "FU_SCALAR", {"123"}); auto fxxx_res = def_fxxx.eval(context); - BOOST_CHECK_EQUAL( fxxx_res[0].value(), 123.0 ); + BOOST_CHECK_EQUAL( fxxx_res[0].get(), 123.0 ); BOOST_CHECK( fxxx_res.var_type() == UDQVarType::FIELD_VAR); } */ @@ -247,7 +207,7 @@ BOOST_AUTO_TEST_CASE(UDQFieldSetTest) { { UDQDefine def_fopr(udqp, "FUOPR", {"SUM", "(", "WOPR", ")"}); auto fopr_res = def_fopr.eval(context); - BOOST_CHECK_EQUAL( fopr_res[0].value(), 10.0 ); + BOOST_CHECK_EQUAL( fopr_res[0].get(), 10.0 ); } } @@ -281,8 +241,8 @@ BOOST_AUTO_TEST_CASE(UDQWellSetTest) { ws.assign("P1", 1.0); const auto& value = ws["P1"]; - BOOST_CHECK_EQUAL(value.value(), 1.0); - BOOST_CHECK_EQUAL(ws["P1"].value(), 1.0); + BOOST_CHECK_EQUAL(value.get(), 1.0); + BOOST_CHECK_EQUAL(ws["P1"].get(), 1.0); BOOST_REQUIRE_THROW(ws.assign("NO_SUCH_WELL", 1.0), std::out_of_range); BOOST_REQUIRE_THROW(ws[10], std::out_of_range); @@ -290,26 +250,26 @@ BOOST_AUTO_TEST_CASE(UDQWellSetTest) { ws.assign("*", 2.0); for (const auto& w : wells) - BOOST_CHECK_EQUAL(ws[w].value(), 2.0); + BOOST_CHECK_EQUAL(ws[w].get(), 2.0); ws.assign(3.0); for (const auto& w : wells) - BOOST_CHECK_EQUAL(ws[w].value(), 3.0); + BOOST_CHECK_EQUAL(ws[w].get(), 3.0); ws.assign("P*", 4.0); - BOOST_CHECK_EQUAL(ws["P1"].value(), 4.0); - BOOST_CHECK_EQUAL(ws["P2"].value(), 4.0); + BOOST_CHECK_EQUAL(ws["P1"].get(), 4.0); + BOOST_CHECK_EQUAL(ws["P2"].get(), 4.0); ws.assign("I2", 5.0); - BOOST_CHECK_EQUAL(ws["I2"].value(), 5.0); + BOOST_CHECK_EQUAL(ws["I2"].get(), 5.0); for (const auto& w : wells) - BOOST_CHECK_EQUAL(ws2[w].value(), 100.0); + BOOST_CHECK_EQUAL(ws2[w].get(), 100.0); UDQSet scalar = UDQSet::scalar("NAME", 1.0); BOOST_CHECK_EQUAL(scalar.size() , 1); - BOOST_CHECK_EQUAL(scalar[0].value(), 1.0); + BOOST_CHECK_EQUAL(scalar[0].get(), 1.0); UDQSet empty = UDQSet::empty("EMPTY"); BOOST_CHECK_EQUAL(empty.size() , 0); @@ -324,13 +284,14 @@ BOOST_AUTO_TEST_CASE(UDQ_GROUP_TEST) { gs.assign("G1", 1.0); const auto& value = gs["G1"]; - BOOST_CHECK_EQUAL(value.value(), 1.0); + BOOST_CHECK_EQUAL(value.get(), 1.0); { UDQParams udqp; UDQFunctionTable udqft(udqp); UDQDefine def_fopr(udqp, "FUOPR", {"SUM", "(", "GOPR", ")"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_group_var("G1", "GOPR", 1.0); st.update_group_var("G2", "GOPR", 2.0); @@ -339,7 +300,7 @@ BOOST_AUTO_TEST_CASE(UDQ_GROUP_TEST) { auto res = def_fopr.eval(context); - BOOST_CHECK_EQUAL(res[0].value(), 10.0); + BOOST_CHECK_EQUAL(res[0].get(), 10.0); } } @@ -351,21 +312,23 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) { { UDQDefine def(udqp, "WUBHP", {"WBHP"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("W1", "WBHP", 11); st.update_well_var("W2", "WBHP", 2); st.update_well_var("W3", "WBHP", 3); auto res = def.eval(context); BOOST_CHECK_EQUAL(res.size(), 3); - BOOST_CHECK_EQUAL( res["W1"].value(), 11 ); - BOOST_CHECK_EQUAL( res["W2"].value(), 2 ); - BOOST_CHECK_EQUAL( res["W3"].value(), 3 ); + BOOST_CHECK_EQUAL( res["W1"].get(), 11 ); + BOOST_CHECK_EQUAL( res["W2"].get(), 2 ); + BOOST_CHECK_EQUAL( res["W3"].get(), 3 ); } { UDQDefine def(udqp, "WUBHP", {"WBHP" , "'P*'"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WBHP", 1); @@ -374,25 +337,26 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) { st.update_well_var("I2", "WBHP", 2); auto res = def.eval(context); BOOST_CHECK_EQUAL(res.size(), 4); - BOOST_CHECK_EQUAL( res["P1"].value(), 1 ); - BOOST_CHECK_EQUAL( res["P2"].value(), 2 ); + BOOST_CHECK_EQUAL( res["P1"].get(), 1 ); + BOOST_CHECK_EQUAL( res["P2"].get(), 2 ); BOOST_CHECK_EQUAL( res["I1"].defined(), false); BOOST_CHECK_EQUAL( res["I1"].defined(), false); } { UDQDefine def(udqp, "WUBHP", {"NINT" , "(", "WBHP", ")"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WBHP", 4); st.update_well_var("P2", "WBHP", 3); st.update_well_var("I1", "WBHP", 2); st.update_well_var("I2", "WBHP", 1); auto res = def.eval(context); - BOOST_CHECK_EQUAL( res["P1"].value(), 4 ); - BOOST_CHECK_EQUAL( res["P2"].value(), 3 ); - BOOST_CHECK_EQUAL( res["I1"].value(), 2 ); - BOOST_CHECK_EQUAL( res["I2"].value(), 1 ); + BOOST_CHECK_EQUAL( res["P1"].get(), 4 ); + BOOST_CHECK_EQUAL( res["P2"].get(), 3 ); + BOOST_CHECK_EQUAL( res["I1"].get(), 2 ); + BOOST_CHECK_EQUAL( res["I2"].get(), 1 ); } } @@ -581,13 +545,13 @@ ASSIGN WU2 8.0 / BOOST_CHECK_EQUAL(w1.name(), "WU1"); BOOST_CHECK_EQUAL(w2.name(), "WU2"); - BOOST_CHECK_EQUAL( w1["P12"].value(), 4.0 ); + BOOST_CHECK_EQUAL( w1["P12"].get(), 4.0 ); BOOST_CHECK_EQUAL( w1["P1"].defined(), false ); BOOST_CHECK_EQUAL( w1["P2"].defined(), false ); - BOOST_CHECK_EQUAL( w2["P12"].value(), 8.0 ); - BOOST_CHECK_EQUAL( w2["P1"].value(), 8.0 ); - BOOST_CHECK_EQUAL( w2["P2"].value(), 8.0 ); + BOOST_CHECK_EQUAL( w2["P12"].get(), 8.0 ); + BOOST_CHECK_EQUAL( w2["P1"].get(), 8.0 ); + BOOST_CHECK_EQUAL( w2["P2"].get(), 8.0 ); } @@ -597,16 +561,18 @@ BOOST_AUTO_TEST_CASE(UDQ_CONTEXT) { SummaryState st(std::chrono::system_clock::now()); UDQFunctionTable func_table; UDQParams udqp; - UDQContext ctx(func_table, st); - BOOST_CHECK_EQUAL(ctx.get("JAN"), 1.0); + UDQState udq_state(udqp.undefinedValue()); + UDQContext ctx(func_table, st, udq_state); + BOOST_CHECK_EQUAL(*ctx.get("JAN"), 1.0); - BOOST_REQUIRE_THROW(ctx.get("NO_SUCH_KEY"), std::out_of_range); + auto invalid = ctx.get("NO_SUCH_KEY"); + BOOST_CHECK(!invalid.has_value()); for (std::string& key : std::vector({"ELAPSED", "MSUMLINS", "MSUMNEWT", "NEWTON", "TCPU", "TIME", "TIMESTEP"})) BOOST_CHECK_NO_THROW( ctx.get(key) ); - st.update("SUMMARY:KEY", 1.0); - BOOST_CHECK_EQUAL(ctx.get("SUMMARY:KEY") , 1.0 ); + st.update("SX:KEY", 1.0); + BOOST_CHECK_EQUAL(*ctx.get("SX:KEY") , 1.0 ); } BOOST_AUTO_TEST_CASE(UDQ_SET) { @@ -614,14 +580,14 @@ BOOST_AUTO_TEST_CASE(UDQ_SET) { for (const auto& v : s1) { BOOST_CHECK_EQUAL(false, v.defined()); - BOOST_REQUIRE_THROW( v.value(), std::invalid_argument); + BOOST_REQUIRE_THROW( v.get(), std::invalid_argument); } BOOST_CHECK_EQUAL(s1.defined_size(), 0); s1.assign(1); for (const auto& v : s1) { BOOST_CHECK_EQUAL(true, v.defined()); - BOOST_CHECK_EQUAL( v.value(), 1.0); + BOOST_CHECK_EQUAL( v.get(), 1.0); } BOOST_CHECK_EQUAL(s1.defined_size(), s1.size()); @@ -636,7 +602,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SET) { auto s3 = s1 + s2; auto v0 = s3[0]; - BOOST_CHECK_EQUAL(v0.value(), 25); + BOOST_CHECK_EQUAL(v0.get(), 25); auto v4 = s3[4]; BOOST_CHECK( !v4.defined() ); @@ -648,17 +614,17 @@ BOOST_AUTO_TEST_CASE(UDQ_SET) { UDQSet s4 = s1 - 1.0; for (const auto& v : s2) { BOOST_CHECK_EQUAL(true, v.defined()); - BOOST_CHECK_EQUAL( v.value(), 2.0); + BOOST_CHECK_EQUAL( v.get(), 2.0); } for (const auto& v : s3) { BOOST_CHECK_EQUAL(true, v.defined()); - BOOST_CHECK_EQUAL( v.value(), 4.0); + BOOST_CHECK_EQUAL( v.get(), 4.0); } for (const auto& v : s4) { BOOST_CHECK_EQUAL(true, v.defined()); - BOOST_CHECK_EQUAL( v.value(), 0); + BOOST_CHECK_EQUAL( v.get(), 0); } } } @@ -675,47 +641,47 @@ BOOST_AUTO_TEST_CASE(UDQ_FUNCTION_TABLE) { { const auto& func = dynamic_cast(udqft.get("SUM")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), 7); + BOOST_CHECK_EQUAL(result[0].get(), 7); } { const auto& func = dynamic_cast(udqft.get("NORM1")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), 7); + BOOST_CHECK_EQUAL(result[0].get(), 7); } { const auto& func = dynamic_cast(udqft.get("NORM2")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), std::sqrt(1 + 4+ 16)); + BOOST_CHECK_EQUAL(result[0].get(), std::sqrt(1 + 4+ 16)); } { const auto& func = dynamic_cast(udqft.get("NORMI")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), 4); + BOOST_CHECK_EQUAL(result[0].get(), 4); } { const auto& func = dynamic_cast(udqft.get("MIN")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), 1); + BOOST_CHECK_EQUAL(result[0].get(), 1); } { const auto& func = dynamic_cast(udqft.get("MAX")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), 4); + BOOST_CHECK_EQUAL(result[0].get(), 4); } { const auto& func = dynamic_cast(udqft.get("AVEA")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), 7.0/3); + BOOST_CHECK_EQUAL(result[0].get(), 7.0/3); } { const auto& func = dynamic_cast(udqft.get("AVEG")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), std::exp((std::log(1) + std::log(2.0) + std::log(4))/3)); + BOOST_CHECK_EQUAL(result[0].get(), std::exp((std::log(1) + std::log(2.0) + std::log(4))/3)); } { const auto& func = dynamic_cast(udqft.get("PROD")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL(result[0].value(), 8.0); + BOOST_CHECK_EQUAL(result[0].get(), 8.0); } { UDQSet arg2("NAME", 4); @@ -724,7 +690,7 @@ BOOST_AUTO_TEST_CASE(UDQ_FUNCTION_TABLE) { arg2.assign(3,4); const auto& func = dynamic_cast(udqft.get("AVEH")); auto result = func.eval(arg2); - BOOST_CHECK_EQUAL(result[0].value(), 2.0); + BOOST_CHECK_EQUAL(result[0].get(), 2.0); } } @@ -748,36 +714,36 @@ BOOST_AUTO_TEST_CASE(CMP_FUNCTIONS) { auto result = UDQBinaryFunction::EQ(0, arg1, arg2); BOOST_CHECK_EQUAL( result.defined_size(), 3 ); - BOOST_CHECK_EQUAL( result[0].value(), 0); - BOOST_CHECK_EQUAL( result[2].value(), 0); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 0); + BOOST_CHECK_EQUAL( result[2].get(), 0); + BOOST_CHECK_EQUAL( result[4].get(), 1); result = UDQBinaryFunction::EQ(0.20, arg1, arg2); - BOOST_CHECK_EQUAL( result[0].value(), 1); - BOOST_CHECK_EQUAL( result[2].value(), 0); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 1); + BOOST_CHECK_EQUAL( result[2].get(), 0); + BOOST_CHECK_EQUAL( result[4].get(), 1); const auto& func = dynamic_cast(udqft.get("==")); result = func.eval(arg1, arg2); - BOOST_CHECK_EQUAL( result[0].value(), 0); - BOOST_CHECK_EQUAL( result[2].value(), 0); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 0); + BOOST_CHECK_EQUAL( result[2].get(), 0); + BOOST_CHECK_EQUAL( result[4].get(), 1); } { const auto& func = dynamic_cast(udqft.get("<")); auto result = func.eval(arg1, arg2); BOOST_CHECK_EQUAL( result.defined_size(), 3 ); - BOOST_CHECK_EQUAL( result[0].value(), 0); - BOOST_CHECK_EQUAL( result[2].value(), 1); - BOOST_CHECK_EQUAL( result[4].value(), 0); + BOOST_CHECK_EQUAL( result[0].get(), 0); + BOOST_CHECK_EQUAL( result[2].get(), 1); + BOOST_CHECK_EQUAL( result[4].get(), 0); } { const auto& func = dynamic_cast(udqft.get(">")); auto result = func.eval(arg1, arg2); BOOST_CHECK_EQUAL( result.defined_size(), 3 ); - BOOST_CHECK_EQUAL( result[0].value(), 1); - BOOST_CHECK_EQUAL( result[2].value(), 0); - BOOST_CHECK_EQUAL( result[4].value(), 0); + BOOST_CHECK_EQUAL( result[0].get(), 1); + BOOST_CHECK_EQUAL( result[2].get(), 0); + BOOST_CHECK_EQUAL( result[4].get(), 0); } { const auto& func = dynamic_cast(udqft.get("^")); @@ -790,29 +756,38 @@ BOOST_AUTO_TEST_CASE(CMP_FUNCTIONS) { } auto result = func.eval(arg1_local, arg2_local); for (std::size_t i=0; i < arg1_local.size(); i++) - BOOST_CHECK_EQUAL( result[i].value(), (i+1)*(i+1)); + BOOST_CHECK_EQUAL( result[i].get(), (i+1)*(i+1)); } { auto result = UDQBinaryFunction::GE(1.0, arg1, arg2); - BOOST_CHECK_EQUAL( result[0].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 1); // This is bisarre - but due to the large epsilon 2 and 2.5 compare as // equal; and then we evaluate 2 >= 2.5 as TRUE! - BOOST_CHECK_EQUAL( result[2].value(), 1); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[2].get(), 1); + BOOST_CHECK_EQUAL( result[4].get(), 1); } { const auto& func = dynamic_cast(udqft.get("<=")); auto result = func.eval(arg1, arg2); - BOOST_CHECK_EQUAL( result[0].value(), 0); - BOOST_CHECK_EQUAL( result[2].value(), 1); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 0); + BOOST_CHECK_EQUAL( result[2].get(), 1); + BOOST_CHECK_EQUAL( result[4].get(), 1); } } +BOOST_AUTO_TEST_CASE(CMP_FUNCTIONS2) { + UDQFunctionTable udqft; + auto arg1 = UDQSet::scalar("NAME", 0); + auto arg2 = UDQSet::scalar("NAME", 0); + + auto eq = UDQBinaryFunction::EQ(0, arg1, arg2); + BOOST_CHECK_EQUAL(eq[0].get(), 1); +} + BOOST_AUTO_TEST_CASE(ELEMENTAL_UNARY_FUNCTIONS) { UDQFunctionTable udqft; @@ -828,39 +803,39 @@ BOOST_AUTO_TEST_CASE(ELEMENTAL_UNARY_FUNCTIONS) { arg2.assign(2,-2); arg2.assign(4,4); auto result = func.eval(arg2); - BOOST_CHECK_EQUAL( result[0].value(), 1); - BOOST_CHECK_EQUAL( result[2].value(), 2); - BOOST_CHECK_EQUAL( result[4].value(), 4); + BOOST_CHECK_EQUAL( result[0].get(), 1); + BOOST_CHECK_EQUAL( result[2].get(), 2); + BOOST_CHECK_EQUAL( result[4].get(), 4); } { const auto& func = dynamic_cast(udqft.get("DEF")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL( result[0].value(), 1); - BOOST_CHECK_EQUAL( result[2].value(), 1); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 1); + BOOST_CHECK_EQUAL( result[2].get(), 1); + BOOST_CHECK_EQUAL( result[4].get(), 1); } { const auto& func = dynamic_cast(udqft.get("UNDEF")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL( result[1].value(), 1); - BOOST_CHECK_EQUAL( result[3].value(), 1); + BOOST_CHECK_EQUAL( result[1].get(), 1); + BOOST_CHECK_EQUAL( result[3].get(), 1); BOOST_CHECK_EQUAL( result.defined_size(), 2); } { const auto& func = dynamic_cast(udqft.get("EXP")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL( result[0].value(), std::exp(1)); - BOOST_CHECK_EQUAL( result[2].value(), std::exp(2)); - BOOST_CHECK_EQUAL( result[4].value(), std::exp(4)); + BOOST_CHECK_EQUAL( result[0].get(), std::exp(1)); + BOOST_CHECK_EQUAL( result[2].get(), std::exp(2)); + BOOST_CHECK_EQUAL( result[4].get(), std::exp(4)); } { const auto& func = dynamic_cast(udqft.get("IDV")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL( result[0].value(), 1); - BOOST_CHECK_EQUAL( result[1].value(), 0); - BOOST_CHECK_EQUAL( result[2].value(), 1); - BOOST_CHECK_EQUAL( result[3].value(), 0); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 1); + BOOST_CHECK_EQUAL( result[1].get(), 0); + BOOST_CHECK_EQUAL( result[2].get(), 1); + BOOST_CHECK_EQUAL( result[3].get(), 0); + BOOST_CHECK_EQUAL( result[4].get(), 1); } { const auto& func = dynamic_cast(udqft.get("LOG")); @@ -869,9 +844,9 @@ BOOST_AUTO_TEST_CASE(ELEMENTAL_UNARY_FUNCTIONS) { arg_local.assign(2,1000); auto result = func.eval(arg_local); - BOOST_CHECK_EQUAL( result[0].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 1); BOOST_CHECK( !result[1] ); - BOOST_CHECK_EQUAL( result[2].value(), 3); + BOOST_CHECK_EQUAL( result[2].get(), 3); } { const auto& func = dynamic_cast(udqft.get("NINT")); @@ -880,9 +855,9 @@ BOOST_AUTO_TEST_CASE(ELEMENTAL_UNARY_FUNCTIONS) { arg_local.assign(2, 1.25); auto result = func.eval(arg_local); - BOOST_CHECK_EQUAL( result[0].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 1); BOOST_CHECK( !result[1] ); - BOOST_CHECK_EQUAL( result[2].value(), 1); + BOOST_CHECK_EQUAL( result[2].get(), 1); } { const auto& func = dynamic_cast(udqft.get("RANDN")); @@ -892,32 +867,32 @@ BOOST_AUTO_TEST_CASE(ELEMENTAL_UNARY_FUNCTIONS) { auto result1 = func.eval(arg_local); auto result2 = func.eval(arg_local); - BOOST_CHECK( result1[0].value() != -1.0); + BOOST_CHECK( result1[0].get() != -1.0); BOOST_CHECK( !result1[1] ); - BOOST_CHECK( result1[2].value() != -1.0); + BOOST_CHECK( result1[2].get() != -1.0); - BOOST_CHECK( result1[0].value() != result2[0].value()); - BOOST_CHECK( result1[2].value() != result2[2].value()); + BOOST_CHECK( result1[0].get() != result2[0].get()); + BOOST_CHECK( result1[2].get() != result2[2].get()); } { const auto& func = dynamic_cast(udqft.get("SORTA")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL( result[0].value(), 1); + BOOST_CHECK_EQUAL( result[0].get(), 1); BOOST_CHECK( !result[1] ); - BOOST_CHECK_EQUAL( result[2].value(), 2); + BOOST_CHECK_EQUAL( result[2].get(), 2); BOOST_CHECK( !result[3] ); - BOOST_CHECK_EQUAL( result[4].value(), 3); + BOOST_CHECK_EQUAL( result[4].get(), 3); } { const auto& func = dynamic_cast(udqft.get("SORTD")); auto result = func.eval(arg); - BOOST_CHECK_EQUAL( result[0].value(), 3); + BOOST_CHECK_EQUAL( result[0].get(), 3); BOOST_CHECK( !result[1] ); - BOOST_CHECK_EQUAL( result[2].value(), 2); + BOOST_CHECK_EQUAL( result[2].get(), 2); BOOST_CHECK( !result[3] ); - BOOST_CHECK_EQUAL( result[4].value(), 1); + BOOST_CHECK_EQUAL( result[4].get(), 1); } } @@ -936,9 +911,9 @@ BOOST_AUTO_TEST_CASE(UNION_FUNCTIONS) { const auto& func = dynamic_cast(udqft.get("UADD")); auto result = func.eval(arg1, arg2); BOOST_CHECK_EQUAL( 3, result.defined_size() ); - BOOST_CHECK_EQUAL( 2, result[0].value() ); - BOOST_CHECK_EQUAL( 2, result[2].value() ); - BOOST_CHECK_EQUAL( 3, result[3].value() ); + BOOST_CHECK_EQUAL( 2, result[0].get() ); + BOOST_CHECK_EQUAL( 2, result[2].get() ); + BOOST_CHECK_EQUAL( 3, result[3].get() ); } @@ -961,9 +936,9 @@ BOOST_AUTO_TEST_CASE(UDQ_SET_DIV) { auto result = 10 / s; BOOST_CHECK_EQUAL( result.defined_size(), 3); - BOOST_CHECK_EQUAL( result[0].value(), 10); - BOOST_CHECK_EQUAL( result[2].value(), 5); - BOOST_CHECK_EQUAL( result[4].value(), 2); + BOOST_CHECK_EQUAL( result[0].get(), 10); + BOOST_CHECK_EQUAL( result[2].get(), 5); + BOOST_CHECK_EQUAL( result[4].get(), 2); } @@ -976,17 +951,17 @@ BOOST_AUTO_TEST_CASE(UDQASSIGN_TEST) { auto res1 = as1.eval(ws1); BOOST_CHECK_EQUAL(res1.size(), 4); - BOOST_CHECK_EQUAL(res1["P1"].value(), 1.0); - BOOST_CHECK_EQUAL(res1["I2"].value(), 1.0); + BOOST_CHECK_EQUAL(res1["P1"].get(), 1.0); + BOOST_CHECK_EQUAL(res1["I2"].get(), 1.0); auto res2 = as2.eval(ws1); - BOOST_CHECK_EQUAL(res2["P1"].value(), 2.0); - BOOST_CHECK_EQUAL(res2["P2"].value(), 2.0); + BOOST_CHECK_EQUAL(res2["P1"].get(), 2.0); + BOOST_CHECK_EQUAL(res2["P2"].get(), 2.0); BOOST_CHECK(!res2["I1"].defined()); BOOST_CHECK(!res2["I2"].defined()); auto res3 = as3.eval(ws1); - BOOST_CHECK_EQUAL(res3["P1"].value(), 4.0); + BOOST_CHECK_EQUAL(res3["P1"].get(), 4.0); BOOST_CHECK(!res3["P2"].defined()); BOOST_CHECK(!res3["I1"].defined()); BOOST_CHECK(!res3["I2"].defined()); @@ -998,7 +973,8 @@ BOOST_AUTO_TEST_CASE(UDQ_POW_TEST) { UDQDefine def_pow1(udqp, "WU", {"WOPR", "+", "WWPR", "*", "WGOR", "^", "WWIR"}); UDQDefine def_pow2(udqp, "WU", {"(", "WOPR", "+", "WWPR", ")", "^", "(", "WOPR", "+" , "WGOR", "*", "WWIR", "-", "WOPT", ")"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WOPR", 1); st.update_well_var("P1", "WWPR", 2); @@ -1008,8 +984,8 @@ BOOST_AUTO_TEST_CASE(UDQ_POW_TEST) { auto res_pow1 = def_pow1.eval(context); auto res_pow2 = def_pow2.eval(context); - BOOST_CHECK_EQUAL( res_pow1["P1"].value() , 1 + 2 * std::pow(3,4)); - BOOST_CHECK_EQUAL( res_pow2["P1"].value() , std::pow(1 + 2, 1 + 3*4 - 7)); + BOOST_CHECK_EQUAL( res_pow1["P1"].get() , 1 + 2 * std::pow(3,4)); + BOOST_CHECK_EQUAL( res_pow2["P1"].get() , std::pow(1 + 2, 1 + 3*4 - 7)); } BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) { @@ -1017,7 +993,8 @@ BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) { UDQParams udqp; UDQDefine def_cmp(udqp, "WU", {"WOPR", ">", "WWPR", "+", "WGOR", "*", "WWIR"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WOPR", 0); st.update_well_var("P1", "WWPR", 10); @@ -1030,8 +1007,8 @@ BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) { st.update_well_var("P2", "WWIR", 1); auto res_cmp = def_cmp.eval(context); - BOOST_CHECK_EQUAL( res_cmp["P1"].value() , 1.0); - BOOST_CHECK_EQUAL( res_cmp["P2"].value() , 0.0); + BOOST_CHECK_EQUAL( res_cmp["P1"].get() , 1.0); + BOOST_CHECK_EQUAL( res_cmp["P2"].get() , 0.0); } /*BOOST_AUTO_TEST_CASE(UDQPARSE_ERROR) { @@ -1044,7 +1021,8 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) { UDQParams udqp; UDQFunctionTable udqft; SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WOPR", 1); st.update_well_var("P2", "WOPR", 2); @@ -1062,7 +1040,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) { BOOST_CHECK_EQUAL(4, res.size()); auto well1 = res["P1"]; BOOST_CHECK( well1.defined() ); - BOOST_CHECK_EQUAL(well1.value() , 1); + BOOST_CHECK_EQUAL(well1.get() , 1); auto well2 = res["P2"]; BOOST_CHECK( !well2.defined() ); @@ -1076,15 +1054,15 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) { BOOST_CHECK_EQUAL(4, res.size()); auto well1 = res["P1"]; BOOST_CHECK( well1.defined() ); - BOOST_CHECK_EQUAL(well1.value() , 1); + BOOST_CHECK_EQUAL(well1.get() , 1); auto well2 = res["P2"]; BOOST_CHECK( well2.defined() ); - BOOST_CHECK_EQUAL(well2.value() , 1); + BOOST_CHECK_EQUAL(well2.get() , 1); auto well4 = res["P4"]; BOOST_CHECK( well4.defined() ); - BOOST_CHECK_EQUAL(well4.value() , 1); + BOOST_CHECK_EQUAL(well4.get() , 1); } { UDQDefine def(udqp, "WUOPR", {"WOPR", "'P1'"}); @@ -1092,15 +1070,15 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) { BOOST_CHECK_EQUAL(4, res.size()); auto well1 = res["P1"]; BOOST_CHECK( well1.defined() ); - BOOST_CHECK_EQUAL(well1.value() , 1); + BOOST_CHECK_EQUAL(well1.get() , 1); auto well2 = res["P2"]; BOOST_CHECK( well2.defined() ); - BOOST_CHECK_EQUAL(well2.value() , 1); + BOOST_CHECK_EQUAL(well2.get() , 1); auto well4 = res["P4"]; BOOST_CHECK( well4.defined() ); - BOOST_CHECK_EQUAL(well4.value() , 1); + BOOST_CHECK_EQUAL(well4.get() , 1); BOOST_CHECK_EQUAL( "WUOPR", res.name() ); } @@ -1112,7 +1090,8 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTD_NAN) { UDQDefine def(udqp, "WUPR1" , {"1", "/", "(", "WWIR", "'OP*'" , ")"}); UDQDefine def_sort(udqp , "WUPR3", {"SORTD", "(", "WUPR1", ")" }); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("OP1", "WWIR", 1.0); st.update_well_var("OP2", "WWIR", 2.0); @@ -1120,31 +1099,29 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTD_NAN) { st.update_well_var("OP4", "WWIR", 4.0); auto res1 = def.eval(context); - st.update_udq( res1 ); + st.update_udq( res1, 0 ); auto res_sort1 = def_sort.eval(context); - st.update_udq( res_sort1 ); - BOOST_CHECK_EQUAL(res_sort1["OP1"].value(), 1.0); - BOOST_CHECK_EQUAL(res_sort1["OP2"].value(), 2.0); - BOOST_CHECK_EQUAL(res_sort1["OP3"].value(), 3.0); - BOOST_CHECK_EQUAL(res_sort1["OP4"].value(), 4.0); + st.update_udq( res_sort1 , 0); + BOOST_CHECK_EQUAL(res_sort1["OP1"].get(), 1.0); + BOOST_CHECK_EQUAL(res_sort1["OP2"].get(), 2.0); + BOOST_CHECK_EQUAL(res_sort1["OP3"].get(), 3.0); + BOOST_CHECK_EQUAL(res_sort1["OP4"].get(), 4.0); BOOST_CHECK( st.has_well_var("OP1", "WUPR3")); BOOST_CHECK( st.has_well_var("OP4", "WUPR3")); st.update_well_var("OP1", "WWIR", 0); auto res2 = def.eval(context); BOOST_CHECK_EQUAL(res2.defined_size(), 3); - st.update_udq( res2 ); - BOOST_CHECK( !st.has_well_var("OP1", "WUPR1")); + st.update_udq( res2, 0 ); BOOST_CHECK( st.has_well_var("OP4", "WUPR1")); auto res_sort2 = def_sort.eval(context); - st.update_udq( res_sort2 ); + st.update_udq( res_sort2, 0 ); BOOST_CHECK_EQUAL(res_sort2.defined_size(), 3); - BOOST_CHECK_EQUAL(res_sort2["OP2"].value(), 1.0); - BOOST_CHECK_EQUAL(res_sort2["OP3"].value(), 2.0); - BOOST_CHECK_EQUAL(res_sort2["OP4"].value(), 3.0); - BOOST_CHECK( !st.has_well_var("OP1", "WUPR3")); + BOOST_CHECK_EQUAL(res_sort2["OP2"].get(), 1.0); + BOOST_CHECK_EQUAL(res_sort2["OP3"].get(), 2.0); + BOOST_CHECK_EQUAL(res_sort2["OP4"].get(), 3.0); BOOST_CHECK( st.has_well_var("OP4", "WUPR3")); } @@ -1156,7 +1133,8 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA) { UDQDefine def1(udqp, "WUPR1" , {"1", "/", "(", "WWCT", "'OP*'", "+", "0.00001", ")"}); UDQDefine def_sort(udqp , "WUPR3", {"SORTA", "(", "WUPR1", ")" }); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("OPL01", "WWCT", 0.7); st.update_well_var("OPL02", "WWCT", 0.8); @@ -1164,15 +1142,15 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA) { st.update_well_var("OPU02", "WWCT", 0.0); auto res1 = def1.eval(context); - st.update_well_var("OPL01", "WUPR1", res1["OPL01"].value()); - st.update_well_var("OPL02", "WUPR1", res1["OPL02"].value()); - st.update_well_var("OPU01", "WUPR1", res1["OPU01"].value()); - st.update_well_var("OPU02", "WUPR1", res1["OPU02"].value()); + st.update_well_var("OPL01", "WUPR1", res1["OPL01"].get()); + st.update_well_var("OPL02", "WUPR1", res1["OPL02"].get()); + st.update_well_var("OPU01", "WUPR1", res1["OPU01"].get()); + st.update_well_var("OPU02", "WUPR1", res1["OPU02"].get()); auto res_sort = def_sort.eval(context); - BOOST_CHECK_EQUAL(res_sort["OPL02"].value(), 1.0); - BOOST_CHECK_EQUAL(res_sort["OPL01"].value(), 2.0); - BOOST_CHECK_EQUAL(res_sort["OPU01"].value() + res_sort["OPU02"].value(), 7.0); + BOOST_CHECK_EQUAL(res_sort["OPL02"].get(), 1.0); + BOOST_CHECK_EQUAL(res_sort["OPL01"].get(), 2.0); + BOOST_CHECK_EQUAL(res_sort["OPU01"].get() + res_sort["OPU02"].get(), 7.0); } @@ -1187,7 +1165,8 @@ BOOST_AUTO_TEST_CASE(UDQ_BASIC_MATH_TEST) { UDQDefine def_muladd(udqp , "WUX", {"WOPR", "+", "WOPR", "*", "WOPR"}); UDQDefine def_wuwct(udqp , "WUWCT", {"WWPR", "/", "(", "WOPR", "+", "WWPR", ")"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WOPR", 1); st.update_well_var("P2", "WOPR", 2); @@ -1201,45 +1180,45 @@ BOOST_AUTO_TEST_CASE(UDQ_BASIC_MATH_TEST) { auto res_add = def_add.eval(context); BOOST_CHECK_EQUAL( res_add.size(), 4); - BOOST_CHECK_EQUAL( res_add["P1"].value(), 2); - BOOST_CHECK_EQUAL( res_add["P2"].value(), 4); - BOOST_CHECK_EQUAL( res_add["P3"].value(), 6); - BOOST_CHECK_EQUAL( res_add["P4"].value(), 8); + BOOST_CHECK_EQUAL( res_add["P1"].get(), 2); + BOOST_CHECK_EQUAL( res_add["P2"].get(), 4); + BOOST_CHECK_EQUAL( res_add["P3"].get(), 6); + BOOST_CHECK_EQUAL( res_add["P4"].get(), 8); auto res_sub = def_sub.eval(context); BOOST_CHECK_EQUAL( res_sub.size(), 4); - BOOST_CHECK_EQUAL( res_sub["P1"].value(), 0); - BOOST_CHECK_EQUAL( res_sub["P2"].value(), 0); - BOOST_CHECK_EQUAL( res_sub["P3"].value(), 0); - BOOST_CHECK_EQUAL( res_sub["P4"].value(), 0); + BOOST_CHECK_EQUAL( res_sub["P1"].get(), 0); + BOOST_CHECK_EQUAL( res_sub["P2"].get(), 0); + BOOST_CHECK_EQUAL( res_sub["P3"].get(), 0); + BOOST_CHECK_EQUAL( res_sub["P4"].get(), 0); auto res_div = def_div.eval(context); BOOST_CHECK_EQUAL( res_div.size(), 4); - BOOST_CHECK_EQUAL( res_div["P1"].value(), 1); - BOOST_CHECK_EQUAL( res_div["P2"].value(), 1); - BOOST_CHECK_EQUAL( res_div["P3"].value(), 1); - BOOST_CHECK_EQUAL( res_div["P4"].value(), 1); + BOOST_CHECK_EQUAL( res_div["P1"].get(), 1); + BOOST_CHECK_EQUAL( res_div["P2"].get(), 1); + BOOST_CHECK_EQUAL( res_div["P3"].get(), 1); + BOOST_CHECK_EQUAL( res_div["P4"].get(), 1); auto res_mul = def_mul.eval(context); BOOST_CHECK_EQUAL( res_mul.size(), 4); - BOOST_CHECK_EQUAL( res_mul["P1"].value(), 1); - BOOST_CHECK_EQUAL( res_mul["P2"].value(), 4); - BOOST_CHECK_EQUAL( res_mul["P3"].value(), 9); - BOOST_CHECK_EQUAL( res_mul["P4"].value(),16); + BOOST_CHECK_EQUAL( res_mul["P1"].get(), 1); + BOOST_CHECK_EQUAL( res_mul["P2"].get(), 4); + BOOST_CHECK_EQUAL( res_mul["P3"].get(), 9); + BOOST_CHECK_EQUAL( res_mul["P4"].get(),16); auto res_muladd = def_muladd.eval(context); BOOST_CHECK_EQUAL( res_muladd.size(), 4); - BOOST_CHECK_EQUAL( res_muladd["P1"].value(), 1 + 1); - BOOST_CHECK_EQUAL( res_muladd["P2"].value(), 4 + 2); - BOOST_CHECK_EQUAL( res_muladd["P3"].value(), 9 + 3); - BOOST_CHECK_EQUAL( res_muladd["P4"].value(),16 + 4); + BOOST_CHECK_EQUAL( res_muladd["P1"].get(), 1 + 1); + BOOST_CHECK_EQUAL( res_muladd["P2"].get(), 4 + 2); + BOOST_CHECK_EQUAL( res_muladd["P3"].get(), 9 + 3); + BOOST_CHECK_EQUAL( res_muladd["P4"].get(),16 + 4); auto res_wuwct= def_wuwct.eval(context); BOOST_CHECK_EQUAL( res_wuwct.size(), 4); - BOOST_CHECK_EQUAL( res_wuwct["P1"].value(),0.50); - BOOST_CHECK_EQUAL( res_wuwct["P2"].value(),0.50); - BOOST_CHECK_EQUAL( res_wuwct["P3"].value(),0.50); - BOOST_CHECK_EQUAL( res_wuwct["P4"].value(),0.50); + BOOST_CHECK_EQUAL( res_wuwct["P1"].get(),0.50); + BOOST_CHECK_EQUAL( res_wuwct["P2"].get(),0.50); + BOOST_CHECK_EQUAL( res_wuwct["P3"].get(),0.50); + BOOST_CHECK_EQUAL( res_wuwct["P4"].get(),0.50); } BOOST_AUTO_TEST_CASE(DECK_TEST) { @@ -1247,7 +1226,8 @@ BOOST_AUTO_TEST_CASE(DECK_TEST) { UDQFunctionTable udqft(udqp); UDQDefine def(udqp, "WUOPRL", {"(", "WOPR", "OP1", "-", "150", ")", "*", "0.90"}); SummaryState st(std::chrono::system_clock::now()); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("OP1", "WOPR", 300); st.update_well_var("OP2", "WOPR", 3000); @@ -1256,7 +1236,7 @@ BOOST_AUTO_TEST_CASE(DECK_TEST) { auto res = def.eval(context); BOOST_CHECK_EQUAL(res.size(), 3); for (std::size_t index = 0; index < res.size(); index++) - BOOST_CHECK( res[index].value() == (300 - 150)*0.90); + BOOST_CHECK( res[index].get() == (300 - 150)*0.90); } @@ -1280,11 +1260,12 @@ BOOST_AUTO_TEST_CASE(UDQ_PARSE_ERROR) { UDQDefine def1(udqp, "WUBHP", tokens, parseContext, errors); SummaryState st(std::chrono::system_clock::now()); UDQFunctionTable udqft(udqp); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WBHP", 1); auto res = def1.eval(context); - BOOST_CHECK_EQUAL(res["P1"].value(), udqp.undefinedValue()); + BOOST_CHECK_EQUAL(res["P1"].get(), udqp.undefinedValue()); } parseContext.update(ParseContext::UDQ_PARSE_ERROR, InputError::THROW_EXCEPTION); @@ -1304,17 +1285,18 @@ BOOST_AUTO_TEST_CASE(UDQ_TYPE_ERROR) { SummaryState st(std::chrono::system_clock::now()); UDQFunctionTable udqft(udqp); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("P1", "WBHP", 1); st.update_well_var("P2", "WBHP", 2); auto res1 = def1.eval(context); - BOOST_CHECK_EQUAL(res1[0].value(), udqp.undefinedValue()); + BOOST_CHECK_EQUAL(res1[0].get(), udqp.undefinedValue()); auto res2 = def2.eval(context); BOOST_CHECK_EQUAL(res2.size(), st.num_wells()); for (std::size_t index = 0; index < res2.size(); index++) - BOOST_CHECK_EQUAL(res2[index].value(), 3); + BOOST_CHECK_EQUAL(res2[index].get(), 3); } parseContext.update(ParseContext::UDQ_TYPE_ERROR, InputError::THROW_EXCEPTION); @@ -1686,10 +1668,11 @@ UDQ auto def0 = udq.definitions()[0]; SummaryState st(std::chrono::system_clock::now()); UDQFunctionTable udqft(udqp); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); auto res0 = def0.eval(context); - BOOST_CHECK_CLOSE( res0[0].value(), -0.00125*3, 1e-6); + BOOST_CHECK_CLOSE( res0[0].get(), -0.00125*3, 1e-6); } @@ -1699,7 +1682,7 @@ SCHEDULE UDQ DEFINE FUMIN0 - 1.5*FWPR / DEFINE FUMIN1 - 1.5*FWPR*(FGPR + FOPR)^3 - 2*FLPR / - DEFINE FU -2.539E-14 * (FUP1+FUP2)^3 + 1.4464E-8 *(FUP1+FUP2)^2 +0.00028875*(FUP1+FUP2)+2.8541 / + DEFINE FU -2.539E-14 * (FXP1+FXP2)^3 + 1.4464E-8 *(FXP1+FXP2)^2 +0.00028875*(FXP1+FXP2)+2.8541 / / )"; @@ -1711,29 +1694,30 @@ UDQ auto def2 = udq.definitions()[2]; SummaryState st(std::chrono::system_clock::now()); UDQFunctionTable udqft(udqp); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); const double fwpr = 7; const double fopr = 4; const double fgpr = 7; const double flpr = 13; - const double fup1 = 1025; - const double fup2 = 107; + const double fxp1 = 1025; + const double fxp2 = 107; st.update("FWPR", fwpr); st.update("FOPR", fopr); st.update("FGPR", fgpr); st.update("FLPR", flpr); - st.update("FUP1", fup1); - st.update("FUP2", fup2); + st.update("FXP1", fxp1); + st.update("FXP2", fxp2); auto res0 = def0.eval(context); - BOOST_CHECK_EQUAL( res0[0].value(), -1.5*fwpr); + BOOST_CHECK_EQUAL( res0[0].get(), -1.5*fwpr); auto res1 = def1.eval(context); - BOOST_CHECK_EQUAL( res1[0].value(), -1.5*fwpr*std::pow(fgpr+fopr, 3) - 2*flpr ); + BOOST_CHECK_EQUAL( res1[0].get(), -1.5*fwpr*std::pow(fgpr+fopr, 3) - 2*flpr ); auto res2 = def2.eval(context); - auto right = -2.5394E-14 * std::pow(fup1 + fup2, 3) + 1.4464E-8*std::pow(fup1 + fup2, 2) + 0.00028875*(fup1 + fup2) + 2.8541; - BOOST_CHECK_CLOSE( res2[0].value(), right, 1e-6); + auto right = -2.5394E-14 * std::pow(fxp1 + fxp2, 3) + 1.4464E-8*std::pow(fxp1 + fxp2, 2) + 0.00028875*(fxp1 + fxp2) + 2.8541; + BOOST_CHECK_CLOSE( res2[0].get(), right, 1e-6); } BOOST_AUTO_TEST_CASE(UDQ_STARSTAR) { @@ -1752,7 +1736,8 @@ UDQ auto def1 = udq.definitions()[1]; SummaryState st(std::chrono::system_clock::now()); UDQFunctionTable udqft(udqp); - UDQContext context(udqft, st); + UDQState udq_state(udqp.undefinedValue()); + UDQContext context(udqft, st, udq_state); st.update_well_var("W1", "WOPR", 1); st.update_well_var("W2", "WOPR", 2); st.update_well_var("W3", "WOPR", 3); @@ -1762,14 +1747,14 @@ UDQ st.update_well_var("W3", "WGLIR", 3); auto res0 = def0.eval(context); - BOOST_CHECK_EQUAL( res0["W1"].value(), 1); - BOOST_CHECK_EQUAL( res0["W2"].value(), 4); - BOOST_CHECK_EQUAL( res0["W3"].value(), 9); + BOOST_CHECK_EQUAL( res0["W1"].get(), 1); + BOOST_CHECK_EQUAL( res0["W2"].get(), 4); + BOOST_CHECK_EQUAL( res0["W3"].get(), 9); auto res1 = def1.eval(context); - BOOST_CHECK_EQUAL( res1["W1"].value(), 2); - BOOST_CHECK_EQUAL( res1["W2"].value(), 1); - BOOST_CHECK_EQUAL( res1["W3"].value(), 0); + BOOST_CHECK_EQUAL( res1["W1"].get(), 2); + BOOST_CHECK_EQUAL( res1["W2"].get(), 1); + BOOST_CHECK_EQUAL( res1["W3"].get(), 0); } @@ -1789,7 +1774,9 @@ UDQ auto schedule = make_schedule(deck_string); const auto& udq = schedule.getUDQConfig(0); SummaryState st(std::chrono::system_clock::now()); - udq.eval(st); + auto undefined_value = udq.params().undefinedValue(); + UDQState udq_state(undefined_value); + udq.eval(st, udq_state); BOOST_CHECK_EQUAL( st.get("FU_UADD"), 12); // 10 + 2 @@ -1813,12 +1800,80 @@ DEFINE FU_PAR2 FU_PAR3 / auto schedule = make_schedule(deck_string); const auto& udq = schedule.getUDQConfig(0); SummaryState st(std::chrono::system_clock::now()); + auto undefined_value = udq.params().undefinedValue(); + UDQState udq_state(undefined_value); st.update("FMWPR", 100); - udq.eval(st); + udq.eval(st, udq_state); BOOST_CHECK_EQUAL(st.get("FU_PAR2"), 100); } +BOOST_AUTO_TEST_CASE(UDQ_UNDEFINED2) { + std::string deck_string = R"( +SCHEDULE +UDQ +DEFINE FU_PAR2 FU_PAR1 + 1/ +DEFINE FU_PAR3 FU_PAR2 + 1/ +/ +)"; + auto schedule = make_schedule(deck_string); + const auto& udq = schedule.getUDQConfig(0); + SummaryState st(std::chrono::system_clock::now()); + auto undefined_value = udq.params().undefinedValue(); + UDQState udq_state(undefined_value); + udq.eval(st, udq_state); + + BOOST_CHECK_EQUAL(st.get("FU_PAR2"), undefined_value); + BOOST_CHECK_EQUAL(st.get("FU_PAR3"), undefined_value); +} + + + + +BOOST_AUTO_TEST_CASE(UDQSTATE) { + double undefined_value = 1234; + UDQState st(undefined_value); + BOOST_CHECK(!st.has("FUXX")); + BOOST_CHECK(!st.has_well_var("OP1", "WUXX")); + BOOST_CHECK(!st.has_group_var("G1", "GUXX")); + + // Try to get from symbol which is not UDQ -> logic_error + BOOST_CHECK_THROW(st.get("FOPR"), std::logic_error); + + // Try to get from a UDQ which has not registered -> out_of_range + BOOST_CHECK_THROW(st.get("FUPR"), std::out_of_range); + + auto fxpr = UDQSet::scalar("FXPR", 100); + BOOST_CHECK_THROW(st.add("FXPR", fxpr), std::logic_error); + + BOOST_CHECK_THROW(st.get_well_var("OP1", "WUPR"), std::out_of_range); + + auto fupr = UDQSet::scalar("FUPR", 100); + st.add("FUPR", fupr); + + // This is not a well quantity + BOOST_CHECK_THROW(st.get_well_var("OP1", "FUPR"), std::logic_error); + BOOST_CHECK_EQUAL(100, st.get("FUPR")); + + + auto wupr = UDQSet::wells("WUPR", {"P1", "P2"}); + wupr.assign("P1", 75); + st.add("WUPR", wupr); + + BOOST_CHECK(st.has_well_var("P1", "WUPR")); + // We have a well P2 - but we have not assigned a value to it! + BOOST_CHECK(!st.has_well_var("P2", "WUPR")); + + BOOST_CHECK_EQUAL(st.get_well_var("P1", "WUPR"), 75); + BOOST_CHECK_EQUAL(st.get_well_var("P2", "WUPR"), undefined_value); + + const auto buffer = st.serialize(); + UDQState st2(1067); + st2.deserialize( buffer ); + BOOST_CHECK(st == st2); +} + + BOOST_AUTO_TEST_CASE(UDQ_UADD_PARSER2) { std::string deck_string = R"( @@ -1869,6 +1924,202 @@ DEFINE WUGASRA 750000 - WGLIR '*' / / )"; auto schedule = make_schedule(deck_string); + const auto& udq = schedule.getUDQConfig(0); + auto undefined_value = udq.params().undefinedValue(); + UDQState udq_state(undefined_value); + SummaryState st(std::chrono::system_clock::now()); + + st.update("FMWPR", 100); + st.update("FMWIN", 100); + st.update("FMWPA", 100); + st.update("FMWIA", 100); + st.update("FOPR", 100); + st.update_well_var("W1", "WGLIR", 1); + st.update_well_var("W2", "WGLIR", 2); + st.update_well_var("W3", "WGLIR", 3); + + udq.eval(st, udq_state); + + // The current testcase has some ordering & defined / undefined issues which + // are not yet solved; therefor no udq.eval() here. +} + + +BOOST_AUTO_TEST_CASE(UDQ_UNDEFINED) { + std::string deck_string = R"( +-- udq #2 +UDQ +----XX xxxx xxx +--xxxx xxxx xxxx xxxx +ASSIGN FU_VAR1 0 / +DEFINE FU_VAR1 -2.539E-14 * (FU_VAR91+FU_VAR90)^3 + 1.4464E-8 *(FU_VAR91+FU_VAR90)^2 +0.00028875*(FU_VAR91+FU_VAR90)+2.8541 / +--xxxx xx xxxx xxx xxxx xxxx +ASSIGN FU_VAR2 0 / +DEFINE FU_VAR3 FU_VAR1 > 10 / +DEFINE FU_VAR2 NINT(FU_VAR91 / 35000 + 0.499) * FU_VAR3 / +--xxxx xxx XX xxx xxxx xxxx +ASSIGN FU_VAR4 0 / +--Xxxx xxx XX xxx xxxx, xxxx +ASSIGN FU_VAR5 0 / +DEFINE FU_VAR6 FU_VAR2 != 0 / +DEFINE FU_VAR7 FU_VAR6 * FU_VAR2 - 999 * (1 - FU_VAR6) / --Avoiding div by 0 +DEFINE FU_VAR5 FU_VAR6 * FU_VAR91 / FU_VAR7 / 24 / 0.95 / +--Xxx xxx XX xxx xxx, xxxxx +DEFINE FU_VAR8 FU_VAR4 != 0 / +ASSIGN FU_VAR9 0 / +--XX Xxx xxxxx xxxxx xxxxx +ASSIGN FU_VAR10 0 / +DEFINE FU_VAR10 -0.00000041232 * FU_VAR5 ^ 2 + 0.0010395 * FU_VAR5 + 0.16504 / +--XX xxx xxxxx xxxxx xxxxx +ASSIGN FU_VAR11 0 / +--xxxxx xxxxx xxxxx xxxxx, xX +ASSIGN FU_VAR12 0 / +ASSIGN FU_VAR13 0 / +ASSIGN FU_VAR14 0 / +DEFINE FU_VAR12 FU_VAR2 * FU_VAR5 * 1E5 * ((FU_VAR1 - 10) / 3600) / 1000 / FU_VAR10 / 0.8938 / +DEFINE FU_VAR14 FU_VAR12 + FU_VAR13 / + +-----Xxxxx xxxxx xxxxx +--xxxxx xx XX xxxxx xxxxx xxxxx +ASSIGN FU_VAR15 0 / +DEFINE FU_VAR15 NINT((FU_P1SWI + FU_P1WPR) / 30000 + 0.499) / +--xxxxx xx XX xxxxx xxxxx xxxxx +ASSIGN FU_VAR16 0 / +--xxxx xx XX XZ, xx/x +ASSIGN FU_VAR17 0 / +DEFINE FU_VAR18 FU_VAR15 != 0 / +DEFINE FU_VAR17 FU_P1WPB * (FU_P1WPR + FU_P1SWI) / (FU_VAR15 + 0.0001) / 24 / 0.95 / +--xxxx xxx xxxx xxxx xxxx, xxxx +DEFINE FU_VAR19 FU_VAR16 != 0 / +ASSIGN FU_VAR20 0 / +--xxxx xxxx xxxx xxxx +ASSIGN FU_VAR21 0 / +DEFINE FU_VAR21 -0.00000035417*FU_VAR17^2 +0.0010673*FU_VAR17 + 0.029286 / +--XX xxxx xxxx xxxx +ASSIGN FU_VAR22 0 / +--XX XX xxxx xxxx, xX +ASSIGN FU_VAR23 0 / +DEFINE FU_VAR23 FU_VAR15 * FU_VAR17 * 1E5 * ((150-10)/3600) / 1000 / FU_VAR21 / 0.8938 / +--xx XX xx xx, xX +ASSIGN FU_VAR24 0 / +--xxxx xxxx xxxx xxxx, xxxx +DEFINE FU_VAR25 FU_VAR23 + FU_VAR24 / + +-----xxxx xxxx +--xxxx xxxx xxxx, X xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx +ASSIGN FU_VAR26 0 / +--xxxx xxxx xxxx xxxx +ASSIGN FU_VAR27 0 / +DEFINE FU_VAR27 ((FU_P1TGP/1E6*4546.667)/0.9215+1474) * (1-FU_VAR26) + ((FU_P1TGP/1E6*4911)/0.9215+1474) * FU_VAR26 / +--xxxx xxxx xxxx xxxx +ASSIGN FU_VAR28 0 / +--xxxx xxxx xxxx +ASSIGN FU_VAR29 0 / +DEFINE FU_VAR29 FU_VAR27 + FU_VAR28 / + +-----xxxx xxxx +ASSIGN FU_VAR30 6682 / +ASSIGN FU_VAR31 0 / +ASSIGN FU_VAR32 4155 / --xxxx xx xxxx xxxx XX xxxx +ASSIGN FU_VAR33 9685 / +ASSIGN FU_VAR34 4000 / +ASSIGN FU_VAR35 1230 / --xxxx xx xxxx xxxx XX xxxx +--Total base load +ASSIGN FU_VAR36 0 / +DEFINE FU_VAR36 FU_P1BL + FU_P2BL + FU_VAR32 + FU_VAR33 + FU_VAR34 + FU_VAR35 / + +-----XX xxxx xxxx +ASSIGN FU_VAR37 2300 / +ASSIGN FU_VAR38 0 / -- xxxxxx xx xxxx xxxx XX xxxx +ASSIGN FU_VAR39 2300 / -- xxxx * Y xxxx xx Z xxxx XX xxxx +-- xxxx xxxx xxxx xxxx +ASSIGN FU_VAR40 0 / +DEFINE FU_VAR40 FU_VAR37 + FU_VAR38 + FU_VAR39 / + +-----xxxx xxxx xxxx xxxx +--xxxx xxxx +ASSIGN FU_VAR41 0 / +DEFINE FU_VAR41 0.005 * FU_VAR90 / +DEFINE FU_VAR42 FU_P2WPR < FU_VAR41 / +ASSIGN FU_VAR43 0 / +--xxxx xxxx +ASSIGN FU_VAR44 0 / +--xxxx xxxx xxxx +ASSIGN FU_VAR45 0 / +DEFINE FU_VAR45 FU_VAR43 + FU_VAR44 / + +-----xxxx xxxx xxxx +ASSIGN FU_VAR46 0 / +DEFINE FU_VAR47 FU_P1SWI > 10 / +DEFINE FU_VAR46 NINT(FU_P1SWI / 36000 + 0.499) * 761 / 0.9025 * FU_VAR47 / +ASSIGN FU_VAR48 0 / +DEFINE FU_VAR49 FU_P1WPR > 10 / +DEFINE FU_VAR48 NINT(FU_P1WPR / 30576 + 0.499) * 864 / 0.9025 * FU_VAR49 / +DEFINE FU_VAR50 FU_P2SWI > 10 / +ASSIGN FU_VAR51 0 / +DEFINE FU_VAR52 FU_P2WPR > 10 / +ASSIGN FU_VAR53 0 / +--xxxx xxxx xxxx +ASSIGN FU_VAR54 0 / +DEFINE FU_VAR54 FU_VAR46 + FU_VAR48 + FU_VAR51 + FU_VAR53 / + +-----xxxx xxxx loadxxxxs +--xxxx xxxx xxxx xxxx xxxx, xxxxxxxx +ASSIGN FU_VAR55 0 / +DEFINE FU_VAR55 FU_VAR91 * 30.6571 / 1000 / 0.8754 / +--xxxx xxxx xxxx xxxx xxxx, xxxx +ASSIGN FU_VAR56 0 / +--xxxx +ASSIGN FU_VAR57 0 / +DEFINE FU_VAR57 FU_VAR91 * 61.4286 / 1000 / 0.9215 + 280 / +--xxxx +ASSIGN FU_VAR58 0 / +--xxxx +ASSIGN FU_VAR59 0 / +DEFINE FU_VAR59 FU_P1TGP * 120 / 1E6 / +--xxxx xxxx xxxx xxxx, xxxx +ASSIGN FU_VAR60 0 / +DEFINE FU_VAR60 (FU_VAR91 + FU_VAR90) * 5.52 / 1000 / +--xxxx xxxx xxxx xxxx, xxxx +ASSIGN FU_VAR61 0 / +DEFINE FU_VAR61 FU_VAR60 + FU_VAR59 + FU_VAR58 + FU_VAR57 + FU_VAR56 + FU_VAR55 / + +-----xxxx-xxxx, xxxx +ASSIGN FU_VAR62 0 / +DEFINE FU_VAR62 (FU_VAR61 + FU_VAR54 + FU_VAR45 + FU_VAR40 + FU_VAR36 + FU_VAR29 + FU_VAR25 + FU_VAR14)/1000 / + +--xxxx xxxx, xxxx +ASSIGN FU_VAR63 0 / -- xxxx xxxx xxxx xxxx xxxx xxxx xxxx +--Allowance, MW +ASSIGN FU_VAR64 5 / --xxxx xxxx xxxx MxxxxW xxxx xxxx XX xxxx +--xxxx +ASSIGN FU_VAR65 0 / +DEFINE FU_VAR65 0.02 * FU_VAR62 / + +-----xxxx xxxx xxxx xxxx, xxxx +ASSIGN FU_VAR66 0 / +DEFINE FU_VAR66 FU_VAR65 + FU_VAR64 + FU_VAR63 + FU_VAR62 / + +---- xxxx xxxx xxxx +DEFINE FU_VAR67 0 / +DEFINE FU_VAR67 FU_VAR66 * 0.79 / + +---- xxxx xxxx xxxx xxxx +DEFINE FU_VAR68 0 / +DEFINE FU_VAR68 FU_VAR67 * 1.08 / +/ + +-- udq #6 + +UDQ +ASSIGN FU_VAR90 0.0 / +DEFINE FU_VAR91 GOPR TEST / +/ +)"; + auto schedule = make_schedule(deck_string); + const auto& udq = schedule.getUDQConfig(0); + auto undefined_value = udq.params().undefinedValue(); + UDQState udq_state(undefined_value); SummaryState st(std::chrono::system_clock::now()); st.update("FMWPR", 100); st.update("FMWIN", 100); @@ -1879,6 +2130,7 @@ DEFINE WUGASRA 750000 - WGLIR '*' / st.update_well_var("W2", "WGLIR", 2); st.update_well_var("W3", "WGLIR", 3); + udq.eval(st, udq_state); + // The current testcase has some ordering & defined / undefined issues which - // are not yet solved; therefor no udq.eval() here. } diff --git a/tests/test_AggregateActionxData.cpp b/tests/test_AggregateActionxData.cpp index d94e783b1..8650f6126 100644 --- a/tests/test_AggregateActionxData.cpp +++ b/tests/test_AggregateActionxData.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -105,6 +106,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) Opm::EclipseState es = simCase.es; Opm::Runspec rspec = es.runspec(); Opm::SummaryState st = sum_state_TEST1(); + Opm::UDQState udq_state(1); Opm::Action::State action_state; Opm::Schedule sched = simCase.sched; Opm::EclipseGrid grid = simCase.grid; @@ -135,7 +137,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data) const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih); auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims); - udqData.captureDeclaredUDQData(sched, rptStep, st, ih); + udqData.captureDeclaredUDQData(sched, rptStep, udq_state, ih); const auto actDims = Opm::RestartIO::Helpers::createActionxDims(rspec, sched, rptStep); auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims); diff --git a/tests/test_AggregateUDQData.cpp b/tests/test_AggregateUDQData.cpp index c20b603c4..10f98db96 100644 --- a/tests/test_AggregateUDQData.cpp +++ b/tests/test_AggregateUDQData.cpp @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include //#include //#include @@ -71,6 +74,48 @@ namespace { */ } + +Opm::UDQSet make_udq_set(const std::string& name, Opm::UDQVarType var_type, const std::vector& wgnames, const std::vector& values) { + Opm::UDQSet s(name, var_type, wgnames); + for (std::size_t i=0; i < values.size(); i++) + s.assign(i , values[i]); + + return s; +} + + Opm::UDQState make_udq_state() + { + auto state = Opm::UDQState{0}; + + state.add("WUOPRL", make_udq_set("WUOPRL", + Opm::UDQVarType::WELL_VAR, + {"PROD1", "PROD2", "WINJ1", "WINJ2"}, + {210, 211, 212, 213})); + + state.add("WUOPRU", make_udq_set("WUOPRU", + Opm::UDQVarType::WELL_VAR, + {"PROD1", "PROD2", "WINJ1", "WINJ2"}, + {220, 221, 222, 223})); + + state.add("WULPRL", make_udq_set("WULPRL", + Opm::UDQVarType::WELL_VAR, + {"PROD1", "PROD2", "WINJ1", "WINJ2"}, + {230, 231, 232, 233})); + + state.add("WULPRU", make_udq_set("WULPRU", + Opm::UDQVarType::WELL_VAR, + {"PROD1", "PROD2", "WINJ1", "WINJ2"}, + {160, 161, 162, 163})); + + state.add("GUOPRU", make_udq_set("GUOPRU", + Opm::UDQVarType::GROUP_VAR, + {"WGRP1", "WGRP2", "GRP1"}, + {360, 361, 362})); + + state.add("FULPR", Opm::UDQSet::scalar("FULPR", 460)); + return state; + } + Opm::SummaryState sum_state() { auto state = Opm::SummaryState{std::chrono::system_clock::now()}; @@ -133,6 +178,7 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data) Opm::EclipseState es = simCase.es; Opm::SummaryState st = sum_state(); + Opm::UDQState udq_state = make_udq_state(); Opm::Schedule sched = simCase.sched; Opm::EclipseGrid grid = simCase.grid; const auto& ioConfig = es.getIOConfig(); @@ -162,7 +208,7 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data) const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih); auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims); - udqData.captureDeclaredUDQData(sched, rptStep, st, ih); + udqData.captureDeclaredUDQData(sched, rptStep, udq_state, ih); rstFile.write("ZUDN", udqData.getZUDN()); rstFile.write("ZUDL", udqData.getZUDL()); diff --git a/tests/test_Restart.cpp b/tests/test_Restart.cpp index f3bbf7360..96e957fdc 100644 --- a/tests/test_Restart.cpp +++ b/tests/test_Restart.cpp @@ -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(st); + udq.eval(st, udq_state); eclWriter.writeTimeStep( action_state, st, udq_state, @@ -613,6 +613,7 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) { auto groups = mkGroups(); Opm::SummaryState sumState(std::chrono::system_clock::now()); Opm::Action::State action_state; + Opm::UDQState udq_state(19); const auto seqnum = 1; auto rstFile = OS::Restart { @@ -627,7 +628,8 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) { setup.grid , setup.schedule, action_state, - sumState), + sumState, + udq_state), std::runtime_error); } } @@ -663,6 +665,7 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) { Setup setup("BASE_SIM.DATA"); { Action::State action_state; + UDQState udq_state(10); auto num_cells = setup.grid.getNumActive( ); auto cells = mkSolution( num_cells ); auto wells = mkWells(); @@ -691,7 +694,8 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) { setup.grid, setup.schedule, action_state, - sumState); + sumState, + udq_state); } const auto rstFile = ::Opm::EclIO::OutputStream:: @@ -767,6 +771,7 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) { restart_value.addExtra("THRESHPR", UnitSystem::measure::pressure, {0,1}); const auto sumState = sim_state(); Action::State action_state; + UDQState udq_state(99); /* THPRES data has wrong size in extra container. */ { @@ -783,7 +788,8 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) { base_setup.grid, base_setup.schedule, action_state, - sumState), + sumState, + udq_state), std::runtime_error); } @@ -806,7 +812,8 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) { base_setup.grid, base_setup.schedule, action_state, - sumState); + sumState, + udq_state); } { @@ -853,7 +860,7 @@ BOOST_AUTO_TEST_CASE(Restore_Cumulatives) mkGroups() }; const auto sumState = sim_state(); - + UDQState udq_state(98); namespace OS = ::Opm::EclIO::OutputStream; const auto rset = OS::ResultSet{ wa.currentWorkingDirectory(), "FILE" }; @@ -865,7 +872,7 @@ BOOST_AUTO_TEST_CASE(Restore_Cumulatives) }; RestartIO::save(rstFile, seqnum, 100, restart_value, - setup.es, setup.grid, setup.schedule, action_state, sumState); + setup.es, setup.grid, setup.schedule, action_state, sumState, udq_state); } Action::State action_state;