Merge pull request #2049 from joakim-hove/udq-leading-sign
Udq leading sign
This commit is contained in:
commit
9011ca0e78
@ -40,7 +40,7 @@ public:
|
|||||||
UDQASTNode();
|
UDQASTNode();
|
||||||
explicit UDQASTNode(UDQTokenType type_arg);
|
explicit UDQASTNode(UDQTokenType type_arg);
|
||||||
explicit UDQASTNode(double scalar_value);
|
explicit UDQASTNode(double scalar_value);
|
||||||
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg, const UDQASTNode& arg);
|
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg, const UDQASTNode& left_arg);
|
||||||
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg, const UDQASTNode& left, const UDQASTNode& right);
|
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg, const UDQASTNode& left, const UDQASTNode& right);
|
||||||
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg);
|
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg);
|
||||||
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg, const std::vector<std::string>& selector);
|
UDQASTNode(UDQTokenType type_arg, const std::variant<std::string, double>& value_arg, const std::vector<std::string>& selector);
|
||||||
@ -57,6 +57,7 @@ public:
|
|||||||
void set_right(const UDQASTNode& arg);
|
void set_right(const UDQASTNode& arg);
|
||||||
UDQASTNode* get_left() const;
|
UDQASTNode* get_left() const;
|
||||||
UDQASTNode* get_right() const;
|
UDQASTNode* get_right() const;
|
||||||
|
void scale(double sign_factor);
|
||||||
|
|
||||||
bool operator==(const UDQASTNode& data) const;
|
bool operator==(const UDQASTNode& data) const;
|
||||||
void required_summary(std::unordered_set<std::string>& summary_keys) const;
|
void required_summary(std::unordered_set<std::string>& summary_keys) const;
|
||||||
@ -67,6 +68,7 @@ public:
|
|||||||
serializer(var_type);
|
serializer(var_type);
|
||||||
serializer(type);
|
serializer(type);
|
||||||
serializer(value);
|
serializer(value);
|
||||||
|
serializer(sign);
|
||||||
serializer(selector);
|
serializer(selector);
|
||||||
serializer(left);
|
serializer(left);
|
||||||
serializer(right);
|
serializer(right);
|
||||||
@ -77,11 +79,15 @@ private:
|
|||||||
void func_tokens(std::set<UDQTokenType>& tokens) const;
|
void func_tokens(std::set<UDQTokenType>& tokens) const;
|
||||||
|
|
||||||
std::variant<std::string, double> value;
|
std::variant<std::string, double> value;
|
||||||
|
double sign = 1.0;
|
||||||
std::vector<std::string> selector;
|
std::vector<std::string> selector;
|
||||||
std::shared_ptr<UDQASTNode> left;
|
std::shared_ptr<UDQASTNode> left;
|
||||||
std::shared_ptr<UDQASTNode> right;
|
std::shared_ptr<UDQASTNode> right;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UDQASTNode operator*(const UDQASTNode&lhs, double rhs);
|
||||||
|
UDQASTNode operator*(double lhs, const UDQASTNode& rhs);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -111,6 +111,7 @@ UDQASTNode UDQASTNode::serializeObject()
|
|||||||
result.type = UDQTokenType::error;
|
result.type = UDQTokenType::error;
|
||||||
result.value = "test1";
|
result.value = "test1";
|
||||||
result.selector = {"test2"};
|
result.selector = {"test2"};
|
||||||
|
result.sign = -1;
|
||||||
UDQASTNode left = result;
|
UDQASTNode left = result;
|
||||||
result.left = std::make_shared<UDQASTNode>(left);
|
result.left = std::make_shared<UDQASTNode>(left);
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
|||||||
if (this->selector.size() > 0) {
|
if (this->selector.size() > 0) {
|
||||||
const std::string& well_pattern = this->selector[0];
|
const std::string& well_pattern = this->selector[0];
|
||||||
if (well_pattern.find("*") == std::string::npos)
|
if (well_pattern.find("*") == std::string::npos)
|
||||||
return UDQSet::scalar(string_value, context.get_well_var(well_pattern, string_value));
|
return this->sign * UDQSet::scalar(string_value, context.get_well_var(well_pattern, string_value));
|
||||||
else {
|
else {
|
||||||
auto res = UDQSet::wells(string_value, wells);
|
auto res = UDQSet::wells(string_value, wells);
|
||||||
int fnmatch_flags = 0;
|
int fnmatch_flags = 0;
|
||||||
@ -157,14 +158,14 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
|||||||
if (fnmatch(well_pattern.c_str(), well.c_str(), fnmatch_flags) == 0)
|
if (fnmatch(well_pattern.c_str(), well.c_str(), fnmatch_flags) == 0)
|
||||||
res.assign(well, context.get_well_var(well, string_value));
|
res.assign(well, context.get_well_var(well, string_value));
|
||||||
}
|
}
|
||||||
return res;
|
return this->sign * res;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto res = UDQSet::wells(string_value, wells);
|
auto res = UDQSet::wells(string_value, wells);
|
||||||
for (const auto& well : wells)
|
for (const auto& well : wells)
|
||||||
res.assign(well, context.get_well_var(well, string_value));
|
res.assign(well, context.get_well_var(well, string_value));
|
||||||
|
|
||||||
return res;
|
return this->sign * res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,16 +181,16 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
|||||||
auto res = UDQSet::groups(string_value, groups);
|
auto res = UDQSet::groups(string_value, groups);
|
||||||
for (const auto& group : groups)
|
for (const auto& group : groups)
|
||||||
res.assign(group, context.get_group_var(group, string_value));
|
res.assign(group, context.get_group_var(group, string_value));
|
||||||
return res;
|
return this->sign * res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_type == UDQVarType::FIELD_VAR)
|
if (data_type == UDQVarType::FIELD_VAR)
|
||||||
return UDQSet::scalar(string_value, context.get(string_value));
|
return this->sign * UDQSet::scalar(string_value, context.get(string_value));
|
||||||
|
|
||||||
auto scalar = context.get(string_value);
|
auto scalar = context.get(string_value);
|
||||||
if (scalar.has_value())
|
if (scalar.has_value())
|
||||||
return UDQSet::scalar(string_value, scalar.value());
|
return this->sign * UDQSet::scalar(string_value, scalar.value());
|
||||||
|
|
||||||
throw std::logic_error("Should not be here: var_type: " + UDQ::typeName(data_type) + " stringvalue:" + string_value);
|
throw std::logic_error("Should not be here: var_type: " + UDQ::typeName(data_type) + " stringvalue:" + string_value);
|
||||||
}
|
}
|
||||||
@ -199,7 +200,7 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
|||||||
const auto& string_value = std::get<std::string>( this->value );
|
const auto& string_value = std::get<std::string>( this->value );
|
||||||
const auto& udqft = context.function_table();
|
const auto& udqft = context.function_table();
|
||||||
const UDQScalarFunction& func = dynamic_cast<const UDQScalarFunction&>(udqft.get(string_value));
|
const UDQScalarFunction& func = dynamic_cast<const UDQScalarFunction&>(udqft.get(string_value));
|
||||||
return func.eval( this->left->eval(target_type, context) );
|
return this->sign * func.eval( this->left->eval(target_type, context) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -209,7 +210,7 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
|||||||
|
|
||||||
const auto& udqft = context.function_table();
|
const auto& udqft = context.function_table();
|
||||||
const UDQUnaryElementalFunction& func = dynamic_cast<const UDQUnaryElementalFunction&>(udqft.get(string_value));
|
const UDQUnaryElementalFunction& func = dynamic_cast<const UDQUnaryElementalFunction&>(udqft.get(string_value));
|
||||||
return func.eval(func_arg);
|
return this->sign * func.eval(func_arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UDQ::binaryFunc(this->type)) {
|
if (UDQ::binaryFunc(this->type)) {
|
||||||
@ -220,7 +221,7 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
|||||||
const auto& udqft = context.function_table();
|
const auto& udqft = context.function_table();
|
||||||
const UDQBinaryFunction& func = dynamic_cast<const UDQBinaryFunction&>(udqft.get(string_value));
|
const UDQBinaryFunction& func = dynamic_cast<const UDQBinaryFunction&>(udqft.get(string_value));
|
||||||
auto res = func.eval(left_arg, right_arg);
|
auto res = func.eval(left_arg, right_arg);
|
||||||
return res;
|
return this->sign * res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->type == UDQTokenType::number) {
|
if (this->type == UDQTokenType::number) {
|
||||||
@ -228,13 +229,13 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
|
|||||||
double numeric_value = std::get<double>(this->value);
|
double numeric_value = std::get<double>(this->value);
|
||||||
switch(target_type) {
|
switch(target_type) {
|
||||||
case UDQVarType::WELL_VAR:
|
case UDQVarType::WELL_VAR:
|
||||||
return UDQSet::wells(dummy_name, context.wells(), numeric_value);
|
return this->sign * UDQSet::wells(dummy_name, context.wells(), numeric_value);
|
||||||
case UDQVarType::GROUP_VAR:
|
case UDQVarType::GROUP_VAR:
|
||||||
return UDQSet::groups(dummy_name, context.groups(), numeric_value);
|
return this->sign * UDQSet::groups(dummy_name, context.groups(), numeric_value);
|
||||||
case UDQVarType::SCALAR:
|
case UDQVarType::SCALAR:
|
||||||
return UDQSet::scalar(dummy_name, numeric_value);
|
return this->sign * UDQSet::scalar(dummy_name, numeric_value);
|
||||||
case UDQVarType::FIELD_VAR:
|
case UDQVarType::FIELD_VAR:
|
||||||
return UDQSet::field(dummy_name, numeric_value);
|
return this->sign * UDQSet::field(dummy_name, numeric_value);
|
||||||
default:
|
default:
|
||||||
throw std::invalid_argument("Unsupported target_type: " + std::to_string(static_cast<int>(target_type)));
|
throw std::invalid_argument("Unsupported target_type: " + std::to_string(static_cast<int>(target_type)));
|
||||||
}
|
}
|
||||||
@ -290,6 +291,10 @@ void UDQASTNode::set_right(const UDQASTNode& arg) {
|
|||||||
this->update_type(arg);
|
this->update_type(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UDQASTNode::scale(double sign_factor) {
|
||||||
|
this->sign *= sign_factor;
|
||||||
|
}
|
||||||
|
|
||||||
bool UDQASTNode::operator==(const UDQASTNode& data) const {
|
bool UDQASTNode::operator==(const UDQASTNode& data) const {
|
||||||
if ((this->left && !data.left) ||
|
if ((this->left && !data.left) ||
|
||||||
(!this->left && data.left))
|
(!this->left && data.left))
|
||||||
@ -341,4 +346,15 @@ void UDQASTNode::required_summary(std::unordered_set<std::string>& summary_keys)
|
|||||||
this->right->required_summary(summary_keys);
|
this->right->required_summary(summary_keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UDQASTNode operator*(const UDQASTNode&lhs, double sign_factor) {
|
||||||
|
UDQASTNode prod = lhs;
|
||||||
|
prod.scale(sign_factor);
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UDQASTNode operator*(double lhs, const UDQASTNode& rhs) {
|
||||||
|
return rhs * lhs;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -189,16 +189,7 @@ UDQDefine::UDQDefine(const UDQParams& udq_params,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
This is hysterical special casing; the parser does not correctly handle a
|
|
||||||
leading '-' to change sign; we just hack it up by adding a fictious '0'
|
|
||||||
token in front.
|
|
||||||
*/
|
|
||||||
if (string_tokens[0] == "-")
|
|
||||||
string_tokens.insert( string_tokens.begin(), "0" );
|
|
||||||
std::vector<UDQToken> tokens = make_tokens(string_tokens);
|
std::vector<UDQToken> tokens = make_tokens(string_tokens);
|
||||||
|
|
||||||
|
|
||||||
this->ast = std::make_shared<UDQASTNode>( UDQParser::parse(udq_params, this->m_var_type, this->m_keyword, this->m_location, tokens, parseContext, errors) );
|
this->ast = std::make_shared<UDQASTNode>( UDQParser::parse(udq_params, this->m_var_type, this->m_keyword, this->m_location, tokens, parseContext, errors) );
|
||||||
this->string_data = "";
|
this->string_data = "";
|
||||||
for (std::size_t index = 0; index < deck_data.size(); index++) {
|
for (std::size_t index = 0; index < deck_data.size(); index++) {
|
||||||
|
@ -83,7 +83,15 @@ UDQParseNode UDQParser::current() const {
|
|||||||
|
|
||||||
|
|
||||||
UDQASTNode UDQParser::parse_factor() {
|
UDQASTNode UDQParser::parse_factor() {
|
||||||
|
double sign = 1.0;
|
||||||
auto current = this->current();
|
auto current = this->current();
|
||||||
|
if (current.type == UDQTokenType::binary_op_add || current.type == UDQTokenType::binary_op_sub) {
|
||||||
|
if (current.type == UDQTokenType::binary_op_sub)
|
||||||
|
sign = -1.0;
|
||||||
|
this->next();
|
||||||
|
current = this->current();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (current.type == UDQTokenType::open_paren) {
|
if (current.type == UDQTokenType::open_paren) {
|
||||||
this->next();
|
this->next();
|
||||||
@ -94,7 +102,7 @@ UDQASTNode UDQParser::parse_factor() {
|
|||||||
return UDQASTNode(UDQTokenType::error);
|
return UDQASTNode(UDQTokenType::error);
|
||||||
|
|
||||||
this->next();
|
this->next();
|
||||||
return inner_expr;
|
return sign * inner_expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UDQ::scalarFunc(current.type) || UDQ::elementalUnaryFunc(current.type)) {
|
if (UDQ::scalarFunc(current.type) || UDQ::elementalUnaryFunc(current.type)) {
|
||||||
@ -109,14 +117,14 @@ UDQASTNode UDQParser::parse_factor() {
|
|||||||
return UDQASTNode(UDQTokenType::error);
|
return UDQASTNode(UDQTokenType::error);
|
||||||
|
|
||||||
this->next();
|
this->next();
|
||||||
return UDQASTNode(func_node.type, func_node.value, arg_expr);
|
return sign * UDQASTNode(func_node.type, func_node.value, arg_expr);
|
||||||
} else
|
} else
|
||||||
return UDQASTNode(UDQTokenType::error);
|
return UDQASTNode(UDQTokenType::error);
|
||||||
}
|
}
|
||||||
|
|
||||||
UDQASTNode node(current.type, current.value, current.selector);
|
UDQASTNode node(current.type, current.value, current.selector);
|
||||||
this->next();
|
this->next();
|
||||||
return node;
|
return sign * node;
|
||||||
}
|
}
|
||||||
|
|
||||||
UDQASTNode UDQParser::parse_pow() {
|
UDQASTNode UDQParser::parse_pow() {
|
||||||
|
@ -2293,3 +2293,37 @@ BOOST_AUTO_TEST_CASE(UDQ_DIV_TEST) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(UDQ_LEADING_SIGN) {
|
||||||
|
std::string deck_string = R"(
|
||||||
|
SCHEDULE
|
||||||
|
|
||||||
|
UDQ
|
||||||
|
DEFINE FU_VAR1 - 100 + 215 /
|
||||||
|
DEFINE FU_VAR2 (-100 + 200) / 10 /
|
||||||
|
DEFINE FU_VAR3 -(100 + 200) * -10 /
|
||||||
|
DEFINE FU_VAR4 2^-1 /
|
||||||
|
ASSIGN FU_VAR6 2 /
|
||||||
|
ASSIGN FU_VAR7 3 /
|
||||||
|
DEFINE FU_VAR5 (-0.00000041232 * (FU_VAR6 ^ 2)) + (0.0010395 * FU_VAR7) + 0.16504 /
|
||||||
|
/
|
||||||
|
|
||||||
|
)";
|
||||||
|
|
||||||
|
auto schedule = make_schedule(deck_string);
|
||||||
|
UDQState udq_state(0);
|
||||||
|
SummaryState st(std::chrono::system_clock::now());
|
||||||
|
|
||||||
|
const auto& udq = schedule.getUDQConfig(0);
|
||||||
|
udq.eval(0, st, udq_state);
|
||||||
|
auto fu_var1 = st.get("FU_VAR1");
|
||||||
|
auto fu_var2 = st.get("FU_VAR2");
|
||||||
|
auto fu_var3 = st.get("FU_VAR3");
|
||||||
|
auto fu_var4 = st.get("FU_VAR4");
|
||||||
|
auto fu_var5 = st.get("FU_VAR5");
|
||||||
|
BOOST_CHECK_EQUAL(fu_var1, 115);
|
||||||
|
BOOST_CHECK_EQUAL(fu_var2, 10);
|
||||||
|
BOOST_CHECK_EQUAL(fu_var3, 3000);
|
||||||
|
BOOST_CHECK_EQUAL(fu_var4, 0.5);
|
||||||
|
BOOST_CHECK_CLOSE(fu_var5, -0.00000041232 * 4 + 0.0010395 * 3 + 0.16504, 1e-5);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user