Changed UDQDefine to take UDQParams argument
This commit is contained in:
@@ -37,16 +37,18 @@ class ErrorGuard;
|
||||
|
||||
class UDQDefine{
|
||||
public:
|
||||
UDQDefine(const UDQFunctionTable& udqft, const std::string& keyword, const std::vector<std::string>& deck_data);
|
||||
UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
const std::vector<std::string>& deck_data);
|
||||
|
||||
UDQDefine(const UDQFunctionTable& udqft,
|
||||
UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors);
|
||||
|
||||
template <typename T>
|
||||
UDQDefine(const UDQFunctionTable& udqft,
|
||||
UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
@@ -62,10 +64,10 @@ public:
|
||||
std::vector<std::string> tokens;
|
||||
UDQVarType var_type() const;
|
||||
private:
|
||||
const UDQParams& udq_params; // Beacuse of the shared RNG stream this must be a reference.
|
||||
std::string m_keyword;
|
||||
std::shared_ptr<UDQASTNode> ast;
|
||||
UDQVarType m_var_type;
|
||||
UDQFunctionTable udqft;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -247,6 +247,7 @@ namespace Opm {
|
||||
*/
|
||||
const static std::string UNSUPPORTED_TERMINATE_IF_BHP;
|
||||
|
||||
const static std::string UDQ_PARSE_ERROR;
|
||||
|
||||
/*
|
||||
If the third item in the THPRES keyword is defaulted the
|
||||
|
||||
@@ -43,6 +43,12 @@ UDQASTNode::UDQASTNode(UDQTokenType type) :
|
||||
throw std::invalid_argument("The one argument constructor is only available for error and end");
|
||||
}
|
||||
|
||||
UDQASTNode::UDQASTNode(double scalar_value) :
|
||||
type(UDQTokenType::number),
|
||||
scalar_value(scalar_value)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
|
||||
UDQASTNode::UDQASTNode(UDQTokenType type_arg,
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
UDQASTNode();
|
||||
|
||||
UDQASTNode(UDQTokenType type_arg);
|
||||
UDQASTNode(double scalar_value);
|
||||
UDQASTNode(UDQTokenType type_arg, const std::string& string_value, const std::vector<std::string>& selector);
|
||||
UDQASTNode(UDQTokenType type_arg, const std::string& func_name, const UDQASTNode& arg);
|
||||
UDQASTNode(UDQTokenType type_arg, const std::string& func_name, const UDQASTNode& left, const UDQASTNode& right);
|
||||
|
||||
@@ -62,30 +62,30 @@ std::vector<std::string> quote_split(const std::string& item) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
UDQDefine::UDQDefine(const UDQFunctionTable& udqft,
|
||||
UDQDefine::UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
T&& errors) :
|
||||
UDQDefine(udqft, keyword, deck_data, parseContext, errors)
|
||||
UDQDefine(udq_params, keyword, deck_data, parseContext, errors)
|
||||
{}
|
||||
|
||||
|
||||
UDQDefine::UDQDefine(const UDQFunctionTable& udqft,
|
||||
UDQDefine::UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
const std::vector<std::string>& deck_data) :
|
||||
UDQDefine(udqft, keyword, deck_data, ParseContext(), ErrorGuard())
|
||||
UDQDefine(udq_params, keyword, deck_data, ParseContext(), ErrorGuard())
|
||||
{}
|
||||
|
||||
|
||||
UDQDefine::UDQDefine(const UDQFunctionTable& udqft,
|
||||
UDQDefine::UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors) :
|
||||
udq_params(udq_params),
|
||||
m_keyword(keyword),
|
||||
m_var_type(UDQ::varType(keyword)),
|
||||
udqft(udqft)
|
||||
m_var_type(UDQ::varType(keyword))
|
||||
{
|
||||
std::vector<std::string> tokens;
|
||||
for (const std::string& deck_item : deck_data) {
|
||||
@@ -121,7 +121,7 @@ UDQDefine::UDQDefine(const UDQFunctionTable& udqft,
|
||||
|
||||
}
|
||||
}
|
||||
this->ast = std::make_shared<UDQASTNode>( UDQParser::parse(udqft, tokens) );
|
||||
this->ast = std::make_shared<UDQASTNode>( UDQParser::parse(this->udq_params, tokens, parseContext, errors) );
|
||||
this->tokens = tokens;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,8 +55,7 @@ namespace Opm {
|
||||
double value = std::stod(data.back());
|
||||
this->m_assignments.emplace_back( quantity, selector, value );
|
||||
} else
|
||||
this->m_expressions.emplace_back(this->udqft, quantity, data);
|
||||
|
||||
this->m_definitions.emplace_back(this->udq_params, quantity, data);
|
||||
this->keywords.insert(quantity);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include "UDQParser.hpp"
|
||||
|
||||
namespace Opm {
|
||||
@@ -145,6 +146,8 @@ UDQASTNode UDQParser::parse_pow() {
|
||||
auto func_node = current;
|
||||
this->next();
|
||||
auto right = this->parse_mul();
|
||||
if (right.type == UDQTokenType::end)
|
||||
return UDQASTNode(UDQTokenType::error);
|
||||
|
||||
return UDQASTNode(current.type, current.value, left, right);
|
||||
}
|
||||
@@ -164,6 +167,8 @@ UDQASTNode UDQParser::parse_mul() {
|
||||
auto func_node = current;
|
||||
this->next();
|
||||
auto right = this->parse_mul();
|
||||
if (right.type == UDQTokenType::end)
|
||||
return UDQASTNode(UDQTokenType::error);
|
||||
|
||||
return UDQASTNode(current.type, current.value, left, right);
|
||||
}
|
||||
@@ -180,8 +185,10 @@ UDQASTNode UDQParser::parse_add() {
|
||||
|
||||
if (current.type == UDQTokenType::binary_op_add || current.type == UDQTokenType::binary_op_sub) {
|
||||
auto func_node = current;
|
||||
this->next();
|
||||
auto next = this->next();
|
||||
auto right = this->parse_add();
|
||||
if (right.type == UDQTokenType::end)
|
||||
return UDQASTNode(UDQTokenType::error);
|
||||
|
||||
return UDQASTNode(current.type, current.value, left, right);
|
||||
}
|
||||
@@ -195,10 +202,11 @@ UDQASTNode UDQParser::parse_add() {
|
||||
|
||||
auto cmp = a + b < c;
|
||||
|
||||
The sum (a+b) is evaluated and then compared with c, that is the the order of
|
||||
The sum (a+b) is evaluated and then compared with c, that is the order of
|
||||
presedence implemented here. But reading the eclipse UDQ manual one can get
|
||||
the imporession that the relation operators should bind "very strong", i.e.
|
||||
that (b < c) should be evaluated first, and then the result added to a.
|
||||
that (b < c) should be evaluated first, and then the result of the comparison
|
||||
added to a.
|
||||
*/
|
||||
|
||||
UDQASTNode UDQParser::parse_cmp() {
|
||||
@@ -211,6 +219,8 @@ UDQASTNode UDQParser::parse_cmp() {
|
||||
auto func_node = current;
|
||||
this->next();
|
||||
auto right = this->parse_cmp();
|
||||
if (right.type == UDQTokenType::end)
|
||||
return UDQASTNode(UDQTokenType::error);
|
||||
|
||||
return UDQASTNode(current.type, current.value, left, right);
|
||||
}
|
||||
@@ -222,23 +232,29 @@ UDQASTNode UDQParser::parse_cmp() {
|
||||
|
||||
|
||||
|
||||
UDQASTNode UDQParser::parse(const UDQFunctionTable& udqft, const std::vector<std::string>& tokens)
|
||||
UDQASTNode UDQParser::parse(const UDQParams& udq_params, const std::vector<std::string>& tokens, const ParseContext& parseContext, ErrorGuard& errors)
|
||||
{
|
||||
UDQParser parser(udqft, tokens);
|
||||
UDQParser parser(udq_params, tokens);
|
||||
parser.next();
|
||||
|
||||
auto tree = parser.parse_cmp();
|
||||
auto current = parser.current();
|
||||
if (current.type != UDQTokenType::end) {
|
||||
size_t index = parser.current_pos;
|
||||
throw std::invalid_argument("Extra unhandled data starting with token[" + std::to_string(index) + "] = " + current.value);
|
||||
}
|
||||
|
||||
if (tree.type == UDQTokenType::error)
|
||||
throw std::invalid_argument("Failed to parse UDQ DEFINE tokens");
|
||||
if (current.type != UDQTokenType::end || tree.type == UDQTokenType::error) {
|
||||
if (current.type != UDQTokenType::end) {
|
||||
size_t index = parser.current_pos;
|
||||
std::string msg = "Extra unhandled data starting with token[" + std::to_string(index) + "] = " + current.value;
|
||||
parseContext.handleError(ParseContext::UDQ_PARSE_ERROR, msg, errors);
|
||||
}
|
||||
|
||||
if (tree.type == UDQTokenType::error) {
|
||||
std::string msg = "Failed to parse UDQ expression";
|
||||
parseContext.handleError(ParseContext::UDQ_PARSE_ERROR, msg, errors);
|
||||
}
|
||||
return UDQASTNode( udq_params.undefinedValue() );
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -24,12 +24,16 @@
|
||||
#include <vector>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQFunctionTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
|
||||
#include "UDQASTNode.hpp"
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class ParseContext;
|
||||
class ErrorGuard;
|
||||
|
||||
struct UDQParseNode {
|
||||
UDQParseNode(UDQTokenType type_arg, const std::string& value_arg, const std::vector<std::string>& selector) :
|
||||
type(type_arg),
|
||||
@@ -54,11 +58,12 @@ struct UDQParseNode {
|
||||
|
||||
class UDQParser {
|
||||
public:
|
||||
static UDQASTNode parse(const UDQFunctionTable& udqft, const std::vector<std::string>& tokens);
|
||||
static UDQASTNode parse(const UDQParams& udq_params, const std::vector<std::string>& tokens, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
|
||||
private:
|
||||
UDQParser(const UDQFunctionTable& udqft, const std::vector<std::string>& tokens) :
|
||||
udqft(udqft),
|
||||
UDQParser(const UDQParams& udq_params, const std::vector<std::string>& tokens) :
|
||||
udq_params(udq_params),
|
||||
udqft(UDQFunctionTable(udq_params)),
|
||||
tokens(tokens)
|
||||
{}
|
||||
|
||||
@@ -73,7 +78,8 @@ private:
|
||||
UDQTokenType get_type(const std::string& arg) const;
|
||||
std::size_t current_size() const;
|
||||
|
||||
const UDQFunctionTable& udqft;
|
||||
const UDQParams& udq_params;
|
||||
UDQFunctionTable udqft;
|
||||
std::vector<std::string> tokens;
|
||||
ssize_t current_pos = -1;
|
||||
};
|
||||
|
||||
@@ -105,6 +105,8 @@ namespace Opm {
|
||||
|
||||
addKey(SIMULATOR_KEYWORD_NOT_SUPPORTED, InputError::WARN);
|
||||
addKey(SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED, InputError::WARN);
|
||||
|
||||
addKey(UDQ_PARSE_ERROR, InputError::THROW_EXCEPTION);
|
||||
}
|
||||
|
||||
void ParseContext::initEnv() {
|
||||
@@ -334,4 +336,6 @@ namespace Opm {
|
||||
|
||||
const std::string ParseContext::SIMULATOR_KEYWORD_NOT_SUPPORTED = "SIMULATOR_KEYWORD_NOT_SUPPORTED";
|
||||
const std::string ParseContext::SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED = "SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED";
|
||||
|
||||
const std::string ParseContext::UDQ_PARSE_ERROR = "UDQ_PARSE_ERROR";
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ Schedule make_schedule(const std::string& input) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(MIX_SCALAR) {
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def_add(udqft, "WU", {"WOPR", "+", "1"});
|
||||
UDQParams udqp;
|
||||
UDQDefine def_add(udqp, "WU", {"WOPR", "+", "1"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -62,8 +63,8 @@ BOOST_AUTO_TEST_CASE(MIX_SCALAR) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_TABLE_EXCEPTION) {
|
||||
UDQFunctionTable udqft;
|
||||
BOOST_CHECK_THROW(UDQDefine(udqft, "WU", {"TUPRICE[WOPR]"}), std::invalid_argument);
|
||||
UDQParams udqp;
|
||||
BOOST_CHECK_THROW(UDQDefine(udqp, "WU", {"TUPRICE[WOPR]"}), std::invalid_argument);
|
||||
}
|
||||
|
||||
|
||||
@@ -113,9 +114,10 @@ BOOST_AUTO_TEST_CASE(UDQWellSetTest) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQFunctionTable udqft;
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft(udqp);
|
||||
{
|
||||
UDQDefine def(udqft, "WUBHP", {"WBHP"});
|
||||
UDQDefine def(udqp, "WUBHP", {"WBHP"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -129,7 +131,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
BOOST_CHECK_EQUAL( res["W3"].value(), 3 );
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqft, "WUBHP", {"WBHP" , "'P*'"});
|
||||
UDQDefine def(udqp, "WUBHP", {"WBHP" , "'P*'"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -146,7 +148,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
BOOST_CHECK_EQUAL( res["I1"].defined(), false);
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqft, "WUBHP", {"WBHP" , "'P1'"});
|
||||
UDQDefine def(udqp, "WUBHP", {"WBHP" , "'P1'"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -156,7 +158,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
}
|
||||
|
||||
{
|
||||
UDQDefine def(udqft, "WUBHP", {"NINT" , "(", "WBHP", ")"});
|
||||
UDQDefine def(udqp, "WUBHP", {"NINT" , "(", "WBHP", ")"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
st.add_well_var("P1", "WBHP", 4);
|
||||
@@ -175,7 +177,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
// scalar context and that is not appropriate for the WUBHP variable which
|
||||
// should evaluate to a full well set.
|
||||
{
|
||||
UDQDefine def(udqft, "WUBHP", {"SUM" , "(", "WBHP", ")"});
|
||||
UDQDefine def(udqp, "WUBHP", {"SUM" , "(", "WBHP", ")"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -804,8 +806,9 @@ BOOST_AUTO_TEST_CASE(UDQASSIGN_TEST) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_POW_TEST) {
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def_pow1(udqft, "WU", {"WOPR", "+", "WWPR", "*", "WGOR", "^", "WWIR"});
|
||||
UDQDefine def_pow2(udqft, "WU", {"(", "WOPR", "+", "WWPR", ")", "^", "(", "WOPR", "+" , "WGOR", "*", "WWIR", "-", "WOPT", ")"});
|
||||
UDQParams udqp;
|
||||
UDQDefine def_pow1(udqp, "WU", {"WOPR", "+", "WWPR", "*", "WGOR", "^", "WWIR"});
|
||||
UDQDefine def_pow2(udqp, "WU", {"(", "WOPR", "+", "WWPR", ")", "^", "(", "WOPR", "+" , "WGOR", "*", "WWIR", "-", "WOPT", ")"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -823,7 +826,8 @@ BOOST_AUTO_TEST_CASE(UDQ_POW_TEST) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) {
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def_cmp(udqft, "WU", {"WOPR", ">", "WWPR", "+", "WGOR", "*", "WWIR"});
|
||||
UDQParams udqp;
|
||||
UDQDefine def_cmp(udqp, "WU", {"WOPR", ">", "WWPR", "+", "WGOR", "*", "WWIR"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -842,15 +846,22 @@ BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) {
|
||||
BOOST_CHECK_EQUAL( res_cmp["P2"].value() , 0.0);
|
||||
}
|
||||
|
||||
/*BOOST_AUTO_TEST_CASE(UDQPARSE_ERROR) {
|
||||
setUDQFunctionTable udqft;
|
||||
UDQDefine def1(udqft, "WUBHP", {"WWCT", "+"});
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_BASIC_MATH_TEST) {
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def_add(udqft, "WU2OPR", {"WOPR", "+", "WOPR"});
|
||||
UDQDefine def_sub(udqft, "WU2OPR", {"WOPR", "-", "WOPR"});
|
||||
UDQDefine def_mul(udqft, "WU2OPR", {"WOPR", "*", "WOPR"});
|
||||
UDQDefine def_div(udqft, "WU2OPR", {"WOPR", "/", "WOPR"});
|
||||
UDQDefine def_muladd(udqft , "WUX", {"WOPR", "+", "WOPR", "*", "WOPR"});
|
||||
UDQDefine def_wuwct(udqft , "WUWCT", {"WWPR", "/", "(", "WOPR", "+", "WWPR", ")"});
|
||||
UDQDefine def_add(udqp, "WU2OPR", {"WOPR", "+", "WOPR"});
|
||||
UDQDefine def_sub(udqp, "WU2OPR", {"WOPR", "-", "WOPR"});
|
||||
UDQDefine def_mul(udqp, "WU2OPR", {"WOPR", "*", "WOPR"});
|
||||
UDQDefine def_div(udqp, "WU2OPR", {"WOPR", "/", "WOPR"});
|
||||
UDQDefine def_muladd(udqp , "WUX", {"WOPR", "+", "WOPR", "*", "WOPR"});
|
||||
UDQDefine def_wuwct(udqp , "WUWCT", {"WWPR", "/", "(", "WOPR", "+", "WWPR", ")"});
|
||||
SummaryState st;
|
||||
UDQContext context(udqft, st);
|
||||
|
||||
@@ -909,16 +920,37 @@ BOOST_AUTO_TEST_CASE(UDQ_BASIC_MATH_TEST) {
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQPARSE_TEST1) {
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def1(udqft, "WUBHP", {"1/(WWCT", "'W1*')"});
|
||||
UDQParams udqp;
|
||||
UDQDefine def1(udqp, "WUBHP", {"1/(WWCT", "'W1*')"});
|
||||
std::vector<std::string> tokens1 = {"1", "/", "(", "WWCT", "W1*", ")"};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(tokens1.begin(), tokens1.end(),
|
||||
def1.tokens.begin(), def1.tokens.end());
|
||||
|
||||
|
||||
UDQDefine def2(udqft, "WUBHP", {"2*(1", "+" , "WBHP)"});
|
||||
UDQDefine def2(udqp, "WUBHP", {"2*(1", "+" , "WBHP)"});
|
||||
std::vector<std::string> tokens2 = {"2", "*", "(", "1", "+", "WBHP", ")"};
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(tokens2.begin(), tokens2.end(),
|
||||
def2.tokens.begin(), def2.tokens.end());
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQPARSE_PARSECONTEXT) {
|
||||
UDQParams udqp;
|
||||
ParseContext parseContext;
|
||||
ErrorGuard errors;
|
||||
std::vector<std::string> tokens = {"WBHP", "+"};
|
||||
parseContext.update(ParseContext::UDQ_PARSE_ERROR, InputError::IGNORE);
|
||||
{
|
||||
UDQDefine def1(udqp, "WUBHP", tokens, parseContext, errors);
|
||||
SummaryState st;
|
||||
UDQContext context(UDQFunctionTable(udqp), st);
|
||||
st.add_well_var("P1", "WOPR", 1);
|
||||
printf("Have returned with def1 \n");
|
||||
|
||||
auto res = def1.eval_wells(context);
|
||||
BOOST_CHECK_EQUAL(res["P1"].value(), udqp.undefinedValue());
|
||||
}
|
||||
|
||||
parseContext.update(ParseContext::UDQ_PARSE_ERROR, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "WUBHP", tokens, parseContext, errors), std::invalid_argument);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user