Include perforation data in SingleWellState

This commit is contained in:
Joakim Hove 2021-08-06 13:14:00 +02:00
parent 46f45e3999
commit 579aba8d08
9 changed files with 45 additions and 62 deletions

View File

@ -189,7 +189,7 @@ loadRestartData(const data::Wells& rst_wells,
ws.surface_rates[i] = rst_well.rates.get(phs[i]);
}
auto& perf_data = well_state.perfData(well_index);
auto& perf_data = ws.perf_data;
auto& perf_pressure = perf_data.pressure;
auto& perf_rates = perf_data.rates;
auto& perf_phase_rates = perf_data.phase_rates;

View File

@ -1707,7 +1707,8 @@ namespace Opm {
auto& well_info = *local_parallel_well_info_[wellID];
const int num_perf_this_well = well_info.communication().sum(well_perf_data_[wellID].size());
auto& perf_data = this->wellState().perfData(wellID);
auto& ws = this->wellState().well(wellID);
auto& perf_data = ws.perf_data;
auto& perf_phase_rate = perf_data.phase_rates;
for (int perf = 0; perf < num_perf_this_well; ++perf) {

View File

@ -598,7 +598,7 @@ namespace Opm
};
auto& ws = well_state.well(this->index_of_well_);
auto& perf_data = well_state.perfData(this->index_of_well_);
auto& perf_data = ws.perf_data;
auto* connPI = perf_data.prod_index.data();
auto* wellPI = ws.productivity_index.data();
@ -1267,7 +1267,7 @@ namespace Opm
// calculating the perforation rate for each perforation that belongs to this segment
const EvalWell seg_pressure = this->getSegmentPressure(seg);
auto& perf_data = well_state.perfData(this->index_of_well_);
auto& perf_data = ws.perf_data;
auto& perf_rates = perf_data.phase_rates;
auto& perf_press_state = perf_data.pressure;
for (const int perf : this->segment_perforations_[seg]) {

View File

@ -694,7 +694,8 @@ StandardWellEval<FluidSystem,Indices,Scalar>::
updateWellStateFromPrimaryVariablesPolyMW(WellState& well_state) const
{
if (baseif_.isInjector()) {
auto& perf_data = well_state.perfData(baseif_.indexOfWell());
auto& ws = well_state.well(baseif_.indexOfWell());
auto& perf_data = ws.perf_data;
auto& perf_water_velocity = perf_data.water_velocity;
auto& perf_skin_pressure = perf_data.skin_pressure;
for (int perf = 0; perf < baseif_.numPerfs(); ++perf) {

View File

@ -431,7 +431,7 @@ namespace Opm
const int np = number_of_phases_;
std::vector<RateVector> connectionRates = connectionRates_; // Copy to get right size.
auto& perf_data = well_state.perfData(this->index_of_well_);
auto& perf_data = ws.perf_data;
auto& perf_rates = perf_data.phase_rates;
for (int perf = 0; perf < number_of_perforations_; ++perf) {
// Calculate perforation quantities.
@ -546,8 +546,8 @@ namespace Opm
computePerfRateEval(intQuants, mob, bhp, Tw, perf, allow_cf,
cq_s, perf_dis_gas_rate, perf_vap_oil_rate, deferred_logger);
auto& perf_data = well_state.perfData(this->index_of_well_);
auto& ws = well_state.well(this->index_of_well_);
auto& perf_data = ws.perf_data;
if constexpr (has_polymer && Base::has_polymermw) {
if (this->isInjector()) {
// Store the original water flux computed from the reservoir quantities.
@ -1225,7 +1225,7 @@ namespace Opm
}
// Compute the average pressure in each well block
const auto& perf_press = well_state.perfData(w).pressure;
const auto& perf_press = ws.perf_data.pressure;
auto p_above = this->parallel_well_info_.communicateAboveValues(ws.bhp,
perf_press.data(),
nperf);
@ -1375,7 +1375,7 @@ namespace Opm
};
auto& ws = well_state.well(this->index_of_well_);
auto& perf_data = well_state.perfData(this->index_of_well_);
auto& perf_data = ws.perf_data;
auto* wellPI = ws.productivity_index.data();
auto* connPI = perf_data.prod_index.data();
@ -1438,7 +1438,8 @@ namespace Opm
const int nperf = number_of_perforations_;
const int np = number_of_phases_;
std::vector<double> perfRates(b_perf.size(),0.0);
const auto& perf_data = well_state.perfData(this->index_of_well_);
const auto& ws = well_state.well(this->index_of_well_);
const auto& perf_data = ws.perf_data;
const auto& perf_rates_state = perf_data.phase_rates;
for (int perf = 0; perf < nperf; ++perf) {
@ -1908,7 +1909,8 @@ namespace Opm
// other primary variables related to polymer injection
if constexpr (Base::has_polymermw) {
if (this->isInjector()) {
const auto& perf_data = well_state.perfData(this->index_of_well_);
const auto& ws = well_state.well(this->index_of_well_);
const auto& perf_data = ws.perf_data;
const auto& water_velocity = perf_data.water_velocity;
const auto& skin_pressure = perf_data.skin_pressure;
for (int perf = 0; perf < number_of_perforations_; ++perf) {
@ -2134,7 +2136,8 @@ namespace Opm
{
if constexpr (Base::has_polymermw) {
if (this->isInjector()) {
auto& perf_water_throughput = well_state.perfData(this->index_of_well_).water_throughput;
auto& ws = well_state.well(this->index_of_well_);
auto& perf_water_throughput = ws.perf_data.water_throughput;
for (int perf = 0; perf < number_of_perforations_; ++perf) {
const double perf_water_vel = this->primary_variables_[Bhp + 1 + perf];
// we do not consider the formation damage due to water flowing from reservoir into wellbore
@ -2195,7 +2198,8 @@ namespace Opm
const EvalWell eq_wat_vel = this->primary_variables_evaluation_[wat_vel_index] - water_velocity;
this->resWell_[0][wat_vel_index] = eq_wat_vel.value();
const auto& perf_data = well_state.perfData(this->index_of_well_);
const auto& ws = well_state.well(this->index_of_well_);
const auto& perf_data = ws.perf_data;
const auto& perf_water_throughput = perf_data.water_throughput;
const double throughput = perf_water_throughput[perf];
const int pskin_index = Bhp + 1 + number_of_perforations_ + perf;
@ -2257,7 +2261,8 @@ namespace Opm
const int wat_vel_index = Bhp + 1 + perf;
const EvalWell water_velocity = this->primary_variables_evaluation_[wat_vel_index];
if (water_velocity > 0.) { // injecting
const auto& perf_water_throughput = well_state.perfData(this->index_of_well_).water_throughput;
const auto& ws = well_state.well(this->index_of_well_);
const auto& perf_water_throughput = ws.perf_data.water_throughput;
const double throughput = perf_water_throughput[perf];
const EvalWell molecular_weight = wpolymermw(throughput, water_velocity, deferred_logger);
cq_s_polymw *= molecular_weight;

View File

@ -854,7 +854,8 @@ checkMaxRatioLimitCompletions(const WellState& well_state,
double max_ratio_completion = 0;
const int np = number_of_phases_;
const auto& perf_data = well_state.perfData(this->index_of_well_);
const auto& ws = well_state.well(this->index_of_well_);
const auto& perf_data = ws.perf_data;
const auto& perf_phase_rates = perf_data.phase_rates;
// look for the worst_offending_completion
for (const auto& completion : completions_) {

View File

@ -40,7 +40,6 @@ void WellState::base_init(const std::vector<double>& cellPressures,
{
// clear old name mapping
this->wellMap_.clear();
this->perfdata.clear();
this->parallel_well_info_.clear();
this->wells_.clear();
{
@ -87,8 +86,7 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
this->parallel_well_info_.add(well.name(), well_info);
const int num_perf_this_well = well_info->communication().sum(well_perf_data.size());
this->perfdata.add(well.name(), PerfData{static_cast<std::size_t>(num_perf_this_well), well.isInjector(), this->phase_usage_.num_phases});
auto& ws = this->wells_.add(well.name(), SingleWellState{well.isProducer(), num_perf_this_well, static_cast<std::size_t>(np), temp});
auto& ws = this->wells_.add(well.name(), SingleWellState{well.isProducer(), static_cast<std::size_t>(num_perf_this_well), static_cast<std::size_t>(np), temp});
if ( num_perf_this_well == 0 )
return;
@ -261,9 +259,9 @@ void WellState::init(const std::vector<double>& cellPressures,
const auto& well_info = this->wellMap().at(wname);
const int num_perf_this_well = well_info[2];
const int global_num_perf_this_well = ecl_well.getConnections().num_open();
auto& perf_data = this->perfData(w);
auto& ws = this->well(w);
auto& perf_data = ws.perf_data;
const auto& perf_input = well_perf_data[w];
const auto& ws = this->well(w);
for (int perf = 0; perf < num_perf_this_well; ++perf) {
perf_data.cell_index[perf] = perf_input[perf].cell_index;
@ -366,12 +364,12 @@ void WellState::init(const std::vector<double>& cellPressures,
// number of perforations.
if (global_num_perf_same)
{
auto& perf_data = this->perfData(w);
const auto& prev_perf_data = prevState->perfData(w);
auto& perf_data = new_well.perf_data;
const auto& prev_perf_data = prev_well.perf_data;
perf_data.try_assign( prev_perf_data );
} else {
const int global_num_perf_this_well = well.getConnections().num_open();
auto& perf_data = this->perfData(w);
auto& perf_data = new_well.perf_data;
auto& target_rates = perf_data.phase_rates;
for (int perf_index = 0; perf_index < num_perf_this_well; perf_index++) {
for (int p = 0; p < np; ++p) {
@ -561,7 +559,7 @@ void WellState::reportConnections(std::vector<data::Connection>& connections,
const int* globalCellIdxMap) const
{
using rt = data::Rates::opt;
const auto& perf_data = this->perfData(well_index);
const auto& perf_data = this->well(well_index).perf_data;
const int num_perf_well = perf_data.size();
connections.resize(num_perf_well);
const auto& perf_rates = perf_data.rates;
@ -672,7 +670,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
}
auto& perf_data = this->perfData(w);
auto& perf_data = ws.perf_data;
// for the seg_rates_, now it becomes a recursive solution procedure.
{
// make sure the information from wells_ecl consistent with wells
@ -778,21 +776,24 @@ WellState::calculateSegmentRates(const std::vector<std::vector<int>>& segment_in
double WellState::solventWellRate(const int w) const
{
const auto& perf_data = this->perfData(w);
auto& ws = this->well(w);
const auto& perf_data = ws.perf_data;
const auto& perf_rates_solvent = perf_data.solvent_rates;
return parallel_well_info_[w]->sumPerfValues(perf_rates_solvent.begin(), perf_rates_solvent.end());
}
double WellState::polymerWellRate(const int w) const
{
const auto& perf_data = this->perfData(w);
auto& ws = this->well(w);
const auto& perf_data = ws.perf_data;
const auto& perf_rates_polymer = perf_data.polymer_rates;
return parallel_well_info_[w]->sumPerfValues(perf_rates_polymer.begin(), perf_rates_polymer.end());
}
double WellState::brineWellRate(const int w) const
{
const auto& perf_data = this->perfData(w);
auto& ws = this->well(w);
const auto& perf_data = ws.perf_data;
const auto& perf_rates_brine = perf_data.brine_rates;
return parallel_well_info_[w]->sumPerfValues(perf_rates_brine.begin(), perf_rates_brine.end());
}
@ -809,7 +810,7 @@ void WellState::shutWell(int well_index)
auto& ws = this->well(well_index);
ws.shut();
auto& perf_data = this->perfData(well_index);
auto& perf_data = ws.perf_data;
auto& connpi = perf_data.prod_index;
connpi.assign(connpi.size(), 0);
}
@ -991,16 +992,16 @@ void WellState::updateWellsDefaultALQ( const std::vector<Well>& wells_ecl )
void WellState::resetConnectionTransFactors(const int well_index,
const std::vector<PerforationData>& new_perf_data)
{
if (this->perfdata[well_index].size() != new_perf_data.size()) {
auto& ws = this->well(well_index);
auto& perf_data = ws.perf_data;
if (perf_data.size() != new_perf_data.size()) {
throw std::invalid_argument {
"Size mismatch for perforation data in well "
+ std::to_string(well_index)
};
}
auto& perf_data = this->perfData(well_index);
for (std::size_t conn_index = 0; conn_index < new_perf_data.size(); conn_index++) {
if (perf_data.cell_index[conn_index] != static_cast<std::size_t>(new_perf_data[conn_index].cell_index)) {
throw std::invalid_argument {
"Cell index mismatch in connection "

View File

@ -246,24 +246,6 @@ public:
std::vector<double>& wellRates(std::size_t well_index) { return this->wells_[well_index].surface_rates; }
const std::vector<double>& wellRates(std::size_t well_index) const { return this->wells_[well_index].surface_rates; }
std::size_t numPerf(std::size_t well_index) const { return this->perfdata[well_index].size(); }
PerfData& perfData(const std::string& wname) {
return this->perfdata[wname];
}
const PerfData& perfData(const std::string& wname) const {
return this->perfdata[wname];
}
PerfData& perfData(std::size_t well_index) {
return this->perfdata[well_index];
}
const PerfData& perfData(std::size_t well_index) const {
return this->perfdata[well_index];
}
const std::string& name(std::size_t well_index) const {
return this->wells_.well_name(well_index);
}
@ -300,8 +282,6 @@ private:
WellContainer<SingleWellState> wells_;
WellContainer<const ParallelWellInfo*> parallel_well_info_;
WellContainer<PerfData> perfdata;
// The well_rates variable is defined for all wells on all processors. The
// bool in the value pair is whether the current process owns the well or
// not.

View File

@ -294,8 +294,8 @@ BOOST_AUTO_TEST_CASE(Pressure)
}
}
const auto& perf_data = wstate.perfData("PROD01");
const auto& ws = wstate.well("PROD01");
const auto& perf_data = ws.perf_data;
(void) perf_data;
}
@ -362,7 +362,8 @@ BOOST_AUTO_TEST_CASE(STOP_well)
std::vector<Opm::ParallelWellInfo> pinfos;
auto wstate = buildWellState(setup, 0, pinfos);
for (std::size_t well_index = 0; well_index < setup.sched.numWells(0); well_index++) {
const auto& perf_data = wstate.perfData(well_index);
const auto& ws = wstate.well(well_index);
const auto& perf_data = ws.perf_data;
for (const auto& p : perf_data.pressure)
BOOST_CHECK(p > 0);
}
@ -541,13 +542,6 @@ BOOST_AUTO_TEST_CASE(TESTSegmentState2) {
BOOST_AUTO_TEST_CASE(TESTPerfData) {
const auto& deck_string = R"(
RUNSPEC
OIL
WATER
GAS
)";
Opm::PerfData pd1(3, true, 3);
Opm::PerfData pd2(3, true, 3);
Opm::PerfData pd3(2, true, 3);