adding groupProdTargetConverged() to WellsGroup

When the group is producing its target, we consider it is converged.
When the group is not producing its target, while the group can not
produce more based on its own limits, we also consider it is converged.

When the group is not producing its target, while the group can
potentially produce more, we consider it is not converged.
This commit is contained in:
Kai Bao 2017-01-16 14:14:26 +01:00
parent 8f658a92f2
commit 3a06a2dd50
2 changed files with 81 additions and 4 deletions

View File

@ -186,7 +186,7 @@ namespace Opm
return tot_rate;
}
double WellsGroupInterface::getTarget(ProductionSpecification::ControlMode mode)
double WellsGroupInterface::getTarget(ProductionSpecification::ControlMode mode) const
{
double target = -1.0;
switch (mode) {
@ -216,7 +216,7 @@ namespace Opm
return target;
}
double WellsGroupInterface::getTarget(InjectionSpecification::ControlMode mode)
double WellsGroupInterface::getTarget(InjectionSpecification::ControlMode mode) const
{
double target = -1.0;
switch (mode) {
@ -831,6 +831,65 @@ namespace Opm
return false;
}
bool WellsGroup::groupProdTargetConverged(const std::vector<double>& well_rates) const
{
// TODO: should consider the efficiency factor in getProductionRate()
for (const std::shared_ptr<const WellsGroupInterface>& child_node : children_) {
if ( ! child_node->groupProdTargetConverged(well_rates) ) {
return false;
}
}
// We need to check whether the current group target is satisfied
// we need to decide the modes we want to support here.
const ProductionSpecification::ControlMode prod_mode = prodSpec().control_mode_;
switch(prod_mode) {
case ProductionSpecification::LRAT :
case ProductionSpecification::ORAT :
case ProductionSpecification::WRAT :
case ProductionSpecification::GRAT :
{
const double production_rate = std::abs(getProductionRate(well_rates, prod_mode));
const double production_target = std::abs(getTarget(prod_mode));
// 0.01 is a hard-coded relative tolerance
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) {
// 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
OpmLog::info("group " + name() + " can not meet its target!");
}
}
}
case ProductionSpecification::FLD :
case ProductionSpecification::NONE :
case ProductionSpecification::GRUP :
break;
default:
{
const std::string msg = "Not handling target checking for control type " + ProductionSpecification::toString(prod_mode);
OPM_THROW(std::runtime_error, msg);
}
}
return true;
}
double WellsGroup::getProductionRate(const std::vector<double>& well_rates,
const ProductionSpecification::ControlMode prod_mode) const
{
@ -1553,4 +1612,10 @@ namespace Opm
return (isProducer() && !individualControl());
}
bool WellNode::groupProdTargetConverged(const std::vector<double>& /* well_rates */) const
{
return true;
}
}

View File

@ -163,10 +163,10 @@ namespace Opm
ProductionSpecification::ControlMode mode) = 0;
/// Gets the target rate for the given mode.
double getTarget(ProductionSpecification::ControlMode mode);
double getTarget(ProductionSpecification::ControlMode mode) const;
/// Gets the target rate for the given mode.
double getTarget(InjectionSpecification::ControlMode mode);
double getTarget(InjectionSpecification::ControlMode mode) const;
/// Applies any production group control relevant to all children nodes.
/// If no group control is set, this is called recursively to the children.
@ -239,6 +239,14 @@ namespace Opm
// they have the potential to adjust their targets to produce more to match the higher level target
virtual bool canProduceMore() const = 0;
// checking wether group production target converged
// if the group is producing following the target, then it should be considered okay
// if the group is not producing following the target, then we should check wether the group
// should be able to produce more to match the target.
// if the group can not produce more, we also consider the effort to match the group target is
// also done and the group target converged while we should give a message
virtual bool groupProdTargetConverged(const std::vector<double>& well_rates) const = 0;
double efficiencyFactor() const;
void setEfficiencyFactor(const double efficiency_factor);
@ -375,6 +383,8 @@ namespace Opm
virtual bool canProduceMore() const;
virtual bool groupProdTargetConverged(const std::vector<double>& well_rates) const;
private:
std::vector<std::shared_ptr<WellsGroupInterface> > children_;
};
@ -505,6 +515,8 @@ namespace Opm
virtual bool canProduceMore() const;
virtual bool groupProdTargetConverged(const std::vector<double>& well_rates) const;
private:
Wells* wells_;
int self_index_;