adding groupTargetConverged() to WellCollection

This commit is contained in:
Kai Bao 2017-01-16 15:55:35 +01:00
parent 3a06a2dd50
commit 9fe6d80f99
3 changed files with 24 additions and 9 deletions

View File

@ -282,7 +282,7 @@ namespace Opm
void WellCollection::updateWellTargets(const std::vector<double>& well_rates)
{
if ( !needUpdateWellTargets() ) {
if ( !needUpdateWellTargets() && groupTargetConverged(well_rates)) {
return;
}
@ -323,4 +323,17 @@ namespace Opm
return group_control_active_;
}
bool WellCollection::groupTargetConverged(const std::vector<double>& well_rates) const
{
// TODO: eventually, there should be only one root node
// TODO: we also need to check the injection target, while we have not done that.
for (const std::shared_ptr<WellsGroupInterface>& root_node : roots_) {
if ( !root_node->groupProdTargetConverged(well_rates) ) {
return false;
}
}
return true;
}
}

View File

@ -139,6 +139,13 @@ namespace Opm
/// Whether we have active group control
bool groupControlActive() const;
/// Whether the group target is converged
// It is considered converged if eitehr the group targets are matched or the group targets are not matched while the wells are
// running under their own limits so that they can not produce more
// It is considered not converged if the group targets are not matched while some of the wells are still running under group control
// The strategy may need to be adjusted when more complicated multi-layered group control situation applied, not sure about thatyet.
bool groupTargetConverged(const std::vector<double>& well_rates) const;
private:
// To account for the possibility of a forest
std::vector<std::shared_ptr<WellsGroupInterface> > roots_;

View File

@ -857,20 +857,14 @@ namespace Opm
const double relative_tolerance = 0.01;
// the bigger one of the two values
const double bigger_of_two = std::max(production_rate, production_target);
// if production_rate is greater than production_target, there must be something wrong
// in the logic or the implementation
if (production_rate - production_target > relative_tolerance * bigger_of_two) {
const std::string msg = " The group " + name() + " is over producing the target, something might be wrong ";
OPM_THROW(std::runtime_error, msg);
}
if (production_target - production_rate > relative_tolerance * bigger_of_two) {
if (std::abs(production_target - production_rate) > relative_tolerance * bigger_of_two) {
// underproducing the target while potentially can produce more
// then we should not consider the effort to match the group target is done yet
if (canProduceMore()) {
return false;
} else {
// can not produce more
// can not produce more to meet the target
OpmLog::info("group " + name() + " can not meet its target!");
}
}
@ -1296,6 +1290,7 @@ namespace Opm
if (!phase_used[BlackoilPhases::Aqua]) {
OPM_THROW(std::runtime_error, "Water phase not active and LRAT control specified.");
}
distr[phase_pos[BlackoilPhases::Liquid]] = 1.0;
distr[phase_pos[BlackoilPhases::Aqua]] = 1.0;
break;