correction for lift quantity well-data
corrections to IUAD and IUAP various improvements of E100 compatible restart file add debug output additonal debug print corrected loop placement for active prod/inj wells remove debug print and clean up code
This commit is contained in:
parent
985cb279ff
commit
ec976db684
@ -55,6 +55,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
GasFlowFract = 10, // Normalised Gas flow rate fraction
|
||||
Pressure = 11, // Segment pressure
|
||||
|
||||
item31 = 30, // Very close to Normalised Water flow rate fraction - value used pr today
|
||||
|
||||
item40 = 39, // Unknown
|
||||
|
||||
ValveLength = 40, // Length of valve
|
||||
|
@ -113,6 +113,7 @@ namespace Opm { namespace RestartIO { namespace Helpers { namespace VectorItems
|
||||
BHPTarget = 6, // Well's bottom hole pressure target
|
||||
|
||||
DatumDepth = 9, // Well's reference depth for BHP
|
||||
Alq_value = 10, // Well's artificial lift quantity
|
||||
|
||||
DrainageRadius = 17, // Well's drainage radius - item 7 from WELSPECS
|
||||
EfficiencyFactor1 = 24, // Item2 from WEFAC; this value is repeated at two locations.
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
std::size_t use_index = 0;
|
||||
UDAControl control;
|
||||
int uad_code;
|
||||
std::string wg_name() const;
|
||||
std::size_t use_count;
|
||||
private:
|
||||
// The wgname is need in the update process, but it should
|
||||
|
@ -230,9 +230,6 @@ int higherLevelProdControlGroupSeqIndex(const Opm::Schedule& sched,
|
||||
cur_prod_ctrl = sumState.get(group_key);
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Current group control is not defined for group: " << current.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Current group control is not defined for group: " << current.name() << " at timestep: " << simStep << std::endl;
|
||||
cur_prod_ctrl = 0.;
|
||||
}
|
||||
@ -269,9 +266,6 @@ int higherLevelProdControlMode(const Opm::Schedule& sched,
|
||||
cur_prod_ctrl = sumState.get(group_key);
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Current group control is not defined for group: " << current.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Current group control is not defined for group: " << current.name() << " at timestep: " << simStep << std::endl;
|
||||
cur_prod_ctrl = 0.;
|
||||
}
|
||||
@ -313,9 +307,6 @@ int higherLevelInjControlGroupSeqIndex(const Opm::Schedule& sched,
|
||||
cur_inj_ctrl = sumState.get(group_key);
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Current injection group control: " << curInjCtrlKey << " is not defined for group: " << current.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Current injection group control: " << curInjCtrlKey << " is not defined for group: " << current.name() << " at timestep: " << simStep << std::endl;
|
||||
cur_inj_ctrl = 0.;
|
||||
}
|
||||
@ -353,9 +344,6 @@ int higherLevelInjControlMode(const Opm::Schedule& sched,
|
||||
cur_inj_ctrl = sumState.get(group_key);
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Current injection group control: " << curInjCtrlKey << " is not defined for group: " << current.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Current injection group control: " << curInjCtrlKey << " is not defined for group: " << current.name() << " at timestep: " << simStep << std::endl;
|
||||
cur_inj_ctrl = 0.;
|
||||
}
|
||||
@ -519,6 +507,33 @@ void staticContrib(const Opm::Schedule& sched,
|
||||
// location nwgmax
|
||||
iGrp[nwgmax] = groupSize(group);
|
||||
|
||||
// Find number of active production wells and injection wells for group
|
||||
std::string group_key_1;
|
||||
group_key_1 = gf_key("GMWPR", group.name());
|
||||
double g_act_pwells = -1.;
|
||||
if (sumState.has(group_key_1)) {
|
||||
g_act_pwells = sumState.get(group_key_1);
|
||||
}
|
||||
else {
|
||||
g_act_pwells = 0.;
|
||||
}
|
||||
|
||||
group_key_1 = gf_key("GMWIN", group.name());
|
||||
double g_act_iwells = -1.;
|
||||
if (sumState.has(group_key_1)) {
|
||||
g_act_iwells = sumState.get(group_key_1);
|
||||
}
|
||||
else {
|
||||
g_act_iwells = 0.;
|
||||
}
|
||||
// set the number of active wells for a group
|
||||
if (g_act_pwells >= 0 && g_act_iwells >= 0) {
|
||||
iGrp[nwgmax + 33] = g_act_pwells + g_act_iwells;
|
||||
}
|
||||
else {
|
||||
iGrp[nwgmax + 33] = 0;
|
||||
}
|
||||
|
||||
//Treat groups that have production
|
||||
if ((group.getGroupType() == Opm::Group::GroupType::NONE) || (group.getGroupType() == Opm::Group::GroupType::PRODUCTION)
|
||||
|| (group.getGroupType() == Opm::Group::GroupType::MIXED)) {
|
||||
@ -527,7 +542,6 @@ void staticContrib(const Opm::Schedule& sched,
|
||||
const auto& prod_guide_rate_def = group.productionControls(sumState).guide_rate_def;
|
||||
const auto& p_exceed_act = group.productionControls(sumState).exceed_action;
|
||||
// Find production control mode for group
|
||||
std::string group_key_1;
|
||||
group_key_1 = gf_key("GMCTP", group.name());
|
||||
double cur_prod_ctrl = -1.;
|
||||
Opm::Group::ProductionCMode pctl_mode = Opm::Group::ProductionCMode::NONE;
|
||||
@ -545,34 +559,6 @@ void staticContrib(const Opm::Schedule& sched,
|
||||
//throw std::invalid_argument(str.str());
|
||||
}
|
||||
|
||||
// Find number of active production wells and injection wells for group
|
||||
|
||||
group_key_1 = gf_key("GMWPR", group.name());
|
||||
double g_act_pwells = -1.;
|
||||
if (sumState.has(group_key_1)) {
|
||||
g_act_pwells = sumState.get(group_key_1);
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Number of flowing production wells is not defined for group: " << group.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Number of flowing production wells is not defined for group: " << group.name() << " at timestep: " << simStep << std::endl;
|
||||
g_act_pwells = 0.;
|
||||
}
|
||||
|
||||
group_key_1 = gf_key("GMWIN", group.name());
|
||||
double g_act_iwells = -1.;
|
||||
if (sumState.has(group_key_1)) {
|
||||
g_act_iwells = sumState.get(group_key_1);
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Number of flowing injection wells is not defined for group: " << group.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Number of flowing injection wells is not defined for group: " << group.name() << " at timestep: " << simStep << std::endl;
|
||||
g_act_iwells = 0.;
|
||||
}
|
||||
|
||||
/*IGRP[NWGMAX + 5]
|
||||
- the value is determined by a relatively complex logic, a pseudo code scetch follows:
|
||||
if (group is free to respond to higher level production rate target_reinj_fraction)
|
||||
@ -762,15 +748,6 @@ void staticContrib(const Opm::Schedule& sched,
|
||||
iGrp[nwgmax + 10] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// set the number of active wells for a group
|
||||
|
||||
if (g_act_pwells >= 0 && g_act_iwells >= 0) {
|
||||
iGrp[nwgmax + 33] = g_act_pwells + g_act_iwells;
|
||||
}
|
||||
else {
|
||||
iGrp[nwgmax + 33] = 0;
|
||||
}
|
||||
}
|
||||
//default value -
|
||||
iGrp[nwgmax + 17] = -1;
|
||||
@ -800,9 +777,6 @@ void staticContrib(const Opm::Schedule& sched,
|
||||
}
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Current group water injection control is not defined for group: " << group.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Current group water injection control is not defined for group: " << group.name() << " at timestep: " << simStep << std::endl;
|
||||
}
|
||||
if (group.name() != "FIELD") {
|
||||
@ -900,9 +874,6 @@ void staticContrib(const Opm::Schedule& sched,
|
||||
}
|
||||
}
|
||||
else {
|
||||
//std::stringstream str;
|
||||
//str << "Current group gas injection control is not defined for group: " << group.name() << " at timestep: " << simStep;
|
||||
//throw std::invalid_argument(str.str());
|
||||
std::cout << "Current group gas injection control is not defined for group: " << group.name() << " at timestep: " << simStep << std::endl;
|
||||
}
|
||||
|
||||
@ -1109,12 +1080,10 @@ void staticContrib(const Opm::Group& group,
|
||||
|
||||
if (prod_cntl.oil_target > 0.) {
|
||||
sGrp[Isp::OilRateLimit] = sgprop(M::liquid_surface_rate, prod_cntl.oil_target);
|
||||
//sGrp[37] = sGrp[Isp::OilRateLimit];
|
||||
sGrp[52] = sGrp[Isp::OilRateLimit]; // "ORAT" control
|
||||
}
|
||||
if (prod_cntl.water_target > 0.) {
|
||||
sGrp[Isp::WatRateLimit] = sgprop(M::liquid_surface_rate, prod_cntl.water_target);
|
||||
//sGrp[38] = sGrp[Isp::WatRateLimit];
|
||||
sGrp[53] = sGrp[Isp::WatRateLimit]; //"WRAT" control
|
||||
}
|
||||
if (prod_cntl.gas_target > 0.) {
|
||||
@ -1123,7 +1092,6 @@ void staticContrib(const Opm::Group& group,
|
||||
}
|
||||
if (prod_cntl.liquid_target > 0.) {
|
||||
sGrp[Isp::LiqRateLimit] = sgprop(M::liquid_surface_rate, prod_cntl.liquid_target);
|
||||
//sGrp[40] = sGrp[Isp::LiqRateLimit];
|
||||
sGrp[54] = sGrp[Isp::LiqRateLimit]; //"LRAT" control
|
||||
}
|
||||
}
|
||||
|
@ -698,6 +698,9 @@ namespace {
|
||||
rSeg[iS + Ix::WatFlowFract] = (std::abs(temp_w) > 0) ? temp_w / rSeg[8] : 0.;
|
||||
rSeg[iS + Ix::GasFlowFract] = (std::abs(temp_g) > 0) ? temp_g / rSeg[8] : 0.;
|
||||
|
||||
|
||||
rSeg[iS + Ix::item31] = rSeg[iS + Ix::WatFlowFract];
|
||||
|
||||
// value is 1. based on tests on several data sets
|
||||
rSeg[iS + Ix::item40] = 1.;
|
||||
|
||||
@ -751,6 +754,8 @@ namespace {
|
||||
rSeg[iS + Ix::WatFlowFract] = (std::abs(temp_w) > 0) ? temp_w / rSeg[iS + 8] : 0.;
|
||||
rSeg[iS + Ix::GasFlowFract] = (std::abs(temp_g) > 0) ? temp_g / rSeg[iS + 8] : 0.;
|
||||
|
||||
rSeg[iS + Ix::item31] = rSeg[iS + Ix::WatFlowFract];
|
||||
|
||||
rSeg[iS + Ix::item40] = 1.;
|
||||
|
||||
rSeg[iS + Ix::item106] = 1.0;
|
||||
|
@ -64,11 +64,10 @@ namespace {
|
||||
return inteHead[163];
|
||||
}
|
||||
|
||||
|
||||
// Categorize function in terms of which token-types are used in formula
|
||||
// Categorize function in terms of which token-types are used in formula
|
||||
int define_type(const std::set<Opm::UDQTokenType> tokens) {
|
||||
int type = -4;
|
||||
std::vector <Opm::UDQTokenType> type_1 = {
|
||||
std::vector <Opm::UDQTokenType> type_1 = {
|
||||
Opm::UDQTokenType::elemental_func_sorta,
|
||||
Opm::UDQTokenType::elemental_func_sortd,
|
||||
Opm::UDQTokenType::elemental_func_undef,
|
||||
@ -77,18 +76,17 @@ namespace {
|
||||
Opm::UDQTokenType::scalar_func_aveg,
|
||||
Opm::UDQTokenType::scalar_func_aveh,
|
||||
Opm::UDQTokenType::scalar_func_max,
|
||||
Opm::UDQTokenType::scalar_func_min,
|
||||
Opm::UDQTokenType::scalar_func_min,
|
||||
Opm::UDQTokenType::binary_op_div
|
||||
};
|
||||
|
||||
|
||||
int num_type_1 = 0;
|
||||
for (const auto& tok_type : type_1) {
|
||||
num_type_1 += tokens.count(tok_type);
|
||||
}
|
||||
}
|
||||
type = (num_type_1 > 0) ? -1 : -4;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
namespace iUdq {
|
||||
|
||||
@ -134,7 +132,7 @@ namespace {
|
||||
}
|
||||
|
||||
template <class IUADArray>
|
||||
void staticContrib(const Opm::UDQActive::Record& udq_record, IUADArray& iUad)
|
||||
void staticContrib(const Opm::UDQActive::Record& udq_record, IUADArray& iUad, int use_cnt_diff)
|
||||
{
|
||||
iUad[0] = udq_record.uad_code;
|
||||
iUad[1] = udq_record.input_index + 1;
|
||||
@ -143,7 +141,7 @@ namespace {
|
||||
iUad[2] = 1;
|
||||
|
||||
iUad[3] = udq_record.use_count;
|
||||
iUad[4] = udq_record.use_index + 1;
|
||||
iUad[4] = udq_record.use_index + 1 - use_cnt_diff;
|
||||
}
|
||||
} // iUad
|
||||
|
||||
@ -445,7 +443,9 @@ const std::vector<int> iuap_data(const Opm::Schedule& sched,
|
||||
}
|
||||
else if ((wg_key == Opm::UDAKeyword::GCONPROD) || (wg_key == Opm::UDAKeyword::GCONINJE)) {
|
||||
const auto& group = sched.getGroup(iuap[ind].wgname, simStep);
|
||||
wg_no.push_back(group.insert_index() - 1);
|
||||
if (iuap[ind].wgname != "FIELD") {
|
||||
wg_no.push_back(group.insert_index() - 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "Invalid Control keyword: " << static_cast<int>(ctrl) << std::endl;
|
||||
@ -511,9 +511,14 @@ captureDeclaredUDQData(const Opm::Schedule& sched,
|
||||
int cnt_iuad = 0;
|
||||
for (std::size_t index = 0; index < udq_records.size(); index++) {
|
||||
const auto& record = udq_records[index];
|
||||
auto i_uad = this->iUAD_[index];
|
||||
iUad::staticContrib(record, i_uad);
|
||||
cnt_iuad += 1;
|
||||
auto i_uad = this->iUAD_[cnt_iuad];
|
||||
const auto& ctrl = record.control;
|
||||
const auto wg_key = Opm::UDQ::keyword(ctrl);
|
||||
if (!(((wg_key == Opm::UDAKeyword::GCONPROD) || (wg_key == Opm::UDAKeyword::GCONINJE)) && (record.wg_name() == "FIELD"))) {
|
||||
int use_count_diff = static_cast<int>(index) - cnt_iuad;
|
||||
iUad::staticContrib(record, i_uad, use_count_diff);
|
||||
cnt_iuad += 1;
|
||||
}
|
||||
}
|
||||
if (cnt_iuad != inteHead[VI::intehead::NO_IUADS]) {
|
||||
std::stringstream str;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#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/VFPProdTable.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
|
||||
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
|
||||
#include <opm/parser/eclipse/Units/Units.hpp>
|
||||
@ -496,6 +497,11 @@ namespace {
|
||||
: swprop(M::pressure, 1.0*::Opm::unit::atm);
|
||||
sWell[Ix::HistBHPTarget] = sWell[Ix::BHPTarget];
|
||||
|
||||
//alq_value - has no unit conversion according to parser code
|
||||
if (pc.alq_value != 0.0) {
|
||||
sWell[Ix::Alq_value] = pc.alq_value;
|
||||
}
|
||||
|
||||
if (predMode) {
|
||||
//if (well.getStatus() == Opm::Well::Status::OPEN) {
|
||||
sWell[Ix::OilRateTarget] = getRateLimit(units, M::liquid_surface_rate, pc.oil_rate);
|
||||
@ -903,7 +909,7 @@ captureDeclaredWellData(const Schedule& sched,
|
||||
|
||||
void
|
||||
Opm::RestartIO::Helpers::AggregateWellData::
|
||||
captureDynamicWellData(const Schedule& sched,
|
||||
captureDynamicWellData(const Opm::Schedule& sched,
|
||||
const std::size_t sim_step,
|
||||
const Opm::data::WellRates& xw,
|
||||
const ::Opm::SummaryState& smry)
|
||||
|
@ -154,6 +154,39 @@ namespace {
|
||||
return std::count_if(input.begin(), input.end(), [](const Opm::UDQInput inp) { return (inp.var_type() == Opm::UDQVarType::GROUP_VAR); });
|
||||
}
|
||||
|
||||
int noIuads(const Opm::Schedule& sched,
|
||||
const std::size_t rptStep,
|
||||
const std::size_t simStep)
|
||||
{
|
||||
if (rptStep == std::size_t{0}) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& udqAct = sched.udqActive(simStep);
|
||||
const auto& iuad = udqAct.get_iuad();
|
||||
|
||||
return std::count_if(iuad.begin(), iuad.end(), [](const Opm::UDQActive::Record rec) {
|
||||
return (!(((Opm::UDQ::keyword(rec.control) == Opm::UDAKeyword::GCONPROD) || (Opm::UDQ::keyword(rec.control) == Opm::UDAKeyword::GCONINJE))
|
||||
&& (rec.wg_name() == "FIELD"))); });
|
||||
}
|
||||
|
||||
int noIuaps(const Opm::Schedule& sched,
|
||||
const std::size_t rptStep,
|
||||
const std::size_t simStep)
|
||||
{
|
||||
if (rptStep == std::size_t{0}) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& udqAct = sched.udqActive(simStep);
|
||||
const auto& iuap = udqAct.get_iuap();
|
||||
|
||||
return std::count_if(iuap.begin(), iuap.end(), [](const Opm::UDQActive::InputRecord rec) {
|
||||
return (!(((Opm::UDQ::keyword(rec.control) == Opm::UDAKeyword::GCONPROD) || (Opm::UDQ::keyword(rec.control) == Opm::UDAKeyword::GCONINJE))
|
||||
&& (rec.wgname == "FIELD"))); });
|
||||
}
|
||||
|
||||
|
||||
int noFieldUdqs(const Opm::Schedule& sched,
|
||||
const std::size_t rptStep,
|
||||
const std::size_t simStep)
|
||||
@ -288,8 +321,8 @@ namespace {
|
||||
const auto no_wudq = noWellUdqs(sched, rptStep, simStep);
|
||||
const auto no_gudq = noGroupUdqs(sched, rptStep, simStep);
|
||||
const auto no_fudq = noFieldUdqs(sched, rptStep, simStep);
|
||||
const auto no_iuads = udqActive.IUAD_size();
|
||||
const auto no_iuaps = udqActive.IUAP_size();
|
||||
const auto no_iuads = noIuads(sched, rptStep, simStep);
|
||||
const auto no_iuaps = noIuaps(sched, rptStep, simStep);
|
||||
|
||||
return {
|
||||
r_seed,
|
||||
|
@ -50,6 +50,11 @@ UDQActive::operator bool() const {
|
||||
return this->input_data.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
std::string UDQActive::Record::wg_name() const {
|
||||
return this->wgname;
|
||||
}
|
||||
|
||||
std::string UDQActive::udq_hash(const std::string& udq, UDAControl control) {
|
||||
return udq + std::to_string(static_cast<int64_t>(control));
|
||||
}
|
||||
@ -144,10 +149,6 @@ const std::vector<UDQActive::Record>& UDQActive::get_iuad() const {
|
||||
this->output_data.emplace_back(input_record.udq, input_record.input_index, 0, input_record.wgname, input_record.control);
|
||||
}
|
||||
|
||||
std::sort(this->output_data.begin(), this->output_data.end(),
|
||||
[](const UDQActive::Record& rec1, const UDQActive::Record& rec2) { return rec1.input_index < rec2.input_index;});
|
||||
|
||||
|
||||
if (!output_data.empty()) {
|
||||
for (std::size_t index = 1; index < output_data.size(); index++) {
|
||||
const auto& prev_record = this->output_data[index - 1];
|
||||
|
Loading…
Reference in New Issue
Block a user