adding function isOperable() to WellInterface

to indicate if the well is operable.
This commit is contained in:
Kai Bao 2018-11-17 23:14:51 +01:00
parent ae3b514e0b
commit ea42d1de9d
4 changed files with 60 additions and 11 deletions

View File

@ -803,7 +803,9 @@ namespace Opm {
// Get global (from all processes) convergence report.
ConvergenceReport local_report;
for (const auto& well : well_container_) {
local_report += well->getWellConvergence(B_avg);
if (well->isOperable() ) {
local_report += well->getWellConvergence(B_avg);
}
}
ConvergenceReport report = gatherConvergenceReport(local_report);
@ -828,9 +830,10 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
calculateExplicitQuantities() const
{
for (auto& well : well_container_) {
well->calculateExplicitQuantities(ebosSimulator_, well_state_);
}
// TODO: checking isOperable() ?
for (auto& well : well_container_) {
well->calculateExplicitQuantities(ebosSimulator_, well_state_);
}
}
@ -934,6 +937,10 @@ namespace Opm {
// process group control related
prepareGroupControl();
for (const auto& well : well_container_) {
well->checkWellOperatability(ebosSimulator_);
}
// since the controls are all updated, we should update well_state accordingly
for (const auto& well : well_container_) {
const int w = well->indexOfWell();
@ -941,16 +948,22 @@ namespace Opm {
const int control = well_controls_get_current(wc);
well_state_.currentControls()[w] = control;
if (!well->isOperable() ) continue;
if (well_state_.effectiveEventsOccurred(w) ) {
well->updateWellStateWithTarget(ebosSimulator_, well_state_);
}
// there is no new well control change input within a report step,
// so next time step, the well does not consider to have effective events anymore
// TODO: if we can know whether this is the first time step within the report step,
// we do not need to change this
// TODO: we should do this at the end of the time step in case we will need it within
// this time step somewhere
if (well_state_.effectiveEventsOccurred(w) ) {
well_state_.setEffectiveEventsOccurred(w, false);
}
} // end of for (int w = 0; w < nw; ++w)
} // end of for (const auto& well : well_container_)
updatePrimaryVariables();
}

View File

@ -440,9 +440,9 @@ namespace Opm
WellState& well_state)
{
const Opm::SummaryConfig& summaryConfig = ebosSimulator.vanguard().summaryConfig();
checkWellOperatability(ebosSimulator);
const int np = number_of_phases_;
if (!this->isOperable()) return;
// clear all entries
duneB_ = 0.0;
@ -461,6 +461,7 @@ namespace Opm
well_state.wellVaporizedOilRates()[index_of_well_] = 0.;
well_state.wellDissolvedGasRates()[index_of_well_] = 0.;
const int np = number_of_phases_;
for (int p = 0; p < np; ++p) {
well_state.productivityIndex()[np*index_of_well_ + p] = 0.;
}
@ -588,7 +589,8 @@ namespace Opm
well_state.perfPress()[first_perf_ + perf] = well_state.bhp()[index_of_well_] + perf_pressure_diffs_[perf];
// Compute Productivity index if asked for
const auto& pu = phaseUsage();
const auto& pu = phaseUsage();
const Opm::SummaryConfig& summaryConfig = ebosSimulator.vanguard().summaryConfig();
for (int p = 0; p < np; ++p) {
if ( (pu.phase_pos[Water] == p && (summaryConfig.hasSummaryKey("WPIW:" + name()) || summaryConfig.hasSummaryKey("WPIL:" + name())))
|| (pu.phase_pos[Oil] == p && (summaryConfig.hasSummaryKey("WPIO:" + name()) || summaryConfig.hasSummaryKey("WPIL:" + name())))
@ -821,6 +823,8 @@ namespace Opm
updateWellState(const BVectorWell& dwells,
WellState& well_state) const
{
if (!this->isOperable()) return;
updatePrimaryVariablesNewton(dwells, well_state);
updateWellStateFromPrimaryVariables(well_state);
@ -1287,7 +1291,7 @@ namespace Opm
// wellTestingPhysical can share some code with this function
// on solution is that this function will be called updateWellOperatability
// and the actual checking part become another function checkWellOperatability
// Let us finish the wellTestingPhysical first.
// Let us wait until finishing the wellTestingPhysical first.
// focusing on PRODUCER for now
if (well_type_ == INJECTOR) {
@ -1318,6 +1322,12 @@ namespace Opm
this->operability_status_.negative_well_rates = allDrawDownWrongDirection(ebos_simulator);
const bool well_operable = this->operability_status_.isOperable();
if (!well_operable && old_well_operable) {
OpmLog::info(" well " + name() + " gets SHUT during iteration ");
} else if (well_operable && !old_well_operable) {
OpmLog::info(" well " + name() + " gets REVIVED during iteration ");
}
}
@ -1943,6 +1953,8 @@ namespace Opm
StandardWell<TypeTag>::
solveEqAndUpdateWellState(WellState& well_state)
{
if (!this->isOperable()) return;
// We assemble the well equations, then we check the convergence,
// which is why we do not put the assembleWellEq here.
BVectorWell dx_well(1);
@ -1988,6 +2000,8 @@ namespace Opm
StandardWell<TypeTag>::
apply(const BVector& x, BVector& Ax) const
{
if (!this->isOperable()) return;
if ( param_.matrix_add_well_contributions_ )
{
// Contributions are already in the matrix itself
@ -2016,6 +2030,8 @@ namespace Opm
StandardWell<TypeTag>::
apply(BVector& r) const
{
if (!this->isOperable()) return;
assert( invDrw_.size() == invDuneD_.N() );
// invDrw_ = invDuneD_ * resWell_
@ -2033,6 +2049,8 @@ namespace Opm
StandardWell<TypeTag>::
recoverSolutionWell(const BVector& x, BVectorWell& xw) const
{
if (!this->isOperable()) return;
BVectorWell resWell = resWell_;
// resWell = resWell - B * x
duneB_.mmv(x, resWell);
@ -2050,6 +2068,8 @@ namespace Opm
recoverWellSolutionAndUpdateWellState(const BVector& x,
WellState& well_state) const
{
if (!this->isOperable()) return;
BVectorWell xw(1);
recoverSolutionWell(x, xw);
updateWellState(xw, well_state);
@ -2254,6 +2274,8 @@ namespace Opm
StandardWell<TypeTag>::
updatePrimaryVariables(const WellState& well_state) const
{
if (!this->isOperable()) return;
const int well_index = index_of_well_;
const int np = number_of_phases_;

View File

@ -225,6 +225,9 @@ namespace Opm
virtual void checkWellOperatability(const Simulator& ebos_simulator) = 0;
// whether the well is operable
bool isOperable() const;
protected:
// to indicate a invalid completion
@ -400,7 +403,7 @@ namespace Opm
violate_thp_limit_under_bhp_limit = false;
obtain_solution_with_thp_limit = true;
violate_bhp_limit_with_thp_limit = false;
// TODO: the following one might need to be different
// TODO: the following one might need to be treated differently
negative_well_rates = false;
}
@ -425,7 +428,7 @@ namespace Opm
// could not get converged, maybe at the end of the time step, after chopping for some steps.
// TODO: the best way is that this well can not get converged during local iterations.
bool could_not_get_converged = false;
// bool could_not_get_converged = false;
};
}

View File

@ -1223,4 +1223,15 @@ namespace Opm
}
template<typename TypeTag>
bool
WellInterface<TypeTag>::
isOperable() const {
return operability_status_.isOperable();
}
}