Bugfix in setup guiderates

- Handle shut wells
- Use the groups control type to determine which phase to calculate
the guide rates from. i.e for a ORAT controlled group, calculate the
guide rates from the oil phase well potentials etc.
This commit is contained in:
Tor Harald Sandve 2016-04-08 15:47:49 +02:00
parent 277b3a2e58
commit acade0bb5f
2 changed files with 92 additions and 47 deletions

View File

@ -61,6 +61,11 @@ namespace Opm
} }
void WellCollection::addWell(WellConstPtr wellChild, size_t timeStep, const PhaseUsage& phaseUsage) { void WellCollection::addWell(WellConstPtr wellChild, size_t timeStep, const PhaseUsage& phaseUsage) {
if (wellChild->getStatus(timeStep) == WellCommon::SHUT) {
//SHUT wells are not added to the well collection
return;
}
WellsGroupInterface* parent = findNode(wellChild->getGroupName(timeStep)); WellsGroupInterface* parent = findNode(wellChild->getGroupName(timeStep));
if (!parent) { if (!parent) {
OPM_THROW(std::runtime_error, "Trying to add well " << wellChild->name() << " Step: " << boost::lexical_cast<std::string>(timeStep) << " to group named " << wellChild->getGroupName(timeStep) << ", but this group does not exist in the WellCollection."); OPM_THROW(std::runtime_error, "Trying to add well " << wellChild->name() << " Step: " << boost::lexical_cast<std::string>(timeStep) << " to group named " << wellChild->getGroupName(timeStep) << ", but this group does not exist in the WellCollection.");

View File

@ -27,6 +27,7 @@
#include <opm/core/well_controls.h> #include <opm/core/well_controls.h>
#include <opm/common/ErrorMacros.hpp> #include <opm/common/ErrorMacros.hpp>
#include <opm/core/wells/WellCollection.hpp> #include <opm/core/wells/WellCollection.hpp>
#include <opm/core/wells/WellsGroup.hpp>
#include <opm/core/props/phaseUsageFromDeck.hpp> #include <opm/core/props/phaseUsageFromDeck.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
@ -733,6 +734,12 @@ namespace Opm
const int np = phaseUsage.num_phases; const int np = phaseUsage.num_phases;
for (auto wellIter = wells.begin(); wellIter != wells.end(); ++wellIter ) { for (auto wellIter = wells.begin(); wellIter != wells.end(); ++wellIter ) {
WellConstPtr well = *wellIter; WellConstPtr well = *wellIter;
if (well->getStatus(timeStep) == WellCommon::SHUT) {
//SHUT wells does not need guide rates
continue;
}
const int wix = well_names_to_index[well->name()]; const int wix = well_names_to_index[well->name()];
WellNode& wellnode = *well_collection_.getLeafNodes()[wix]; WellNode& wellnode = *well_collection_.getLeafNodes()[wix];
@ -759,56 +766,89 @@ namespace Opm
} else if (well_potentials.size() > 0) { // default: calculate guide rates from well potentials } else if (well_potentials.size() > 0) { // default: calculate guide rates from well potentials
// Note: Modification of the guide rate using GUIDERAT is not supported // Note: Modification of the guide rate using GUIDERAT is not supported
switch (well->getPreferredPhase()) { const WellsGroupInterface& group = *wellnode.getParent();
case Phase::WATER: { // only set the guide rates if there is a parent group with valied control
if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) { if (&group != NULL) {
OPM_THROW(std::runtime_error, "Water phase not used, yet found water-preferring well.");
}
const int water_index = phaseUsage.phase_pos[BlackoilPhases::Aqua];
if ( well->isProducer(timeStep) ) { if ( well->isProducer(timeStep) ) {
wellnode.prodSpec().guide_rate_ = well_potentials[np*wix + water_index]; // The guide rates is calculated based on the group control
wellnode.prodSpec().guide_rate_type_ = ProductionSpecification::WATER; // Currently only supporting WRAT, ORAT and GRAT.
switch (group.prodSpec().control_mode_) {
case ProductionSpecification::WRAT: {
if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) {
OPM_THROW(std::runtime_error, "Water phase not used, yet found water rate controlled well.");
}
const int water_index = phaseUsage.phase_pos[BlackoilPhases::Aqua];
wellnode.prodSpec().guide_rate_ = well_potentials[np*wix + water_index];
wellnode.prodSpec().guide_rate_type_ = ProductionSpecification::WATER;
break;
}
case ProductionSpecification::ORAT: {
if (!phaseUsage.phase_used[BlackoilPhases::Liquid]) {
OPM_THROW(std::runtime_error, "Oil phase not used, yet found oil rate controlled well.");
}
const int oil_index = phaseUsage.phase_pos[BlackoilPhases::Liquid];
wellnode.prodSpec().guide_rate_ = well_potentials[np*wix + oil_index];
wellnode.prodSpec().guide_rate_type_ = ProductionSpecification::OIL;
break;
}
case ProductionSpecification::GRAT: {
if (!phaseUsage.phase_used[BlackoilPhases::Vapour]) {
OPM_THROW(std::runtime_error, "Gas phase not used, yet found gas rate controlled well.");
}
const int gas_index = phaseUsage.phase_pos[BlackoilPhases::Vapour];
wellnode.prodSpec().guide_rate_ = well_potentials[np*wix + gas_index];
wellnode.prodSpec().guide_rate_type_ = ProductionSpecification::GAS;
break;
}
case ProductionSpecification::NONE: {
// Group control is not in use for this group.
break;
}
default:
OPM_THROW(std::logic_error, "Not supported control_mode for guide rate computed" <<
" from well potentials: " << group.prodSpec().control_mode_);
}
} else { } else {
wellnode.injSpec().guide_rate_ = well_potentials[np*wix + water_index]; // The guide rates is calculated based on the group injector type
// Guide rates applies to the phase that the well is injecting i.e water switch (group.injSpec().injector_type_) {
wellnode.injSpec().guide_rate_type_ = InjectionSpecification::RAT; case InjectionSpecification::WATER: {
} if (!phaseUsage.phase_used[BlackoilPhases::Aqua]) {
break; OPM_THROW(std::runtime_error, "Water phase not used, yet found water injecting well.");
} }
case Phase::OIL: { const int water_index = phaseUsage.phase_pos[BlackoilPhases::Aqua];
if (!phaseUsage.phase_used[BlackoilPhases::Liquid]) { wellnode.injSpec().guide_rate_ = well_potentials[np*wix + water_index];
OPM_THROW(std::runtime_error, "Oil phase not used, yet found oil-preferring well."); // Guide rates applies to the phase that the well is injecting i.e water
} wellnode.injSpec().guide_rate_type_ = InjectionSpecification::RAT;
const int oil_index = phaseUsage.phase_pos[BlackoilPhases::Liquid]; break;
if ( well->isProducer(timeStep) ) { }
wellnode.prodSpec().guide_rate_ = well_potentials[np*wix + oil_index]; case InjectionSpecification::OIL: {
wellnode.prodSpec().guide_rate_type_ = ProductionSpecification::OIL; if (!phaseUsage.phase_used[BlackoilPhases::Liquid]) {
} else { OPM_THROW(std::runtime_error, "Oil phase not used, yet found oil injecting well.");
wellnode.injSpec().guide_rate_ = well_potentials[np*wix + oil_index]; }
// Guide rates applies to the phase that the well is injecting i.e. oil const int oil_index = phaseUsage.phase_pos[BlackoilPhases::Liquid];
wellnode.injSpec().guide_rate_type_ = InjectionSpecification::RAT; wellnode.injSpec().guide_rate_ = well_potentials[np*wix + oil_index];
} // Guide rates applies to the phase that the well is injecting i.e. oil
break; wellnode.injSpec().guide_rate_type_ = InjectionSpecification::RAT;
} break;
case Phase::GAS: { }
if (!phaseUsage.phase_used[BlackoilPhases::Vapour]) { case InjectionSpecification::GAS: {
OPM_THROW(std::runtime_error, "Gas phase not used, yet found gas-preferring well."); if (!phaseUsage.phase_used[BlackoilPhases::Vapour]) {
} OPM_THROW(std::runtime_error, "Gas phase not used, yet found gas injecting well.");
const int gas_index = phaseUsage.phase_pos[BlackoilPhases::Vapour]; }
if ( well->isProducer(timeStep) ) { const int gas_index = phaseUsage.phase_pos[BlackoilPhases::Vapour];
wellnode.prodSpec().guide_rate_ = well_potentials[np*wix + gas_index]; wellnode.injSpec().guide_rate_ = well_potentials[np*wix + gas_index];
wellnode.prodSpec().guide_rate_type_ = ProductionSpecification::GAS; // Guide rates applies to the phase that the well is injecting i.e gas
} else { wellnode.injSpec().guide_rate_type_ = InjectionSpecification::RAT;
wellnode.injSpec().guide_rate_ = well_potentials[np*wix + gas_index];
// Guide rates applies to the phase that the well is injecting i.e gas
wellnode.injSpec().guide_rate_type_ = InjectionSpecification::RAT;
}
break;
}
default:
OPM_THROW(std::logic_error, "Unknown preferred phase: " << well->getPreferredPhase());
}
break;
}
default:
OPM_THROW(std::logic_error, "Not supported injector type for guide rate computed" <<
" from well potentials: " << group.injSpec().injector_type_);
}
}
}
} // if neither WGRUPCON nor well_potentials is given, distribute the flow equaly } // if neither WGRUPCON nor well_potentials is given, distribute the flow equaly
} }