Use SegmentState for rates

This commit is contained in:
Joakim Hove 2021-06-01 11:34:11 +02:00
parent 357cb11667
commit ac12c8b3a4
5 changed files with 19 additions and 68 deletions

View File

@ -2023,7 +2023,7 @@ namespace Opm {
auto& segments = well_state.segments(well_index);
auto& segment_pressure = segments.pressure;
auto segment_rates = well_state.segRates(well_index);
auto& segment_rates = segments.rates;
for (const auto& rst_segment : rst_segments) {
const int segment_index = segment_set.segmentNumberToIndex(rst_segment.first);

View File

@ -278,7 +278,8 @@ namespace Opm
MultisegmentWell<TypeTag>::
scaleSegmentRatesWithWellRates(WellState& well_state) const
{
auto segment_rates = well_state.segRates(index_of_well_);
auto& segments = well_state.segments(this->index_of_well_);
auto& segment_rates = segments.rates;
for (int phase = 0; phase < number_of_phases_; ++phase) {
const double unscaled_top_seg_rate = segment_rates[phase];
const double well_phase_rate = well_state.wellRates(index_of_well_)[phase];
@ -302,9 +303,8 @@ namespace Opm
}
std::vector<double> rates;
WellState::calculateSegmentRates(segment_inlets_, segment_perforations_, perforation_rates, number_of_phases_,
0, rates);
std::copy(rates.begin(), rates.end(), segment_rates);
WellState::calculateSegmentRates(segment_inlets_, segment_perforations_, perforation_rates, number_of_phases_, 0, rates);
std::copy(rates.begin(), rates.end(), segment_rates.begin());
}
}
}
@ -716,7 +716,7 @@ namespace Opm
// the index of the top segment in the WellState
const auto& segments = well_state.segments(this->index_of_well_);
const auto segment_rates = well_state.segRates(index_of_well_);
const auto& segment_rates = segments.rates;
const auto& segment_pressure = segments.pressure;
const PhaseUsage& pu = phaseUsage();
@ -2335,7 +2335,7 @@ namespace Opm
const int oil_pos = pu.phase_pos[Oil];
auto& segments = well_state.segments(this->index_of_well_);
auto segment_rates = well_state.segRates(this->index_of_well_);
auto& segment_rates = segments.rates;
auto& segment_pressure = segments.pressure;
for (int seg = 0; seg < numberOfSegments(); ++seg) {
std::vector<double> fractions(number_of_phases_, 0.0);

View File

@ -531,8 +531,6 @@ void WellState::init(const std::vector<double>& cellPressures,
top_segment_index_[w] = w;
seg_number_[w] = 1; // Top segment is segment #1
}
//seg_rates_ = wellRates();
seg_rates_.assign(nw*np, 0);
}
updateWellsDefaultALQ(wells_ecl);
@ -820,7 +818,6 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
const int np = pu.num_phases;
top_segment_index_.clear();
seg_rates_.clear();
seg_number_.clear();
nseg_ = 0;
@ -833,14 +830,10 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
const int connpos = well_info[1];
const int num_perf_this_well = well_info[2];
const auto& rates = this->wellRates(w);
top_segment_index_.push_back(nseg_);
if ( !well_ecl.isMultiSegment() ) { // not multi-segment well
nseg_ += 1;
seg_number_.push_back(1); // Assign single segment (top) as number 1.
for (int p = 0; p < np; ++p) {
seg_rates_.push_back(rates[p]);
}
} else { // it is a multi-segment well
const WellSegments& segment_set = well_ecl.getSegments();
// assuming the order of the perforations in well_ecl is the same with Wells
@ -901,12 +894,10 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
const auto * perf_rates = &perfPhaseRates()[np*start_perf];
std::vector<double> perforation_rates(perf_rates, perf_rates + num_perf_this_well*np);
std::vector<double> segment_rates;
calculateSegmentRates(segment_inlets, segment_perforations, perforation_rates, np, 0 /* top segment */, segment_rates);
std::copy(segment_rates.begin(), segment_rates.end(), std::back_inserter(seg_rates_));
auto& segments = this->segments(w);
calculateSegmentRates(segment_inlets, segment_perforations, perforation_rates, np, 0 /* top segment */, segments.rates);
}
// for the segment pressure, the segment pressure is the same with the first perforation belongs to the segment
// if there is no perforation associated with this segment, it uses the pressure from the outlet segment
// which requres the ordering is successful
@ -935,8 +926,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
assert(int(seg_rates_.size()) == nseg_ * numPhases() );
if (prev_well_state && !prev_well_state->wellMap().empty()) {
const auto& end = prev_well_state->wellMap().end();
if (prev_well_state) {
for (int w = 0; w < nw; ++w) {
const Well& well = wells_ecl[w];
if (well.getStatus() == Well::Status::SHUT)
@ -946,39 +936,15 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
continue;
const auto& wname = well.name();
const auto& it = prev_well_state->wellMap().find( wells_ecl[w].name() );
if (it != end) { // the well is found in the prev_well_state
// TODO: the well with same name can change a lot, like they might not have same number of segments
// we need to handle that later.
// for now, we just copy them.
const int old_index_well = (*it).second[0];
const int new_index_well = w;
if (prev_well_state->status_[old_index_well] == Well::Status::SHUT) {
if (prev_well_state->segment_state.has(wname)) {
if (prev_well_state->status_[wname] == Well::Status::SHUT) {
continue;
}
const int new_top_segment_index = topSegmentIndex(new_index_well);
int number_of_segment = 0;
// if it is the last well in list
if (new_index_well == int(top_segment_index_.size()) - 1) {
number_of_segment = nseg_ - new_top_segment_index;
} else {
number_of_segment = topSegmentIndex(new_index_well + 1) - new_top_segment_index;
}
auto& segments = this->segments(wname);
const auto& prev_segments = prev_well_state->segments(wname);
segments.pressure = prev_segments.pressure;
auto segment_rates = this->segRates(w);
const auto prev_segment_rates = prev_well_state->segRates(old_index_well);
for (int seg=0; seg < number_of_segment; ++seg) {
for (int p = 0; p < np; ++p)
segment_rates[seg*np + p] = prev_segment_rates[seg*np + p];
}
// TODO: the well with same name can change a lot, like they might not have same number of segments
// we need to handle that later.
// for now, we just copy them.
this->segment_state.copy_welldata(prev_well_state->segment_state, wname);
}
}
}
@ -1158,7 +1124,7 @@ WellState::reportSegmentResults(const PhaseUsage& pu,
segpress[Value::PDropAccel] = segments.pressure_drop_accel[seg_ix];
}
const auto rate = &this->segRates(well_id)[seg_ix * pu.num_phases];
const auto rate = &segments.rates[seg_ix * pu.num_phases];
if (pu.phase_used[Water]) {
seg_res.rates.set(data::Rates::opt::wat,
rate[pu.phase_pos[Water]]);

View File

@ -196,19 +196,6 @@ public:
}
const double * segRates(std::size_t well_index) const
{
const int top_segment_index = this->top_segment_index_[well_index];
return &this->seg_rates_[top_segment_index * this->phase_usage_.num_phases];
}
double * segRates(std::size_t well_index)
{
const int top_segment_index = this->top_segment_index_[well_index];
return &this->seg_rates_[top_segment_index * this->phase_usage_.num_phases];
}
int numSegment() const
{
return nseg_;
@ -488,9 +475,6 @@ private:
WellContainer<Events> events_;
WellContainer<SegmentState> segment_state;
// MS well related
// for StandardWell, the number of segments will be one
std::vector<double> seg_rates_;
// the index of the top segments, which is used to locate the
// multisegment well related information in WellState
std::vector<int> top_segment_index_;

View File

@ -213,7 +213,8 @@ namespace {
}
const auto rateTop = 1000.0 * wellID;
auto segRates = wstate.segRates(wellID);
auto& segments = wstate.segments(wellID);
auto& segRates = segments.rates;
if (wat) { segRates[iw] = rateTop; }
if (oil) { segRates[io] = rateTop; }