Merge pull request #3045 from bska/joakim-hove-well-open-in-report-step

Don't Initialize Well State for Shut Wells
This commit is contained in:
Tor Harald Sandve 2021-03-22 12:34:54 +01:00 committed by GitHub
commit 124b98504b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 63 additions and 29 deletions

View File

@ -301,7 +301,7 @@ namespace Opm {
std::vector<bool> is_cell_perforated_;
std::function<bool(const Well&)> is_shut_or_defunct_;
std::function<bool(const Well&)> not_on_process_;
void initializeWellProdIndCalculators();
void initializeWellPerfData();
@ -373,8 +373,8 @@ namespace Opm {
/// \brief Get the wells of our partition that are not shut.
/// \param timeStepIdx The index of the time step.
/// \param[out] globalNumWells the number of wells globally.
std::vector< Well > getLocalNonshutWells(const int timeStepIdx,
int& globalNumWells) const;
std::vector< Well > getLocalWells(const int timeStepIdx,
int& globalNumWells) const;
/// \brief Create the parallel well information
/// \param localWells The local wells from ECL schedule

View File

@ -55,7 +55,7 @@ namespace Opm {
parallel_well_info_.assign(parallel_wells.begin(), parallel_wells.end());
const auto& pwell_info = parallel_well_info_;
std::size_t numProcs = ebosSimulator.gridView().comm().size();
is_shut_or_defunct_ = [&pwell_info, numProcs](const Well& well) {
not_on_process_ = [&pwell_info, numProcs](const Well& well) {
if (well.getStatus() == Well::Status::SHUT)
return true;
if (numProcs == 1u)
@ -214,11 +214,11 @@ namespace Opm {
template<typename TypeTag>
std::vector< Well >
BlackoilWellModel<TypeTag>::
getLocalNonshutWells(const int timeStepIdx, int& globalNumWells) const
getLocalWells(const int timeStepIdx, int& globalNumWells) const
{
auto w = schedule().getWells(timeStepIdx);
globalNumWells = w.size();
w.erase(std::remove_if(w.begin(), w.end(), is_shut_or_defunct_), w.end());
w.erase(std::remove_if(w.begin(), w.end(), not_on_process_), w.end());
return w;
}
@ -252,8 +252,8 @@ namespace Opm {
const Grid& grid = ebosSimulator_.vanguard().grid();
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
int globalNumWells = 0;
// Make wells_ecl_ contain only this partition's non-shut wells.
wells_ecl_ = getLocalNonshutWells(timeStepIdx, globalNumWells);
// Make wells_ecl_ contain only this partition's wells.
wells_ecl_ = getLocalWells(timeStepIdx, globalNumWells);
local_parallel_well_info_ = createLocalParallelWellInfo(wells_ecl_);
// The well state initialize bhp with the cell pressure in the top cell.
@ -621,8 +621,8 @@ namespace Opm {
const int report_step = std::max(eclState().getInitConfig().getRestartStep() - 1, 0);
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
int globalNumWells = 0;
// Make wells_ecl_ contain only this partition's non-shut wells.
wells_ecl_ = getLocalNonshutWells(report_step, globalNumWells);
// wells_ecl_ should only contain wells on this processor.
wells_ecl_ = getLocalWells(report_step, globalNumWells);
local_parallel_well_info_ = createLocalParallelWellInfo(wells_ecl_);
this->initializeWellProdIndCalculators();

View File

@ -244,7 +244,7 @@ namespace Opm
using Base::ebosCompIdxToFlowCompIdx;
using Base::getAllowCrossFlow;
using Base::scalingFactor;
using Base::wellIsStopped_;
using Base::wellIsStopped;
using Base::updateWellOperability;
using Base::checkWellOperability;

View File

@ -302,7 +302,7 @@ namespace Opm
const int np = well_state.numPhases();
const auto& summaryState = ebos_simulator.vanguard().summaryState();
if (wellIsStopped_) {
if (this->wellIsStopped()) {
for (int p = 0; p<np; ++p) {
well_state.wellRates()[well_index*np + p] = 0.0;
}
@ -2030,7 +2030,7 @@ namespace Opm
return rates;
};
if (wellIsStopped_) {
if (this->wellIsStopped()) {
control_eq = getWQTotal();
} else if (this->isInjector() ) {
// Find scaling factor to get injection rate,

View File

@ -336,6 +336,7 @@ namespace Opm
using Base::mostStrictBhpFromBhpLimits;
using Base::updateWellOperability;
using Base::checkWellOperability;
using Base::wellIsStopped;
// protected member variables from the Base class
using Base::current_step_;
@ -362,7 +363,6 @@ namespace Opm
using Base::ipr_b_;
using Base::changed_to_stopped_this_step_;
using Base::wellIsStopped_;
// total number of the well equations and primary variables
// there might be extra equations be used, numWellEq will be updated during the initialization

View File

@ -892,7 +892,7 @@ namespace Opm
return rates;
};
if (wellIsStopped_) {
if (this->wellIsStopped()) {
control_eq = getWQTotal();
} else if (this->isInjector()) {
// Find injection rate.
@ -1365,7 +1365,7 @@ namespace Opm
const int np = well_state.numPhases();
const auto& summaryState = ebos_simulator.vanguard().summaryState();
if (wellIsStopped_) {
if (this->wellIsStopped()) {
for (int p = 0; p<np; ++p) {
well_state.wellRates()[well_index*np + p] = 0.0;
}
@ -3490,7 +3490,7 @@ namespace Opm
CR::WellFailure::Type ctrltype = CR::WellFailure::Type::Invalid;
const int well_index = index_of_well_;
if (wellIsStopped_) {
if (this->wellIsStopped()) {
ctrltype = CR::WellFailure::Type::ControlRate;
control_tolerance = 1.e-6; // use smaller tolerance for zero control?
}

View File

@ -307,14 +307,15 @@ namespace Opm
DeferredLogger& deferred_logger) const;
void stopWell() {
wellIsStopped_ = true;
this->wellStatus_ = Well::Status::STOP;
}
void openWell() {
wellIsStopped_ = false;
this->wellStatus_ = Well::Status::OPEN;
}
bool wellIsStopped() const {
return wellIsStopped_;
return this->wellStatus_ == Well::Status::STOP;
}
void setWsolvent(const double wsolvent);
@ -419,7 +420,7 @@ namespace Opm
std::vector<RateVector> connectionRates_;
bool wellIsStopped_;
Well::Status wellStatus_;
double wsolvent_;

View File

@ -90,9 +90,9 @@ namespace Opm
connectionRates_.resize(number_of_perforations_);
wellIsStopped_ = false;
this->wellStatus_ = Well::Status::OPEN;
if (well.getStatus() == Well::Status::STOP) {
wellIsStopped_ = true;
this->wellStatus_ = Well::Status::STOP;
}
wsolvent_ = 0.0;
@ -973,7 +973,7 @@ namespace Opm
WellTestState& well_test_state,
Opm::DeferredLogger& deferred_logger) const
{
if (wellIsStopped_)
if (this->wellIsStopped())
return;
const WellEconProductionLimits& econ_production_limits = well_ecl_.getEconLimits();

View File

@ -398,9 +398,15 @@ namespace Opm
: (prod_controls.cmode == Well::ProducerCMode::GRUP);
const double inj_surf_rate = well.isInjector() ? inj_controls.surface_rate : 0.0; // To avoid a "maybe-uninitialized" warning.
const double local_pressure = well_perf_data_[w].empty() ?
0 : cellPressures[well_perf_data_[w][0].cell_index];
const double global_pressure = well_info.broadcastFirstPerforationValue(local_pressure);
if (well.getStatus() == Well::Status::OPEN) {
this->openWell(w);
}
if (well.getStatus() == Well::Status::STOP) {
// Stopped well:
// 1. Rates: zero well rates.

View File

@ -190,13 +190,33 @@ namespace Opm
perfRateBrine_.clear();
perfRateBrine_.resize(nperf, 0.0);
for (int w = 0; w < nw; ++w) {
switch (wells_ecl[w].getStatus()) {
case Well::Status::SHUT:
this->shutWell(w);
break;
case Well::Status::STOP:
this->stopWell(w);
break;
default:
this->openWell(w);
break;
}
}
// intialize wells that have been there before
// order may change so the mapping is based on the well name
if (prevState && !prevState->wellMap().empty()) {
auto end = prevState->wellMap().end();
for (int w = 0; w < nw; ++w) {
const Well& well = wells_ecl[w];
const int num_perf_this_well = well_perf_data[w].size();
if (well.getStatus() == Well::Status::SHUT) {
continue;
}
auto it = prevState->wellMap().find(well.name());
if ( it != end )
{
@ -241,6 +261,17 @@ namespace Opm
// perfPhaseRates
const int oldPerf_idx_beg = (*it).second[ 1 ];
const int num_perf_old_well = (*it).second[ 2 ];
const auto new_iter = this->wellMap().find(well.name());
if (new_iter == this->wellMap().end()) {
throw std::logic_error {
well.name() + " is not in internal well map - "
"Bug in WellStateFullyImplicitBlackoil"
};
}
const int connpos = new_iter->second[1];
const int num_perf_this_well = new_iter->second[2];
int num_perf_changed = (num_perf_old_well != num_perf_this_well) ? 1 : 0;
num_perf_changed = parallel_well_info[w]->communication().sum(num_perf_changed);
bool global_num_perf_same = (num_perf_changed == 0);
@ -248,10 +279,6 @@ namespace Opm
// copy perforation rates when the number of perforations is equal,
// otherwise initialize perfphaserates to well rates divided by the number of perforations.
const auto new_iter = this->wellMap().find(well.name());
if (new_iter == this->wellMap().end())
throw std::logic_error("Fatal error in WellStateFullyImplicitBlackoil - could not find well: " + well.name());
int connpos = new_iter->second[1];
if( global_num_perf_same )
{
int old_perf_phase_idx = oldPerf_idx_beg *np;