mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-01 21:39:09 -06:00
Merge pull request #1362 from GitPaean/fixing_history_mode
Fixing history mode
This commit is contained in:
commit
848072f658
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user