Merge pull request #2112 from joakim-hove/udq-update
Support UDQ UPDATE
This commit is contained in:
commit
8ffb918650
@ -59,8 +59,9 @@ namespace Opm {
|
||||
void add_record(const DeckRecord& record, const KeywordLocation& location, std::size_t report_step);
|
||||
|
||||
void add_unit(const std::string& keyword, const std::string& unit);
|
||||
void add_update(const std::string& keyword, std::size_t report_step, const KeywordLocation& location, const std::vector<std::string>& data);
|
||||
void add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value, std::size_t report_step);
|
||||
void add_define(const std::string& quantity, const KeywordLocation& location, const std::vector<std::string>& expression);
|
||||
void add_define(const std::string& quantity, const KeywordLocation& location, const std::vector<std::string>& expression, std::size_t report_step);
|
||||
|
||||
void eval(std::size_t report_step, const WellMatcher& wm, SummaryState& st, UDQState& udq_state) const;
|
||||
const UDQDefine& define(const std::string& key) const;
|
||||
|
@ -44,7 +44,7 @@ namespace Opm {
|
||||
std::optional<double> get_group_var(const std::string& group, const std::string& var) const;
|
||||
void add(const std::string& key, double value);
|
||||
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);
|
||||
void update_define(std::size_t report_step, const std::string& keyword, const UDQSet& udq_result);
|
||||
const UDQFunctionTable& function_table() const;
|
||||
std::vector<std::string> wells() const;
|
||||
std::vector<std::string> wells(const std::string& pattern) const;
|
||||
|
@ -44,11 +44,13 @@ public:
|
||||
|
||||
UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
std::size_t report_step,
|
||||
const KeywordLocation& location,
|
||||
const std::vector<std::string>& deck_data);
|
||||
|
||||
UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
std::size_t report_step,
|
||||
const KeywordLocation& location,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
@ -57,6 +59,7 @@ public:
|
||||
template <typename T>
|
||||
UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
std::size_t report_step,
|
||||
const KeywordLocation& location,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
@ -71,6 +74,8 @@ public:
|
||||
UDQVarType var_type() const;
|
||||
std::set<UDQTokenType> func_tokens() const;
|
||||
void required_summary(std::unordered_set<std::string>& summary_keys) const;
|
||||
void update_status(UDQUpdate update_status, std::size_t report_step);
|
||||
std::pair<UDQUpdate, std::size_t> status() const;
|
||||
|
||||
bool operator==(const UDQDefine& data) const;
|
||||
|
||||
@ -82,6 +87,8 @@ public:
|
||||
serializer(m_var_type);
|
||||
m_location.serializeOp(serializer);
|
||||
serializer(string_data);
|
||||
serializer(m_update_status);
|
||||
serializer(m_report_step);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -89,6 +96,8 @@ private:
|
||||
std::shared_ptr<UDQASTNode> ast;
|
||||
UDQVarType m_var_type;
|
||||
KeywordLocation m_location;
|
||||
std::size_t m_report_step;
|
||||
UDQUpdate m_update_status;
|
||||
std::string string_data;
|
||||
};
|
||||
}
|
||||
|
@ -133,6 +133,13 @@ enum class UDQAction {
|
||||
UPDATE
|
||||
};
|
||||
|
||||
enum class UDQUpdate {
|
||||
ON,
|
||||
OFF,
|
||||
NEXT
|
||||
};
|
||||
|
||||
|
||||
enum class UDAControl {
|
||||
WCONPROD_ORAT,
|
||||
WCONPROD_GRAT,
|
||||
@ -170,6 +177,7 @@ namespace UDQ {
|
||||
UDQVarType varType(const std::string& keyword);
|
||||
UDQVarType coerce(UDQVarType t1, UDQVarType t2);
|
||||
UDQAction actionType(const std::string& action_string);
|
||||
UDQUpdate updateType(const std::string& update_string);
|
||||
UDQTokenType tokenType(const std::string& func_name);
|
||||
UDQTokenType funcType(const std::string& func_name);
|
||||
bool binaryFunc(UDQTokenType token_type);
|
||||
|
@ -64,7 +64,6 @@ public:
|
||||
|
||||
class UDQSet {
|
||||
public:
|
||||
UDQSet(const std::string& name);
|
||||
UDQSet(const std::string& name, UDQVarType var_type);
|
||||
UDQSet(const std::string& name, UDQVarType var_type, const std::vector<std::string>& wgnames);
|
||||
UDQSet(const std::string& name, UDQVarType var_type, std::size_t size);
|
||||
|
@ -39,9 +39,10 @@ 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_define(const std::string& udq_key, const UDQSet& result);
|
||||
void add_define(std::size_t report_step, 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;
|
||||
bool define(const std::string& udq_key, std::pair<UDQUpdate, std::size_t> update_status) const;
|
||||
double undefined_value() const;
|
||||
|
||||
std::vector<char> serialize() const;
|
||||
@ -53,6 +54,7 @@ private:
|
||||
double undef_value;
|
||||
std::unordered_map<std::string, UDQSet> values;
|
||||
std::unordered_map<std::string, std::size_t> assignments;
|
||||
std::unordered_map<std::string, std::size_t> defines;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -2070,6 +2070,7 @@ namespace Evaluator {
|
||||
const auto val = st.get_elapsed() + stepSize;
|
||||
|
||||
st.update(this->saveKey_, usys.from_si(m, val));
|
||||
st.update("TIME", usys.from_si(m, val));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2997,6 +2998,7 @@ std::vector<Opm::EclIO::SummaryNode> make_default_nodes(const std::string& keywo
|
||||
|
||||
|
||||
void Opm::out::Summary::SummaryImplementation::configureUDQ(const SummaryConfig& summary_config, const Schedule& sched) {
|
||||
const std::unordered_set<std::string> time_vectors = {"TIME", "DAY", "MONTH", "YEAR", "YEARS"};
|
||||
auto nodes = std::vector<Opm::EclIO::SummaryNode> {};
|
||||
std::unordered_set<std::string> summary_keys;
|
||||
for (const auto& udq_ptr : sched.udqConfigList())
|
||||
@ -3009,20 +3011,31 @@ void Opm::out::Summary::SummaryImplementation::configureUDQ(const SummaryConfig&
|
||||
}
|
||||
|
||||
for (const auto& node: nodes) {
|
||||
// Handler already configured/requested through the normal SummaryConfig path.
|
||||
if (summary_config.hasSummaryKey(node.unique_key()))
|
||||
// Handler already exists. Don't add second evaluation.
|
||||
continue;
|
||||
|
||||
// Time related vectors are special cased in the valueKeys_ vector and must be checked explicitly.
|
||||
if (time_vectors.count(node.keyword) > 0)
|
||||
continue;
|
||||
|
||||
// Handler already registered in the summary evaluator, in some other way.
|
||||
if ( std::find(this->valueKeys_.begin(), this->valueKeys_.end(), node.unique_key()) != this->valueKeys_.end())
|
||||
continue;
|
||||
|
||||
auto fun_pos = funs.find(node.keyword);
|
||||
if (fun_pos != funs.end())
|
||||
if (fun_pos != funs.end()) {
|
||||
this->extra_parameters.emplace( node.unique_key(), std::make_unique<Evaluator::FunctionRelation>(node, fun_pos->second) );
|
||||
else {
|
||||
auto unit = single_values_units.find(node.keyword);
|
||||
if (unit == single_values_units.end())
|
||||
throw std::logic_error(fmt::format("Evaluation function for: {} not found ", node.keyword));
|
||||
|
||||
this->extra_parameters.emplace( node.unique_key(), std::make_unique<Evaluator::GlobalProcessValue>(node, unit->second));
|
||||
continue;
|
||||
}
|
||||
|
||||
auto unit = single_values_units.find(node.keyword);
|
||||
if (unit != single_values_units.end()) {
|
||||
this->extra_parameters.emplace( node.unique_key(), std::make_unique<Evaluator::GlobalProcessValue>(node, unit->second));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw std::logic_error(fmt::format("Evaluation function for: {} not found ", node.keyword));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,11 @@
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
|
||||
#include <opm/common/OpmLog/KeywordLocation.hpp>
|
||||
#include <opm/common/utility/OpmInputError.hpp>
|
||||
#include <opm/parser/eclipse/Deck/Deck.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
|
||||
@ -87,13 +91,13 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void UDQConfig::add_define(const std::string& quantity, const KeywordLocation& location, const std::vector<std::string>& expression) {
|
||||
void UDQConfig::add_define(const std::string& quantity, const KeywordLocation& location, const std::vector<std::string>& expression, std::size_t report_step) {
|
||||
this->add_node(quantity, UDQAction::DEFINE);
|
||||
auto defined_iter = this->m_definitions.find( quantity );
|
||||
if (defined_iter != this->m_definitions.end())
|
||||
this->m_definitions.erase( defined_iter );
|
||||
|
||||
this->m_definitions.insert( std::make_pair(quantity, UDQDefine(this->udq_params, quantity, location, expression)));
|
||||
this->m_definitions.insert( std::make_pair(quantity, UDQDefine(this->udq_params, quantity, report_step, location, expression)));
|
||||
this->define_order.insert(quantity);
|
||||
}
|
||||
|
||||
@ -120,15 +124,28 @@ namespace Opm {
|
||||
}
|
||||
|
||||
|
||||
void UDQConfig::add_update(const std::string& keyword, std::size_t report_step, const KeywordLocation& location, const std::vector<std::string>& data) {
|
||||
if (data.empty())
|
||||
throw OpmInputError( fmt::format("Missing third item: ON|OFF|NEXT for UDQ update of {}", keyword), location);
|
||||
|
||||
if (this->m_definitions.count(keyword) == 0)
|
||||
throw OpmInputError( fmt::format("UDQ variable: {} must be defined before you can use UPDATE", keyword), location);
|
||||
|
||||
auto update_status = UDQ::updateType(data[0]);
|
||||
auto& define = this->m_definitions[keyword];
|
||||
define.update_status( update_status, report_step );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void UDQConfig::add_record(const DeckRecord& record, const KeywordLocation& location, std::size_t report_step) {
|
||||
auto action = UDQ::actionType(record.getItem("ACTION").get<RawString>(0));
|
||||
const auto& quantity = record.getItem("QUANTITY").get<std::string>(0);
|
||||
const auto& data = RawString::strings( record.getItem("DATA").getData<RawString>() );
|
||||
|
||||
if (action == UDQAction::UPDATE)
|
||||
throw std::invalid_argument("The UDQ action UPDATE is not yet implemented in opm/flow");
|
||||
|
||||
if (action == UDQAction::UNITS)
|
||||
this->add_update(quantity, report_step, location, data);
|
||||
else if (action == UDQAction::UNITS)
|
||||
this->add_unit( quantity, data[0] );
|
||||
else {
|
||||
if (action == UDQAction::ASSIGN) {
|
||||
@ -136,7 +153,7 @@ namespace Opm {
|
||||
double value = std::stod(data.back());
|
||||
this->add_assign(quantity, selector, value, report_step);
|
||||
} else if (action == UDQAction::DEFINE)
|
||||
this->add_define(quantity, location, data);
|
||||
this->add_define(quantity, location, data, report_step);
|
||||
else
|
||||
throw std::runtime_error("Internal error - should not be here");
|
||||
}
|
||||
@ -314,8 +331,10 @@ namespace Opm {
|
||||
}
|
||||
|
||||
for (const auto& def : this->definitions(UDQVarType::WELL_VAR)) {
|
||||
auto ws = def.eval(context);
|
||||
context.update_define(def.keyword(), ws);
|
||||
if (udq_state.define(def.keyword(), def.status())) {
|
||||
auto ws = def.eval(context);
|
||||
context.update_define(report_step, def.keyword(), ws);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& assign : this->assignments(UDQVarType::GROUP_VAR)) {
|
||||
@ -326,8 +345,10 @@ namespace Opm {
|
||||
}
|
||||
|
||||
for (const auto& def : this->definitions(UDQVarType::GROUP_VAR)) {
|
||||
auto ws = def.eval(context);
|
||||
context.update_define(def.keyword(), ws);
|
||||
if (udq_state.define(def.keyword(), def.status())) {
|
||||
auto ws = def.eval(context);
|
||||
context.update_define(report_step, def.keyword(), ws);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& assign : this->assignments(UDQVarType::FIELD_VAR)) {
|
||||
@ -338,8 +359,10 @@ namespace Opm {
|
||||
}
|
||||
|
||||
for (const auto& def : this->definitions(UDQVarType::FIELD_VAR)) {
|
||||
auto field_udq = def.eval(context);
|
||||
context.update_define(def.keyword(), field_udq);
|
||||
if (udq_state.define(def.keyword(), def.status())) {
|
||||
auto field_udq = def.eval(context);
|
||||
context.update_define(report_step, def.keyword(), field_udq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,12 +56,10 @@ bool is_udq(const std::string& key) {
|
||||
the underlying summary state object.
|
||||
*/
|
||||
|
||||
this->add("ELAPSED", 0.0);
|
||||
this->add("MSUMLINS", 0.0);
|
||||
this->add("MSUMNEWT", 0.0);
|
||||
this->add("NEWTON", 0.0);
|
||||
this->add("TCPU", 0.0);
|
||||
this->add("TIME", 0.0);
|
||||
}
|
||||
|
||||
|
||||
@ -138,8 +136,8 @@ bool is_udq(const std::string& key) {
|
||||
this->summary_state.update_udq(udq_result, this->udq_state.undefined_value());
|
||||
}
|
||||
|
||||
void UDQContext::update_define(const std::string& keyword, const UDQSet& udq_result) {
|
||||
this->udq_state.add_define(keyword, udq_result);
|
||||
void UDQContext::update_define(std::size_t report_step, const std::string& keyword, const UDQSet& udq_result) {
|
||||
this->udq_state.add_define(report_step, keyword, udq_result);
|
||||
this->summary_state.update_udq(udq_result, this->udq_state.undefined_value());
|
||||
}
|
||||
}
|
||||
|
@ -114,19 +114,21 @@ UDQDefine::UDQDefine()
|
||||
template <typename T>
|
||||
UDQDefine::UDQDefine(const UDQParams& udq_params_arg,
|
||||
const std::string& keyword,
|
||||
std::size_t report_step,
|
||||
const KeywordLocation& location,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
T&& errors) :
|
||||
UDQDefine(udq_params_arg, keyword, location, deck_data, parseContext, errors)
|
||||
UDQDefine(udq_params_arg, keyword, report_step, location, deck_data, parseContext, errors)
|
||||
{}
|
||||
|
||||
|
||||
UDQDefine::UDQDefine(const UDQParams& udq_params_arg,
|
||||
const std::string& keyword,
|
||||
std::size_t report_step,
|
||||
const KeywordLocation& location,
|
||||
const std::vector<std::string>& deck_data) :
|
||||
UDQDefine(udq_params_arg, keyword, location, deck_data, ParseContext(), ErrorGuard())
|
||||
UDQDefine(udq_params_arg, keyword, report_step, location, deck_data, ParseContext(), ErrorGuard())
|
||||
{}
|
||||
|
||||
namespace {
|
||||
@ -163,13 +165,16 @@ std::optional<std::string> next_token(const std::string& item, std::size_t offse
|
||||
|
||||
UDQDefine::UDQDefine(const UDQParams& udq_params,
|
||||
const std::string& keyword,
|
||||
std::size_t report_step,
|
||||
const KeywordLocation& location,
|
||||
const std::vector<std::string>& deck_data,
|
||||
const ParseContext& parseContext,
|
||||
ErrorGuard& errors) :
|
||||
m_keyword(keyword),
|
||||
m_var_type(UDQ::varType(keyword)),
|
||||
m_location(location)
|
||||
m_report_step(report_step),
|
||||
m_location(location),
|
||||
m_update_status(UDQUpdate::ON)
|
||||
{
|
||||
std::vector<std::string> string_tokens;
|
||||
for (const std::string& deck_item : deck_data) {
|
||||
@ -201,6 +206,11 @@ UDQDefine::UDQDefine(const UDQParams& udq_params,
|
||||
}
|
||||
}
|
||||
|
||||
void UDQDefine::update_status(UDQUpdate update, std::size_t report_step) {
|
||||
this->m_update_status = update;
|
||||
this->m_report_step = report_step;
|
||||
}
|
||||
|
||||
|
||||
|
||||
UDQDefine UDQDefine::serializeObject()
|
||||
@ -211,7 +221,8 @@ UDQDefine UDQDefine::serializeObject()
|
||||
result.m_var_type = UDQVarType::SEGMENT_VAR;
|
||||
result.string_data = "test2";
|
||||
result.m_location = KeywordLocation{"KEYWOR", "file", 100};
|
||||
|
||||
result.m_update_status = UDQUpdate::NEXT;
|
||||
result.m_report_step = 99;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -324,6 +335,12 @@ std::set<UDQTokenType> UDQDefine::func_tokens() const {
|
||||
return this->ast->func_tokens();
|
||||
}
|
||||
|
||||
std::pair<UDQUpdate, std::size_t> UDQDefine::status() const {
|
||||
return std::make_pair(this->m_update_status, this->m_report_step);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool UDQDefine::operator==(const UDQDefine& data) const {
|
||||
if ((ast && !data.ast) || (!ast && data.ast))
|
||||
return false;
|
||||
@ -333,6 +350,7 @@ bool UDQDefine::operator==(const UDQDefine& data) const {
|
||||
return this->keyword() == data.keyword() &&
|
||||
this->m_location == data.location() &&
|
||||
this->var_type() == data.var_type() &&
|
||||
this->status() == data.status() &&
|
||||
this->input_string() == data.input_string();
|
||||
}
|
||||
|
||||
|
@ -226,6 +226,21 @@ UDQAction actionType(const std::string& action_string) {
|
||||
}
|
||||
|
||||
|
||||
UDQUpdate updateType(const std::string& update_string) {
|
||||
if (update_string == "ON")
|
||||
return UDQUpdate::ON;
|
||||
|
||||
if (update_string == "OFF")
|
||||
return UDQUpdate::OFF;
|
||||
|
||||
if (update_string == "NEXT")
|
||||
return UDQUpdate::NEXT;
|
||||
|
||||
throw std::invalid_argument("Invalid status update string " + update_string);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool binaryFunc(UDQTokenType token_type) {
|
||||
return (binary_func.count(token_type) > 0);
|
||||
}
|
||||
|
@ -87,7 +87,8 @@ void UDQState::add(const std::string& udq_key, const UDQSet& result) {
|
||||
res_iter->second = result;
|
||||
}
|
||||
|
||||
void UDQState::add_define(const std::string& udq_key, const UDQSet& result) {
|
||||
void UDQState::add_define(std::size_t report_step, const std::string& udq_key, const UDQSet& result) {
|
||||
this->defines[udq_key] = report_step;
|
||||
this->add(udq_key, result);
|
||||
}
|
||||
|
||||
@ -136,7 +137,9 @@ double UDQState::get_group_var(const std::string& group, const std::string& key)
|
||||
|
||||
bool UDQState::operator==(const UDQState& other) const {
|
||||
return this->undef_value == other.undef_value &&
|
||||
this->values == other.values;
|
||||
this->values == other.values &&
|
||||
this->assignments == other.assignments &&
|
||||
this->defines == other.defines;
|
||||
}
|
||||
|
||||
|
||||
@ -149,6 +152,20 @@ bool UDQState::assign(std::size_t report_step, const std::string& udq_key) const
|
||||
return report_step > assign_iter->second;
|
||||
}
|
||||
|
||||
bool UDQState::define(const std::string& udq_key, std::pair<UDQUpdate, std::size_t> update_status) const {
|
||||
if (update_status.first == UDQUpdate::ON)
|
||||
return true;
|
||||
|
||||
if (update_status.first == UDQUpdate::OFF)
|
||||
return false;
|
||||
|
||||
auto define_iter = this->defines.find(udq_key);
|
||||
if (define_iter == this->defines.end())
|
||||
return true;
|
||||
|
||||
return define_iter->second < update_status.second;
|
||||
}
|
||||
|
||||
std::vector<char> UDQState::serialize() const {
|
||||
Serializer ser;
|
||||
ser.put(this->undef_value);
|
||||
@ -158,6 +175,7 @@ std::vector<char> UDQState::serialize() const {
|
||||
set_pair.second.serialize( ser );
|
||||
}
|
||||
ser.put(this->assignments);
|
||||
ser.put(this->defines);
|
||||
return ser.buffer;
|
||||
}
|
||||
|
||||
@ -177,6 +195,7 @@ void UDQState::deserialize(const std::vector<char>& buffer) {
|
||||
}
|
||||
}
|
||||
this->assignments = ser.get<std::string, std::size_t>();
|
||||
this->defines = ser.get<std::string, std::size_t>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,6 +287,8 @@ SUMMARY
|
||||
|
||||
FOPR
|
||||
|
||||
FU_TIME
|
||||
|
||||
WGOR
|
||||
/
|
||||
WOPR
|
||||
@ -382,6 +384,7 @@ UDQ
|
||||
UNITS WUWCT '1' /
|
||||
DEFINE FUOPR SUM(WOPR) /
|
||||
UNITS FUOPR 'SM3/DAY' /
|
||||
DEFINE FU_TIME TIME/
|
||||
/
|
||||
|
||||
|
||||
@ -450,75 +453,87 @@ WCONINJE
|
||||
-- BHP upper limit (item 7) should not be exceeding the highest
|
||||
-- pressure in the PVT table=9014.7psia (default is 100 000psia)
|
||||
|
||||
DATES
|
||||
DATES -- 1
|
||||
1 'JAN' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 2
|
||||
1 'FEB' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 3
|
||||
1 'MAR' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 4
|
||||
1 'APR' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 5
|
||||
1 'MAI' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 6
|
||||
1 'JUN' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 7
|
||||
1 'JUL' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 8
|
||||
1 'AUG' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
UDQ
|
||||
UPDATE FU_TIME OFF /
|
||||
/
|
||||
|
||||
DATES -- 9
|
||||
1 'SEP' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 10
|
||||
1 'OCT' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 11
|
||||
1 'NOV' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 12
|
||||
1 'DEC' 2015 /
|
||||
/
|
||||
|
||||
DATES
|
||||
UDQ
|
||||
UPDATE FU_TIME NEXT /
|
||||
/
|
||||
|
||||
DATES -- 13
|
||||
1 'JAN' 2016 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 14
|
||||
1 'FEB' 2016 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 15
|
||||
1 'MAR' 2016 /
|
||||
/
|
||||
|
||||
DATES
|
||||
UDQ
|
||||
UPDATE FU_TIME ON /
|
||||
/
|
||||
|
||||
DATES -- 16
|
||||
1 'APR' 2016 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 17
|
||||
1 'MAI' 2016 /
|
||||
/
|
||||
|
||||
DATES
|
||||
DATES -- 18
|
||||
1 'JUN' 2016 /
|
||||
/
|
||||
|
||||
|
@ -155,10 +155,12 @@ int ecl_sum_get_last_report_step(const EclIO::ESmry& smry)
|
||||
return static_cast<int>(smry.get_at_rstep("TIME").size());
|
||||
}
|
||||
|
||||
|
||||
int ecl_sum_iget_report_end(const EclIO::ESmry& smry, const int reportStep)
|
||||
{
|
||||
return smry.timestepIdxAtReportstepStart(reportStep + 1) - 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -342,6 +344,23 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
|
||||
ecl_sum_get_general_var(ecl_sum, step, "FUOPR"));
|
||||
BOOST_CHECK_EQUAL( wopr_sum, ecl_sum_get_general_var(ecl_sum, step, "FOPR"));
|
||||
}
|
||||
|
||||
{
|
||||
const auto& fu_time = ecl_sum.get_at_rstep("FU_TIME");
|
||||
BOOST_CHECK_CLOSE(fu_time[7 - 1], 212, 1e-5);
|
||||
// UPDATE OFF
|
||||
BOOST_CHECK_CLOSE(fu_time[8 - 1], 212, 1e-5);
|
||||
BOOST_CHECK_CLOSE(fu_time[9 - 1] , 212, 1e-5);
|
||||
BOOST_CHECK_CLOSE(fu_time[10 - 1], 212, 1e-5);
|
||||
BOOST_CHECK_CLOSE(fu_time[11 - 1], 212, 1e-5);
|
||||
// UPDATE NEXT
|
||||
BOOST_CHECK_CLOSE(fu_time[12 - 1], 342, 1e-5);
|
||||
BOOST_CHECK_CLOSE(fu_time[13 - 1], 342, 1e-5);
|
||||
BOOST_CHECK_CLOSE(fu_time[14 - 1], 342, 1e-5);
|
||||
// UPDATE ON
|
||||
BOOST_CHECK_CLOSE(fu_time[15 - 1], 456, 1e-5);
|
||||
BOOST_CHECK_CLOSE(fu_time[16 - 1], 487, 1e-5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(GROUP_VARIABLES)
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def_group(udqp, "GUOPRL", location, {"(", "5000", "-", "GOPR", "LOWER", "*", "0.13", "-", "GOPR", "UPPER", "*", "0.15", ")" , "*", "0.89"});
|
||||
UDQDefine def_group(udqp, "GUOPRL", 0, location, {"(", "5000", "-", "GOPR", "LOWER", "*", "0.13", "-", "GOPR", "UPPER", "*", "0.15", ")" , "*", "0.89"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
@ -104,8 +104,8 @@ BOOST_AUTO_TEST_CASE(SUBTRACT)
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def(udqp, "WU", location, {"16", "-", "8", "-", "4", "-", "2", "-", "1"});
|
||||
UDQDefine scalar(udqp, "WU", location, {"16"});
|
||||
UDQDefine def(udqp, "WU", 0, location, {"16", "-", "8", "-", "4", "-", "2", "-", "1"});
|
||||
UDQDefine scalar(udqp, "WU", 0, location, {"16"});
|
||||
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
@ -124,10 +124,10 @@ BOOST_AUTO_TEST_CASE(TEST)
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def1(udqp, "WUWI3", location, {"GOPR" , "MAU", "*", "2.0", "*", "0.25", "*", "10"});
|
||||
UDQDefine def2(udqp, "WUWI3", location, {"2.0", "*", "0.25", "*", "3"});
|
||||
UDQDefine def3(udqp, "WUWI3", location, {"GOPR" , "FIELD", "-", "2.0", "*", "3"});
|
||||
UDQDefine def4(udqp, "WUWI3", location, {"FOPR" , "/", "2"});
|
||||
UDQDefine def1(udqp, "WUWI3",0, location, {"GOPR" , "MAU", "*", "2.0", "*", "0.25", "*", "10"});
|
||||
UDQDefine def2(udqp, "WUWI3",0, location, {"2.0", "*", "0.25", "*", "3"});
|
||||
UDQDefine def3(udqp, "WUWI3",0, location, {"GOPR" , "FIELD", "-", "2.0", "*", "3"});
|
||||
UDQDefine def4(udqp, "WUWI3",0, location, {"FOPR" , "/", "2"});
|
||||
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
@ -160,12 +160,12 @@ BOOST_AUTO_TEST_CASE(TEST)
|
||||
This expression has a well set as target type, and involves group with
|
||||
wildcard that is not supported by flow.
|
||||
*/
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "WUWI2", location, {"GOPR", "G*", "*", "2.0"}), OpmInputError);
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "WUWI2",0, location, {"GOPR", "G*", "*", "2.0"}), OpmInputError);
|
||||
|
||||
/*
|
||||
UDQVarType == BLOCK is not yet supported.
|
||||
*/
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "WUWI2", location, {"BPR", "1","1", "1", "*", "2.0"}), OpmInputError);
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "WUWI2",0, location, {"BPR", "1","1", "1", "*", "2.0"}), OpmInputError);
|
||||
}
|
||||
|
||||
|
||||
@ -173,7 +173,7 @@ BOOST_AUTO_TEST_CASE(MIX_SCALAR) {
|
||||
UDQFunctionTable udqft;
|
||||
UDQParams udqp;
|
||||
KeywordLocation location;
|
||||
UDQDefine def_add(udqp, "WU", location, {"WOPR", "+", "1"});
|
||||
UDQDefine def_add(udqp, "WU",0, location, {"WOPR", "+", "1"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"P1"}), st, udq_state);
|
||||
@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(MIX_SCALAR) {
|
||||
BOOST_AUTO_TEST_CASE(UDQ_TABLE_EXCEPTION) {
|
||||
UDQParams udqp;
|
||||
KeywordLocation location;
|
||||
BOOST_CHECK_THROW(UDQDefine(udqp, "WU", location, {"TUPRICE[WOPR]"}), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(UDQDefine(udqp, "WU",0, location, {"TUPRICE[WOPR]"}), std::invalid_argument);
|
||||
}
|
||||
|
||||
|
||||
@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(UDQFieldSetTest) {
|
||||
*/
|
||||
|
||||
{
|
||||
UDQDefine def_fopr(udqp, "FUOPR", location, {"SUM", "(", "WOPR", ")"});
|
||||
UDQDefine def_fopr(udqp, "FUOPR",0, location, {"SUM", "(", "WOPR", ")"});
|
||||
auto fopr_res = def_fopr.eval(context);
|
||||
BOOST_CHECK_EQUAL( fopr_res[0].get(), 10.0 );
|
||||
}
|
||||
@ -300,7 +300,7 @@ BOOST_AUTO_TEST_CASE(UDQ_GROUP_TEST) {
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQDefine def_fopr(udqp, "FUOPR", location, {"SUM", "(", "GOPR", ")"});
|
||||
UDQDefine def_fopr(udqp, "FUOPR",0, location, {"SUM", "(", "GOPR", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
@ -323,7 +323,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
UDQFunctionTable udqft(udqp);
|
||||
KeywordLocation location;
|
||||
{
|
||||
UDQDefine def(udqp, "WUBHP", location, {"WBHP"});
|
||||
UDQDefine def(udqp, "WUBHP",0, location, {"WBHP"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"W1", "W2", "W3"}), st, udq_state);
|
||||
@ -342,7 +342,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
BOOST_CHECK(!empty_value);
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqp, "WUBHP", location, {"WBHP" , "'P*'"});
|
||||
UDQDefine def(udqp, "WUBHP",0, location, {"WBHP" , "'P*'"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"I1", "I2", "P1", "P2"}), st, udq_state);
|
||||
@ -360,7 +360,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DEFINETEST) {
|
||||
BOOST_CHECK_EQUAL( res["I1"].defined(), false);
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqp, "WUBHP", location, {"NINT" , "(", "WBHP", ")"});
|
||||
UDQDefine def(udqp, "WUBHP",0, location, {"NINT" , "(", "WBHP", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2", "I1", "I2"}), st, udq_state);
|
||||
@ -583,7 +583,7 @@ BOOST_AUTO_TEST_CASE(UDQ_CONTEXT) {
|
||||
BOOST_CHECK_EQUAL(*ctx.get("JAN"), 1.0);
|
||||
BOOST_CHECK_THROW(ctx.get("NO_SUCH_KEY"), std::out_of_range);
|
||||
|
||||
for (std::string& key : std::vector<std::string>({"ELAPSED", "MSUMLINS", "MSUMNEWT", "NEWTON", "TCPU", "TIME"}))
|
||||
for (std::string& key : std::vector<std::string>({"MSUMLINS", "MSUMNEWT", "NEWTON", "TCPU"}))
|
||||
BOOST_CHECK_NO_THROW( ctx.get(key) );
|
||||
|
||||
st.update("SX:KEY", 1.0);
|
||||
@ -986,8 +986,8 @@ BOOST_AUTO_TEST_CASE(UDQ_POW_TEST) {
|
||||
KeywordLocation location;
|
||||
UDQFunctionTable udqft;
|
||||
UDQParams udqp;
|
||||
UDQDefine def_pow1(udqp, "WU", location, {"WOPR", "+", "WWPR", "*", "WGOR", "^", "WWIR"});
|
||||
UDQDefine def_pow2(udqp, "WU", location, {"(", "WOPR", "+", "WWPR", ")", "^", "(", "WOPR", "+" , "WGOR", "*", "WWIR", "-", "WBHP", ")"});
|
||||
UDQDefine def_pow1(udqp, "WU",0, location, {"WOPR", "+", "WWPR", "*", "WGOR", "^", "WWIR"});
|
||||
UDQDefine def_pow2(udqp, "WU",0, location, {"(", "WOPR", "+", "WWPR", ")", "^", "(", "WOPR", "+" , "WGOR", "*", "WWIR", "-", "WBHP", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"P1"}), st, udq_state);
|
||||
@ -1008,7 +1008,7 @@ BOOST_AUTO_TEST_CASE(UDQ_CMP_TEST) {
|
||||
KeywordLocation location;
|
||||
UDQFunctionTable udqft;
|
||||
UDQParams udqp;
|
||||
UDQDefine def_cmp(udqp, "WU", location, {"WOPR", ">", "WWPR", "+", "WGOR", "*", "WWIR"});
|
||||
UDQDefine def_cmp(udqp, "WU",0, location, {"WOPR", ">", "WWPR", "+", "WGOR", "*", "WWIR"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2"}), st, udq_state);
|
||||
@ -1053,7 +1053,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) {
|
||||
st.update_well_var("PD4", "WWPR", 4);
|
||||
|
||||
{
|
||||
UDQDefine def(udqp, "WUOPR", location, {"WOPR", "'PA*'"});
|
||||
UDQDefine def(udqp, "WUOPR",0, location, {"WOPR", "'PA*'"});
|
||||
auto res = def.eval(context);
|
||||
BOOST_CHECK_EQUAL(4U, res.size());
|
||||
auto well1 = res["PA1"];
|
||||
@ -1067,7 +1067,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) {
|
||||
BOOST_CHECK( !well4.defined() );
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqp, "WUOPR", location, {"1"});
|
||||
UDQDefine def(udqp, "WUOPR",0, location, {"1"});
|
||||
auto res = def.eval(context);
|
||||
BOOST_CHECK_EQUAL(4U, res.size());
|
||||
auto well1 = res["PA1"];
|
||||
@ -1083,7 +1083,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SCALAR_SET) {
|
||||
BOOST_CHECK_EQUAL(well4.get() , 1);
|
||||
}
|
||||
{
|
||||
UDQDefine def(udqp, "WUOPR", location, {"WOPR", "'PA1'"});
|
||||
UDQDefine def(udqp, "WUOPR",0, location, {"WOPR", "'PA1'"});
|
||||
auto res = def.eval(context);
|
||||
BOOST_CHECK_EQUAL(4U, res.size());
|
||||
auto well1 = res["PA1"];
|
||||
@ -1106,8 +1106,8 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTD_NAN) {
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft;
|
||||
KeywordLocation location;
|
||||
UDQDefine def(udqp, "WUPR1" , location, {"1", "/", "(", "WWIR", "'OP*'" , ")"});
|
||||
UDQDefine def_sort(udqp , "WUPR3", location, {"SORTD", "(", "WUPR1", ")" });
|
||||
UDQDefine def(udqp, "WUPR1" ,0, location, {"1", "/", "(", "WWIR", "'OP*'" , ")"});
|
||||
UDQDefine def_sort(udqp , "WUPR3",0, location, {"SORTD", "(", "WUPR1", ")" });
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"OP1", "OP2", "OP3", "OP4"}), st, udq_state);
|
||||
@ -1118,10 +1118,10 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTD_NAN) {
|
||||
st.update_well_var("OP4", "WWIR", 4.0);
|
||||
|
||||
auto res1 = def.eval(context);
|
||||
context.update_define(def.keyword(), res1);
|
||||
context.update_define(0, def.keyword(), res1);
|
||||
|
||||
auto res_sort1 = def_sort.eval(context);
|
||||
context.update_define(def_sort.keyword(), res_sort1);
|
||||
context.update_define(0, def_sort.keyword(), res_sort1);
|
||||
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);
|
||||
@ -1133,11 +1133,11 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTD_NAN) {
|
||||
auto res2 = def.eval(context);
|
||||
BOOST_CHECK_EQUAL(res2.defined_size(), 3U);
|
||||
|
||||
context.update_define(def.keyword(), res2);
|
||||
context.update_define(0, def.keyword(), res2);
|
||||
BOOST_CHECK( st.has_well_var("OP4", "WUPR1"));
|
||||
|
||||
auto res_sort2 = def_sort.eval(context);
|
||||
context.update_define(def.keyword(), res2);
|
||||
context.update_define(0, def.keyword(), res2);
|
||||
|
||||
BOOST_CHECK_EQUAL(res_sort2.defined_size(), 3U);
|
||||
BOOST_CHECK_EQUAL(res_sort2["OP2"].get(), 1.0);
|
||||
@ -1152,8 +1152,8 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA) {
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft;
|
||||
UDQDefine def1(udqp, "WUPR1" , location, {"1", "/", "(", "WWCT", "'OP*'", "+", "0.00001", ")"});
|
||||
UDQDefine def_sort(udqp , "WUPR3", location, {"SORTA", "(", "WUPR1", ")" });
|
||||
UDQDefine def1(udqp, "WUPR1" ,0, location, {"1", "/", "(", "WWCT", "'OP*'", "+", "0.00001", ")"});
|
||||
UDQDefine def_sort(udqp , "WUPR3",0, location, {"SORTA", "(", "WUPR1", ")" });
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"OPL01", "OPL02", "OPU01", "OPU02"}), st, udq_state);
|
||||
@ -1164,7 +1164,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA) {
|
||||
st.update_well_var("OPU02", "WWCT", 0.0);
|
||||
|
||||
auto res1 = def1.eval(context);
|
||||
context.update_define(def1.keyword(), res1);
|
||||
context.update_define(0, def1.keyword(), res1);
|
||||
|
||||
auto res_sort = def_sort.eval(context);
|
||||
BOOST_CHECK_EQUAL(res_sort["OPL02"].get(), 1.0);
|
||||
@ -1178,12 +1178,12 @@ BOOST_AUTO_TEST_CASE(UDQ_BASIC_MATH_TEST) {
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft;
|
||||
KeywordLocation location;
|
||||
UDQDefine def_add(udqp, "WU2OPR", location, {"WOPR", "+", "WOPR"});
|
||||
UDQDefine def_sub(udqp, "WU2OPR", location, {"WOPR", "-", "WOPR"});
|
||||
UDQDefine def_mul(udqp, "WU2OPR", location, {"WOPR", "*", "WOPR"});
|
||||
UDQDefine def_div(udqp, "WU2OPR", location, {"WOPR", "/", "WOPR"});
|
||||
UDQDefine def_muladd(udqp, "WUX", location, {"WOPR", "+", "WOPR", "*", "WOPR"});
|
||||
UDQDefine def_wuwct(udqp , "WUWCT", location, {"WWPR", "/", "(", "WOPR", "+", "WWPR", ")"});
|
||||
UDQDefine def_add(udqp, "WU2OPR",0, location, {"WOPR", "+", "WOPR"});
|
||||
UDQDefine def_sub(udqp, "WU2OPR",0, location, {"WOPR", "-", "WOPR"});
|
||||
UDQDefine def_mul(udqp, "WU2OPR",0, location, {"WOPR", "*", "WOPR"});
|
||||
UDQDefine def_div(udqp, "WU2OPR",0, location, {"WOPR", "/", "WOPR"});
|
||||
UDQDefine def_muladd(udqp, "WUX",0, location, {"WOPR", "+", "WOPR", "*", "WOPR"});
|
||||
UDQDefine def_wuwct(udqp , "WUWCT",0, location, {"WWPR", "/", "(", "WOPR", "+", "WWPR", ")"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"P1", "P2", "P3", "P4"}), st, udq_state);
|
||||
@ -1245,7 +1245,7 @@ BOOST_AUTO_TEST_CASE(DECK_TEST) {
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQDefine def(udqp, "WUOPRL", location, {"(", "WOPR", "OP1", "-", "150", ")", "*", "0.90"});
|
||||
UDQDefine def(udqp, "WUOPRL",0, location, {"(", "WOPR", "OP1", "-", "150", ")", "*", "0.90"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, WellMatcher({"OP1", "OP2", "OP3"}), st, udq_state);
|
||||
@ -1264,10 +1264,10 @@ BOOST_AUTO_TEST_CASE(DECK_TEST) {
|
||||
BOOST_AUTO_TEST_CASE(UDQPARSE_TEST1) {
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQDefine def1(udqp, "WUBHP", location, {"1/(WWCT", "'W1*')"});
|
||||
UDQDefine def1(udqp, "WUBHP",0, location, {"1/(WWCT", "'W1*')"});
|
||||
BOOST_CHECK_EQUAL( def1.input_string() , "1/(WWCT 'W1*')");
|
||||
|
||||
UDQDefine def2(udqp, "WUBHP", location, {"2*(1", "+" , "WBHP)"});
|
||||
UDQDefine def2(udqp, "WUBHP",0, location, {"2*(1", "+" , "WBHP)"});
|
||||
BOOST_CHECK_EQUAL( def2.input_string() , "2*(1 + WBHP)");
|
||||
}
|
||||
|
||||
@ -1280,7 +1280,7 @@ BOOST_AUTO_TEST_CASE(UDQ_PARSE_ERROR) {
|
||||
KeywordLocation location;
|
||||
parseContext.update(ParseContext::UDQ_PARSE_ERROR, InputError::IGNORE);
|
||||
{
|
||||
UDQDefine def1(udqp, "WUBHP", location, tokens, parseContext, errors);
|
||||
UDQDefine def1(udqp, "WUBHP",0, location, tokens, parseContext, errors);
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQFunctionTable udqft(udqp);
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
@ -1292,7 +1292,7 @@ BOOST_AUTO_TEST_CASE(UDQ_PARSE_ERROR) {
|
||||
}
|
||||
|
||||
parseContext.update(ParseContext::UDQ_PARSE_ERROR, InputError::THROW_EXCEPTION);
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "WUBHP", location, tokens, parseContext, errors), OpmInputError);
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "WUBHP",0, location, tokens, parseContext, errors), OpmInputError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_TYPE_ERROR) {
|
||||
@ -1304,8 +1304,8 @@ BOOST_AUTO_TEST_CASE(UDQ_TYPE_ERROR) {
|
||||
KeywordLocation location;
|
||||
parseContext.update(ParseContext::UDQ_TYPE_ERROR, InputError::IGNORE);
|
||||
{
|
||||
UDQDefine def1(udqp, "FUBHP", location, tokens1, parseContext, errors);
|
||||
UDQDefine def2(udqp, "WUBHP", location, tokens2, parseContext, errors);
|
||||
UDQDefine def1(udqp, "FUBHP",0, location, tokens1, parseContext, errors);
|
||||
UDQDefine def2(udqp, "WUBHP",0, location, tokens2, parseContext, errors);
|
||||
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQFunctionTable udqft(udqp);
|
||||
@ -1326,7 +1326,7 @@ BOOST_AUTO_TEST_CASE(UDQ_TYPE_ERROR) {
|
||||
parseContext.update(ParseContext::UDQ_TYPE_ERROR, InputError::THROW_EXCEPTION);
|
||||
|
||||
// This fails because the well expression (WBHP + 1) is assigned to the field variable FUBHP
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "FUBHP", location, tokens1, parseContext, errors), OpmInputError);
|
||||
BOOST_CHECK_THROW( UDQDefine(udqp, "FUBHP",0, location, tokens1, parseContext, errors), OpmInputError);
|
||||
}
|
||||
|
||||
|
||||
@ -1868,12 +1868,12 @@ BOOST_AUTO_TEST_CASE(UDQSTATE) {
|
||||
BOOST_CHECK_THROW(st.get("FUPR"), std::out_of_range);
|
||||
|
||||
auto fxpr = UDQSet::scalar("FXPR", 100);
|
||||
BOOST_CHECK_THROW(st.add_define("FXPR", fxpr), std::logic_error);
|
||||
BOOST_CHECK_THROW(st.add_define(0, "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_define("FUPR", fupr);
|
||||
st.add_define(0, "FUPR", fupr);
|
||||
|
||||
// This is not a well quantity
|
||||
BOOST_CHECK_THROW(st.get_well_var("OP1", "FUPR"), std::logic_error);
|
||||
@ -1882,7 +1882,7 @@ BOOST_AUTO_TEST_CASE(UDQSTATE) {
|
||||
|
||||
auto wupr = UDQSet::wells("WUPR", {"P1", "P2"});
|
||||
wupr.assign("P1", 75);
|
||||
st.add_define("WUPR", wupr);
|
||||
st.add_define(0, "WUPR", wupr);
|
||||
|
||||
BOOST_CHECK(st.has_well_var("P1", "WUPR"));
|
||||
// We have a well P2 - but we have not assigned a value to it!
|
||||
@ -2283,7 +2283,7 @@ BOOST_AUTO_TEST_CASE(UDQ_DIV_TEST) {
|
||||
KeywordLocation location;
|
||||
UDQFunctionTable udqft;
|
||||
UDQParams udqp;
|
||||
UDQDefine def_div(udqp, "FU", location, {"128", "/", "2", "/", "4", "/", "8"});
|
||||
UDQDefine def_div(udqp, "FU",0, location, {"128", "/", "2", "/", "4", "/", "8"});
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQState udq_state(udqp.undefinedValue());
|
||||
UDQContext context(udqft, {}, st, udq_state);
|
||||
@ -2396,3 +2396,91 @@ UDQ
|
||||
BOOST_CHECK_EQUAL(fu_var3, 50);
|
||||
BOOST_CHECK_EQUAL(fu_var4, 50);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(UDQ_UPDATE) {
|
||||
std::string invalid1 = R"(
|
||||
SCHEDULE
|
||||
|
||||
UDQ
|
||||
UPDATE FU_XXX /
|
||||
/
|
||||
)";
|
||||
|
||||
std::string valid = R"(
|
||||
SCHEDULE
|
||||
|
||||
UDQ
|
||||
DEFINE FU_TIME TIME /
|
||||
/
|
||||
|
||||
TSTEP
|
||||
1 /
|
||||
|
||||
UDQ
|
||||
UPDATE FU_TIME OFF /
|
||||
/
|
||||
TSTEP
|
||||
1 /
|
||||
|
||||
TSTEP
|
||||
1 /
|
||||
|
||||
UDQ
|
||||
UPDATE FU_TIME NEXT /
|
||||
/
|
||||
|
||||
TSTEP
|
||||
1 /
|
||||
|
||||
TSTEP
|
||||
1 /
|
||||
|
||||
UDQ
|
||||
UPDATE FU_TIME OFF /
|
||||
/
|
||||
|
||||
TSTEP
|
||||
1 /
|
||||
|
||||
)";
|
||||
|
||||
|
||||
|
||||
BOOST_CHECK_THROW(make_schedule(invalid1), std::exception);
|
||||
auto schedule = make_schedule(valid);
|
||||
UDQState udq_state(0);
|
||||
SummaryState st(std::chrono::system_clock::now());
|
||||
UDQSet result = UDQSet::scalar("RES", 0);
|
||||
{
|
||||
const auto& udq = schedule.getUDQConfig(0);
|
||||
const auto& def = udq.define("FU_TIME");
|
||||
BOOST_CHECK( udq_state.define(def.keyword(), def.status()));
|
||||
udq_state.add_define(0, def.keyword(), result);
|
||||
}
|
||||
{
|
||||
const auto& udq = schedule.getUDQConfig(1);
|
||||
const auto& def = udq.define("FU_TIME");
|
||||
BOOST_CHECK( !udq_state.define(def.keyword(), def.status()));
|
||||
}
|
||||
{
|
||||
const auto& udq = schedule.getUDQConfig(2);
|
||||
const auto& def = udq.define("FU_TIME");
|
||||
BOOST_CHECK( !udq_state.define(def.keyword(), def.status()));
|
||||
}
|
||||
{
|
||||
const auto& udq = schedule.getUDQConfig(3);
|
||||
const auto& def = udq.define("FU_TIME");
|
||||
BOOST_CHECK( udq_state.define(def.keyword(), def.status()));
|
||||
udq_state.add_define(3, def.keyword(), result);
|
||||
}
|
||||
{
|
||||
const auto& udq = schedule.getUDQConfig(4);
|
||||
const auto& def = udq.define("FU_TIME");
|
||||
BOOST_CHECK( !udq_state.define(def.keyword(), def.status()));
|
||||
}
|
||||
{
|
||||
const auto& udq = schedule.getUDQConfig(5);
|
||||
const auto& def = udq.define("FU_TIME");
|
||||
BOOST_CHECK( !udq_state.define(def.keyword(), def.status()));
|
||||
}
|
||||
}
|
||||
|
@ -87,32 +87,32 @@ Opm::UDQSet make_udq_set(const std::string& name, Opm::UDQVarType var_type, cons
|
||||
{
|
||||
auto state = Opm::UDQState{0};
|
||||
|
||||
state.add_define("WUOPRL", make_udq_set("WUOPRL",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{210, 211, 212, 213}));
|
||||
state.add_define(0, "WUOPRL", make_udq_set("WUOPRL",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{210, 211, 212, 213}));
|
||||
|
||||
state.add_define("WUOPRU", make_udq_set("WUOPRU",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{220, 221, 222, 223}));
|
||||
state.add_define(0, "WUOPRU", make_udq_set("WUOPRU",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{220, 221, 222, 223}));
|
||||
|
||||
state.add_define("WULPRL", make_udq_set("WULPRL",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{230, 231, 232, 233}));
|
||||
state.add_define(0, "WULPRL", make_udq_set("WULPRL",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{230, 231, 232, 233}));
|
||||
|
||||
state.add_define("WULPRU", make_udq_set("WULPRU",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{160, 161, 162, 163}));
|
||||
state.add_define(0, "WULPRU", make_udq_set("WULPRU",
|
||||
Opm::UDQVarType::WELL_VAR,
|
||||
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
|
||||
{160, 161, 162, 163}));
|
||||
|
||||
state.add_define("GUOPRU", make_udq_set("GUOPRU",
|
||||
Opm::UDQVarType::GROUP_VAR,
|
||||
{"WGRP1", "WGRP2", "GRP1"},
|
||||
{360, 361, 362}));
|
||||
state.add_define(0, "GUOPRU", make_udq_set("GUOPRU",
|
||||
Opm::UDQVarType::GROUP_VAR,
|
||||
{"WGRP1", "WGRP2", "GRP1"},
|
||||
{360, 361, 362}));
|
||||
|
||||
state.add_define("FULPR", Opm::UDQSet::scalar("FULPR", 460));
|
||||
state.add_define(0, "FULPR", Opm::UDQSet::scalar("FULPR", 460));
|
||||
return state;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user