This commit is contained in:
Xavier Raynaud
2012-05-09 15:15:13 +02:00
7 changed files with 225 additions and 6 deletions

View File

@@ -122,4 +122,22 @@ namespace Opm
roots_[i]->applyInjGroupControls();
}
}
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
void WellCollection::applyExplicitReinjectionControls(const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase)
{
for (size_t i = 0; i < roots_.size(); ++i) {
roots_[i]->applyExplicitReinjectionControls(well_reservoirrates_phase, well_surfacerates_phase);
}
}
}

View File

@@ -88,6 +88,18 @@ namespace Opm
/// Applies all group controls (injection and production)
void applyGroupControls();
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
void applyExplicitReinjectionControls(const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase);
private:
// To account for the possibility of a forest
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > roots_;

View File

@@ -453,7 +453,7 @@ namespace Opm
// as that would check if we're under group control, something we're not.
const double children_guide_rate = children_[i]->productionGuideRate(true);
children_[i]->applyProdGroupControl(prod_mode,
(children_guide_rate / my_guide_rate) * getTarget(prod_mode),
(children_guide_rate / my_guide_rate) * getTarget(prod_mode),
false);
}
break;
@@ -528,7 +528,66 @@ namespace Opm
return sum;
}
/// Gets the total production flow of the given phase.
/// \param[in] phase_flows A vector containing rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] phase The phase for which to sum up.
double WellsGroup::getTotalProductionFlow(const std::vector<double>& phase_flows,
const BlackoilPhases::PhaseIndex phase)
{
double sum = 0.0;
for (size_t i = 0; i < children_.size(); ++i) {
sum += children_[i]->getTotalProductionFlow(phase_flows, phase);
}
return sum;
}
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
void WellsGroup::applyExplicitReinjectionControls(const std::vector<double>& /*well_reservoirrates_phase*/,
const std::vector<double>& well_surfacerates_phase)
{
if (injSpec().control_mode_ == InjectionSpecification::REIN) {
BlackoilPhases::PhaseIndex phase;
switch (injSpec().injector_type_) {
case InjectionSpecification::WATER:
phase = BlackoilPhases::Aqua;
break;
case InjectionSpecification::GAS:
phase = BlackoilPhases::Vapour;
break;
case InjectionSpecification::OIL:
phase = BlackoilPhases::Liquid;
break;
}
const double total_produced = getTotalProductionFlow(well_surfacerates_phase, phase);
const double my_guide_rate = injectionGuideRate(true);
for (size_t i = 0; i < children_.size(); ++i) {
// Apply for all children.
// Note, we do _not_ want to call the applyProdGroupControl in this object,
// as that would check if we're under group control, something we're not.
const double children_guide_rate = children_[i]->injectionGuideRate(true);
#ifdef DIRTY_WELLCTRL_HACK
children_[i]->applyInjGroupControl(InjectionSpecification::RESV,
(children_guide_rate / my_guide_rate) * total_produced * injSpec().reinjection_fraction_target_,
false);
#else
children_[i]->applyInjGroupControl(InjectionSpecification::RATE,
(children_guide_rate / my_guide_rate) * total_produced * injSpec().reinjection_fraction_target_,
false);
#endif
}
}
}
// ============== WellNode members ============
@@ -691,7 +750,7 @@ namespace Opm
{
// Not changing if we're not forced to change
if (!forced
&& (injSpec().control_mode_ != InjectionSpecification::GRUP || injSpec().control_mode_ != InjectionSpecification::NONE)) {
&& (injSpec().control_mode_ != InjectionSpecification::GRUP && injSpec().control_mode_ != InjectionSpecification::NONE)) {
return;
}
if (!wells_->type[self_index_] == INJECTOR) {
@@ -728,13 +787,47 @@ namespace Opm
}
/// Gets the total production flow of the given phase.
/// \param[in] phase_flows A vector containing rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] phase The phase for which to sum up.
double WellNode::getTotalProductionFlow(const std::vector<double>& phase_flows,
const BlackoilPhases::PhaseIndex phase)
{
if (type() == INJECTOR) {
return 0.0;
}
return phase_flows[self_index_*phaseUsage().num_phases + phaseUsage().phase_pos[phase]];
}
WellType WellNode::type() const {
return wells_->type[self_index_];
}
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
void WellNode::applyExplicitReinjectionControls(const std::vector<double>&,
const std::vector<double>&)
{
// Do nothing at well level.
}
void WellNode::applyProdGroupControl(const ProductionSpecification::ControlMode control_mode,
const double target,
const bool forced)
{
// Not changing if we're not forced to change
if (!forced && (prodSpec().control_mode_ != ProductionSpecification::GRUP
|| prodSpec().control_mode_ != ProductionSpecification::NONE)) {
&& prodSpec().control_mode_ != ProductionSpecification::NONE)) {
std::cout << "Returning" << std::endl;
return;
}
if (!wells_->type[self_index_] == PRODUCER) {
@@ -771,6 +864,7 @@ namespace Opm
distr[phase_pos[BlackoilPhases::Vapour]] = 1.0;
break;
case ProductionSpecification::LRAT:
std::cout << "applying rate" << std::endl;
wct = SURFACE_RATE;
if (!phase_used[BlackoilPhases::Liquid]) {
THROW("Oil phase not active and LRAT control specified.");

View File

@@ -179,6 +179,27 @@ namespace Opm
/// wells under group control
virtual double injectionGuideRate(bool only_group) = 0;
/// Gets the total production flow of the given phase.
/// \param[in] phase_flows A vector containing rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] phase The phase for which to sum up.
virtual double getTotalProductionFlow(const std::vector<double>& phase_flows,
const BlackoilPhases::PhaseIndex phase) = 0;
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
virtual void applyExplicitReinjectionControls(const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase) = 0;
protected:
/// Calculates the correct rate for the given ProductionSpecification::ControlMode
double rateByMode(const double* res_rates,
@@ -259,6 +280,26 @@ namespace Opm
/// wells under group control
virtual double injectionGuideRate(bool only_group);
/// Gets the total production flow of the given phase.
/// \param[in] phase_flows A vector containing rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] phase The phase for which to sum up.
virtual double getTotalProductionFlow(const std::vector<double>& phase_flows,
const BlackoilPhases::PhaseIndex phase);
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
virtual void applyExplicitReinjectionControls(const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase);
private:
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > children_;
};
@@ -328,6 +369,29 @@ namespace Opm
/// wells under group control
virtual double injectionGuideRate(bool only_group);
/// Gets the total production flow of the given phase.
/// \param[in] phase_flows A vector containing rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] phase The phase for which to sum up.
virtual double getTotalProductionFlow(const std::vector<double>& phase_flows,
const BlackoilPhases::PhaseIndex phase);
/// Returns the type of the well.
WellType type() const;
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
virtual void applyExplicitReinjectionControls(const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase);
private:
Wells* wells_;
int self_index_;

View File

@@ -696,4 +696,20 @@ namespace Opm
well_surfacerates_phase);
}
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
void WellsManager::applyExplicitReinjectionControls(const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase)
{
well_collection_.applyExplicitReinjectionControls(well_reservoirrates_phase, well_surfacerates_phase);
}
} // namespace Opm

View File

@@ -87,6 +87,18 @@ namespace Opm
const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase);
/// Applies explicit reinjection controls. This must be called at each timestep to be correct.
/// \param[in] well_reservoirrates_phase
/// A vector containing reservoir rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
/// \param[in] well_surfacerates_phase
/// A vector containing surface rates by phase for each well.
/// Is assumed to be ordered the same way as the related Wells-struct,
/// with all phase rates of a single well adjacent in the array.
void applyExplicitReinjectionControls(const std::vector<double>& well_reservoirrates_phase,
const std::vector<double>& well_surfacerates_phase);
private:
// Disable copying and assignment.
WellsManager(const WellsManager& other);

View File

@@ -211,13 +211,16 @@ namespace Opm
F.bc = bcs;
F.totmob = &totmob[0];
F.wdp = &wdp[0];
int ok = true;
if (rock_comp.empty()) {
ifs_tpfa_assemble(gg, &F, &trans_[0], &gpress_omegaweighted_[0], h_);
ok = ifs_tpfa_assemble(gg, &F, &trans_[0], &gpress_omegaweighted_[0], h_);
} else {
ifs_tpfa_assemble_comprock(gg, &F, &trans_[0], &gpress_omegaweighted_[0],
ok = ifs_tpfa_assemble_comprock(gg, &F, &trans_[0], &gpress_omegaweighted_[0],
&porevol[0], &rock_comp[0], dt, &pressure[0], h_);
}
if (!ok) {
THROW("Failed assembling pressure system.");
}
linsolver_.solve(h_->A, h_->b, h_->x);