diff --git a/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp b/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp index 4da37afca..a6360d752 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp @@ -25,16 +25,21 @@ #include #include +#include +#include + namespace Opm { class Schedule; class GuideRate { +private: struct GuideRateValue { GuideRateValue() = default; - GuideRateValue(double t, double v): + GuideRateValue(double t, double v, GuideRateModel::Target tg): sim_time(t), - value(v) + value(v), + target(tg) {} bool operator==(const GuideRateValue& other) const { @@ -46,23 +51,43 @@ struct GuideRateValue { return !(*this == other); } + double eval(GuideRateModel::Target target_arg) const; + double sim_time; double value; + GuideRateModel::Target target; }; +struct Potential { + Potential() = default; + Potential(double op, double gp, double wp) : + oil_pot(op), + gas_pot(gp), + wat_pot(wp) + {} + + + double eval(GuideRateModel::Target target) const; + + double oil_pot; + double gas_pot; + double wat_pot; +}; public: GuideRate(const Schedule& schedule); - double update(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot); + void compute(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot); + double get(const std::string& well, Well2::GuideRateTarget target) const; + double get(const std::string& group, Group2::GuideRateTarget target) const; private: - void well_update(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot); - void group_update(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot); - double get(const std::string& wgname) const; + void well_compute(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot); + void group_compute(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot); double eval_form(const GuideRateModel& model, double oil_pot, double gas_pot, double wat_pot, const GuideRateValue * prev) const; double eval_group_pot() const; double eval_group_resvinj() const; std::unordered_map values; + std::unordered_map potentials; const Schedule& schedule; }; diff --git a/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp b/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp index 047692425..12ab02d95 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp @@ -21,6 +21,8 @@ #define GUIDE_RATE_MODEL_HPP #include +#include +#include namespace Opm { @@ -59,6 +61,9 @@ public: bool operator==(const GuideRateModel& other) const; bool operator!=(const GuideRateModel& other) const; Target target() const; + + static Target convert_target(Group2::GuideRateTarget group_target); + static Target convert_target(Well2::GuideRateTarget well_target); private: /* Unfortunately the default values will give a GuideRateModel which can not diff --git a/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp b/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp index c92a5d78b..73ae8926e 100644 --- a/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp +++ b/opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp @@ -157,7 +157,7 @@ public: double scale_factor; }; - + struct InjectionControls { public: InjectionControls(int controls_arg) : diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp index 5c9268af8..eeecbf494 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp @@ -22,32 +22,66 @@ namespace Opm { +double GuideRate::GuideRateValue::eval(GuideRateModel::Target target_arg) const +{ + if (target == this->target) + return this->value; + else + throw std::logic_error("Don't know how to convert .... "); +} + +double GuideRate::Potential::eval(GuideRateModel::Target target) const { + if (target == GuideRateModel::Target::OIL) + return this->oil_pot; + + if (target == GuideRateModel::Target::GAS) + return this->gas_pot; + + if (target == GuideRateModel::Target::LIQ) + return this->oil_pot + this->wat_pot; + + throw std::logic_error("Don't know how to convert .... "); +} + + GuideRate::GuideRate(const Schedule& schedule_arg) : schedule(schedule_arg) {} -double GuideRate::get(const std::string& wgname) const { - const auto& value = this->values.at(wgname); - return value.value; + +double GuideRate::get(const std::string& well, Well2::GuideRateTarget target) const { + const auto iter = this->values.find(well); + auto model_target = GuideRateModel::convert_target(target); + if (iter != this->values.end()) { + const auto& value = iter->second; + return value.eval(model_target); + } else { + const auto& pot = this->potentials.at(well); + return pot.eval(model_target); + } +} + +double GuideRate::get(const std::string& group, Group2::GuideRateTarget target) const { + const auto& value = this->values.at(group); + auto model_target = GuideRateModel::convert_target(target); + return value.eval(model_target); } -double GuideRate::update(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot) { +void GuideRate::compute(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot) { const auto& config = this->schedule.guideRateConfig(report_step); + this->potentials[wgname] = Potential{oil_pot, gas_pot, wat_pot}; - if (config.has_well(wgname)) - this->well_update(wgname, report_step, sim_time, oil_pot, gas_pot, wat_pot); - else if (config.has_group(wgname)) { - this->group_update(wgname, report_step, sim_time, oil_pot, gas_pot, wat_pot); - } else - throw std::out_of_range("No such well/group: "); + if (config.has_group(wgname)) + this->group_compute(wgname, report_step, sim_time, oil_pot, gas_pot, wat_pot); + else if (config.has_well(wgname)) + this->well_compute(wgname, report_step, sim_time, oil_pot, gas_pot, wat_pot); - return this->get(wgname); } -void GuideRate::group_update(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot) { +void GuideRate::group_compute(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot) { const auto& config = this->schedule.guideRateConfig(report_step); const auto& group = config.group(wgname); auto iter = this->values.find(wgname); @@ -67,15 +101,14 @@ void GuideRate::group_update(const std::string& wgname, size_t report_step, doub } - double guide_rate = group.guide_rate; - - if (group.guide_rate == 0 || group.target == Group2::GuideRateTarget::POTN) - guide_rate = this->eval_group_pot(); - if (group.target == Group2::GuideRateTarget::INJV) - guide_rate = this->eval_group_resvinj(); + throw std::logic_error("Group guide rate mode: INJV not implemented"); + + if (group.target == Group2::GuideRateTarget::POTN) + throw std::logic_error("Group guide rate mode: POTN not implemented"); if (group.target == Group2::GuideRateTarget::FORM) { + double guide_rate; if (!config.has_model()) throw std::logic_error("When specifying GUIDERATE target FORM you must enter a guiderate model with the GUIDERAT keyword"); @@ -83,19 +116,20 @@ void GuideRate::group_update(const std::string& wgname, size_t report_step, doub guide_rate = this->eval_form(config.model(), oil_pot, gas_pot, wat_pot, nullptr); else guide_rate = this->eval_form(config.model(), oil_pot, gas_pot, wat_pot, std::addressof(iter->second)); - } - this->values[wgname] = GuideRateValue{sim_time, guide_rate}; + this->values[wgname] = GuideRateValue{sim_time, guide_rate, config.model().target()}; + } } -void GuideRate::well_update(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot) { +void GuideRate::well_compute(const std::string& wgname, size_t report_step, double sim_time, double oil_pot, double gas_pot, double wat_pot) { const auto& config = this->schedule.guideRateConfig(report_step); const auto& well = config.well(wgname); - if (well.guide_rate > 0) - this->values[wgname] = GuideRateValue( sim_time, well.guide_rate ); - else { + if (well.guide_rate > 0) { + auto model_target = GuideRateModel::convert_target(well.target); + this->values[wgname] = GuideRateValue( sim_time, well.guide_rate, model_target ); + } else { auto iter = this->values.find(wgname); if (iter != this->values.end()) { @@ -114,7 +148,7 @@ void GuideRate::well_update(const std::string& wgname, size_t report_step, doubl else guide_rate = this->eval_form(config.model(), oil_pot, gas_pot, wat_pot, std::addressof(iter->second)); - this->values[wgname] = GuideRateValue{sim_time, guide_rate}; + this->values[wgname] = GuideRateValue{sim_time, guide_rate, config.model().target()}; } } diff --git a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp index 7fbd1709c..fc56a7c54 100644 --- a/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp +++ b/src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp @@ -200,5 +200,29 @@ bool GuideRateModel::updateLINCOM(const UDAValue& , const UDAValue& , const UDAV } +GuideRateModel::Target GuideRateModel::convert_target(Well2::GuideRateTarget well_target) { + if (well_target == Well2::GuideRateTarget::OIL) + return Target::OIL; + if (well_target == Well2::GuideRateTarget::GAS) + return Target::GAS; + + if (well_target == Well2::GuideRateTarget::LIQ) + return Target::LIQ; + + throw std::logic_error("Can not convert this .... "); +} + +GuideRateModel::Target GuideRateModel::convert_target(Group2::GuideRateTarget group_target) { + if (group_target == Group2::GuideRateTarget::OIL) + return Target::OIL; + + if (group_target == Group2::GuideRateTarget::GAS) + return Target::GAS; + + if (group_target == Group2::GuideRateTarget::LIQ) + return Target::LIQ; + + throw std::logic_error("Can not convert this .... "); +} } diff --git a/tests/parser/ScheduleTests.cpp b/tests/parser/ScheduleTests.cpp index 1d9fcce2d..0418d9e05 100644 --- a/tests/parser/ScheduleTests.cpp +++ b/tests/parser/ScheduleTests.cpp @@ -3565,7 +3565,8 @@ DATES -- 4 double oil_pot = 1; double gas_pot = 1; double wat_pot = 1; - BOOST_CHECK_THROW(gr.update("XYZ",1, 1.0, oil_pot, gas_pot, wat_pot), std::out_of_range); + + gr.compute("XYZ",1, 1.0, oil_pot, gas_pot, wat_pot); }