Merge pull request #1362 from GitPaean/fixing_history_mode

Fixing history mode
This commit is contained in:
Joakim Hove 2019-01-11 18:05:01 +01:00 committed by GitHub
commit 848072f658
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 119 deletions

View File

@ -1481,11 +1481,8 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
computeRESV(const std::size_t step)
{
typedef SimFIBODetails::WellMap WellMap;
const WellMap& wmap = SimFIBODetails::mapWells(wells_ecl_);
const std::vector<int>& resv_wells = SimFIBODetails::resvWells(wells(), step, wmap);
const std::vector<int>& resv_wells = SimFIBODetails::resvWells(wells());
int global_number_resv_wells = resv_wells.size();
global_number_resv_wells = ebosSimulator_.gridView().comm().sum(global_number_resv_wells);
@ -1495,11 +1492,8 @@ namespace Opm {
}
if (! resv_wells.empty()) {
const PhaseUsage& pu = phase_usage_;
const std::vector<double>::size_type np = pu.num_phases;
std::vector<double> distr (np);
std::vector<double> hrates(np);
typedef SimFIBODetails::WellMap WellMap;
const WellMap& wmap = SimFIBODetails::mapWells(wells_ecl_);
for (std::vector<int>::const_iterator
rp = resv_wells.begin(), e = resv_wells.end();
@ -1513,6 +1507,8 @@ namespace Opm {
// RESV control mode, all wells
{
const int rctrl = SimFIBODetails::resv_control(ctrl);
const int np = numPhases();
std::vector<double> distr (np);
if (0 <= rctrl) {
const int fipreg = 0; // Hack. Ignore FIP regions.
@ -1524,94 +1520,32 @@ namespace Opm {
// original distr contains 0 and 1 to indicate phases under control
const double* old_distr = well_controls_get_current_distr(ctrl);
for (size_t p = 0; p < np; ++p) {
for (int p = 0; p < np; ++p) {
distr[p] *= old_distr[p];
}
}
well_controls_iset_distr(ctrl, rctrl, & distr[0]);
}
}
// RESV control, WCONHIST wells. A bit of duplicate
// work, regrettably.
if (is_producer && wells()->name[*rp] != 0) {
WellMap::const_iterator i = wmap.find(wells()->name[*rp]);
// for the WCONHIST wells, we need to calculate the RESV rates since it can not be specified directly
if (is_producer) {
const WellMap::const_iterator i = wmap.find(wells()->name[*rp]);
if (i != wmap.end()) {
const auto* wp = i->second;
if (i == wmap.end()) {
OPM_THROW(std::runtime_error, "Failed to find the well " << wells()->name[*rp] << " in wmap.");
}
const auto* wp = i->second;
const WellProductionProperties& production_properties = wp->getProductionProperties(step);
// historical phase rates
std::vector<double> hrates(np);
SimFIBODetails::historyRates(phase_usage_, production_properties, hrates);
const WellProductionProperties& p =
wp->getProductionProperties(step);
if (! p.predictionMode) {
// History matching (WCONHIST/RESV)
SimFIBODetails::historyRates(pu, p, hrates);
const int fipreg = 0; // Hack. Ignore FIP regions.
rateConverter_->calcCoeff(fipreg, pvtreg, distr);
// WCONHIST/RESV target is sum of all
// observed phase rates translated to
// reservoir conditions. Recall sign
// convention: Negative for producers.
std::vector<double> hrates_resv(np);
rateConverter_->calcReservoirVoidageRates(fipreg, pvtreg, hrates, hrates_resv);
const double target = -std::accumulate(hrates_resv.begin(), hrates_resv.end(), 0.0);
well_controls_clear(ctrl);
well_controls_assert_number_of_phases(ctrl, int(np));
static const double invalid_alq = -std::numeric_limits<double>::max();
static const int invalid_vfp = -std::numeric_limits<int>::max();
const int ok_resv =
well_controls_add_new(RESERVOIR_RATE, target,
invalid_alq, invalid_vfp,
& distr[0], ctrl);
// For WCONHIST the BHP limit is set to 1 atm.
// or a value specified using WELTARG
double bhp_limit = (p.BHPLimit > 0) ? p.BHPLimit : unit::convert::from(1.0, unit::atm);
const int ok_bhp =
well_controls_add_new(BHP, bhp_limit,
invalid_alq, invalid_vfp,
NULL, ctrl);
if (ok_resv != 0 && ok_bhp != 0) {
well_state_.currentControls()[*rp] = 0;
well_controls_set_current(ctrl, 0);
}
}
}
}
}
}
if( wells() )
{
for (int w = 0, nw = numWells(); w < nw; ++w) {
WellControls* ctrl = wells()->ctrls[w];
const bool is_producer = wells()->type[w] == PRODUCER;
if (!is_producer && wells()->name[w] != 0) {
WellMap::const_iterator i = wmap.find(wells()->name[w]);
if (i != wmap.end()) {
const auto* wp = i->second;
const WellInjectionProperties& injector = wp->getInjectionProperties(step);
if (!injector.predictionMode) {
//History matching WCONINJEH
static const double invalid_alq = -std::numeric_limits<double>::max();
static const int invalid_vfp = -std::numeric_limits<int>::max();
// For WCONINJEH the BHP limit is set to a large number
// or a value specified using WELTARG
double bhp_limit = (injector.BHPLimit > 0) ? injector.BHPLimit : std::numeric_limits<double>::max();
const int ok_bhp =
well_controls_add_new(BHP, bhp_limit,
invalid_alq, invalid_vfp,
NULL, ctrl);
if (!ok_bhp) {
OPM_THROW(std::runtime_error, "Failed to add well control.");
}
well_controls_iset_target(ctrl, rctrl, target);
}
}
}

View File

@ -69,42 +69,14 @@ namespace Opm
return (0 <= resv_control(wells.ctrls[w]));
}
inline bool
is_resv(const WellMap& wmap,
const std::string& name,
const std::size_t step)
{
bool match = false;
WellMap::const_iterator i = wmap.find(name);
if (i != wmap.end()) {
const Well* wp = i->second;
match = (wp->isProducer(step) &&
wp->getProductionProperties(step)
.hasProductionControl(WellProducer::RESV))
|| (wp->isInjector(step) &&
wp->getInjectionProperties(step)
.hasInjectionControl(WellInjector::RESV));
}
return match;
}
inline std::vector<int>
resvWells(const Wells* wells,
const std::size_t step,
const WellMap& wmap)
resvWells(const Wells* wells)
{
std::vector<int> resv_wells;
if( wells )
{
for (int w = 0, nw = wells->number_of_wells; w < nw; ++w) {
if (is_resv(*wells, w) ||
((wells->name[w] != 0) &&
is_resv(wmap, wells->name[w], step)))
{
if ( is_resv(*wells, w) ) {
resv_wells.push_back(w);
}
}

View File

@ -535,10 +535,7 @@ namespace Opm
}
if (ok) {
// Always append a BHP control.
// If no explicit BHP control given, use a 1 atm control.
const bool has_explicit_limit = productionProperties.hasProductionControl(WellProducer::BHP);
const double bhp_limit = has_explicit_limit ? productionProperties.BHPLimit : unit::convert::from(1.0, unit::atm);
const double bhp_limit = productionProperties.BHPLimit;
control_pos[WellsManagerDetail::ProductionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]);
ok = append_well_controls(BHP,
bhp_limit,