Compute Well-Level PI For Shut Wells

This commit includes the shut wells in 'wells_ecl_' and expands the
PI/II value calculation to apply to those shut wells too.  With this
in place we are able to run cases that have a 'WELPI' keyword before
the well opens, even at the very first report step.
This commit is contained in:
Bård Skaflestad 2021-03-02 01:11:19 +01:00
parent 6e9d2bd89e
commit a6c374a27c
2 changed files with 81 additions and 20 deletions

View File

@ -413,6 +413,7 @@ namespace Opm {
std::vector< Well > wells_ecl_{};
std::vector< std::vector<PerforationData> > well_perf_data_{};
std::vector< WellProdIndexCalculator > prod_index_calc_{};
std::vector<int> local_shut_wells_{};
std::vector< ParallelWellInfo > parallel_well_info_;
std::vector< ParallelWellInfo* > local_parallel_well_info_;
@ -440,6 +441,8 @@ namespace Opm {
// create the well container
std::vector<WellInterfacePtr > createWellContainer(const int time_step);
void inferLocalShutWells();
WellInterfacePtr
createWellPointer(const int wellID,
const int time_step) const;
@ -543,7 +546,10 @@ namespace Opm {
void calculateEfficiencyFactors(const int reportStepIdx);
void calculateProductivityIndexValuesShutWells(const int reportStepIdx, DeferredLogger& deferred_logger);
void calculateProductivityIndexValues(DeferredLogger& deferred_logger);
void calculateProductivityIndexValues(const WellInterface<TypeTag>* wellPtr,
DeferredLogger& deferred_logger);
// The number of components in the model.
int numComponents() const;

View File

@ -65,9 +65,6 @@ namespace Opm {
const auto numProcs = ebosSimulator.gridView().comm().size();
this->not_on_process_ = [this, numProcs](const Well& well) {
if (well.getStatus() == Well::Status::SHUT)
return true;
if (numProcs == decltype(numProcs){1})
return false;
@ -922,6 +919,30 @@ namespace Opm {
template <typename TypeTag>
void BlackoilWellModel<TypeTag>::
inferLocalShutWells()
{
this->local_shut_wells_.clear();
const auto nw = this->numLocalWells();
auto used = std::vector<bool>(nw, false);
for (const auto& wellPtr : this->well_container_) {
used[wellPtr->indexOfWell()] = true;
}
for (auto wellID = 0; wellID < nw; ++wellID) {
if (! used[wellID]) {
this->local_shut_wells_.push_back(wellID);
}
}
}
template <typename TypeTag>
typename BlackoilWellModel<TypeTag>::WellInterfacePtr
BlackoilWellModel<TypeTag>::
@ -1597,21 +1618,13 @@ namespace Opm {
template<typename TypeTag>
template <typename TypeTag>
void
BlackoilWellModel<TypeTag>::
calculateProductivityIndexValues(DeferredLogger& deferred_logger)
{
if (! this->localWellsActive()) {
return;
}
for (const auto& wellPtr : this->well_container_) {
wellPtr->updateProductivityIndex(this->ebosSimulator_,
this->prod_index_calc_[wellPtr->indexOfWell()],
this->wellState(),
deferred_logger);
this->calculateProductivityIndexValues(wellPtr.get(), deferred_logger);
}
}
@ -1619,6 +1632,48 @@ namespace Opm {
template <typename TypeTag>
void
BlackoilWellModel<TypeTag>::
calculateProductivityIndexValuesShutWells(const int reportStepIdx,
DeferredLogger& deferred_logger)
{
// For the purpose of computing PI/II values, it is sufficient to
// construct StandardWell instances only. We don't need to form
// well objects that honour the 'isMultisegment()' flag of the
// corresponding "this->wells_ecl_[shutWell]".
for (const auto& shutWell : this->local_shut_wells_) {
auto wellPtr = this->template createTypedWellPointer
<StandardWell<TypeTag>>(shutWell, reportStepIdx);
wellPtr->init(&this->phase_usage_, this->depth_, this->gravity_,
this->local_num_cells_, this->B_avg_);
this->calculateProductivityIndexValues(wellPtr.get(), deferred_logger);
}
}
template <typename TypeTag>
void
BlackoilWellModel<TypeTag>::
calculateProductivityIndexValues(const WellInterface<TypeTag>* wellPtr,
DeferredLogger& deferred_logger)
{
wellPtr->updateProductivityIndex(this->ebosSimulator_,
this->prod_index_calc_[wellPtr->indexOfWell()],
this->wellState(),
deferred_logger);
}
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
@ -2838,17 +2893,17 @@ namespace Opm {
auto saved_previous_wgstate = this->prevWGState();
this->commitWGState();
well_container_ = createWellContainer(timeStepIdx);
for (auto& well : well_container_) {
well->init(&phase_usage_, depth_, gravity_, local_num_cells_, B_avg_);
}
this->well_container_ = this->createWellContainer(timeStepIdx);
this->inferLocalShutWells();
std::fill(is_cell_perforated_.begin(), is_cell_perforated_.end(), false);
for (auto& well : well_container_) {
well->updatePerforatedCell(is_cell_perforated_);
for (auto& wellPtr : this->well_container_) {
wellPtr->init(&this->phase_usage_, this->depth_, this->gravity_,
this->local_num_cells_, this->B_avg_);
}
this->calculateProductivityIndexValues(local_deferredLogger);
this->calculateProductivityIndexValuesShutWells(timeStepIdx, local_deferredLogger);
this->commitWGState(std::move(saved_previous_wgstate));
}