Differentiate better between UDQ ASSIGN and UDQ DEFINE
A quite typical situation is that a UDQ keyword is first initialized with UDQ ASSIGN statement, and then subsequently a formula for updates every timestep is entered with UDQ DEFINE: UDQ ASSIGN FU_VAR1 0 / DEFINE FU_VAR1 FU_VAR1 + 1 / / Then the assign statement should be run once, and the define formula should be evaluated for every subsequent timestep.
This commit is contained in:
parent
49460edf39
commit
5a060910a3
@ -42,10 +42,12 @@ public:
|
|||||||
struct AssignRecord {
|
struct AssignRecord {
|
||||||
std::vector<std::string> selector;
|
std::vector<std::string> selector;
|
||||||
double value;
|
double value;
|
||||||
|
std::size_t report_step;
|
||||||
|
|
||||||
bool operator==(const AssignRecord& data) const {
|
bool operator==(const AssignRecord& data) const {
|
||||||
return selector == data.selector &&
|
return selector == data.selector &&
|
||||||
value == data.value;
|
report_step == data.report_step &&
|
||||||
|
value == data.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Serializer>
|
template<class Serializer>
|
||||||
@ -53,19 +55,21 @@ public:
|
|||||||
{
|
{
|
||||||
serializer(selector);
|
serializer(selector);
|
||||||
serializer(value);
|
serializer(value);
|
||||||
|
serializer(report_step);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
UDQAssign();
|
UDQAssign();
|
||||||
UDQAssign(const std::string& keyword, const std::vector<std::string>& selector, double value);
|
UDQAssign(const std::string& keyword, const std::vector<std::string>& selector, double value, std::size_t report_step);
|
||||||
|
|
||||||
static UDQAssign serializeObject();
|
static UDQAssign serializeObject();
|
||||||
|
|
||||||
const std::string& keyword() const;
|
const std::string& keyword() const;
|
||||||
UDQVarType var_type() const;
|
UDQVarType var_type() const;
|
||||||
void add_record(const std::vector<std::string>& selector, double value);
|
void add_record(const std::vector<std::string>& selector, double value, std::size_t report_step);
|
||||||
UDQSet eval(const std::vector<std::string>& wells) const;
|
UDQSet eval(const std::vector<std::string>& wells) const;
|
||||||
UDQSet eval() const;
|
UDQSet eval() const;
|
||||||
|
std::size_t report_step() const;
|
||||||
|
|
||||||
bool operator==(const UDQAssign& data) const;
|
bool operator==(const UDQAssign& data) const;
|
||||||
|
|
||||||
|
@ -53,10 +53,10 @@ namespace Opm {
|
|||||||
const std::string& unit(const std::string& key) const;
|
const std::string& unit(const std::string& key) const;
|
||||||
bool has_unit(const std::string& keyword) const;
|
bool has_unit(const std::string& keyword) const;
|
||||||
bool has_keyword(const std::string& keyword) const;
|
bool has_keyword(const std::string& keyword) const;
|
||||||
void add_record(const DeckRecord& record);
|
void add_record(const DeckRecord& record, std::size_t report_step);
|
||||||
|
|
||||||
void add_unit(const std::string& keyword, const std::string& unit);
|
void add_unit(const std::string& keyword, const std::string& unit);
|
||||||
void add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value);
|
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 std::vector<std::string>& expression);
|
void add_define(const std::string& quantity, 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, SummaryState& st, UDQState& udq_state) const;
|
||||||
@ -96,6 +96,8 @@ namespace Opm {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void add_node(const std::string& quantity, UDQAction action);
|
void add_node(const std::string& quantity, UDQAction action);
|
||||||
|
UDQAction action_type(const std::string& udq_key) const;
|
||||||
|
|
||||||
|
|
||||||
UDQParams udq_params;
|
UDQParams udq_params;
|
||||||
UDQFunctionTable udqft;
|
UDQFunctionTable udqft;
|
||||||
|
@ -42,7 +42,8 @@ namespace Opm {
|
|||||||
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;
|
||||||
void add(const std::string& key, double value);
|
void add(const std::string& key, double value);
|
||||||
void update(const std::string& keyword, const UDQSet& udq_result);
|
void update_assign(std::size_t report_step, 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> groups() const;
|
std::vector<std::string> groups() const;
|
||||||
|
@ -39,15 +39,19 @@ public:
|
|||||||
double get(const std::string& key) const;
|
double get(const std::string& key) const;
|
||||||
double get_group_var(const std::string& well, const std::string& var) 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;
|
double get_well_var(const std::string& well, const std::string& var) const;
|
||||||
void add(const std::string& udq_key, const UDQSet& result);
|
void add_define(const std::string& udq_key, const UDQSet& result);
|
||||||
|
void add_assign(std::size_t report_step, const std::string& udq_key, const UDQSet& result);
|
||||||
|
bool assign(std::size_t report_step, const std::string& udq_key) const;
|
||||||
|
|
||||||
std::vector<char> serialize() const;
|
std::vector<char> serialize() const;
|
||||||
void deserialize(const std::vector<char>& buffer);
|
void deserialize(const std::vector<char>& buffer);
|
||||||
bool operator==(const UDQState& other) const;
|
bool operator==(const UDQState& other) const;
|
||||||
private:
|
private:
|
||||||
|
void add(const std::string& udq_key, const UDQSet& result);
|
||||||
double get_wg_var(const std::string& well, const std::string& key, UDQVarType var_type) const;
|
double get_wg_var(const std::string& well, const std::string& key, UDQVarType var_type) const;
|
||||||
double undefined_value;
|
double undefined_value;
|
||||||
std::unordered_map<std::string, UDQSet> values;
|
std::unordered_map<std::string, UDQSet> values;
|
||||||
|
std::unordered_map<std::string, std::size_t> assignments;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1389,7 +1389,7 @@ Schedule::Schedule(const Deck& deck, const EclipseState& es, const ParseContext&
|
|||||||
const auto& current = *this->udq_config.get(currentStep);
|
const auto& current = *this->udq_config.get(currentStep);
|
||||||
std::shared_ptr<UDQConfig> new_udq = std::make_shared<UDQConfig>(current);
|
std::shared_ptr<UDQConfig> new_udq = std::make_shared<UDQConfig>(current);
|
||||||
for (const auto& record : keyword)
|
for (const auto& record : keyword)
|
||||||
new_udq->add_record(record);
|
new_udq->add_record(record, currentStep);
|
||||||
|
|
||||||
this->udq_config.update(currentStep, new_udq);
|
this->udq_config.update(currentStep, new_udq);
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,11 @@ UDQAssign::UDQAssign() :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
UDQAssign::UDQAssign(const std::string& keyword, const std::vector<std::string>& selector, double value) :
|
UDQAssign::UDQAssign(const std::string& keyword, const std::vector<std::string>& selector, double value, std::size_t report_step) :
|
||||||
m_keyword(keyword),
|
m_keyword(keyword),
|
||||||
m_var_type(UDQ::varType(keyword))
|
m_var_type(UDQ::varType(keyword))
|
||||||
{
|
{
|
||||||
this->add_record(selector, value);
|
this->add_record(selector, value, report_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
UDQAssign UDQAssign::serializeObject()
|
UDQAssign UDQAssign::serializeObject()
|
||||||
@ -39,13 +39,13 @@ UDQAssign UDQAssign::serializeObject()
|
|||||||
UDQAssign result;
|
UDQAssign result;
|
||||||
result.m_keyword = "test";
|
result.m_keyword = "test";
|
||||||
result.m_var_type = UDQVarType::CONNECTION_VAR;
|
result.m_var_type = UDQVarType::CONNECTION_VAR;
|
||||||
result.records = {{{"test1"}, 1.0}};
|
result.records = {{{"test1"}, 1.0, 0}};
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDQAssign::add_record(const std::vector<std::string>& selector, double value) {
|
void UDQAssign::add_record(const std::vector<std::string>& selector, double value, std::size_t report_step) {
|
||||||
this->records.push_back({selector, value});
|
this->records.push_back({selector, value, report_step});
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& UDQAssign::keyword() const {
|
const std::string& UDQAssign::keyword() const {
|
||||||
@ -56,6 +56,12 @@ UDQVarType UDQAssign::var_type() const {
|
|||||||
return this->m_var_type;
|
return this->m_var_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t UDQAssign::report_step() const {
|
||||||
|
return this->records.back().report_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
UDQSet UDQAssign::eval(const std::vector<std::string>& wells) const {
|
UDQSet UDQAssign::eval(const std::vector<std::string>& wells) const {
|
||||||
if (this->m_var_type == UDQVarType::WELL_VAR) {
|
if (this->m_var_type == UDQVarType::WELL_VAR) {
|
||||||
UDQSet ws = UDQSet::wells(this->m_keyword, wells);
|
UDQSet ws = UDQSet::wells(this->m_keyword, wells);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp>
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
@ -75,13 +76,13 @@ namespace Opm {
|
|||||||
index_iter->second.action = action;
|
index_iter->second.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDQConfig::add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value) {
|
void UDQConfig::add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value, std::size_t report_step) {
|
||||||
this->add_node(quantity, UDQAction::ASSIGN);
|
this->add_node(quantity, UDQAction::ASSIGN);
|
||||||
auto assignment = this->m_assignments.find(quantity);
|
auto assignment = this->m_assignments.find(quantity);
|
||||||
if (assignment == this->m_assignments.end())
|
if (assignment == this->m_assignments.end())
|
||||||
this->m_assignments.insert( std::make_pair(quantity, UDQAssign(quantity, selector, value )));
|
this->m_assignments.insert( std::make_pair(quantity, UDQAssign(quantity, selector, value, report_step )));
|
||||||
else
|
else
|
||||||
assignment->second.add_record(selector, value);
|
assignment->second.add_record(selector, value, report_step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -113,12 +114,12 @@ namespace Opm {
|
|||||||
keyword.
|
keyword.
|
||||||
*/
|
*/
|
||||||
if (!this->has_keyword(keyword))
|
if (!this->has_keyword(keyword))
|
||||||
this->add_assign(keyword, {}, 0);
|
this->add_assign(keyword, {}, 0, 0);
|
||||||
this->units[keyword] = unit;
|
this->units[keyword] = unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UDQConfig::add_record(const DeckRecord& record) {
|
void UDQConfig::add_record(const DeckRecord& record, std::size_t report_step) {
|
||||||
auto action = UDQ::actionType(record.getItem("ACTION").get<RawString>(0));
|
auto action = UDQ::actionType(record.getItem("ACTION").get<RawString>(0));
|
||||||
const auto& quantity = record.getItem("QUANTITY").get<std::string>(0);
|
const auto& quantity = record.getItem("QUANTITY").get<std::string>(0);
|
||||||
const auto& data = RawString::strings( record.getItem("DATA").getData<RawString>() );
|
const auto& data = RawString::strings( record.getItem("DATA").getData<RawString>() );
|
||||||
@ -132,7 +133,7 @@ namespace Opm {
|
|||||||
if (action == UDQAction::ASSIGN) {
|
if (action == UDQAction::ASSIGN) {
|
||||||
std::vector<std::string> selector(data.begin(), data.end() - 1);
|
std::vector<std::string> selector(data.begin(), data.end() - 1);
|
||||||
double value = std::stod(data.back());
|
double value = std::stod(data.back());
|
||||||
this->add_assign(quantity, selector, value);
|
this->add_assign(quantity, selector, value, report_step);
|
||||||
} else if (action == UDQAction::DEFINE)
|
} else if (action == UDQAction::DEFINE)
|
||||||
this->add_define(quantity, data);
|
this->add_define(quantity, data);
|
||||||
else
|
else
|
||||||
@ -144,13 +145,18 @@ namespace Opm {
|
|||||||
return this->m_definitions.at(key);
|
return this->m_definitions.at(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UDQAction UDQConfig::action_type(const std::string& udq_key) const {
|
||||||
|
auto action_iter = this->input_index.find(udq_key);
|
||||||
|
return action_iter->second.action;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<UDQDefine> UDQConfig::definitions() const {
|
std::vector<UDQDefine> UDQConfig::definitions() const {
|
||||||
std::vector<UDQDefine> ret;
|
std::vector<UDQDefine> ret;
|
||||||
|
|
||||||
for (const auto& key : this->define_order)
|
for (const auto& key : this->define_order) {
|
||||||
ret.push_back(this->m_definitions.at(key));
|
if (this->action_type(key) == UDQAction::DEFINE)
|
||||||
|
ret.push_back(this->m_definitions.at(key));
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +165,7 @@ namespace Opm {
|
|||||||
std::vector<UDQDefine> filtered_defines;
|
std::vector<UDQDefine> filtered_defines;
|
||||||
for (const auto& key : this->define_order) {
|
for (const auto& key : this->define_order) {
|
||||||
const auto& udq_define = this->m_definitions.at(key);
|
const auto& udq_define = this->m_definitions.at(key);
|
||||||
if (udq_define.var_type() == var_type)
|
if (udq_define.var_type() == var_type && this->action_type(key) == UDQAction::DEFINE)
|
||||||
filtered_defines.push_back(udq_define);
|
filtered_defines.push_back(udq_define);
|
||||||
}
|
}
|
||||||
return filtered_defines;
|
return filtered_defines;
|
||||||
@ -210,16 +216,16 @@ namespace Opm {
|
|||||||
|
|
||||||
|
|
||||||
std::vector<UDQAssign> UDQConfig::assignments(UDQVarType var_type) const {
|
std::vector<UDQAssign> UDQConfig::assignments(UDQVarType var_type) const {
|
||||||
std::vector<UDQAssign> filtered_defines;
|
std::vector<UDQAssign> filtered_assigns;
|
||||||
for (const auto& index_pair : this->input_index) {
|
for (const auto& index_pair : this->input_index) {
|
||||||
if (index_pair.second.action == UDQAction::ASSIGN) {
|
const std::string& key = index_pair.first;
|
||||||
const std::string& key = index_pair.first;
|
const auto& assign_iter = this->m_assignments.find(key);
|
||||||
const auto& udq_define = this->m_assignments.at(key);
|
if (assign_iter != this->m_assignments.end()) {
|
||||||
if (udq_define.var_type() == var_type)
|
if (assign_iter->second.var_type() == var_type)
|
||||||
filtered_defines.push_back(udq_define);
|
filtered_assigns.push_back(assign_iter->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return filtered_defines;
|
return filtered_assigns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -295,38 +301,44 @@ namespace Opm {
|
|||||||
UDQContext context(func_table, st, udq_state);
|
UDQContext context(func_table, st, udq_state);
|
||||||
|
|
||||||
for (const auto& assign : this->assignments(UDQVarType::WELL_VAR)) {
|
for (const auto& assign : this->assignments(UDQVarType::WELL_VAR)) {
|
||||||
auto ws = assign.eval(st.wells());
|
if (udq_state.assign(report_step, assign.keyword())) {
|
||||||
context.update(assign.keyword(), ws);
|
auto ws = assign.eval(st.wells());
|
||||||
st.update_udq(ws, undefined_value);
|
context.update_assign(report_step, assign.keyword(), ws);
|
||||||
|
st.update_udq(ws, undefined_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& def : this->definitions(UDQVarType::WELL_VAR)) {
|
for (const auto& def : this->definitions(UDQVarType::WELL_VAR)) {
|
||||||
auto ws = def.eval(context);
|
auto ws = def.eval(context);
|
||||||
context.update(def.keyword(), ws);
|
context.update_define(def.keyword(), ws);
|
||||||
st.update_udq(ws, undefined_value);
|
st.update_udq(ws, undefined_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& assign : this->assignments(UDQVarType::GROUP_VAR)) {
|
for (const auto& assign : this->assignments(UDQVarType::GROUP_VAR)) {
|
||||||
auto ws = assign.eval(st.groups());
|
if (udq_state.assign(report_step, assign.keyword())) {
|
||||||
context.update(assign.keyword(), ws);
|
auto ws = assign.eval(st.groups());
|
||||||
st.update_udq(ws, undefined_value);
|
context.update_assign(report_step, assign.keyword(), ws);
|
||||||
|
st.update_udq(ws, undefined_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& def : this->definitions(UDQVarType::GROUP_VAR)) {
|
for (const auto& def : this->definitions(UDQVarType::GROUP_VAR)) {
|
||||||
auto ws = def.eval(context);
|
auto ws = def.eval(context);
|
||||||
context.update(def.keyword(), ws);
|
context.update_define(def.keyword(), ws);
|
||||||
st.update_udq(ws, undefined_value);
|
st.update_udq(ws, undefined_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& assign : this->assignments(UDQVarType::FIELD_VAR)) {
|
for (const auto& assign : this->assignments(UDQVarType::FIELD_VAR)) {
|
||||||
auto ws = assign.eval();
|
if (udq_state.assign(assign.report_step(), assign.keyword())) {
|
||||||
context.update(assign.keyword(), ws);
|
auto ws = assign.eval();
|
||||||
st.update_udq(ws, undefined_value);
|
context.update_assign(report_step, assign.keyword(), ws);
|
||||||
|
st.update_udq(ws, undefined_value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& def : this->definitions(UDQVarType::FIELD_VAR)) {
|
for (const auto& def : this->definitions(UDQVarType::FIELD_VAR)) {
|
||||||
auto field_udq = def.eval(context);
|
auto field_udq = def.eval(context);
|
||||||
context.update(def.keyword(), field_udq);
|
context.update_define(def.keyword(), field_udq);
|
||||||
st.update_udq(field_udq, undefined_value);
|
st.update_udq(field_udq, undefined_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,6 @@ bool is_udq(const std::string& key) {
|
|||||||
this->add("TIME", 0.0);
|
this->add("TIME", 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) {
|
void UDQContext::add(const std::string& key, double value) {
|
||||||
this->values[key] = value;
|
this->values[key] = value;
|
||||||
@ -116,4 +113,12 @@ bool is_udq(const std::string& key) {
|
|||||||
const UDQFunctionTable& UDQContext::function_table() const {
|
const UDQFunctionTable& UDQContext::function_table() const {
|
||||||
return this->udqft;
|
return this->udqft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDQContext::update_assign(std::size_t report_step, const std::string& keyword, const UDQSet& udq_result) {
|
||||||
|
this->udq_state.add_assign(report_step, keyword, udq_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDQContext::update_define(const std::string& keyword, const UDQSet& udq_result) {
|
||||||
|
this->udq_state.add_define(keyword, udq_result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ UDQSet UDQDefine::eval(UDQContext& context) const {
|
|||||||
std::string msg = "Invalid runtime type conversion detected when evaluating UDQ";
|
std::string msg = "Invalid runtime type conversion detected when evaluating UDQ";
|
||||||
throw std::invalid_argument(msg);
|
throw std::invalid_argument(msg);
|
||||||
}
|
}
|
||||||
context.update(this->keyword(), res);
|
context.update_define(this->keyword(), res);
|
||||||
|
|
||||||
if (res.var_type() == UDQVarType::SCALAR) {
|
if (res.var_type() == UDQVarType::SCALAR) {
|
||||||
/*
|
/*
|
||||||
|
@ -82,6 +82,15 @@ void UDQState::add(const std::string& udq_key, const UDQSet& result) {
|
|||||||
res_iter->second = result;
|
res_iter->second = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDQState::add_define(const std::string& udq_key, const UDQSet& result) {
|
||||||
|
this->add(udq_key, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UDQState::add_assign(std::size_t report_step, const std::string& udq_key, const UDQSet& result) {
|
||||||
|
this->assignments[udq_key] = report_step;
|
||||||
|
this->add(udq_key, result);
|
||||||
|
}
|
||||||
|
|
||||||
double UDQState::get(const std::string& key) const {
|
double UDQState::get(const std::string& key) const {
|
||||||
if (!is_udq(key))
|
if (!is_udq(key))
|
||||||
throw std::logic_error("Key is not a UDQ variable:" + key);
|
throw std::logic_error("Key is not a UDQ variable:" + key);
|
||||||
@ -125,6 +134,16 @@ bool UDQState::operator==(const UDQState& other) const {
|
|||||||
this->values == other.values;
|
this->values == other.values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool UDQState::assign(std::size_t report_step, const std::string& udq_key) const {
|
||||||
|
auto assign_iter = this->assignments.find(udq_key);
|
||||||
|
if (assign_iter == this->assignments.end())
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return report_step > assign_iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<char> UDQState::serialize() const {
|
std::vector<char> UDQState::serialize() const {
|
||||||
Serializer ser;
|
Serializer ser;
|
||||||
ser.put(this->undefined_value);
|
ser.put(this->undefined_value);
|
||||||
@ -133,7 +152,8 @@ std::vector<char> UDQState::serialize() const {
|
|||||||
ser.put( set_pair.first );
|
ser.put( set_pair.first );
|
||||||
set_pair.second.serialize( ser );
|
set_pair.second.serialize( ser );
|
||||||
}
|
}
|
||||||
return std::move(ser.buffer);
|
ser.put(this->assignments);
|
||||||
|
return ser.buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -151,6 +171,7 @@ void UDQState::deserialize(const std::vector<char>& buffer) {
|
|||||||
this->values.insert( std::make_pair(key, udq_set) );
|
this->values.insert( std::make_pair(key, udq_set) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->assignments = ser.get<std::string, std::size_t>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -942,9 +942,9 @@ BOOST_AUTO_TEST_CASE(UDQ_SET_DIV) {
|
|||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(UDQASSIGN_TEST) {
|
BOOST_AUTO_TEST_CASE(UDQASSIGN_TEST) {
|
||||||
UDQAssign as1("WUPR", {}, 1.0);
|
UDQAssign as1("WUPR", {}, 1.0, 1);
|
||||||
UDQAssign as2("WUPR", {"P*"}, 2.0);
|
UDQAssign as2("WUPR", {"P*"}, 2.0, 2);
|
||||||
UDQAssign as3("WUPR", {"P1"}, 4.0);
|
UDQAssign as3("WUPR", {"P1"}, 4.0, 3);
|
||||||
std::vector<std::string> ws1 = {"P1", "P2", "I1", "I2"};
|
std::vector<std::string> ws1 = {"P1", "P2", "I1", "I2"};
|
||||||
|
|
||||||
auto res1 = as1.eval(ws1);
|
auto res1 = as1.eval(ws1);
|
||||||
@ -1455,7 +1455,7 @@ BOOST_AUTO_TEST_CASE(UDQ_USAGE) {
|
|||||||
BOOST_CHECK_EQUAL( usage.IUAD_size(), 0 );
|
BOOST_CHECK_EQUAL( usage.IUAD_size(), 0 );
|
||||||
|
|
||||||
UDAValue uda1("WUX");
|
UDAValue uda1("WUX");
|
||||||
conf.add_assign(uda1.get<std::string>(), {}, 100);
|
conf.add_assign(uda1.get<std::string>(), {}, 100, 0);
|
||||||
|
|
||||||
usage.update(conf, uda1, "W1", UDAControl::WCONPROD_ORAT);
|
usage.update(conf, uda1, "W1", UDAControl::WCONPROD_ORAT);
|
||||||
BOOST_CHECK_EQUAL( usage.IUAD_size(), 1 );
|
BOOST_CHECK_EQUAL( usage.IUAD_size(), 1 );
|
||||||
@ -1842,12 +1842,12 @@ BOOST_AUTO_TEST_CASE(UDQSTATE) {
|
|||||||
BOOST_CHECK_THROW(st.get("FUPR"), std::out_of_range);
|
BOOST_CHECK_THROW(st.get("FUPR"), std::out_of_range);
|
||||||
|
|
||||||
auto fxpr = UDQSet::scalar("FXPR", 100);
|
auto fxpr = UDQSet::scalar("FXPR", 100);
|
||||||
BOOST_CHECK_THROW(st.add("FXPR", fxpr), std::logic_error);
|
BOOST_CHECK_THROW(st.add_define("FXPR", fxpr), std::logic_error);
|
||||||
|
|
||||||
BOOST_CHECK_THROW(st.get_well_var("OP1", "WUPR"), std::out_of_range);
|
BOOST_CHECK_THROW(st.get_well_var("OP1", "WUPR"), std::out_of_range);
|
||||||
|
|
||||||
auto fupr = UDQSet::scalar("FUPR", 100);
|
auto fupr = UDQSet::scalar("FUPR", 100);
|
||||||
st.add("FUPR", fupr);
|
st.add_define("FUPR", fupr);
|
||||||
|
|
||||||
// This is not a well quantity
|
// This is not a well quantity
|
||||||
BOOST_CHECK_THROW(st.get_well_var("OP1", "FUPR"), std::logic_error);
|
BOOST_CHECK_THROW(st.get_well_var("OP1", "FUPR"), std::logic_error);
|
||||||
@ -1856,7 +1856,7 @@ BOOST_AUTO_TEST_CASE(UDQSTATE) {
|
|||||||
|
|
||||||
auto wupr = UDQSet::wells("WUPR", {"P1", "P2"});
|
auto wupr = UDQSet::wells("WUPR", {"P1", "P2"});
|
||||||
wupr.assign("P1", 75);
|
wupr.assign("P1", 75);
|
||||||
st.add("WUPR", wupr);
|
st.add_define("WUPR", wupr);
|
||||||
|
|
||||||
BOOST_CHECK(st.has_well_var("P1", "WUPR"));
|
BOOST_CHECK(st.has_well_var("P1", "WUPR"));
|
||||||
// We have a well P2 - but we have not assigned a value to it!
|
// We have a well P2 - but we have not assigned a value to it!
|
||||||
@ -1946,6 +1946,8 @@ DEFINE WUGASRA 750000 - WGLIR '*' /
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(UDQ_UNDEFINED) {
|
BOOST_AUTO_TEST_CASE(UDQ_UNDEFINED) {
|
||||||
std::string deck_string = R"(
|
std::string deck_string = R"(
|
||||||
|
SCHEDULE
|
||||||
|
|
||||||
-- udq #2
|
-- udq #2
|
||||||
UDQ
|
UDQ
|
||||||
----XX xxxx xxx
|
----XX xxxx xxx
|
||||||
@ -2129,15 +2131,13 @@ DEFINE FU_VAR91 GOPR TEST /
|
|||||||
st.update_well_var("W1", "WGLIR", 1);
|
st.update_well_var("W1", "WGLIR", 1);
|
||||||
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);
|
||||||
|
st.update_group_var("TEST", "GOPR", 1);
|
||||||
|
|
||||||
udq.eval(0, st, udq_state);
|
udq.eval(0, st, udq_state);
|
||||||
|
|
||||||
// The current testcase has some ordering & defined / undefined issues which
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(UDQ_KEY_ERROR) {
|
BOOST_AUTO_TEST_CASE(UDQ_KEY_ERROR) {
|
||||||
std::string deck_string = R"(
|
std::string deck_string = R"(
|
||||||
-- udq #2
|
-- udq #2
|
||||||
@ -2156,3 +2156,85 @@ UDQ
|
|||||||
|
|
||||||
BOOST_CHECK_THROW(udq.eval(0, st, udq_state), std::out_of_range);
|
BOOST_CHECK_THROW(udq.eval(0, st, udq_state), std::out_of_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) {
|
||||||
|
std::string deck_string = R"(
|
||||||
|
-- udq #2
|
||||||
|
SCHEDULE
|
||||||
|
|
||||||
|
UDQ
|
||||||
|
ASSIGN FU_VAR1 5 /
|
||||||
|
DEFINE FU_VAR1 FU_VAR1 + 5 /
|
||||||
|
/
|
||||||
|
)";
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
udq.eval(0, st, udq_state);
|
||||||
|
BOOST_CHECK_EQUAL(st.get("FU_VAR1"), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(UDQ_ASSIGN_REASSIGN) {
|
||||||
|
std::string deck_string = R"(
|
||||||
|
-- udq #2
|
||||||
|
SCHEDULE
|
||||||
|
|
||||||
|
UDQ
|
||||||
|
ASSIGN FU_VAR1 0 /
|
||||||
|
DEFINE FU_VAR1 FU_VAR1 + 1 /
|
||||||
|
/
|
||||||
|
|
||||||
|
TSTEP
|
||||||
|
1 1 1 1 1 /
|
||||||
|
|
||||||
|
UDQ
|
||||||
|
ASSIGN FU_VAR1 0 /
|
||||||
|
DEFINE FU_VAR1 FU_VAR1 + 1 /
|
||||||
|
/
|
||||||
|
|
||||||
|
TSTEP
|
||||||
|
1 1 1 1 1 /
|
||||||
|
|
||||||
|
UDQ
|
||||||
|
ASSIGN FU_VAR1 0 /
|
||||||
|
/
|
||||||
|
|
||||||
|
TSTEP
|
||||||
|
1 1 1 1 1 /
|
||||||
|
|
||||||
|
)";
|
||||||
|
|
||||||
|
auto schedule = make_schedule(deck_string);
|
||||||
|
UDQState udq_state(0);
|
||||||
|
SummaryState st(std::chrono::system_clock::now());
|
||||||
|
|
||||||
|
// Counting: 1,2,3,4,5
|
||||||
|
for (std::size_t report_step = 0; report_step < 5; report_step++) {
|
||||||
|
const auto& udq = schedule.getUDQConfig(report_step);
|
||||||
|
udq.eval(report_step, st, udq_state);
|
||||||
|
auto fu_var1 = st.get("FU_VAR1");
|
||||||
|
BOOST_CHECK_EQUAL(fu_var1, report_step + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset to zero and count: 1,2,3,4,5
|
||||||
|
for (std::size_t report_step = 5; report_step < 10; report_step++) {
|
||||||
|
const auto& udq = schedule.getUDQConfig(report_step);
|
||||||
|
udq.eval(report_step, st, udq_state);
|
||||||
|
auto fu_var1 = st.get("FU_VAR1");
|
||||||
|
BOOST_CHECK_EQUAL(fu_var1, report_step - 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset to zero and stay there.
|
||||||
|
for (std::size_t report_step = 10; report_step < 15; report_step++) {
|
||||||
|
const auto& udq = schedule.getUDQConfig(report_step);
|
||||||
|
udq.eval(report_step, st, udq_state);
|
||||||
|
auto fu_var1 = st.get("FU_VAR1");
|
||||||
|
BOOST_CHECK_EQUAL(fu_var1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -87,32 +87,32 @@ Opm::UDQSet make_udq_set(const std::string& name, Opm::UDQVarType var_type, cons
|
|||||||
{
|
{
|
||||||
auto state = Opm::UDQState{0};
|
auto state = Opm::UDQState{0};
|
||||||
|
|
||||||
state.add("WUOPRL", make_udq_set("WUOPRL",
|
state.add_define("WUOPRL", make_udq_set("WUOPRL",
|
||||||
Opm::UDQVarType::WELL_VAR,
|
Opm::UDQVarType::WELL_VAR,
|
||||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||||
{210, 211, 212, 213}));
|
{210, 211, 212, 213}));
|
||||||
|
|
||||||
state.add("WUOPRU", make_udq_set("WUOPRU",
|
state.add_define("WUOPRU", make_udq_set("WUOPRU",
|
||||||
Opm::UDQVarType::WELL_VAR,
|
Opm::UDQVarType::WELL_VAR,
|
||||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||||
{220, 221, 222, 223}));
|
{220, 221, 222, 223}));
|
||||||
|
|
||||||
state.add("WULPRL", make_udq_set("WULPRL",
|
state.add_define("WULPRL", make_udq_set("WULPRL",
|
||||||
Opm::UDQVarType::WELL_VAR,
|
Opm::UDQVarType::WELL_VAR,
|
||||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||||
{230, 231, 232, 233}));
|
{230, 231, 232, 233}));
|
||||||
|
|
||||||
state.add("WULPRU", make_udq_set("WULPRU",
|
state.add_define("WULPRU", make_udq_set("WULPRU",
|
||||||
Opm::UDQVarType::WELL_VAR,
|
Opm::UDQVarType::WELL_VAR,
|
||||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||||
{160, 161, 162, 163}));
|
{160, 161, 162, 163}));
|
||||||
|
|
||||||
state.add("GUOPRU", make_udq_set("GUOPRU",
|
state.add_define("GUOPRU", make_udq_set("GUOPRU",
|
||||||
Opm::UDQVarType::GROUP_VAR,
|
Opm::UDQVarType::GROUP_VAR,
|
||||||
{"WGRP1", "WGRP2", "GRP1"},
|
{"WGRP1", "WGRP2", "GRP1"},
|
||||||
{360, 361, 362}));
|
{360, 361, 362}));
|
||||||
|
|
||||||
state.add("FULPR", Opm::UDQSet::scalar("FULPR", 460));
|
state.add_define("FULPR", Opm::UDQSet::scalar("FULPR", 460));
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user