Use InjectionControls and ProductionControls data classes

This commit is contained in:
Joakim Hove
2019-05-21 07:31:54 +02:00
parent 17aee483dd
commit 511645d12c
9 changed files with 125 additions and 129 deletions

View File

@@ -104,7 +104,7 @@ public:
void init() void init()
{ {
const Opm::Schedule& deckSchedule = simulator_.vanguard().schedule(); const Opm::Schedule& deckSchedule = simulator_.vanguard().schedule();
Opm::SummaryState summaryState;
// create the wells which intersect with the current process' grid // create the wells which intersect with the current process' grid
for (size_t deckWellIdx = 0; deckWellIdx < deckSchedule.numWells(); ++deckWellIdx) for (size_t deckWellIdx = 0; deckWellIdx < deckSchedule.numWells(); ++deckWellIdx)
{ {
@@ -112,7 +112,7 @@ public:
const std::string& wellName = deckWell.name(); const std::string& wellName = deckWell.name();
Scalar wellTemperature = 273.15 + 15.56; // [K] Scalar wellTemperature = 273.15 + 15.56; // [K]
if (deckWell.isInjector()) if (deckWell.isInjector())
wellTemperature = deckWell.getInjectionProperties().temperature; wellTemperature = deckWell.injectionControls(summaryState).temperature;
// set the name of the well but not much else. (i.e., if it is not completed, // set the name of the well but not much else. (i.e., if it is not completed,
// the well primarily serves as a placeholder.) The big rest of the well is // the well primarily serves as a placeholder.) The big rest of the well is
@@ -136,7 +136,7 @@ public:
const Opm::EclipseState& eclState = simulator_.vanguard().eclState(); const Opm::EclipseState& eclState = simulator_.vanguard().eclState();
const Opm::Schedule& deckSchedule = simulator_.vanguard().schedule(); const Opm::Schedule& deckSchedule = simulator_.vanguard().schedule();
unsigned episodeIdx = simulator_.episodeIndex(); unsigned episodeIdx = simulator_.episodeIndex();
Opm::SummaryState summaryState;
WellConnectionsMap wellCompMap; WellConnectionsMap wellCompMap;
computeWellConnectionsMap_(episodeIdx, wellCompMap); computeWellConnectionsMap_(episodeIdx, wellCompMap);
@@ -156,7 +156,7 @@ public:
auto well = this->well(deckWell.name()); auto well = this->well(deckWell.name());
if (deckWell.isInjector( )) if (deckWell.isInjector( ))
well->setTemperature(deckWell.getInjectionProperties( ).temperature); well->setTemperature(deckWell.injectionControls(summaryState).temperature);
Opm::WellCommon::StatusEnum deckWellStatus = deckWell.getStatus( ); Opm::WellCommon::StatusEnum deckWellStatus = deckWell.getStatus( );
switch (deckWellStatus) { switch (deckWellStatus) {
@@ -181,11 +181,8 @@ public:
if (deckWell.isInjector( )) { if (deckWell.isInjector( )) {
well->setWellType(Well::Injector); well->setWellType(Well::Injector);
const auto controls = deckWell.injectionControls(summaryState);
const Opm::WellInjectionProperties& injectProperties = switch (controls.injector_type) {
deckWell.getInjectionProperties( );
switch (injectProperties.injectorType) {
case Opm::WellInjector::WATER: case Opm::WellInjector::WATER:
well->setInjectedPhaseIndex(FluidSystem::waterPhaseIdx); well->setInjectedPhaseIndex(FluidSystem::waterPhaseIdx);
break; break;
@@ -199,7 +196,7 @@ public:
throw std::runtime_error("Not implemented: Multi-phase injector wells"); throw std::runtime_error("Not implemented: Multi-phase injector wells");
} }
switch (injectProperties.controlMode) { switch (controls.cmode) {
case Opm::WellInjector::RATE: case Opm::WellInjector::RATE:
well->setControlMode(Well::ControlMode::VolumetricSurfaceRate); well->setControlMode(Well::ControlMode::VolumetricSurfaceRate);
break; break;
@@ -226,7 +223,7 @@ public:
continue; continue;
} }
switch (injectProperties.injectorType) { switch (controls.injector_type) {
case Opm::WellInjector::WATER: case Opm::WellInjector::WATER:
well->setVolumetricPhaseWeights(/*oil=*/0.0, /*gas=*/0.0, /*water=*/1.0); well->setVolumetricPhaseWeights(/*oil=*/0.0, /*gas=*/0.0, /*water=*/1.0);
break; break;
@@ -243,44 +240,42 @@ public:
throw std::runtime_error("Not implemented: Multi-phase injection wells"); throw std::runtime_error("Not implemented: Multi-phase injection wells");
} }
well->setMaximumSurfaceRate(injectProperties.surfaceInjectionRate); well->setMaximumSurfaceRate(controls.surface_rate);
well->setMaximumReservoirRate(injectProperties.reservoirInjectionRate); well->setMaximumReservoirRate(controls.reservoir_rate);
well->setTargetBottomHolePressure(injectProperties.BHPLimit); well->setTargetBottomHolePressure(controls.bhp_limit);
// TODO // TODO
well->setTargetTubingHeadPressure(1e30); well->setTargetTubingHeadPressure(1e30);
//well->setTargetTubingHeadPressure(injectProperties.THPLimit); //well->setTargetTubingHeadPressure(controls.thp_limit);
} }
if (deckWell.isProducer( )) { if (deckWell.isProducer( )) {
well->setWellType(Well::Producer); well->setWellType(Well::Producer);
const auto controls = deckWell.productionControls(summaryState);
const Opm::WellProductionProperties& producerProperties = switch (controls.cmode) {
deckWell.getProductionProperties( );
switch (producerProperties.controlMode) {
case Opm::WellProducer::ORAT: case Opm::WellProducer::ORAT:
well->setControlMode(Well::ControlMode::VolumetricSurfaceRate); well->setControlMode(Well::ControlMode::VolumetricSurfaceRate);
well->setVolumetricPhaseWeights(/*oil=*/1.0, /*gas=*/0.0, /*water=*/0.0); well->setVolumetricPhaseWeights(/*oil=*/1.0, /*gas=*/0.0, /*water=*/0.0);
well->setMaximumSurfaceRate(producerProperties.OilRate); well->setMaximumSurfaceRate(controls.oil_rate);
break; break;
case Opm::WellProducer::GRAT: case Opm::WellProducer::GRAT:
well->setControlMode(Well::ControlMode::VolumetricSurfaceRate); well->setControlMode(Well::ControlMode::VolumetricSurfaceRate);
well->setVolumetricPhaseWeights(/*oil=*/0.0, /*gas=*/1.0, /*water=*/0.0); well->setVolumetricPhaseWeights(/*oil=*/0.0, /*gas=*/1.0, /*water=*/0.0);
well->setMaximumSurfaceRate(producerProperties.GasRate); well->setMaximumSurfaceRate(controls.gas_rate);
break; break;
case Opm::WellProducer::WRAT: case Opm::WellProducer::WRAT:
well->setControlMode(Well::ControlMode::VolumetricSurfaceRate); well->setControlMode(Well::ControlMode::VolumetricSurfaceRate);
well->setVolumetricPhaseWeights(/*oil=*/0.0, /*gas=*/0.0, /*water=*/1.0); well->setVolumetricPhaseWeights(/*oil=*/0.0, /*gas=*/0.0, /*water=*/1.0);
well->setMaximumSurfaceRate(producerProperties.WaterRate); well->setMaximumSurfaceRate(controls.water_rate);
break; break;
case Opm::WellProducer::LRAT: case Opm::WellProducer::LRAT:
well->setControlMode(Well::ControlMode::VolumetricSurfaceRate); well->setControlMode(Well::ControlMode::VolumetricSurfaceRate);
well->setVolumetricPhaseWeights(/*oil=*/1.0, /*gas=*/0.0, /*water=*/1.0); well->setVolumetricPhaseWeights(/*oil=*/1.0, /*gas=*/0.0, /*water=*/1.0);
well->setMaximumSurfaceRate(producerProperties.LiquidRate); well->setMaximumSurfaceRate(controls.liquid_rate);
break; break;
case Opm::WellProducer::CRAT: case Opm::WellProducer::CRAT:
@@ -289,7 +284,7 @@ public:
case Opm::WellProducer::RESV: case Opm::WellProducer::RESV:
well->setControlMode(Well::ControlMode::VolumetricReservoirRate); well->setControlMode(Well::ControlMode::VolumetricReservoirRate);
well->setVolumetricPhaseWeights(/*oil=*/1.0, /*gas=*/1.0, /*water=*/1.0); well->setVolumetricPhaseWeights(/*oil=*/1.0, /*gas=*/1.0, /*water=*/1.0);
well->setMaximumSurfaceRate(producerProperties.ResVRate); well->setMaximumSurfaceRate(controls.resv_rate);
break; break;
case Opm::WellProducer::BHP: case Opm::WellProducer::BHP:
@@ -312,11 +307,11 @@ public:
continue; continue;
} }
well->setTargetBottomHolePressure(producerProperties.BHPLimit); well->setTargetBottomHolePressure(controls.bhp_limit);
// TODO // TODO
well->setTargetTubingHeadPressure(-1e30); well->setTargetTubingHeadPressure(-1e30);
//well->setTargetTubingHeadPressure(producerProperties.THPLimit); //well->setTargetTubingHeadPressure(controls.thp_limit);
} }
} }
} }

View File

@@ -85,10 +85,10 @@ namespace Opm
inline void inline void
historyRates(const PhaseUsage& pu, historyRates(const PhaseUsage& pu,
const WellProductionProperties& p, const ProductionControls& p,
std::vector<double>& rates) std::vector<double>& rates)
{ {
assert (! p.predictionMode); assert (! p.prediction_mode);
assert (rates.size() == assert (rates.size() ==
std::vector<double>::size_type(pu.num_phases)); std::vector<double>::size_type(pu.num_phases));
@@ -96,21 +96,21 @@ namespace Opm
const std::vector<double>::size_type const std::vector<double>::size_type
i = pu.phase_pos[ BlackoilPhases::Aqua ]; i = pu.phase_pos[ BlackoilPhases::Aqua ];
rates[i] = p.WaterRate; rates[i] = p.water_rate;
} }
if (pu.phase_used[ BlackoilPhases::Liquid ]) { if (pu.phase_used[ BlackoilPhases::Liquid ]) {
const std::vector<double>::size_type const std::vector<double>::size_type
i = pu.phase_pos[ BlackoilPhases::Liquid ]; i = pu.phase_pos[ BlackoilPhases::Liquid ];
rates[i] = p.OilRate; rates[i] = p.oil_rate;
} }
if (pu.phase_used[ BlackoilPhases::Vapour ]) { if (pu.phase_used[ BlackoilPhases::Vapour ]) {
const std::vector<double>::size_type const std::vector<double>::size_type
i = pu.phase_pos[ BlackoilPhases::Vapour ]; i = pu.phase_pos[ BlackoilPhases::Vapour ];
rates[i] = p.GasRate; rates[i] = p.gas_rate;
} }
} }
} // namespace SimFIBODetails } // namespace SimFIBODetails

View File

@@ -1590,28 +1590,29 @@ namespace Opm
*/ */
std::shared_ptr<WellsGroupInterface> createWellWellsGroup(const Well2& well, size_t timeStep, const PhaseUsage& phase_usage ) std::shared_ptr<WellsGroupInterface> createWellWellsGroup(const Well2& well, size_t timeStep, const PhaseUsage& phase_usage )
{ {
SummaryState summaryState;
InjectionSpecification injection_specification; InjectionSpecification injection_specification;
ProductionSpecification production_specification; ProductionSpecification production_specification;
if (well.isInjector()) { if (well.isInjector()) {
const WellInjectionProperties& properties = well.getInjectionProperties(); const auto controls = well.injectionControls(summaryState);
injection_specification.BHP_limit_ = properties.BHPLimit; injection_specification.BHP_limit_ = controls.bhp_limit;
injection_specification.injector_type_ = toInjectorType(WellInjector::Type2String(properties.injectorType)); injection_specification.injector_type_ = toInjectorType(WellInjector::Type2String(controls.injector_type));
injection_specification.surface_flow_max_rate_ = properties.surfaceInjectionRate; injection_specification.surface_flow_max_rate_ = controls.surface_rate;
injection_specification.reservoir_flow_max_rate_ = properties.reservoirInjectionRate; injection_specification.reservoir_flow_max_rate_ = controls.reservoir_rate;
production_specification.guide_rate_ = 0.0; // We know we're not a producer production_specification.guide_rate_ = 0.0; // We know we're not a producer
if (properties.controlMode != WellInjector::CMODE_UNDEFINED) { if (controls.cmode != WellInjector::CMODE_UNDEFINED) {
injection_specification.control_mode_ = toInjectionControlMode(WellInjector::ControlMode2String(properties.controlMode)); injection_specification.control_mode_ = toInjectionControlMode(WellInjector::ControlMode2String(controls.cmode));
} }
} }
else if (well.isProducer()) { else if (well.isProducer()) {
const WellProductionProperties& properties = well.getProductionProperties(); const auto controls = well.productionControls(summaryState);
production_specification.BHP_limit_ = properties.BHPLimit; production_specification.BHP_limit_ = controls.bhp_limit;
production_specification.reservoir_flow_max_rate_ = properties.ResVRate; production_specification.reservoir_flow_max_rate_ = controls.resv_rate;
production_specification.oil_max_rate_ = properties.OilRate; production_specification.oil_max_rate_ = controls.oil_rate;
production_specification.water_max_rate_ = properties.WaterRate; production_specification.water_max_rate_ = controls.water_rate;
injection_specification.guide_rate_ = 0.0; // we know we're not an injector injection_specification.guide_rate_ = 0.0; // we know we're not an injector
if (properties.controlMode != WellProducer::CMODE_UNDEFINED) { if (controls.cmode != WellProducer::CMODE_UNDEFINED) {
production_specification.control_mode_ = toProductionControlMode(WellProducer::ControlMode2String(properties.controlMode)); production_specification.control_mode_ = toProductionControlMode(WellProducer::ControlMode2String(controls.cmode));
} }
} }
// Efficiency factor given specified with WEFAC // Efficiency factor given specified with WEFAC

View File

@@ -296,6 +296,7 @@ namespace Opm
const std::vector<int>& wells_on_proc) { const std::vector<int>& wells_on_proc) {
int well_index = 0; int well_index = 0;
auto well_on_proc = wells_on_proc.begin(); auto well_on_proc = wells_on_proc.begin();
SummaryState summaryState;
for (auto wellIter = wells.begin(); wellIter != wells.end(); ++wellIter, ++well_on_proc) { for (auto wellIter = wells.begin(); wellIter != wells.end(); ++wellIter, ++well_on_proc) {
if( ! *well_on_proc ) if( ! *well_on_proc )
@@ -318,15 +319,15 @@ namespace Opm
if (well.isInjector()) { if (well.isInjector()) {
const WellInjectionProperties& injectionProperties = well.getInjectionProperties( ); const auto controls = well.injectionControls(summaryState);
int ok = 1; int ok = 1;
int control_pos[5] = { -1, -1, -1, -1, -1 }; int control_pos[5] = { -1, -1, -1, -1, -1 };
clear_well_controls(well_index, w_); clear_well_controls(well_index, w_);
if (injectionProperties.hasInjectionControl(WellInjector::RATE)) { if (controls.hasControl(WellInjector::RATE)) {
control_pos[WellsManagerDetail::InjectionControl::RATE] = well_controls_get_num(w_->ctrls[well_index]); control_pos[WellsManagerDetail::InjectionControl::RATE] = well_controls_get_num(w_->ctrls[well_index]);
double distr[3] = { 0.0, 0.0, 0.0 }; double distr[3] = { 0.0, 0.0, 0.0 };
WellInjector::TypeEnum injectorType = injectionProperties.injectorType; WellInjector::TypeEnum injectorType = controls.injector_type;
if (injectorType == WellInjector::TypeEnum::WATER) { if (injectorType == WellInjector::TypeEnum::WATER) {
distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0; distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0;
@@ -337,7 +338,7 @@ namespace Opm
} }
ok = append_well_controls(SURFACE_RATE, ok = append_well_controls(SURFACE_RATE,
injectionProperties.surfaceInjectionRate, controls.surface_rate,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
distr, distr,
@@ -345,10 +346,10 @@ namespace Opm
w_); w_);
} }
if (ok && injectionProperties.hasInjectionControl(WellInjector::RESV)) { if (ok && controls.hasControl(WellInjector::RESV)) {
control_pos[WellsManagerDetail::InjectionControl::RESV] = well_controls_get_num(w_->ctrls[well_index]); control_pos[WellsManagerDetail::InjectionControl::RESV] = well_controls_get_num(w_->ctrls[well_index]);
double distr[3] = { 0.0, 0.0, 0.0 }; double distr[3] = { 0.0, 0.0, 0.0 };
WellInjector::TypeEnum injectorType = injectionProperties.injectorType; WellInjector::TypeEnum injectorType = controls.injector_type;
if (injectorType == WellInjector::TypeEnum::WATER) { if (injectorType == WellInjector::TypeEnum::WATER) {
distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0; distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0;
@@ -359,7 +360,7 @@ namespace Opm
} }
ok = append_well_controls(RESERVOIR_RATE, ok = append_well_controls(RESERVOIR_RATE,
injectionProperties.reservoirInjectionRate, controls.reservoir_rate,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
distr, distr,
@@ -367,10 +368,10 @@ namespace Opm
w_); w_);
} }
if (ok && injectionProperties.hasInjectionControl(WellInjector::BHP)) { if (ok && controls.hasControl(WellInjector::BHP)) {
control_pos[WellsManagerDetail::InjectionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]); control_pos[WellsManagerDetail::InjectionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]);
ok = append_well_controls(BHP, ok = append_well_controls(BHP,
injectionProperties.BHPLimit, controls.bhp_limit,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
NULL, NULL,
@@ -378,10 +379,10 @@ namespace Opm
w_); w_);
} }
if (ok && injectionProperties.hasInjectionControl(WellInjector::THP)) { if (ok && controls.hasControl(WellInjector::THP)) {
control_pos[WellsManagerDetail::InjectionControl::THP] = well_controls_get_num(w_->ctrls[well_index]); control_pos[WellsManagerDetail::InjectionControl::THP] = well_controls_get_num(w_->ctrls[well_index]);
const double thp_limit = injectionProperties.THPLimit; const double thp_limit = controls.thp_limit;
const int vfp_number = injectionProperties.VFPTableNumber; const int vfp_number = controls.vfp_table_number;
ok = append_well_controls(THP, ok = append_well_controls(THP,
thp_limit, thp_limit,
invalid_alq, invalid_alq,
@@ -395,8 +396,8 @@ namespace Opm
OPM_THROW(std::runtime_error, "Failure occured appending controls for well " << well_names[well_index]); OPM_THROW(std::runtime_error, "Failure occured appending controls for well " << well_names[well_index]);
} }
if (injectionProperties.controlMode != WellInjector::CMODE_UNDEFINED) { if (controls.cmode != WellInjector::CMODE_UNDEFINED) {
WellsManagerDetail::InjectionControl::Mode mode = WellsManagerDetail::InjectionControl::mode( injectionProperties.controlMode ); WellsManagerDetail::InjectionControl::Mode mode = WellsManagerDetail::InjectionControl::mode(controls.cmode);
int cpos = control_pos[mode]; int cpos = control_pos[mode];
if (cpos == -1 && mode != WellsManagerDetail::InjectionControl::GRUP) { if (cpos == -1 && mode != WellsManagerDetail::InjectionControl::GRUP) {
OPM_THROW(std::runtime_error, "Control not specified in well " << well_names[well_index]); OPM_THROW(std::runtime_error, "Control not specified in well " << well_names[well_index]);
@@ -408,7 +409,7 @@ namespace Opm
// Set well component fraction. // Set well component fraction.
double cf[3] = { 0.0, 0.0, 0.0 }; double cf[3] = { 0.0, 0.0, 0.0 };
{ {
WellInjector::TypeEnum injectorType = injectionProperties.injectorType; WellInjector::TypeEnum injectorType = controls.injector_type;
if (injectorType == WellInjector::WATER) { if (injectorType == WellInjector::WATER) {
if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) { if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) {
@@ -434,12 +435,12 @@ namespace Opm
// Add all controls that are present in well. // Add all controls that are present in well.
// First we must clear existing controls, in case the // First we must clear existing controls, in case the
// current WCONPROD line is modifying earlier controls. // current WCONPROD line is modifying earlier controls.
const WellProductionProperties& productionProperties = well.getProductionProperties( ); const auto controls = well.productionControls(summaryState);
int control_pos[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 }; int control_pos[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
int ok = 1; int ok = 1;
clear_well_controls(well_index, w_); clear_well_controls(well_index, w_);
if (ok && productionProperties.hasProductionControl(WellProducer::ORAT)) { if (ok && controls.hasControl(WellProducer::ORAT)) {
if (!phaseUsage.phase_used[BlackoilPhases::Liquid]) { if (!phaseUsage.phase_used[BlackoilPhases::Liquid]) {
OPM_THROW(std::runtime_error, "Oil phase not active and ORAT control specified."); OPM_THROW(std::runtime_error, "Oil phase not active and ORAT control specified.");
} }
@@ -448,7 +449,7 @@ namespace Opm
double distr[3] = { 0.0, 0.0, 0.0 }; double distr[3] = { 0.0, 0.0, 0.0 };
distr[phaseUsage.phase_pos[BlackoilPhases::Liquid]] = 1.0; distr[phaseUsage.phase_pos[BlackoilPhases::Liquid]] = 1.0;
ok = append_well_controls(SURFACE_RATE, ok = append_well_controls(SURFACE_RATE,
-productionProperties.OilRate, -controls.oil_rate,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
distr, distr,
@@ -456,7 +457,7 @@ namespace Opm
w_); w_);
} }
if (ok && productionProperties.hasProductionControl(WellProducer::WRAT)) { if (ok && controls.hasControl(WellProducer::WRAT)) {
if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) { if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) {
OPM_THROW(std::runtime_error, "Water phase not active and WRAT control specified."); OPM_THROW(std::runtime_error, "Water phase not active and WRAT control specified.");
} }
@@ -464,7 +465,7 @@ namespace Opm
double distr[3] = { 0.0, 0.0, 0.0 }; double distr[3] = { 0.0, 0.0, 0.0 };
distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0; distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0;
ok = append_well_controls(SURFACE_RATE, ok = append_well_controls(SURFACE_RATE,
-productionProperties.WaterRate, -controls.water_rate,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
distr, distr,
@@ -472,7 +473,7 @@ namespace Opm
w_); w_);
} }
if (ok && productionProperties.hasProductionControl(WellProducer::GRAT)) { if (ok && controls.hasControl(WellProducer::GRAT)) {
if (!phaseUsage.phase_used[BlackoilPhases::Vapour]) { if (!phaseUsage.phase_used[BlackoilPhases::Vapour]) {
OPM_THROW(std::runtime_error, "Gas phase not active and GRAT control specified."); OPM_THROW(std::runtime_error, "Gas phase not active and GRAT control specified.");
} }
@@ -480,7 +481,7 @@ namespace Opm
double distr[3] = { 0.0, 0.0, 0.0 }; double distr[3] = { 0.0, 0.0, 0.0 };
distr[phaseUsage.phase_pos[BlackoilPhases::Vapour]] = 1.0; distr[phaseUsage.phase_pos[BlackoilPhases::Vapour]] = 1.0;
ok = append_well_controls(SURFACE_RATE, ok = append_well_controls(SURFACE_RATE,
-productionProperties.GasRate, -controls.gas_rate,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
distr, distr,
@@ -488,7 +489,7 @@ namespace Opm
w_); w_);
} }
if (ok && productionProperties.hasProductionControl(WellProducer::LRAT)) { if (ok && controls.hasControl(WellProducer::LRAT)) {
if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) { if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) {
OPM_THROW(std::runtime_error, "Water phase not active and LRAT control specified."); OPM_THROW(std::runtime_error, "Water phase not active and LRAT control specified.");
} }
@@ -500,7 +501,7 @@ namespace Opm
distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0; distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0;
distr[phaseUsage.phase_pos[BlackoilPhases::Liquid]] = 1.0; distr[phaseUsage.phase_pos[BlackoilPhases::Liquid]] = 1.0;
ok = append_well_controls(SURFACE_RATE, ok = append_well_controls(SURFACE_RATE,
-productionProperties.LiquidRate, -controls.liquid_rate,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
distr, distr,
@@ -508,11 +509,11 @@ namespace Opm
w_); w_);
} }
if (ok && productionProperties.hasProductionControl(WellProducer::RESV)) { if (ok && controls.hasControl(WellProducer::RESV)) {
control_pos[WellsManagerDetail::ProductionControl::RESV] = well_controls_get_num(w_->ctrls[well_index]); control_pos[WellsManagerDetail::ProductionControl::RESV] = well_controls_get_num(w_->ctrls[well_index]);
double distr[3] = { 1.0, 1.0, 1.0 }; double distr[3] = { 1.0, 1.0, 1.0 };
ok = append_well_controls(RESERVOIR_RATE, ok = append_well_controls(RESERVOIR_RATE,
-productionProperties.ResVRate, -controls.resv_rate,
invalid_alq, invalid_alq,
invalid_vfp, invalid_vfp,
distr, distr,
@@ -520,10 +521,10 @@ namespace Opm
w_); w_);
} }
if (ok && productionProperties.hasProductionControl(WellProducer::THP)) { if (ok && controls.hasControl(WellProducer::THP)) {
const double thp_limit = productionProperties.THPLimit; const double thp_limit = controls.thp_limit;
const double alq_value = productionProperties.ALQValue; const double alq_value = controls.alq_value;
const int vfp_number = productionProperties.VFPTableNumber; const int vfp_number = controls.vfp_table_number;
control_pos[WellsManagerDetail::ProductionControl::THP] = well_controls_get_num(w_->ctrls[well_index]); control_pos[WellsManagerDetail::ProductionControl::THP] = well_controls_get_num(w_->ctrls[well_index]);
ok = append_well_controls(THP, ok = append_well_controls(THP,
thp_limit, thp_limit,
@@ -535,7 +536,7 @@ namespace Opm
} }
if (ok) { if (ok) {
const double bhp_limit = productionProperties.BHPLimit; const double bhp_limit = controls.bhp_limit;
control_pos[WellsManagerDetail::ProductionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]); control_pos[WellsManagerDetail::ProductionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]);
ok = append_well_controls(BHP, ok = append_well_controls(BHP,
bhp_limit, bhp_limit,
@@ -550,8 +551,8 @@ namespace Opm
OPM_THROW(std::runtime_error, "Failure occured appending controls for well " << well_names[well_index]); OPM_THROW(std::runtime_error, "Failure occured appending controls for well " << well_names[well_index]);
} }
if (productionProperties.controlMode != WellProducer::CMODE_UNDEFINED) { if (controls.cmode != WellProducer::CMODE_UNDEFINED) {
WellsManagerDetail::ProductionControl::Mode mode = WellsManagerDetail::ProductionControl::mode(productionProperties.controlMode); WellsManagerDetail::ProductionControl::Mode mode = WellsManagerDetail::ProductionControl::mode(controls.cmode);
int cpos = control_pos[mode]; int cpos = control_pos[mode];
if (cpos == -1 && mode != WellsManagerDetail::ProductionControl::GRUP) { if (cpos == -1 && mode != WellsManagerDetail::ProductionControl::GRUP) {
OPM_THROW(std::runtime_error, "Control mode type " << mode << " not present in well " << well_names[well_index]); OPM_THROW(std::runtime_error, "Control mode type " << mode << " not present in well " << well_names[well_index]);

View File

@@ -1589,6 +1589,7 @@ namespace Opm {
{ {
const std::vector<int>& resv_wells = SimFIBODetails::resvWells(wells()); const std::vector<int>& resv_wells = SimFIBODetails::resvWells(wells());
Opm::SummaryState summaryState;
int global_number_resv_wells = resv_wells.size(); int global_number_resv_wells = resv_wells.size();
global_number_resv_wells = ebosSimulator_.gridView().comm().sum(global_number_resv_wells); global_number_resv_wells = ebosSimulator_.gridView().comm().sum(global_number_resv_wells);
@@ -1641,10 +1642,10 @@ namespace Opm {
OPM_DEFLOG_THROW(std::logic_error, "Failed to find the well " << wells()->name[*rp] << " in wmap.", deferred_logger); OPM_DEFLOG_THROW(std::logic_error, "Failed to find the well " << wells()->name[*rp] << " in wmap.", deferred_logger);
} }
const auto& wp = i->second; const auto& wp = i->second;
const WellProductionProperties& production_properties = wp.getProductionProperties(); const auto production_controls = wp.productionControls(summaryState);
// historical phase rates // historical phase rates
std::vector<double> hrates(np); std::vector<double> hrates(np);
SimFIBODetails::historyRates(phase_usage_, production_properties, hrates); SimFIBODetails::historyRates(phase_usage_, production_controls, hrates);
std::vector<double> hrates_resv(np); std::vector<double> hrates_resv(np);
rateConverter_->calcReservoirVoidageRates(fipreg, pvtreg, hrates, hrates_resv); rateConverter_->calcReservoirVoidageRates(fipreg, pvtreg, hrates, hrates_resv);

View File

@@ -487,7 +487,7 @@ namespace Opm
) )
{ {
// TODO: only_wells should be put back to save some computation // TODO: only_wells should be put back to save some computation
Opm::SummaryState summaryState;
checkWellOperability(ebosSimulator, well_state, deferred_logger); checkWellOperability(ebosSimulator, well_state, deferred_logger);
if (!this->isOperable()) return; if (!this->isOperable()) return;
@@ -605,8 +605,11 @@ namespace Opm
// change temperature for injecting fluids // change temperature for injecting fluids
if (well_type_ == INJECTOR && cq_s[activeCompIdx] > 0.0){ if (well_type_ == INJECTOR && cq_s[activeCompIdx] > 0.0){
const auto& injProps = this->well_ecl_.getInjectionProperties(); const auto controls = this->well_ecl_.injectionControls(summaryState);
fs.setTemperature(injProps.temperature); // only handles single phase injection now
assert(controls.injector_type != WellInjector::MULTI);
fs.setTemperature(controls.temperature);
typedef typename std::decay<decltype(fs)>::type::Scalar FsScalar; typedef typename std::decay<decltype(fs)>::type::Scalar FsScalar;
typename FluidSystem::template ParameterCache<FsScalar> paramCache; typename FluidSystem::template ParameterCache<FsScalar> paramCache;
const unsigned pvtRegionIdx = intQuants.pvtRegionIndex(); const unsigned pvtRegionIdx = intQuants.pvtRegionIndex();
@@ -749,8 +752,6 @@ namespace Opm
{ {
const double target_rate = well_controls_get_current_target(well_controls_); // surface rate target const double target_rate = well_controls_get_current_target(well_controls_); // surface rate target
if (well_type_ == INJECTOR) { if (well_type_ == INJECTOR) {
// only handles single phase injection now
assert(well_ecl_.getInjectionProperties().injectorType != WellInjector::MULTI);
control_eq = getWQTotal() - target_rate; control_eq = getWQTotal() - target_rate;
} else if (well_type_ == PRODUCER) { } else if (well_type_ == PRODUCER) {
if (target_rate != 0.) { if (target_rate != 0.) {
@@ -795,7 +796,6 @@ namespace Opm
const double target_rate = well_controls_get_current_target(well_controls_); // reservoir rate target const double target_rate = well_controls_get_current_target(well_controls_); // reservoir rate target
if (well_type_ == INJECTOR) { if (well_type_ == INJECTOR) {
// only handles single phase injection now // only handles single phase injection now
assert(well_ecl_.getInjectionProperties().injectorType != WellInjector::MULTI);
const double* distr = well_controls_get_current_distr(well_controls_); const double* distr = well_controls_get_current_distr(well_controls_);
for (int phase = 0; phase < number_of_phases_; ++phase) { for (int phase = 0; phase < number_of_phases_; ++phase) {
if (distr[phase] > 0.0) { if (distr[phase] > 0.0) {
@@ -2614,6 +2614,7 @@ namespace Opm
{ {
assert(int(rates.size()) == 3); // the vfp related only supports three phases now. assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
SummaryState summaryState;
const double aqua = rates[Water]; const double aqua = rates[Water];
const double liquid = rates[Oil]; const double liquid = rates[Oil];
const double vapour = rates[Gas]; const double vapour = rates[Gas];
@@ -2623,15 +2624,17 @@ namespace Opm
double thp = 0.0; double thp = 0.0;
if (well_type_ == INJECTOR) { if (well_type_ == INJECTOR) {
const int table_id = well_ecl_.getInjectionProperties().VFPTableNumber; const auto controls = well_ecl_.injectionControls(summaryState);
const int table_id = controls.vfp_table_number;
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth(); const double vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_); const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
thp = vfp_properties_->getInj()->thp(table_id, aqua, liquid, vapour, bhp + dp); thp = vfp_properties_->getInj()->thp(table_id, aqua, liquid, vapour, bhp + dp);
} }
else if (well_type_ == PRODUCER) { else if (well_type_ == PRODUCER) {
const int table_id = well_ecl_.getProductionProperties().VFPTableNumber; const auto controls = well_ecl_.productionControls(summaryState);
const double alq = well_ecl_.getProductionProperties().ALQValue; const int table_id = controls.vfp_table_number;
const double alq = controls.alq_value;
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth(); const double vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_); const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);

View File

@@ -449,6 +449,7 @@ namespace Opm
WellState& well_state, WellState& well_state,
Opm::DeferredLogger& deferred_logger) Opm::DeferredLogger& deferred_logger)
{ {
SummaryState summaryState;
checkWellOperability(ebosSimulator, well_state, deferred_logger); checkWellOperability(ebosSimulator, well_state, deferred_logger);
@@ -564,7 +565,11 @@ namespace Opm
// change temperature for injecting fluids // change temperature for injecting fluids
if (well_type_ == INJECTOR && cq_s[activeCompIdx] > 0.0){ if (well_type_ == INJECTOR && cq_s[activeCompIdx] > 0.0){
const auto& injProps = this->well_ecl_.getInjectionProperties(); const auto& injProps = this->well_ecl_.injectionControls(summaryState);
// only handles single phase injection now
assert(injProps.injector_type != WellInjector::MULTI);
fs.setTemperature(injProps.temperature); fs.setTemperature(injProps.temperature);
typedef typename std::decay<decltype(fs)>::type::Scalar FsScalar; typedef typename std::decay<decltype(fs)>::type::Scalar FsScalar;
typename FluidSystem::template ParameterCache<FsScalar> paramCache; typename FluidSystem::template ParameterCache<FsScalar> paramCache;
@@ -695,8 +700,6 @@ namespace Opm
{ {
const double target_rate = well_controls_get_current_target(well_controls_); // surface rate target const double target_rate = well_controls_get_current_target(well_controls_); // surface rate target
if (well_type_ == INJECTOR) { if (well_type_ == INJECTOR) {
// only handles single phase injection now
assert(well_ecl_.getInjectionProperties().injectorType != WellInjector::MULTI);
control_eq = getWQTotal() - target_rate; control_eq = getWQTotal() - target_rate;
} else if (well_type_ == PRODUCER) { } else if (well_type_ == PRODUCER) {
if (target_rate != 0.) { if (target_rate != 0.) {
@@ -740,8 +743,6 @@ namespace Opm
{ {
const double target_rate = well_controls_get_current_target(well_controls_); // reservoir rate target const double target_rate = well_controls_get_current_target(well_controls_); // reservoir rate target
if (well_type_ == INJECTOR) { if (well_type_ == INJECTOR) {
// only handles single phase injection now
assert(well_ecl_.getInjectionProperties().injectorType != WellInjector::MULTI);
const double* distr = well_controls_get_current_distr(well_controls_); const double* distr = well_controls_get_current_distr(well_controls_);
for (int phase = 0; phase < number_of_phases_; ++phase) { for (int phase = 0; phase < number_of_phases_; ++phase) {
if (distr[phase] > 0.0) { if (distr[phase] > 0.0) {
@@ -2510,6 +2511,7 @@ namespace Opm
{ {
assert(int(rates.size()) == 3); // the vfp related only supports three phases now. assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
SummaryState summaryState;
const double aqua = rates[Water]; const double aqua = rates[Water];
const double liquid = rates[Oil]; const double liquid = rates[Oil];
const double vapour = rates[Gas]; const double vapour = rates[Gas];
@@ -2519,15 +2521,16 @@ namespace Opm
double thp = 0.0; double thp = 0.0;
if (well_type_ == INJECTOR) { if (well_type_ == INJECTOR) {
const int table_id = well_ecl_.getInjectionProperties().VFPTableNumber; const int table_id = well_ecl_.injectionControls(summaryState).vfp_table_number;
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth(); const double vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_); const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
thp = vfp_properties_->getInj()->thp(table_id, aqua, liquid, vapour, bhp + dp); thp = vfp_properties_->getInj()->thp(table_id, aqua, liquid, vapour, bhp + dp);
} }
else if (well_type_ == PRODUCER) { else if (well_type_ == PRODUCER) {
const int table_id = well_ecl_.getProductionProperties().VFPTableNumber; const auto controls = well_ecl_.productionControls(summaryState);
const double alq = well_ecl_.getProductionProperties().ALQValue; const int table_id = controls.vfp_table_number;
const double alq = controls.alq_value;
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth(); const double vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_); const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);

View File

@@ -284,8 +284,9 @@ namespace Opm
return 0.0; return 0.0;
} }
WellInjectionProperties injection = well_ecl_.getInjectionProperties(); SummaryState summaryState;
if (injection.injectorType == WellInjector::GAS) { const auto controls = well_ecl_.injectionControls(summaryState);
if (controls.injector_type == WellInjector::GAS) {
double solvent_fraction = well_ecl_.getSolventFraction(); double solvent_fraction = well_ecl_.getSolventFraction();
return solvent_fraction; return solvent_fraction;
} else { } else {
@@ -307,10 +308,11 @@ namespace Opm
return 0.0; return 0.0;
} }
WellInjectionProperties injection = well_ecl_.getInjectionProperties(); SummaryState summaryState;
const auto controls = well_ecl_.injectionControls(summaryState);
WellPolymerProperties polymer = well_ecl_.getPolymerProperties(); WellPolymerProperties polymer = well_ecl_.getPolymerProperties();
if (injection.injectorType == WellInjector::WATER) { if (controls.injector_type == WellInjector::WATER) {
const double polymer_injection_concentration = polymer.m_polymerConcentration; const double polymer_injection_concentration = polymer.m_polymerConcentration;
return polymer_injection_concentration; return polymer_injection_concentration;
} else { } else {
@@ -518,20 +520,7 @@ namespace Opm
WellInterface<TypeTag>:: WellInterface<TypeTag>::
underPredictionMode(Opm::DeferredLogger& deferred_logger) const underPredictionMode(Opm::DeferredLogger& deferred_logger) const
{ {
bool under_prediction_mode = false; return well_ecl_.predictionMode();
switch( well_type_ ) {
case PRODUCER:
under_prediction_mode = well_ecl_.getProductionProperties().predictionMode;
break;
case INJECTOR:
under_prediction_mode = well_ecl_.getInjectionProperties().predictionMode;
break;
default:
OPM_DEFLOG_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type for well " << name(), deferred_logger);
}
return under_prediction_mode;
} }
@@ -1130,9 +1119,11 @@ namespace Opm
// we need to get the table number through the parser, in case THP constraint/target is not there. // we need to get the table number through the parser, in case THP constraint/target is not there.
// When THP control/limit is not active, if available VFP table is provided, we will still need to // When THP control/limit is not active, if available VFP table is provided, we will still need to
// update THP value. However, it will only used for output purpose. // update THP value. However, it will only used for output purpose.
SummaryState summaryState;
if (well_type_ == PRODUCER) { // producer if (well_type_ == PRODUCER) { // producer
const int table_id = well_ecl_.getProductionProperties().VFPTableNumber; const auto controls = well_ecl_.productionControls(summaryState);
const int table_id = controls.vfp_table_number;
if (table_id <= 0) { if (table_id <= 0) {
return false; return false;
} else { } else {
@@ -1145,7 +1136,8 @@ namespace Opm
} }
} else { // injector } else { // injector
const int table_id = well_ecl_.getInjectionProperties().VFPTableNumber; const auto controls = well_ecl_.injectionControls(summaryState);
const int table_id = controls.vfp_table_number;
if (table_id <= 0) { if (table_id <= 0) {
return false; return false;
} else { } else {

View File

@@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(ConstructGroupFromWell) {
const Eclipse3DProperties eclipseProperties ( deck , table, grid); const Eclipse3DProperties eclipseProperties ( deck , table, grid);
const Opm::Runspec runspec (deck); const Opm::Runspec runspec (deck);
const Schedule sched(deck, grid, eclipseProperties, runspec); const Schedule sched(deck, grid, eclipseProperties, runspec);
SummaryState summaryState;
PhaseUsage pu = phaseUsageFromDeck(eclipseState); PhaseUsage pu = phaseUsageFromDeck(eclipseState);
auto wells = sched.getWells2atEnd(); auto wells = sched.getWells2atEnd();
@@ -62,18 +62,18 @@ BOOST_AUTO_TEST_CASE(ConstructGroupFromWell) {
std::shared_ptr<WellsGroupInterface> wellsGroup = createWellWellsGroup(well, 2, pu); std::shared_ptr<WellsGroupInterface> wellsGroup = createWellWellsGroup(well, 2, pu);
BOOST_CHECK_EQUAL(well.name(), wellsGroup->name()); BOOST_CHECK_EQUAL(well.name(), wellsGroup->name());
if (well.isInjector()) { if (well.isInjector()) {
const WellInjectionProperties& properties = well.getInjectionProperties(); const auto controls = well.injectionControls(summaryState);
BOOST_CHECK_EQUAL(properties.surfaceInjectionRate, wellsGroup->injSpec().surface_flow_max_rate_); BOOST_CHECK_EQUAL(controls.surface_rate, wellsGroup->injSpec().surface_flow_max_rate_);
BOOST_CHECK_EQUAL(properties.BHPLimit, wellsGroup->injSpec().BHP_limit_); BOOST_CHECK_EQUAL(controls.bhp_limit, wellsGroup->injSpec().BHP_limit_);
BOOST_CHECK_EQUAL(properties.reservoirInjectionRate, wellsGroup->injSpec().reservoir_flow_max_rate_); BOOST_CHECK_EQUAL(controls.reservoir_rate, wellsGroup->injSpec().reservoir_flow_max_rate_);
BOOST_CHECK_EQUAL(0.0, wellsGroup->prodSpec().guide_rate_); BOOST_CHECK_EQUAL(0.0, wellsGroup->prodSpec().guide_rate_);
} }
if (well.isProducer()) { if (well.isProducer()) {
const WellProductionProperties& properties = well.getProductionProperties(); const auto controls = well.productionControls(summaryState);
BOOST_CHECK_EQUAL(properties.ResVRate, wellsGroup->prodSpec().reservoir_flow_max_rate_); BOOST_CHECK_EQUAL(controls.resv_rate, wellsGroup->prodSpec().reservoir_flow_max_rate_);
BOOST_CHECK_EQUAL(properties.BHPLimit, wellsGroup->prodSpec().BHP_limit_); BOOST_CHECK_EQUAL(controls.bhp_limit, wellsGroup->prodSpec().BHP_limit_);
BOOST_CHECK_EQUAL(properties.OilRate, wellsGroup->prodSpec().oil_max_rate_); BOOST_CHECK_EQUAL(controls.oil_rate, wellsGroup->prodSpec().oil_max_rate_);
BOOST_CHECK_EQUAL(properties.WaterRate, wellsGroup->prodSpec().water_max_rate_); BOOST_CHECK_EQUAL(controls.water_rate, wellsGroup->prodSpec().water_max_rate_);
BOOST_CHECK_EQUAL(0.0, wellsGroup->injSpec().guide_rate_); BOOST_CHECK_EQUAL(0.0, wellsGroup->injSpec().guide_rate_);
} }
} }