Unconditionally Calculate PI at End of Timestep

This commit ensures that we calculate the well and connection level
per-phase steady-state productivity index (PI) at the end of a
completed time step (triggered from endTimeStep()).

We add a new data member,

    BlackoilWellModel<>::prod_index_calc_

which holds one WellProdIndexCalculator for each of the process'
local wells and a new interface member function

    WellInterface::updateProductivityIndex

which uses a per-well PI calculator to actually compute the PI
values and store those in the WellState.  Implement this member
function for both StandardWell and MultisegmentWell.  Were it not
for 'getMobility' existing only in the derived classes, the two
equal implementations could be merged and moved to the interface.

We also add a new data member to the WellStateFullyImplicitBlackoil
to hold the connection-level PI values.  Finally, remove the
conditional PI calculation from StandardWell's well equation
assembly routine.
This commit is contained in:
Bård Skaflestad
2020-10-09 13:38:33 +02:00
parent 9f12a2edba
commit 75156cd872
9 changed files with 271 additions and 81 deletions

View File

@@ -85,8 +85,6 @@ namespace Opm
connectionRates_.resize(number_of_perforations_);
well_productivity_index_logger_counter_ = 0;
wellIsStopped_ = false;
if (well.getStatus() == Well::Status::STOP) {
wellIsStopped_ = true;
@@ -1380,40 +1378,6 @@ namespace Opm
}
}
template<typename TypeTag>
void
WellInterface<TypeTag>::scaleProductivityIndex(const int perfIdx, double& productivity_index, const bool new_well, Opm::DeferredLogger& deferred_logger) const
{
const auto& connection = well_ecl_.getConnections()[(*perf_data_)[perfIdx].ecl_index];
if (well_ecl_.getDrainageRadius() < 0) {
if (new_well && perfIdx == 0) {
deferred_logger.warning("PRODUCTIVITY_INDEX_WARNING", "Negative drainage radius not supported. The productivity index is set to zero");
}
productivity_index = 0.0;
return;
}
if (connection.r0() > well_ecl_.getDrainageRadius()) {
if (new_well && well_productivity_index_logger_counter_ < 1) {
deferred_logger.info("PRODUCTIVITY_INDEX_INFO", "The effective radius is larger than the well drainage radius for well " + name() +
" They are set to equal in the well productivity index calculations");
well_productivity_index_logger_counter_++;
}
return;
}
// For zero drainage radius the productivity index is just the transmissibility times the mobility
if (well_ecl_.getDrainageRadius() == 0) {
return;
}
// Scale the productivity index to account for the drainage radius.
// Assumes steady radial flow only valied for horizontal wells
productivity_index *=
(std::log(connection.r0() / connection.rw()) + connection.skinFactor()) /
(std::log(well_ecl_.getDrainageRadius() / connection.rw()) + connection.skinFactor());
}
template<typename TypeTag>
void
WellInterface<TypeTag>::addCellRates(RateVector& rates, int cellIdx) const