138 lines
4.6 KiB
C++
138 lines
4.6 KiB
C++
/*
|
|
Copyright 2019 Equinor ASA.
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
OPM is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OPM is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
|
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp>
|
|
|
|
namespace Opm {
|
|
|
|
GuideRate::GuideRate(const Schedule& schedule_arg) :
|
|
schedule(schedule_arg)
|
|
{}
|
|
|
|
|
|
double GuideRate::get(const std::string& wgname, size_t report_step) const {
|
|
const auto& value = this->values.at(wgname);
|
|
return value.value;
|
|
}
|
|
|
|
|
|
double GuideRate::update(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);
|
|
|
|
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: ");
|
|
|
|
return this->get(wgname, report_step);
|
|
}
|
|
|
|
|
|
void GuideRate::group_update(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);
|
|
|
|
// If the FORM mode is used we check if the last computation is recent enough;
|
|
// then we just return.
|
|
if (iter != this->values.end()) {
|
|
const auto& grv = iter->second;
|
|
if (group.target == Group2::GuideRateTarget::FORM) {
|
|
auto time_diff = sim_time - grv.sim_time;
|
|
if (config.model().update_delay() > time_diff)
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
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();
|
|
|
|
if (group.target == Group2::GuideRateTarget::FORM) {
|
|
if (iter != this->values.end())
|
|
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};
|
|
}
|
|
|
|
|
|
void GuideRate::well_update(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 {
|
|
auto iter = this->values.find(wgname);
|
|
|
|
if (iter != this->values.end()) {
|
|
const auto& grv = iter->second;
|
|
auto time_diff = sim_time - grv.sim_time;
|
|
if (config.model().update_delay() > time_diff)
|
|
return;
|
|
}
|
|
|
|
double guide_rate;
|
|
if (iter == this->values.end())
|
|
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};
|
|
}
|
|
}
|
|
|
|
double GuideRate::eval_form(const GuideRateModel& model, double oil_pot, double gas_pot, double wat_pot, const GuideRateValue * prev) const {
|
|
double pot = 0;
|
|
double R1 = 0.5;
|
|
double R2 = 0.5;
|
|
|
|
double new_guide_rate = model.eval(pot, R1, R2);
|
|
if (!prev)
|
|
return new_guide_rate;
|
|
|
|
if (new_guide_rate > prev->value && !model.allow_increase())
|
|
new_guide_rate = prev->value;
|
|
|
|
auto damping_factor = model.damping_factor();
|
|
|
|
return damping_factor * new_guide_rate + (1 - damping_factor) * prev->value;
|
|
}
|
|
|
|
double GuideRate::eval_group_pot() const {
|
|
return 0;
|
|
}
|
|
|
|
double GuideRate::eval_group_resvinj() const {
|
|
return 0;
|
|
}
|
|
|
|
}
|