Add GuideRate state/cache object
This commit is contained in:
@@ -91,6 +91,7 @@ if(ENABLE_ECL_INPUT)
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Events.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/Group2.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.cpp
|
||||
src/opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.cpp
|
||||
@@ -564,6 +565,7 @@ if(ENABLE_ECL_INPUT)
|
||||
opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GTNode.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/Group2.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp
|
||||
opm/parser/eclipse/EclipseState/Schedule/MessageLimits.hpp
|
||||
|
||||
71
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp
Normal file
71
opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef GUIDE_RATE_HPP
|
||||
#define GUIDE_RATE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <cstddef>
|
||||
#include <ctime>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class Schedule;
|
||||
class GuideRate {
|
||||
|
||||
struct GuideRateValue {
|
||||
GuideRateValue() = default;
|
||||
GuideRateValue(std::time_t t, double v):
|
||||
sim_time(t),
|
||||
value(v)
|
||||
{}
|
||||
|
||||
bool operator==(const GuideRateValue& other) const {
|
||||
return (this->sim_time == other.sim_time &&
|
||||
this->value == other.value);
|
||||
}
|
||||
|
||||
bool operator!=(const GuideRateValue& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
std::time_t sim_time;
|
||||
double value;
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
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, size_t report_step) const;
|
||||
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<std::string,GuideRateValue> values;
|
||||
const Schedule& schedule;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -35,13 +35,13 @@ public:
|
||||
|
||||
struct Well {
|
||||
double guide_rate;
|
||||
Well2::GuideRateTarget phase;
|
||||
Well2::GuideRateTarget target;
|
||||
double scaling_factor;
|
||||
};
|
||||
|
||||
struct Group {
|
||||
double guide_rate;
|
||||
Group2::GuideRateTarget phase;
|
||||
Group2::GuideRateTarget target;
|
||||
};
|
||||
|
||||
const GuideRateModel& model() const;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef GUIDE_RATE_MODEL_HPP
|
||||
#define GUIDE_RATE_MODEL_HPP
|
||||
|
||||
#include <opm/parser/eclipse/Deck/UDAValue.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
class GuideRateModel {
|
||||
@@ -49,28 +51,34 @@ public:
|
||||
bool use_free_gas_arg);
|
||||
|
||||
GuideRateModel() = default;
|
||||
double eval(double pot, double R1, double R2) const;
|
||||
bool updateLINCOM(const UDAValue& alpha, const UDAValue& beta, const UDAValue& gamma);
|
||||
double eval(double oil_pot, double gas_pot, double wat_pot) const;
|
||||
double update_delay() const;
|
||||
bool allow_increase() const;
|
||||
double damping_factor() const;
|
||||
bool operator==(const GuideRateModel& other) const;
|
||||
bool operator!=(const GuideRateModel& other) const;
|
||||
|
||||
Target target() const;
|
||||
private:
|
||||
/*
|
||||
Unfortunately the default values will give a GuideRateModel which can not
|
||||
be evaluated, due to a division by zero problem.
|
||||
*/
|
||||
double time_interval = 0;
|
||||
Target target = Target::NONE;
|
||||
Target m_target = Target::NONE;
|
||||
double A = 0;
|
||||
double B = 0;
|
||||
double C = 0;
|
||||
double D = 0;
|
||||
double E = 0;
|
||||
double F = 0;
|
||||
bool allow_increase = true;
|
||||
double damping_factor = 1.0;
|
||||
bool allow_increase_ = true;
|
||||
double damping_factor_ = 1.0;
|
||||
bool use_free_gas = false;
|
||||
bool default_model = true;
|
||||
UDAValue alpha;
|
||||
UDAValue beta;
|
||||
UDAValue gamma;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -281,6 +281,7 @@ namespace Opm
|
||||
void handleGCONPROD( const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
void handleGEFAC( const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
void handleGUIDERAT( const DeckKeyword& keyword, size_t currentStep);
|
||||
void handleLINCOM( const DeckKeyword& keyword, size_t currentStep);
|
||||
void handleWEFAC( const DeckKeyword& keyword, size_t currentStep, const ParseContext& parseContext, ErrorGuard& errors);
|
||||
void handleTUNING( const DeckKeyword& keyword, size_t currentStep);
|
||||
void handleNUPCOL( const DeckKeyword& keyword, size_t currentStep);
|
||||
|
||||
137
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp
Normal file
137
src/opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -41,7 +41,7 @@ void GuideRateConfig::update_well(const Well2& well) {
|
||||
if (well.isAvailableForGroupControl()) {
|
||||
auto& well_node = this->wells[well.name()];
|
||||
well_node.guide_rate = well.getGuideRate();
|
||||
well_node.phase = well.getGuideRatePhase();
|
||||
well_node.target= well.getGuideRatePhase();
|
||||
well_node.scaling_factor = well.getGuideRateScalingFactor();
|
||||
} else
|
||||
this->wells.erase(well.name());
|
||||
@@ -64,7 +64,7 @@ void GuideRateConfig::update_group(const Group2& group) {
|
||||
|
||||
auto& group_node = this->groups[group.name()];
|
||||
group_node.guide_rate = properties.guide_rate;
|
||||
group_node.phase = guide_target;
|
||||
group_node.target = guide_target;
|
||||
}
|
||||
|
||||
const GuideRateConfig::Group& GuideRateConfig::group(const std::string& group) const {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/L.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp>
|
||||
|
||||
namespace Opm {
|
||||
@@ -36,17 +37,20 @@ GuideRateModel::GuideRateModel(double time_interval_arg,
|
||||
double damping_factor_arg,
|
||||
bool use_free_gas_arg) :
|
||||
time_interval(time_interval_arg),
|
||||
target(target_arg),
|
||||
m_target(target_arg),
|
||||
A(A_arg),
|
||||
B(B_arg),
|
||||
C(C_arg),
|
||||
D(D_arg),
|
||||
E(E_arg),
|
||||
F(F_arg),
|
||||
allow_increase(allow_increase_arg),
|
||||
damping_factor(damping_factor_arg),
|
||||
allow_increase_(allow_increase_arg),
|
||||
damping_factor_(damping_factor_arg),
|
||||
use_free_gas(use_free_gas_arg),
|
||||
default_model(false)
|
||||
default_model(false),
|
||||
alpha(UDAValue(ParserKeywords::LINCOM::ALPHA::defaultValue)),
|
||||
beta(UDAValue(ParserKeywords::LINCOM::BETA::defaultValue)),
|
||||
gamma(UDAValue(ParserKeywords::LINCOM::GAMMA::defaultValue))
|
||||
{
|
||||
if (this->A > 3 || this->A < -3)
|
||||
throw std::invalid_argument("Invalid value for A must be in interval [-3,3]");
|
||||
@@ -59,18 +63,52 @@ GuideRateModel::GuideRateModel(double time_interval_arg,
|
||||
|
||||
if (this->F > 3 || this->F < -3)
|
||||
throw std::invalid_argument("Invalid value for F must be in interval [-3,3]");
|
||||
|
||||
if (this->m_target == Target::COMB)
|
||||
throw std::logic_error("Sorry - the 'COMB' mode is not supported");
|
||||
}
|
||||
|
||||
|
||||
double GuideRateModel::update_delay() const {
|
||||
return this->time_interval;
|
||||
}
|
||||
|
||||
|
||||
double GuideRateModel::eval(double pot, double R1, double R2) const {
|
||||
double GuideRateModel::eval(double oil_pot, double gas_pot, double wat_pot) const {
|
||||
if (this->default_model)
|
||||
throw std::invalid_argument("The default GuideRateModel can not be evaluated - must enter GUIDERAT information explicitly.");
|
||||
|
||||
double pot;
|
||||
double R1;
|
||||
double R2;
|
||||
|
||||
switch (this->m_target) {
|
||||
case Target::OIL:
|
||||
pot = oil_pot;
|
||||
R1 = wat_pot / oil_pot;
|
||||
R2 = gas_pot / oil_pot;
|
||||
break;
|
||||
|
||||
case Target::LIQ:
|
||||
pot = oil_pot + wat_pot;;
|
||||
R1 = oil_pot / (oil_pot + wat_pot);
|
||||
R2 = wat_pot / (oil_pot + wat_pot);
|
||||
break;
|
||||
|
||||
case Target::GAS:
|
||||
pot = gas_pot;
|
||||
R1 = wat_pot / gas_pot;
|
||||
R2 = oil_pot / gas_pot;
|
||||
break;
|
||||
|
||||
case Target::COMB:
|
||||
throw std::logic_error("Not implemented - don't have a clue?");
|
||||
|
||||
case Target::RES:
|
||||
throw std::logic_error("Not implemented - don't have a clue?");
|
||||
|
||||
default:
|
||||
throw std::logic_error("Hmmm - should not be here?");
|
||||
}
|
||||
|
||||
|
||||
double denom = this->B + this->C*std::pow(R1, this->D) + this->E*std::pow(R2, this->F);
|
||||
/*
|
||||
The values pot, R1 and R2 are runtime simulation results, so here
|
||||
@@ -85,15 +123,15 @@ double GuideRateModel::eval(double pot, double R1, double R2) const {
|
||||
|
||||
bool GuideRateModel::operator==(const GuideRateModel& other) const {
|
||||
return (this->time_interval == other.time_interval) &&
|
||||
(this->target == other.target) &&
|
||||
(this->m_target == other.m_target) &&
|
||||
(this->A == other.A) &&
|
||||
(this->B == other.B) &&
|
||||
(this->C == other.C) &&
|
||||
(this->D == other.D) &&
|
||||
(this->E == other.E) &&
|
||||
(this->F == other.F) &&
|
||||
(this->allow_increase == other.allow_increase) &&
|
||||
(this->damping_factor == other.damping_factor) &&
|
||||
(this->allow_increase_ == other.allow_increase_) &&
|
||||
(this->damping_factor_ == other.damping_factor_) &&
|
||||
(this->use_free_gas == other.use_free_gas);
|
||||
}
|
||||
|
||||
@@ -102,6 +140,23 @@ bool GuideRateModel::operator!=(const GuideRateModel& other) const {
|
||||
}
|
||||
|
||||
|
||||
double GuideRateModel::update_delay() const {
|
||||
return this->time_interval;
|
||||
}
|
||||
|
||||
double GuideRateModel::damping_factor() const {
|
||||
return this->damping_factor_;
|
||||
}
|
||||
|
||||
bool GuideRateModel::allow_increase() const {
|
||||
return this->allow_increase_;
|
||||
}
|
||||
|
||||
GuideRateModel::Target GuideRateModel::target() const {
|
||||
return this->m_target;
|
||||
}
|
||||
|
||||
|
||||
GuideRateModel::Target GuideRateModel::TargetFromString(const std::string& s) {
|
||||
if (s == "OIL")
|
||||
return Target::OIL;
|
||||
@@ -124,4 +179,26 @@ GuideRateModel::Target GuideRateModel::TargetFromString(const std::string& s) {
|
||||
throw std::invalid_argument("Could not convert: " + s + " to a valid Target enum value");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The COMB target - which requires parameters from the LINCOM keyword, is not
|
||||
supported. There are at least two pieces of missing functionality:
|
||||
|
||||
1. The parameters in the LINCOM come with unit specified by the LCUNIT
|
||||
keyword; seemingly decoupled from the unit system in the rest of deck.
|
||||
This functionality is not supported.
|
||||
|
||||
2. The values in the LINCOM kewyords are UDA values, have not yet integrated
|
||||
the necessary SummaryState into this.
|
||||
*/
|
||||
|
||||
bool GuideRateModel::updateLINCOM(const UDAValue& , const UDAValue& , const UDAValue& ) {
|
||||
if (this->m_target == Target::COMB)
|
||||
throw std::logic_error("The LINCOM keyword is not supported - at all!");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/C.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/G.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/L.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/V.hpp>
|
||||
#include <opm/parser/eclipse/Parser/ParserKeywords/W.hpp>
|
||||
|
||||
@@ -338,6 +339,9 @@ namespace {
|
||||
else if (keyword.name() == "GUIDERAT")
|
||||
handleGUIDERAT(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "LINCOM")
|
||||
handleLINCOM(keyword, currentStep);
|
||||
|
||||
else if (keyword.name() == "TUNING")
|
||||
handleTUNING(keyword, currentStep);
|
||||
|
||||
@@ -1611,6 +1615,21 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
void Schedule::handleLINCOM( const DeckKeyword& keyword, size_t currentStep) {
|
||||
const auto& record = keyword.getRecord(0);
|
||||
auto alpha = record.getItem<ParserKeywords::LINCOM::ALPHA>().get<UDAValue>(0);
|
||||
auto beta = record.getItem<ParserKeywords::LINCOM::BETA>().get<UDAValue>(0);
|
||||
auto gamma = record.getItem<ParserKeywords::LINCOM::GAMMA>().get<UDAValue>(0);
|
||||
auto new_config = std::make_shared<GuideRateConfig>( this->guideRateConfig(currentStep) );
|
||||
auto new_model = new_config->model();
|
||||
|
||||
if (new_model.updateLINCOM(alpha, beta, gamma)) {
|
||||
new_config->update_model(new_model);
|
||||
this->guide_rate_config.update( currentStep, new_config );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Schedule::handleTUNING( const DeckKeyword& keyword, size_t currentStep) {
|
||||
|
||||
int numrecords = keyword.size();
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/Group2.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateModel.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
@@ -299,9 +300,81 @@ BOOST_AUTO_TEST_CASE(createDeckWithGCONPROD) {
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TESTGuideRateModel) {
|
||||
Opm::GuideRateModel grc_default;
|
||||
BOOST_CHECK_THROW(Opm::GuideRateModel(0.0,GuideRateModel::Target::NONE, -5,0,0,0,0,0,true,1,true), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(Opm::GuideRateModel(0.0,GuideRateModel::Target::OIL, -5,0,0,0,0,0,true,1,true), std::invalid_argument);
|
||||
BOOST_CHECK_THROW(grc_default.eval(1,0.50,0.50), std::invalid_argument);
|
||||
|
||||
Opm::GuideRateModel grc_delay(10, GuideRateModel::Target::NONE, 1,1,0,0,0,0,true,1,true);
|
||||
Opm::GuideRateModel grc_delay(10, GuideRateModel::Target::OIL, 1,1,0,0,0,0,true,1,true);
|
||||
BOOST_CHECK_NO_THROW(grc_delay.eval(1.0, 0.5, 0.5));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TESTGuideRateLINCOM) {
|
||||
Parser parser;
|
||||
std::string input = R"(
|
||||
START -- 0
|
||||
31 AUG 1993 /
|
||||
SCHEDULE
|
||||
|
||||
GRUPTREE
|
||||
'G1' 'FIELD' /
|
||||
'G2' 'FIELD' /
|
||||
/
|
||||
|
||||
GCONPROD
|
||||
'G1' 'ORAT' 10000 3* 'CON' /
|
||||
'G2' 'RESV' 10000 3* 'CON' /
|
||||
/
|
||||
|
||||
GUIDERAT
|
||||
1* 'COMB' 1.0 1.0 /
|
||||
|
||||
LINCOM
|
||||
1 2 'WWCT:OPX' /
|
||||
|
||||
)";
|
||||
|
||||
auto deck = parser.parseString(input);
|
||||
EclipseGrid grid(10,10,10);
|
||||
TableManager table ( deck );
|
||||
Eclipse3DProperties eclipseProperties ( deck , table, grid);
|
||||
Runspec runspec (deck );
|
||||
|
||||
/* The 'COMB' target mode is not supported */
|
||||
BOOST_CHECK_THROW(Opm::Schedule schedule(deck, grid, eclipseProperties, runspec), std::logic_error);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TESTGuideRate) {
|
||||
Parser parser;
|
||||
std::string input = R"(
|
||||
START -- 0
|
||||
31 AUG 1993 /
|
||||
SCHEDULE
|
||||
|
||||
GRUPTREE
|
||||
'G1' 'FIELD' /
|
||||
'G2' 'FIELD' /
|
||||
/
|
||||
|
||||
GCONPROD
|
||||
'G1' 'ORAT' 10000 3* 'CON' /
|
||||
'G2' 'RESV' 10000 3* 'CON' /
|
||||
/
|
||||
|
||||
GUIDERAT
|
||||
1* 'OIL' 1.0 1.0 /
|
||||
|
||||
LINCOM
|
||||
1 2 'WWCT:OPX' /
|
||||
|
||||
TSTEP
|
||||
1 1 1 1 1 1 1 1 1 1 1 /
|
||||
)";
|
||||
|
||||
auto deck = parser.parseString(input);
|
||||
EclipseGrid grid(10,10,10);
|
||||
TableManager table ( deck );
|
||||
Eclipse3DProperties eclipseProperties ( deck , table, grid);
|
||||
Runspec runspec (deck );
|
||||
Schedule schedule(deck, grid, eclipseProperties, runspec);
|
||||
|
||||
GuideRate gr(schedule);
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellProductionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellInjectionProperties.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRateConfig.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GuideRate.hpp>
|
||||
|
||||
using namespace Opm;
|
||||
|
||||
@@ -3459,10 +3460,10 @@ DATES -- 4
|
||||
{
|
||||
const auto& grc = schedule.guideRateConfig(0);
|
||||
const auto& w1_node = grc.well("W1");
|
||||
BOOST_CHECK(w1_node.phase == Well2::GuideRateTarget::OIL);
|
||||
BOOST_CHECK(w1_node.target == Well2::GuideRateTarget::OIL);
|
||||
|
||||
const auto& w2_node = grc.well("W2");
|
||||
BOOST_CHECK(w2_node.phase == Well2::GuideRateTarget::GAS);
|
||||
BOOST_CHECK(w2_node.target == Well2::GuideRateTarget::GAS);
|
||||
|
||||
BOOST_CHECK(!grc.has_group("G1"));
|
||||
BOOST_CHECK(grc.has_group("G2"));
|
||||
@@ -3470,7 +3471,7 @@ DATES -- 4
|
||||
{
|
||||
const auto& grc = schedule.guideRateConfig(2);
|
||||
const auto& w1_node = grc.well("W1");
|
||||
BOOST_CHECK(w1_node.phase == Well2::GuideRateTarget::WAT);
|
||||
BOOST_CHECK(w1_node.target == Well2::GuideRateTarget::WAT);
|
||||
BOOST_CHECK_EQUAL(w1_node.guide_rate, 0.75);
|
||||
|
||||
BOOST_CHECK(grc.has_well("W1"));
|
||||
@@ -3480,4 +3481,13 @@ DATES -- 4
|
||||
BOOST_CHECK(grc.has_group("G1"));
|
||||
BOOST_CHECK(!grc.has_group("G2"));
|
||||
}
|
||||
|
||||
GuideRate gr(schedule);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user