Handle undefined UDQ expressions

This commit is contained in:
Joakim Hove 2020-08-31 07:38:52 +02:00
parent a74855f74b
commit 11e70ca779
24 changed files with 827 additions and 409 deletions

View File

@ -121,7 +121,7 @@ void msim::run_step(const Schedule& schedule, Action::State& action_state, Summa
group_data,
{});
schedule.getUDQConfig( report_step ).eval(st);
schedule.getUDQConfig( report_step ).eval(st, udq_state);
this->output(action_state,
st,

View File

@ -41,6 +41,7 @@ namespace Opm {
class Schedule;
class UDQInput;
class UDQActive;
class UDQState;
} // Opm
namespace Opm { namespace RestartIO { namespace Helpers {
@ -57,7 +58,7 @@ public:
void captureDeclaredUDQData(const Opm::Schedule& sched,
const std::size_t simStep,
const Opm::SummaryState& st,
const Opm::UDQState& udqState,
const std::vector<int>& inteHead);
const std::vector<int>& getIUDQ() const

View File

@ -26,7 +26,6 @@
#include <opm/output/eclipse/RestartValue.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <string>
#include <utility>
@ -37,6 +36,8 @@ namespace Opm {
class EclipseGrid;
class EclipseState;
class Schedule;
class UDQState;
class SummaryState;
} // namespace Opm
@ -84,6 +85,7 @@ namespace Opm { namespace RestartIO {
const Schedule& schedule,
const Action::State& action_state,
const SummaryState& sumState,
const UDQState& udqState,
bool write_double = false);

View File

@ -88,7 +88,7 @@ public:
void update_well_var(const std::string& well, const std::string& var, double value);
void update_group_var(const std::string& group, const std::string& var, double value);
void update_elapsed(double delta);
void update_udq(const UDQSet& udq_set);
void update_udq(const UDQSet& udq_set, double undefined_value);
double get(const std::string&) const;
double get(const std::string&, double) const;

View File

@ -40,6 +40,8 @@ namespace Opm {
class DeckRecord;
class Deck;
class SummaryState;
class UDQState;
class UDQConfig {
public:
UDQConfig() = default;
@ -57,7 +59,7 @@ namespace Opm {
void add_assign(const std::string& quantity, const std::vector<std::string>& selector, double value);
void add_define(const std::string& quantity, const std::vector<std::string>& expression);
void eval(SummaryState& st) const;
void eval(SummaryState& st, UDQState& udq_state) const;
const UDQDefine& define(const std::string& key) const;
std::vector<UDQDefine> definitions() const;
std::vector<UDQDefine> definitions(UDQVarType var_type) const;

View File

@ -21,32 +21,36 @@
#ifndef UDQ_CONTEXT_HPP
#define UDQ_CONTEXT_HPP
#include <vector>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp>
namespace Opm {
class SummaryState;
class UDQFunctionTable;
class UDQState;
class UDQContext{
public:
UDQContext(const UDQFunctionTable& udqft, const SummaryState& summary_state);
double get(const std::string& key) const;
bool has_well_var(const std::string& well, const std::string& var) const;
double get_well_var(const std::string& well, const std::string& var) const;
bool has_group_var(const std::string& group, const std::string& var) const;
double get_group_var(const std::string& group, const std::string& var) const;
UDQContext(const UDQFunctionTable& udqft, SummaryState& summary_state, UDQState& udq_state);
std::optional<double> get(const std::string& key) 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;
void add(const std::string& key, double value);
void update(const std::string& keyword, const UDQSet& udq_result);
const UDQFunctionTable& function_table() const;
std::vector<std::string> wells() const;
std::vector<std::string> groups() const;
private:
const UDQFunctionTable& udqft;
const SummaryState& summary_state;
SummaryState& summary_state;
UDQState& udq_state;
//std::unordered_map<std::string, UDQSet> udq_results;
std::unordered_map<std::string, double> values;
};
}

View File

@ -64,7 +64,7 @@ public:
static UDQDefine serializeObject();
UDQSet eval(const UDQContext& context) const;
UDQSet eval(UDQContext& context) const;
const std::string& keyword() const;
const std::string& input_string() const;
UDQVarType var_type() const;

View File

@ -47,9 +47,11 @@ public:
void operator-=(double rhs);
operator bool() const;
void assign(const std::optional<double>& value);
void assign(double value);
bool defined() const;
double value() const;
double get() const;
const std::optional<double>& value() const;
const std::string& wgname() const;
bool operator==(const UDQScalar& other) const;
static UDQScalar deserialize(Serializer& ser);
@ -69,6 +71,7 @@ public:
UDQSet(const std::string& name, std::size_t size);
void serialize(Serializer& ser) const;
static UDQSet deserialize(Serializer& ser);
static UDQSet scalar(const std::string& name, const std::optional<double>& scalar_value);
static UDQSet scalar(const std::string& name, double value);
static UDQSet empty(const std::string& name);
static UDQSet wells(const std::string& name, const std::vector<std::string>& wells);
@ -77,6 +80,9 @@ public:
static UDQSet groups(const std::string& name, const std::vector<std::string>& groups, double scalar_value);
static UDQSet field(const std::string& name, double scalar_value);
void assign(const std::optional<double>& value);
void assign(const std::string& wgname, const std::optional<double>& value);
void assign(double value);
void assign(std::size_t index, double value);
void assign(const std::string& wgname, double value);

View File

@ -39,7 +39,7 @@ public:
double get(const std::string& key) const;
double get_group_var(const std::string& well, const std::string& var) const;
double get_well_var(const std::string& well, const std::string& var) const;
void add(const UDQSet& result);
void add(const std::string& udq_key, const UDQSet& result);
std::vector<char> serialize() const;
void deserialize(const std::vector<char>& buffer);

View File

@ -26,9 +26,9 @@
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
//#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
@ -269,7 +269,7 @@ namespace {
}
template <class DUDWArray>
void staticContrib(const Opm::SummaryState& st,
void staticContrib(const Opm::UDQState& udq_state,
const std::vector<std::string>& wnames,
const std::string udq,
const std::size_t nwmaxz,
@ -280,8 +280,8 @@ namespace {
dUdw[ind] = Opm::UDQ::restart_default;
}
for (std::size_t ind = 0; ind < wnames.size(); ind++) {
if (st.has_well_var(wnames[ind], udq)) {
dUdw[ind] = st.get_well_var(wnames[ind], udq);
if (udq_state.has_well_var(wnames[ind], udq)) {
dUdw[ind] = udq_state.get_well_var(wnames[ind], udq);
}
}
}
@ -301,7 +301,7 @@ namespace {
}
template <class DUDGArray>
void staticContrib(const Opm::SummaryState& st,
void staticContrib(const Opm::UDQState& udq_state,
const std::vector<const Opm::Group*> groups,
const std::string udq,
const std::size_t ngmaxz,
@ -313,8 +313,8 @@ namespace {
dUdg[ind] = Opm::UDQ::restart_default;
}
else {
if (st.has_group_var((*groups[ind]).name(), udq)) {
dUdg[ind] = st.get_group_var((*groups[ind]).name(), udq);
if (udq_state.has_group_var((*groups[ind]).name(), udq)) {
dUdg[ind] = udq_state.get_group_var((*groups[ind]).name(), udq);
}
else {
dUdg[ind] = Opm::UDQ::restart_default;
@ -338,13 +338,13 @@ namespace {
}
template <class DUDFArray>
void staticContrib(const Opm::SummaryState& st,
void staticContrib(const Opm::UDQState& udq_state,
const std::string udq,
DUDFArray& dUdf)
{
//set value for group name "FIELD"
if (st.has(udq)) {
dUdf[0] = st.get(udq);
if (udq_state.has(udq)) {
dUdf[0] = udq_state.get(udq);
}
else {
dUdf[0] = Opm::UDQ::restart_default;
@ -458,7 +458,7 @@ void
Opm::RestartIO::Helpers::AggregateUDQData::
captureDeclaredUDQData(const Opm::Schedule& sched,
const std::size_t simStep,
const Opm::SummaryState& st,
const Opm::UDQState& udq_state,
const std::vector<int>& inteHead)
{
const auto& udqCfg = sched.getUDQConfig(simStep);
@ -549,7 +549,7 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
if (udq_input.var_type() == UDQVarType::WELL_VAR) {
const std::string& udq = udq_input.keyword();
auto i_dudw = this->dUDW_[i_wudq];
dUdw::staticContrib(st, wnames, udq, nwmax, i_dudw);
dUdw::staticContrib(udq_state, wnames, udq, nwmax, i_dudw);
i_wudq++;
cnt_dudw += 1;
}
@ -568,7 +568,7 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
if (udq_input.var_type() == UDQVarType::GROUP_VAR) {
const std::string& udq = udq_input.keyword();
auto i_dudg = this->dUDG_[i_gudq];
dUdg::staticContrib(st, curGroups, udq, ngmax, i_dudg);
dUdg::staticContrib(udq_state, curGroups, udq, ngmax, i_dudg);
i_gudq++;
cnt_dudg += 1;
}
@ -585,7 +585,7 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
if (udq_input.var_type() == UDQVarType::FIELD_VAR) {
const std::string& udq = udq_input.keyword();
auto i_dudf = this->dUDF_[i_fudq];
dUdf::staticContrib(st, udq, i_dudf);
dUdf::staticContrib(udq_state, udq, i_dudf);
i_fudq++;
cnt_dudf += 1;
}

View File

@ -189,7 +189,7 @@ void EclipseIO::writeInitial( data::Solution simProps, std::map<std::string, std
// implementation of the writeTimeStep method
void EclipseIO::writeTimeStep(const Action::State& action_state,
const SummaryState& st,
const UDQState& /* udq_state */,
const UDQState& udq_state,
int report_step,
bool isSubstep,
double secs_elapsed,
@ -239,7 +239,7 @@ void EclipseIO::writeTimeStep(const Action::State& action_state,
};
RestartIO::save(rstFile, report_step, secs_elapsed, value,
es, grid, schedule, action_state, st, write_double);
es, grid, schedule, action_state, st, udq_state, write_double);
}
// RFT file written only if requested and never for substeps.

View File

@ -286,7 +286,7 @@ namespace {
void writeUDQ(const int report_step,
const int sim_step,
const Schedule& schedule,
const SummaryState& sum_state,
const UDQState& udq_state,
const std::vector<int>& ih,
EclIO::OutputStream::Restart& rstFile)
{
@ -300,7 +300,7 @@ namespace {
const auto udqDims = Helpers::createUdqDims(schedule, simStep, ih);
auto udqData = Helpers::AggregateUDQData(udqDims);
udqData.captureDeclaredUDQData(schedule, simStep, sum_state, ih);
udqData.captureDeclaredUDQData(schedule, simStep, udq_state, ih);
if (udqDims[0] >= 1) {
rstFile.write("ZUDN", udqData.getZUDN());
@ -567,7 +567,7 @@ namespace {
void writeSolution(const RestartValue& value,
const Schedule& schedule,
const SummaryState& sum_state,
const UDQState& udq_state,
int report_step,
int sim_step,
const bool ecl_compatible_rst,
@ -594,7 +594,7 @@ namespace {
writeRegularSolutionVectors(value, write_double_arg, write);
writeUDQ(report_step, sim_step, schedule, sum_state, inteHD, rstFile);
writeUDQ(report_step, sim_step, schedule, udq_state, inteHD, rstFile);
writeExtraVectors(value, write);
@ -656,6 +656,7 @@ void save(EclIO::OutputStream::Restart& rstFile,
const Schedule& schedule,
const Action::State& action_state,
const SummaryState& sumState,
const UDQState& udqState,
bool write_double)
{
::Opm::RestartIO::checkSaveArguments(es, value, grid);
@ -685,7 +686,7 @@ void save(EclIO::OutputStream::Restart& rstFile,
writeActionx(report_step, sim_step, es, schedule, action_state, sumState, rstFile);
writeSolution(value, schedule, sumState, report_step, sim_step,
writeSolution(value, schedule, udqState, report_step, sim_step,
ecl_compatible_rst, write_double, inteHD, rstFile);
if (! ecl_compatible_rst) {

View File

@ -154,30 +154,24 @@ namespace {
}
}
void SummaryState::update_udq(const UDQSet& udq_set) {
void SummaryState::update_udq(const UDQSet& udq_set, double undefined_value) {
auto var_type = udq_set.var_type();
if (var_type == UDQVarType::WELL_VAR) {
const std::vector<std::string> wells = this->wells();
for (const auto& well : wells) {
const auto& udq_value = udq_set[well];
if (udq_value)
this->update_well_var(well, udq_set.name(), udq_value.value());
else
this->erase_well_var(well, udq_set.name());
const auto& udq_value = udq_set[well].value();
this->update_well_var(well, udq_set.name(), udq_value.value_or(undefined_value));
}
} else if (var_type == UDQVarType::GROUP_VAR) {
const std::vector<std::string> groups = this->groups();
for (const auto& group : groups) {
const auto& udq_value = udq_set[group];
if (udq_value)
this->update_group_var(group, udq_set.name(), udq_value.value());
else
this->erase_group_var(group, udq_set.name());
const auto& udq_value = udq_set[group].value();
this->update_group_var(group, udq_set.name(), udq_value.value_or(undefined_value));
}
} else {
const auto& udq_var = udq_set[0];
if (udq_var)
this->update(udq_set.name(), udq_var.value());
const auto& udq_var = udq_set[0].value();
this->update(udq_set.name(), udq_var.value_or(undefined_value));
}
}

View File

@ -154,19 +154,16 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
auto res = UDQSet::wells(string_value, wells);
int fnmatch_flags = 0;
for (const auto& well : wells) {
if (fnmatch(well_pattern.c_str(), well.c_str(), fnmatch_flags) == 0) {
if (context.has_well_var(well, string_value))
res.assign(well, context.get_well_var(well, string_value));
}
if (fnmatch(well_pattern.c_str(), well.c_str(), fnmatch_flags) == 0)
res.assign(well, context.get_well_var(well, string_value));
}
return res;
}
} else {
auto res = UDQSet::wells(string_value, wells);
for (const auto& well : wells) {
if (context.has_well_var(well, string_value))
res.assign(well, context.get_well_var(well, string_value));
}
for (const auto& well : wells)
res.assign(well, context.get_well_var(well, string_value));
return res;
}
}
@ -181,10 +178,8 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
} else {
const auto& groups = context.groups();
auto res = UDQSet::groups(string_value, groups);
for (const auto& group : groups) {
if (context.has_group_var(group, string_value))
res.assign(group, context.get_group_var(group, string_value));
}
for (const auto& group : groups)
res.assign(group, context.get_group_var(group, string_value));
return res;
}
}
@ -192,7 +187,11 @@ UDQSet UDQASTNode::eval(UDQVarType target_type, const UDQContext& context) const
if (data_type == UDQVarType::FIELD_VAR)
return UDQSet::scalar(string_value, context.get(string_value));
throw std::logic_error("Should not be here: var_type: " + UDQ::typeName(data_type));
auto scalar = context.get(string_value);
if (scalar.has_value())
return UDQSet::scalar(string_value, scalar.value());
throw std::logic_error("Should not be here: var_type: " + UDQ::typeName(data_type) + " stringvalue:" + string_value);
}

View File

@ -289,37 +289,45 @@ namespace Opm {
this->type_count == data.type_count;
}
void UDQConfig::eval(SummaryState& st) const {
void UDQConfig::eval(SummaryState& st, UDQState& udq_state) const {
const auto& func_table = this->function_table();
UDQContext context(func_table, st);
auto undefined_value = this->params().undefinedValue();
UDQContext context(func_table, st, udq_state);
for (const auto& assign : this->assignments(UDQVarType::WELL_VAR)) {
auto ws = assign.eval(st.wells());
st.update_udq(ws);
context.update(assign.keyword(), ws);
st.update_udq(ws, undefined_value);
}
for (const auto& def : this->definitions(UDQVarType::WELL_VAR)) {
auto ws = def.eval(context);
st.update_udq(ws);
context.update(def.keyword(), ws);
st.update_udq(ws, undefined_value);
}
for (const auto& assign : this->assignments(UDQVarType::GROUP_VAR)) {
auto ws = assign.eval(st.groups());
st.update_udq(ws);
context.update(assign.keyword(), ws);
st.update_udq(ws, undefined_value);
}
for (const auto& def : this->definitions(UDQVarType::GROUP_VAR)) {
auto ws = def.eval(context);
st.update_udq(ws);
context.update(def.keyword(), ws);
st.update_udq(ws, undefined_value);
}
for (const auto& assign : this->assignments(UDQVarType::FIELD_VAR)) {
auto ws = assign.eval();
st.update_udq(ws);
context.update(assign.keyword(), ws);
st.update_udq(ws, undefined_value);
}
for (const auto& def : this->definitions(UDQVarType::FIELD_VAR)) {
auto field_udq = def.eval(context);
st.update_udq(field_udq);
context.update(def.keyword(), field_udq);
st.update_udq(field_udq, undefined_value);
}
}
}

View File

@ -20,13 +20,30 @@
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQContext.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp>
namespace Opm {
UDQContext::UDQContext(const UDQFunctionTable& udqft_arg, const SummaryState& summary_state_arg) :
namespace {
bool is_udq(const std::string& key) {
if (key.size() < 2)
return false;
if (key[1] != 'U')
return false;
return true;
}
}
UDQContext::UDQContext(const UDQFunctionTable& udqft_arg, SummaryState& summary_state_arg, UDQState& udq_state_arg) :
udqft(udqft_arg),
summary_state(summary_state_arg)
summary_state(summary_state_arg),
udq_state(udq_state_arg)
{
for (const auto& pair : TimeMap::eclipseMonthIndices())
this->add(pair.first, pair.second);
@ -46,33 +63,56 @@ namespace Opm {
this->add("TIMESTEP", 0.0);
}
void UDQContext::update(const std::string& keyword, const UDQSet& udq_result) {
this->udq_state.add(keyword, udq_result);
}
void UDQContext::add(const std::string& key, double value) {
this->values[key] = value;
}
double UDQContext::get(const std::string& key) const {
std::optional<double> UDQContext::get(const std::string& key) const {
if (is_udq(key)) {
if (this->udq_state.has(key))
return this->udq_state.get(key);
return std::nullopt;
}
const auto& pair_ptr = this->values.find(key);
if (pair_ptr == this->values.end())
if (pair_ptr != this->values.end())
return pair_ptr->second;
if (this->summary_state.has(key))
return this->summary_state.get(key);
return pair_ptr->second;
return std::nullopt;
}
double UDQContext::get_well_var(const std::string& well, const std::string& var) const {
return this->summary_state.get_well_var(well, var);
std::optional<double> UDQContext::get_well_var(const std::string& well, const std::string& var) const {
if (is_udq(var)) {
if (this->udq_state.has_well_var(well, var))
return this->udq_state.get_well_var(well, var);
return std::nullopt;
}
if (this->summary_state.has_well_var(well, var))
return this->summary_state.get_well_var(well, var);
return std::nullopt;
}
bool UDQContext::has_well_var(const std::string& well, const std::string& var) const {
return this->summary_state.has_well_var(well, var);
}
std::optional<double> UDQContext::get_group_var(const std::string& group, const std::string& var) const {
if (is_udq(var)) {
if (this->udq_state.has_group_var(group, var))
return this->udq_state.get_group_var(group, var);
double UDQContext::get_group_var(const std::string& group, const std::string& var) const {
return this->summary_state.get_group_var(group, var);
}
return std::nullopt;
}
if (this->summary_state.has_group_var(group, var))
return this->summary_state.get_group_var(group, var);
bool UDQContext::has_group_var(const std::string& group, const std::string& var) const {
return this->summary_state.has_group_var(group, var);
return std::nullopt;
}
std::vector<std::string> UDQContext::wells() const {

View File

@ -248,12 +248,13 @@ bool dynamic_type_check(UDQVarType lhs, UDQVarType rhs) {
}
UDQSet UDQDefine::eval(const UDQContext& context) const {
UDQSet UDQDefine::eval(UDQContext& context) const {
UDQSet res = this->ast->eval(this->m_var_type, context);
if (!dynamic_type_check(this->var_type(), res.var_type())) {
std::string msg = "Invalid runtime type conversion detected when evaluating UDQ";
throw std::invalid_argument(msg);
}
context.update(this->keyword(), res);
if (res.var_type() == UDQVarType::SCALAR) {
/*
@ -272,7 +273,7 @@ UDQSet UDQDefine::eval(const UDQContext& context) const {
regarding the semantics of group sets.
*/
double scalar_value = res[0].value();
const auto& scalar_value = res[0].value();
if (this->var_type() == UDQVarType::WELL_VAR) {
const std::vector<std::string> wells = context.wells();
UDQSet well_res = UDQSet::wells(this->m_keyword, wells);

View File

@ -167,7 +167,7 @@ UDQSet UDQUnaryElementalFunction::ABS(const UDQSet& arg) {
for (std::size_t index=0; index < result.size(); index++) {
auto& udq_value = result[index];
if (udq_value)
result.assign( index, std::fabs(udq_value.value()));
result.assign( index, std::fabs(udq_value.get()));
}
return result;
}
@ -211,7 +211,7 @@ UDQSet UDQUnaryElementalFunction::EXP(const UDQSet& arg) {
for (std::size_t index=0; index < result.size(); index++) {
auto& udq_value = result[index];
if (udq_value)
result.assign( index, std::exp(udq_value.value()) );
result.assign( index, std::exp(udq_value.get()) );
}
return result;
}
@ -221,7 +221,7 @@ UDQSet UDQUnaryElementalFunction::NINT(const UDQSet& arg) {
for (std::size_t index=0; index < result.size(); index++) {
auto& udq_value = result[index];
if (udq_value)
result.assign( index, std::nearbyint(udq_value.value()) );
result.assign( index, std::nearbyint(udq_value.get()) );
}
return result;
}
@ -259,7 +259,7 @@ UDQSet UDQUnaryElementalFunction::LN(const UDQSet& arg) {
for (std::size_t index=0; index < result.size(); index++) {
auto& udq_value = result[index];
if (udq_value) {
double elm = udq_value.value();
double elm = udq_value.get();
if (elm > 0)
result.assign(index, std::log(elm));
else
@ -275,7 +275,7 @@ UDQSet UDQUnaryElementalFunction::LOG(const UDQSet& arg) {
for (std::size_t index=0; index < result.size(); index++) {
auto& udq_value = result[index];
if (udq_value) {
double elm = udq_value.value();
double elm = udq_value.get();
if (elm > 0)
result.assign(index, std::log10(elm));
else
@ -297,10 +297,10 @@ namespace {
const auto& elm2 = arg2[index];
if (elm1.defined() != elm2.defined()) {
if (elm1)
result.assign(index, elm1.value());
result.assign(index, elm1.get());
if (elm2)
result.assign(index, elm2.value());
result.assign(index, elm2.get());
}
}
return result;
@ -316,9 +316,9 @@ UDQSet UDQUnaryElementalFunction::SORT(const UDQSet& arg, bool ascending) {
const auto& value = arg[index];
if (value.defined()) {
if (ascending)
sort_nodes.emplace_back(index, value.value() );
sort_nodes.emplace_back(index, value.get() );
else
sort_nodes.emplace_back(index, -value.value() );
sort_nodes.emplace_back(index, -value.get() );
}
}
@ -365,11 +365,16 @@ UDQSet UDQBinaryFunction::LE(double eps, const UDQSet& lhs, const UDQSet& rhs) {
for (std::size_t index=0; index < result.size(); index++) {
auto elm = result[index];
if (elm) {
double diff = rel_diff[index].value();
if (diff <= eps)
const double abs_diff = elm.get();
if (abs_diff == 0)
result.assign(index, 1);
else
result.assign(index, 0);
else {
double diff = rel_diff[index].get();
if (diff <= eps)
result.assign(index, 1);
else
result.assign(index, 0);
}
}
}
return result;
@ -382,15 +387,19 @@ UDQSet UDQBinaryFunction::GE(double eps, const UDQSet& lhs, const UDQSet& rhs) {
for (std::size_t index=0; index < result.size(); index++) {
auto elm = result[index];
if (elm) {
double diff = rel_diff[index].value();
if (diff >= -eps)
const double abs_diff = elm.get();
if (abs_diff == 0)
result.assign(index, 1);
else
result.assign(index, 0);
else {
double diff = rel_diff[index].get();
if (diff >= -eps)
result.assign(index, 1);
else
result.assign(index, 0);
}
}
}
return result;
}
@ -401,23 +410,28 @@ UDQSet UDQBinaryFunction::EQ(double eps, const UDQSet& lhs, const UDQSet& rhs) {
for (std::size_t index=0; index < result.size(); index++) {
auto elm = result[index];
if (elm) {
double diff = std::fabs(rel_diff[index].value());
if (diff <= eps)
const double abs_diff = elm.get();
if (abs_diff == 0)
result.assign(index, 1);
else
result.assign(index, 0);
else {
const double diff = std::fabs(rel_diff[index].get());
if (diff <= eps)
result.assign(index, 1);
else
result.assign(index, 0);
}
}
}
return result;
}
UDQSet UDQBinaryFunction::NE(double eps, const UDQSet& lhs, const UDQSet& rhs) {
auto result = UDQBinaryFunction::EQ(eps, lhs, rhs);
for (std::size_t index=0; index < result.size(); index++) {
auto elm = result[index];
if (elm)
result.assign(index, 1 - elm.value());
result.assign(index, 1 - elm.get());
}
return result;
}
@ -429,7 +443,7 @@ UDQSet UDQBinaryFunction::GT(const UDQSet& lhs, const UDQSet& rhs) {
for (std::size_t index=0; index < result.size(); index++) {
auto elm = result[index];
if (elm) {
double diff = elm.value();
double diff = elm.get();
if (diff > 0)
result.assign(index, 1);
else
@ -445,7 +459,7 @@ UDQSet UDQBinaryFunction::LT(const UDQSet& lhs, const UDQSet& rhs) {
for (std::size_t index=0; index < result.size(); index++) {
auto elm = result[index];
if (elm) {
double diff = elm.value();
double diff = elm.get();
if (diff < 0)
result.assign(index, 1);
else
@ -468,7 +482,7 @@ UDQSet UDQBinaryFunction::UADD(const UDQSet& lhs, const UDQSet& rhs) {
const auto& rhs_elm = rhs[index];
if (lhs_elm && rhs_elm)
result.assign(index, rhs_elm.value() + lhs_elm.value());
result.assign(index, rhs_elm.get() + lhs_elm.get());
}
return result;
}
@ -480,7 +494,7 @@ UDQSet UDQBinaryFunction::UMUL(const UDQSet& lhs, const UDQSet& rhs) {
const auto& rhs_elm = rhs[index];
if (lhs_elm && rhs_elm)
result.assign(index, rhs_elm.value() * lhs_elm.value());
result.assign(index, rhs_elm.get() * lhs_elm.get());
}
return result;
}
@ -492,7 +506,7 @@ UDQSet UDQBinaryFunction::UMIN(const UDQSet& lhs, const UDQSet& rhs) {
const auto& rhs_elm = rhs[index];
if (lhs_elm && rhs_elm)
result.assign(index, std::min(rhs_elm.value(), lhs_elm.value()));
result.assign(index, std::min(rhs_elm.get(), lhs_elm.get()));
}
return result;
}
@ -505,7 +519,7 @@ UDQSet UDQBinaryFunction::UMAX(const UDQSet& lhs, const UDQSet& rhs) {
const auto& rhs_elm = rhs[index];
if (lhs_elm && rhs_elm)
result.assign(index, std::max(rhs_elm.value(), lhs_elm.value()));
result.assign(index, std::max(rhs_elm.get(), lhs_elm.get()));
}
return result;
}
@ -533,7 +547,7 @@ UDQSet UDQBinaryFunction::POW(const UDQSet& lhs, const UDQSet& rhs) {
auto& rhs_elm = rhs[index];
if (lhs_elm && rhs_elm)
result.assign(index, std::pow(lhs_elm.value(), rhs_elm.value()));
result.assign(index, std::pow(lhs_elm.get(), rhs_elm.get()));
}
return result;
}

View File

@ -60,7 +60,11 @@ bool UDQScalar::defined() const {
return this->m_value.has_value();
}
double UDQScalar::value() const {
const std::optional<double>& UDQScalar::value() const {
return this->m_value;
}
double UDQScalar::get() const {
if (!this->m_value.has_value())
throw std::invalid_argument("UDQSCalar: Value not defined wgname: " + this->m_wgname);
@ -71,6 +75,16 @@ const std::string& UDQScalar::wgname() const {
return this->m_wgname;
}
void UDQScalar::assign(const std::optional<double>& value) {
if (value.has_value()) {
if (std::isfinite(*value))
this->m_value = value;
else
this->m_value = std::nullopt;
} else
this->m_value = std::nullopt;
}
void UDQScalar::assign(double value) {
if (std::isfinite(value))
this->m_value = value;
@ -180,6 +194,13 @@ UDQSet UDQSet::scalar(const std::string& name, double scalar_value)
return us;
}
UDQSet UDQSet::scalar(const std::string& name, const std::optional<double>& scalar_value)
{
UDQSet us(name, UDQVarType::SCALAR);
us.assign(scalar_value);
return us;
}
UDQSet UDQSet::empty(const std::string& name)
{
return UDQSet(name, 0);
@ -243,11 +264,29 @@ void UDQSet::assign(const std::string& wgname, double value) {
throw std::out_of_range("No well/group matching: " + wgname);
}
void UDQSet::assign(const std::string& wgname, const std::optional<double>& value) {
bool assigned = false;
for (auto& udq_value : this->values) {
int flags = 0;
if (fnmatch(wgname.c_str(), udq_value.wgname().c_str(), flags) == 0) {
udq_value.assign( value );
assigned = true;
}
}
if (!assigned)
throw std::out_of_range("No well/group matching: " + wgname);
}
void UDQSet::assign(double value) {
for (auto& v : this->values)
v.assign(value);
}
void UDQSet::assign(const std::optional<double>& value) {
for (auto& v : this->values)
v.assign(value);
}
void UDQSet::assign(std::size_t index, double value) {
auto& scalar = this->values[index];
scalar.assign(value);
@ -321,7 +360,7 @@ std::vector<double> UDQSet::defined_values() const {
std::vector<double> dv;
for (const auto& v : this->values) {
if (v)
dv.push_back(v.value());
dv.push_back(v.get());
}
return dv;
}
@ -429,7 +468,7 @@ UDQScalar operator/(const UDQScalar&lhs, double rhs) {
UDQScalar operator/(double lhs, const UDQScalar& rhs) {
UDQScalar result = rhs;
if (result)
result.assign(lhs / result.value());
result.assign(lhs / result.get());
return result;
}
@ -451,10 +490,10 @@ UDQSet udq_cast(const UDQSet& lhs, const UDQSet& rhs)
}
if (rhs.var_type() == UDQVarType::WELL_VAR)
return UDQSet::wells(lhs.name(), rhs.wgnames(), lhs[0].value());
return UDQSet::wells(lhs.name(), rhs.wgnames(), lhs[0].get());
if (rhs.var_type() == UDQVarType::GROUP_VAR)
return UDQSet::groups(lhs.name(), rhs.wgnames(), lhs[0].value());
return UDQSet::groups(lhs.name(), rhs.wgnames(), lhs[0].get());
throw std::logic_error("Don't have a clue");
} else
@ -534,7 +573,7 @@ UDQSet operator/(double lhs, const UDQSet&rhs) {
for (std::size_t index = 0; index < rhs.size(); index++) {
const auto& elm = rhs[index];
if (elm)
result.assign(index, lhs / elm.value());
result.assign(index, lhs / elm.get());
}
return result;
}

View File

@ -71,13 +71,13 @@ bool UDQState::has_group_var(const std::string& group, const std::string& key) c
}
void UDQState::add(const UDQSet& result) {
if (!is_udq(result.name()))
throw std::logic_error("Key is not a UDQ variable:" + result.name());
void UDQState::add(const std::string& udq_key, const UDQSet& result) {
if (!is_udq(udq_key))
throw std::logic_error("Key is not a UDQ variable:" + udq_key);
auto res_iter = this->values.find(result.name());
auto res_iter = this->values.find(udq_key);
if (res_iter == this->values.end())
this->values.insert( std::make_pair( result.name(), result ));
this->values.insert( std::make_pair( udq_key, result ));
else
res_iter->second = result;
}
@ -88,7 +88,7 @@ double UDQState::get(const std::string& key) const {
const auto& result = this->values.at(key)[0];
if (result.defined())
return result.value();
return result.get();
else
return this->undefined_value;
}
@ -107,7 +107,7 @@ double UDQState::get_wg_var(const std::string& wgname, const std::string& key, U
const auto& result = result_set[wgname];
if (result.defined())
return result.value();
return result.get();
else
return this->undefined_value;
}

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQInput.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/ActionX.hpp>
@ -105,6 +106,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
Opm::EclipseState es = simCase.es;
Opm::Runspec rspec = es.runspec();
Opm::SummaryState st = sum_state_TEST1();
Opm::UDQState udq_state(1);
Opm::Action::State action_state;
Opm::Schedule sched = simCase.sched;
Opm::EclipseGrid grid = simCase.grid;
@ -135,7 +137,7 @@ BOOST_AUTO_TEST_CASE (Declared_Actionx_data)
const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih);
auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims);
udqData.captureDeclaredUDQData(sched, rptStep, st, ih);
udqData.captureDeclaredUDQData(sched, rptStep, udq_state, ih);
const auto actDims = Opm::RestartIO::Helpers::createActionxDims(rspec, sched, rptStep);
auto actionxData = Opm::RestartIO::Helpers::AggregateActionxData(actDims);

View File

@ -20,6 +20,9 @@
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQActive.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQConfig.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQParams.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
//#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
//#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
@ -71,6 +74,48 @@ namespace {
*/
}
Opm::UDQSet make_udq_set(const std::string& name, Opm::UDQVarType var_type, const std::vector<std::string>& wgnames, const std::vector<double>& values) {
Opm::UDQSet s(name, var_type, wgnames);
for (std::size_t i=0; i < values.size(); i++)
s.assign(i , values[i]);
return s;
}
Opm::UDQState make_udq_state()
{
auto state = Opm::UDQState{0};
state.add("WUOPRL", make_udq_set("WUOPRL",
Opm::UDQVarType::WELL_VAR,
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
{210, 211, 212, 213}));
state.add("WUOPRU", make_udq_set("WUOPRU",
Opm::UDQVarType::WELL_VAR,
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
{220, 221, 222, 223}));
state.add("WULPRL", make_udq_set("WULPRL",
Opm::UDQVarType::WELL_VAR,
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
{230, 231, 232, 233}));
state.add("WULPRU", make_udq_set("WULPRU",
Opm::UDQVarType::WELL_VAR,
{"PROD1", "PROD2", "WINJ1", "WINJ2"},
{160, 161, 162, 163}));
state.add("GUOPRU", make_udq_set("GUOPRU",
Opm::UDQVarType::GROUP_VAR,
{"WGRP1", "WGRP2", "GRP1"},
{360, 361, 362}));
state.add("FULPR", Opm::UDQSet::scalar("FULPR", 460));
return state;
}
Opm::SummaryState sum_state()
{
auto state = Opm::SummaryState{std::chrono::system_clock::now()};
@ -133,6 +178,7 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
Opm::EclipseState es = simCase.es;
Opm::SummaryState st = sum_state();
Opm::UDQState udq_state = make_udq_state();
Opm::Schedule sched = simCase.sched;
Opm::EclipseGrid grid = simCase.grid;
const auto& ioConfig = es.getIOConfig();
@ -162,7 +208,7 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih);
auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims);
udqData.captureDeclaredUDQData(sched, rptStep, st, ih);
udqData.captureDeclaredUDQData(sched, rptStep, udq_state, ih);
rstFile.write("ZUDN", udqData.getZUDN());
rstFile.write("ZUDL", udqData.getZUDL());

View File

@ -399,7 +399,7 @@ RestartValue first_sim(const Setup& setup, Action::State& action_state, SummaryS
RestartValue restart_value(sol, wells, groups);
init_st(st);
udq.eval(st);
udq.eval(st, udq_state);
eclWriter.writeTimeStep( action_state,
st,
udq_state,
@ -613,6 +613,7 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) {
auto groups = mkGroups();
Opm::SummaryState sumState(std::chrono::system_clock::now());
Opm::Action::State action_state;
Opm::UDQState udq_state(19);
const auto seqnum = 1;
auto rstFile = OS::Restart {
@ -627,7 +628,8 @@ BOOST_AUTO_TEST_CASE(WriteWrongSOlutionSize) {
setup.grid ,
setup.schedule,
action_state,
sumState),
sumState,
udq_state),
std::runtime_error);
}
}
@ -663,6 +665,7 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) {
Setup setup("BASE_SIM.DATA");
{
Action::State action_state;
UDQState udq_state(10);
auto num_cells = setup.grid.getNumActive( );
auto cells = mkSolution( num_cells );
auto wells = mkWells();
@ -691,7 +694,8 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) {
setup.grid,
setup.schedule,
action_state,
sumState);
sumState,
udq_state);
}
const auto rstFile = ::Opm::EclIO::OutputStream::
@ -767,6 +771,7 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) {
restart_value.addExtra("THRESHPR", UnitSystem::measure::pressure, {0,1});
const auto sumState = sim_state();
Action::State action_state;
UDQState udq_state(99);
/* THPRES data has wrong size in extra container. */
{
@ -783,7 +788,8 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) {
base_setup.grid,
base_setup.schedule,
action_state,
sumState),
sumState,
udq_state),
std::runtime_error);
}
@ -806,7 +812,8 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) {
base_setup.grid,
base_setup.schedule,
action_state,
sumState);
sumState,
udq_state);
}
{
@ -853,7 +860,7 @@ BOOST_AUTO_TEST_CASE(Restore_Cumulatives)
mkGroups()
};
const auto sumState = sim_state();
UDQState udq_state(98);
namespace OS = ::Opm::EclIO::OutputStream;
const auto rset = OS::ResultSet{ wa.currentWorkingDirectory(), "FILE" };
@ -865,7 +872,7 @@ BOOST_AUTO_TEST_CASE(Restore_Cumulatives)
};
RestartIO::save(rstFile, seqnum, 100, restart_value,
setup.es, setup.grid, setup.schedule, action_state, sumState);
setup.es, setup.grid, setup.schedule, action_state, sumState, udq_state);
}
Action::State action_state;