Merge pull request #3485 from joakim-hove/single-well-state3

Single well state3
This commit is contained in:
Bård Skaflestad 2021-08-23 13:47:35 +02:00 committed by GitHub
commit 076c274352
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 100 additions and 173 deletions

View File

@ -216,7 +216,7 @@ loadRestartData(const data::Wells& rst_wells,
// \Note: eventually we need to handle the situations that some segments are shut
assert(0u + segment_set.size() == rst_segments.size());
auto& segments = well_state.segments(well_index);
auto& segments = ws.segments;
auto& segment_pressure = segments.pressure;
auto& segment_rates = segments.rates;
for (const auto& rst_segment : rst_segments) {
@ -1060,7 +1060,7 @@ BlackoilWellModelGeneric::
wellPI(const int well_index) const
{
const auto& pu = this->phase_usage_;
const auto& pi = this->wellState().productivityIndex(well_index);
const auto& pi = this->wellState().well(well_index).productivity_index;
const auto preferred = this->wells_ecl_[well_index].getPreferredPhase();
switch (preferred) { // Should really have LIQUID = OIL + WATER here too...

View File

@ -1326,8 +1326,9 @@ namespace Opm {
// Store it in the well state
// potentials is resized and set to zero in the beginning of well->ComputeWellPotentials
// and updated only if sucessfull. i.e. the potentials are zero for exceptions
auto& ws = this->wellState().well(well->indexOfWell());
for (int p = 0; p < np; ++p) {
this->wellState().wellPotentials(well->indexOfWell())[p] = std::abs(potentials[p]);
ws.well_potentials[p] = std::abs(potentials[p]);
}
}

View File

@ -444,7 +444,8 @@ updatePrimaryVariables(const WellState& well_state) const
const Well& well = baseif_.wellEcl();
// the index of the top segment in the WellState
const auto& segments = well_state.segments(baseif_.indexOfWell());
const auto& ws = well_state.well(baseif_.indexOfWell());
const auto& segments = ws.segments;
const auto& segment_rates = segments.rates;
const auto& segment_pressure = segments.pressure;
const PhaseUsage& pu = baseif_.phaseUsage();
@ -1537,7 +1538,8 @@ handleAccelerationPressureLoss(const int seg,
const double sign = mass_rate < 0. ? 1.0 : - 1.0;
accelerationPressureLoss *= sign;
well_state.segments(baseif_.indexOfWell()).pressure_drop_accel[seg] = accelerationPressureLoss.value();
auto& segments = well_state.well(baseif_.indexOfWell()).segments;
segments.pressure_drop_accel[seg] = accelerationPressureLoss.value();
resWell_[seg][SPres] -= accelerationPressureLoss.value();
duneD_[seg][seg][SPres][SPres] -= accelerationPressureLoss.derivative(SPres + Indices::numEq);
@ -1566,7 +1568,8 @@ assembleDefaultPressureEq(const int seg,
// TODO: we might be able to add member variables to store these values, then we update well state
// after converged
const auto hydro_pressure_drop = getHydroPressureLoss(seg);
auto& segments = well_state.segments(baseif_.indexOfWell());
auto& ws = well_state.well(baseif_.indexOfWell());
auto& segments = ws.segments;
segments.pressure_drop_hydrostatic[seg] = hydro_pressure_drop.value();
pressure_equation -= hydro_pressure_drop;
@ -1616,8 +1619,8 @@ updateWellStateFromPrimaryVariables(WellState& well_state,
assert( FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) );
const int oil_pos = pu.phase_pos[Oil];
auto& well = well_state.well(baseif_.indexOfWell());
auto& segments = well_state.segments(baseif_.indexOfWell());
auto& ws = well_state.well(baseif_.indexOfWell());
auto& segments = ws.segments;
auto& segment_rates = segments.rates;
auto& segment_pressure = segments.pressure;
for (int seg = 0; seg < this->numberOfSegments(); ++seg) {
@ -1661,7 +1664,7 @@ updateWellStateFromPrimaryVariables(WellState& well_state,
// update the segment pressure
segment_pressure[seg] = primary_variables_[seg][SPres];
if (seg == 0) { // top segment
well.bhp = segment_pressure[seg];
ws.bhp = segment_pressure[seg];
}
}
updateThp(well_state, rho, deferred_logger);
@ -1702,7 +1705,8 @@ assembleICDPressureEq(const int seg,
}
}
pressure_equation = pressure_equation - icd_pressure_drop;
well_state.segments(baseif_.indexOfWell()).pressure_drop_friction[seg] = icd_pressure_drop.value();
auto& ws = well_state.well(baseif_.indexOfWell());
ws.segments.pressure_drop_friction[seg] = icd_pressure_drop.value();
const int seg_upwind = upwinding_segments_[seg];
resWell_[seg][SPres] = pressure_equation.value();

View File

@ -100,7 +100,8 @@ void
MultisegmentWellGeneric<Scalar>::
scaleSegmentRatesWithWellRates(WellState& well_state) const
{
auto& segments = well_state.segments(baseif_.indexOfWell());
auto& ws = well_state.well(baseif_.indexOfWell());
auto& segments = ws.segments;
auto& segment_rates = segments.rates;
for (int phase = 0; phase < baseif_.numPhases(); ++phase) {
const double unscaled_top_seg_rate = segment_rates[phase];
@ -136,10 +137,9 @@ void
MultisegmentWellGeneric<Scalar>::
scaleSegmentPressuresWithBhp(WellState& well_state) const
{
auto& well = well_state.well(baseif_.indexOfWell());
auto& segments = well_state.segments(baseif_.indexOfWell());
const auto bhp = well.bhp;
segments.scale_pressure(bhp);
auto& ws = well_state.well(baseif_.indexOfWell());
auto& segments = ws.segments;
segments.scale_pressure(ws.bhp);
}
template<typename Scalar>

View File

@ -367,8 +367,7 @@ namespace Opm
const int np = number_of_phases_;
const double sign = well_copy.well_ecl_.isInjector() ? 1.0 : -1.0;
for (int phase = 0; phase < np; ++phase){
well_state_copy.wellRates(well_copy.index_of_well_)[phase]
= sign * well_state_copy.wellPotentials(well_copy.index_of_well_)[phase];
well_state_copy.wellRates(well_copy.index_of_well_)[phase] = sign * ws.well_potentials[phase];
}
well_copy.scaleSegmentRatesWithWellRates(well_state_copy);
@ -598,9 +597,10 @@ namespace Opm
std::transform(src, src + np, dest, dest, std::plus<>{});
};
auto& ws = well_state.well(this->index_of_well_);
auto& perf_data = well_state.perfData(this->index_of_well_);
auto* wellPI = well_state.productivityIndex(this->index_of_well_).data();
auto* connPI = perf_data.prod_index.data();
auto* wellPI = ws.productivity_index.data();
setToZero(wellPI);
@ -1189,8 +1189,9 @@ namespace Opm
this->duneDSolver_.reset();
well_state.wellVaporizedOilRates(index_of_well_) = 0.;
well_state.wellDissolvedGasRates(index_of_well_) = 0.;
auto& ws = well_state.well(this->index_of_well_);
ws.dissolved_gas_rate = 0;
ws.vaporized_oil_rate = 0;
// for the black oil cases, there will be four equations,
// the first three of them are the mass balance equations, the last one is the pressure equations.
@ -1284,8 +1285,8 @@ namespace Opm
// updating the solution gas rate and solution oil rate
if (this->isProducer()) {
well_state.wellDissolvedGasRates(index_of_well_) += perf_dis_gas_rate;
well_state.wellVaporizedOilRates(index_of_well_) += perf_vap_oil_rate;
ws.dissolved_gas_rate += perf_dis_gas_rate;
ws.vaporized_oil_rate += perf_vap_oil_rate;
}
// store the perf pressure and rates

View File

@ -21,9 +21,11 @@
namespace Opm {
SingleWellState::SingleWellState(bool is_producer, double temp)
SingleWellState::SingleWellState(bool is_producer, std::size_t num_phases, double temp)
: producer(is_producer)
, temperature(temp)
, well_potentials(num_phases)
, productivity_index(num_phases)
{}

View File

@ -20,6 +20,9 @@
#ifndef OPM_SINGLE_WELL_STATE_HEADER_INCLUDED
#define OPM_SINGLE_WELL_STATE_HEADER_INCLUDED
#include <vector>
#include <opm/simulators/wells/SegmentState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
@ -27,13 +30,18 @@ namespace Opm {
class SingleWellState {
public:
SingleWellState(bool is_producer, double temp);
SingleWellState(bool is_producer, std::size_t num_phases, double temp);
Well::Status status{Well::Status::OPEN};
bool producer;
double bhp{0};
double thp{0};
double temperature{};
double temperature{0};
double dissolved_gas_rate{0};
double vaporized_oil_rate{0};
std::vector<double> well_potentials;
std::vector<double> productivity_index;
SegmentState segments;
Events events;
Well::InjectorCMode injection_cmode{Well::InjectorCMode::CMODE_UNDEFINED};
Well::ProducerCMode production_cmode{Well::ProducerCMode::CMODE_UNDEFINED};

View File

@ -423,10 +423,10 @@ namespace Opm
// TODO: it probably can be static member for StandardWell
const double volume = 0.002831684659200; // 0.1 cu ft;
auto& ws = well_state.well(this->index_of_well_);
// the solution gas rate and solution oil rate needs to be reset to be zero for well_state.
well_state.wellVaporizedOilRates(index_of_well_) = 0.;
well_state.wellDissolvedGasRates(index_of_well_) = 0.;
ws.vaporized_oil_rate = 0;
ws.dissolved_gas_rate = 0;
const int np = number_of_phases_;
@ -562,8 +562,8 @@ namespace Opm
// updating the solution gas rate and solution oil rate
if (this->isProducer()) {
well_state.wellDissolvedGasRates(index_of_well_) += perf_dis_gas_rate;
well_state.wellVaporizedOilRates(index_of_well_) += perf_vap_oil_rate;
ws.dissolved_gas_rate += perf_dis_gas_rate;
ws.vaporized_oil_rate += perf_vap_oil_rate;
}
if constexpr (has_energy) {
@ -1374,8 +1374,9 @@ namespace Opm
std::transform(src, src + np, dest, dest, std::plus<>{});
};
auto& ws = well_state.well(this->index_of_well_);
auto& perf_data = well_state.perfData(this->index_of_well_);
auto* wellPI = well_state.productivityIndex(this->index_of_well_).data();
auto* wellPI = ws.productivity_index.data();
auto* connPI = perf_data.prod_index.data();
setToZero(wellPI);

View File

@ -83,25 +83,6 @@ public:
return (index_map.count(name) != 0);
}
void update(const std::string& name, T&& value) {
auto index = this->index_map.at(name);
this->m_data[index] = std::forward<T>(value);
}
void update(const std::string& name, const T& value) {
auto index = this->index_map.at(name);
this->m_data[index] = value;
}
void update(std::size_t index, T&& value) {
this->m_data.at(index) = std::forward<T>(value);
}
void update(std::size_t index, const T& value) {
this->m_data.at(index) = value;
}
/*
Will copy the value from other to this - for all wells which are present
in both containers.

View File

@ -1383,9 +1383,10 @@ namespace WellGroupHelpers
continue;
}
const auto& ws = wellState.well(well_index);
// add contribution from wells unconditionally
for (int phase = 0; phase < np; phase++) {
pot[phase] += wefac * wellState.wellPotentials(well_index)[phase];
pot[phase] += wefac * ws.well_potentials[phase];
}
}
@ -1431,8 +1432,8 @@ namespace WellGroupHelpers
{
// the well is found and owned
int well_index = it->second[0];
const auto wpot = wellState.wellPotentials(well_index);
const auto& ws = wellState.well(well_index);
const auto& wpot = ws.well_potentials;
if (pu.phase_used[BlackoilPhases::Liquid] > 0)
oilpot = wpot[pu.phase_pos[BlackoilPhases::Liquid]];

View File

@ -693,9 +693,10 @@ updateWellTestStateEconomic(const WellState& well_state,
bool rate_limit_violated = false;
const auto& quantity_limit = econ_production_limits.quantityLimit();
const auto& ws = well_state.well(this->index_of_well_);
if (econ_production_limits.onAnyRateLimit()) {
if (quantity_limit == WellEconProductionLimits::QuantityLimit::POTN)
rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state.wellPotentials(index_of_well_).data(), deferred_logger);
rate_limit_violated = checkRateEconLimits(econ_production_limits, ws.well_potentials.data(), deferred_logger);
else {
rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state.wellRates(index_of_well_).data(), deferred_logger);
}

View File

@ -246,6 +246,7 @@ namespace Opm
deferred_logger.info(" well " + this->name() + " is being tested for economic limits");
WellState well_state_copy = well_state;
auto& ws = well_state_copy.well(this->indexOfWell());
updateWellStateWithTarget(simulator, group_state, well_state_copy, deferred_logger);
calculateExplicitQuantities(simulator, well_state_copy, deferred_logger);
@ -270,7 +271,7 @@ namespace Opm
}
const int np = well_state_copy.numPhases();
for (int p = 0; p < np; ++p) {
well_state_copy.wellPotentials(this->indexOfWell())[p] = std::abs(potentials[p]);
ws.well_potentials[p] = std::abs(potentials[p]);
}
this->updateWellTestState(well_state_copy, simulation_time, /*writeMessageToOPMLog=*/ false, welltest_state_temp, deferred_logger);
this->closeCompletions(welltest_state_temp);
@ -470,6 +471,7 @@ namespace Opm
// create a copy of the well_state to use. If the operability checking is sucessful, we use this one
// to replace the original one
WellState well_state_copy = well_state;
auto& ws = well_state_copy.well(this->indexOfWell());
// TODO: well state for this well is kind of all zero status
// we should be able to provide a better initialization
@ -510,7 +512,7 @@ namespace Opm
}
const int np = well_state_copy.numPhases();
for (int p = 0; p < np; ++p) {
well_state_copy.wellPotentials(this->indexOfWell())[p] = std::abs(potentials[p]);
ws.well_potentials[p] = std::abs(potentials[p]);
}
well_state = well_state_copy;
} else {
@ -673,7 +675,7 @@ namespace Opm
double total_rate = std::accumulate(rates.begin(), rates.end(), 0.0);
if (total_rate <= 0.0){
for (int p = 0; p<np; ++p) {
well_state.wellRates(well_index)[p] = well_state.wellPotentials(well_index)[p];
well_state.wellRates(well_index)[p] = ws.well_potentials[p];
}
}
break;
@ -690,7 +692,7 @@ namespace Opm
// using the well potentials
if (total_rate <= 0.0){
for (int p = 0; p<np; ++p) {
well_state.wellRates(well_index)[p] = well_state.wellPotentials(well_index)[p];
well_state.wellRates(well_index)[p] = ws.well_potentials[p];
}
}
break;
@ -876,7 +878,7 @@ namespace Opm
// using the well potentials
if (total_rate <= 0.0){
for (int p = 0; p<np; ++p) {
well_state.wellRates(well_index)[p] = -well_state.wellPotentials(well_index)[p];
well_state.wellRates(well_index)[p] = -ws.well_potentials[p];
}
}
break;
@ -896,7 +898,7 @@ namespace Opm
double total_rate = -std::accumulate(rates.begin(), rates.end(), 0.0);
if (total_rate <= 0.0){
for (int p = 0; p<np; ++p) {
well_state.wellRates(well_index)[p] = -well_state.wellPotentials(well_index)[p];
well_state.wellRates(well_index)[p] = -ws.well_potentials[p];
}
}
break;
@ -939,14 +941,15 @@ namespace Opm
{
const int np = this->number_of_phases_;
std::vector<double> scaling_factor(np);
const auto& ws = well_state.well(this->index_of_well_);
double total_potentials = 0.0;
for (int p = 0; p<np; ++p) {
total_potentials += well_state.wellPotentials(this->index_of_well_)[p];
total_potentials += ws.well_potentials[p];
}
if (total_potentials > 0) {
for (int p = 0; p<np; ++p) {
scaling_factor[p] = well_state.wellPotentials(this->index_of_well_)[p] / total_potentials;
scaling_factor[p] = ws.well_potentials[p] / total_potentials;
}
return scaling_factor;
}

View File

@ -43,9 +43,6 @@ void WellState::base_init(const std::vector<double>& cellPressures,
this->perfdata.clear();
this->parallel_well_info_.clear();
this->wellrates_.clear();
this->segment_state.clear();
this->well_potentials_.clear();
this->productivity_index_.clear();
this->wells_.clear();
{
// const int nw = wells->number_of_wells;
@ -90,14 +87,11 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
const int np = pu.num_phases;
double temp = well.isInjector() ? well.injectionControls(summary_state).temperature : 273.15 + 15.56;
auto& ws = this->wells_.add(well.name(), SingleWellState{well.isProducer(), temp});
auto& ws = this->wells_.add(well.name(), SingleWellState{well.isProducer(), static_cast<std::size_t>(np), temp});
this->parallel_well_info_.add(well.name(), well_info);
this->wellrates_.add(well.name(), std::vector<double>(np, 0));
this->well_potentials_.add(well.name(), std::vector<double>(np, 0));
const int num_perf_this_well = well_info->communication().sum(well_perf_data.size());
this->segment_state.add(well.name(), SegmentState{});
this->perfdata.add(well.name(), PerfData{static_cast<std::size_t>(num_perf_this_well), well.isInjector(), this->phase_usage_});
this->productivity_index_.add(well.name(), std::vector<double>(np, 0));
if ( num_perf_this_well == 0 )
return;
@ -254,9 +248,6 @@ void WellState::init(const std::vector<double>& cellPressures,
}
well_reservoir_rates_.clear();
well_dissolved_gas_rates_.clear();
well_vaporized_oil_rates_.clear();
{
const auto& wg_events = schedule[report_step].wellgroup_events();
for (const auto& ecl_well : wells_ecl) {
@ -292,8 +283,6 @@ void WellState::init(const std::vector<double>& cellPressures,
}
this->well_reservoir_rates_.add(wname, std::vector<double>(np, 0));
this->well_dissolved_gas_rates_.add(wname, 0);
this->well_vaporized_oil_rates_.add(wname, 0);
}
for (int w = 0; w < nw; ++w) {
@ -334,12 +323,10 @@ void WellState::init(const std::vector<double>& cellPressures,
if (well.getStatus() == Well::Status::SHUT) {
continue;
}
const auto& wname = well.name();
auto& new_well = this->well(w);
auto it = prevState->wellMap().find(well.name());
if (it != end)
{
const int newIndex = w;
const int oldIndex = it->second[ 0 ];
const auto& prev_well = prevState->well(oldIndex);
@ -363,11 +350,7 @@ void WellState::init(const std::vector<double>& cellPressures,
wellRates(w) = prevState->wellRates(oldIndex);
wellReservoirRates(w) = prevState->wellReservoirRates(oldIndex);
// Well potentials
for (int p=0; p < np; p++) {
this->wellPotentials(newIndex)[p] = prevState->wellPotentials(oldIndex)[p];
}
new_well.well_potentials = prev_well.well_potentials;
// perfPhaseRates
const int num_perf_old_well = (*it).second[ 2 ];
@ -403,7 +386,7 @@ void WellState::init(const std::vector<double>& cellPressures,
}
// Productivity index.
this->productivity_index_.copy_welldata( prevState->productivity_index_, wname );
new_well.productivity_index = prev_well.productivity_index;
}
// If in the new step, there is no THP related
@ -492,8 +475,8 @@ WellState::report(const int* globalCellIdxMap,
}
const auto& reservoir_rates = this->well_reservoir_rates_[well_index];
const auto& well_potentials = this->well_potentials_[well_index];
const auto& wpi = this->productivity_index_[well_index];
const auto& well_potentials = ws.well_potentials;
const auto& wpi = ws.productivity_index;
const auto& wv = this->wellRates(well_index);
data::Well well;
@ -541,8 +524,8 @@ WellState::report(const int* globalCellIdxMap,
well.rates.set(rt::alq, 0.0);
}
well.rates.set(rt::dissolved_gas, this->well_dissolved_gas_rates_[well_index]);
well.rates.set(rt::vaporized_oil, this->well_vaporized_oil_rates_[well_index]);
well.rates.set(rt::dissolved_gas, ws.dissolved_gas_rate);
well.rates.set(rt::vaporized_oil, ws.vaporized_oil_rate);
{
auto& curr = well.current_control;
@ -665,7 +648,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
// assuming the order of the perforations in well_ecl is the same with Wells
const WellConnections& completion_set = well_ecl.getConnections();
// number of segment for this single well
this->segment_state.update(w, SegmentState{np, segment_set});
ws.segments = SegmentState{np, segment_set};
const int well_nseg = segment_set.size();
int n_activeperf = 0;
@ -716,8 +699,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
const auto& perf_rates = perf_data.phase_rates;
std::vector<double> perforation_rates(perf_rates.begin(), perf_rates.end());
auto& segments = this->segments(w);
calculateSegmentRates(segment_inlets, segment_perforations, perforation_rates, np, 0 /* top segment */, segments.rates);
calculateSegmentRates(segment_inlets, segment_perforations, perforation_rates, np, 0 /* top segment */, ws.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
@ -726,7 +708,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
// improved during the solveWellEq process
{
// top segment is always the first one, and its pressure is the well bhp
auto& segment_pressure = this->segments(w).pressure;
auto& segment_pressure = ws.segments.pressure;
segment_pressure[0] = ws.bhp;
const auto& perf_press = perf_data.pressure;
for (int seg = 1; seg < well_nseg; ++seg) {
@ -755,7 +737,8 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
continue;
const auto& wname = well.name();
if (prev_well_state->segment_state.has(wname)) {
if (prev_well_state->has(wname)) {
auto& ws = this->well(w);
const auto& prev_ws = prev_well_state->well(wname);
if (prev_ws.status == Well::Status::SHUT) {
continue;
@ -764,7 +747,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
// 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);
ws.segments = prev_ws.segments;
}
}
}
@ -834,7 +817,7 @@ void WellState::shutWell(int well_index)
this->wellrates_[well_index].assign(np, 0);
auto& resv = this->well_reservoir_rates_[well_index];
auto& wpi = this->productivity_index_[well_index];
auto& wpi = ws.productivity_index;
for (int p = 0; p < np; ++p) {
resv[p] = 0.0;
@ -931,7 +914,7 @@ WellState::reportSegmentResults(const PhaseUsage& pu,
const int seg_ix,
const int seg_no) const
{
const auto& segments = this->segments(well_id);
const auto& segments = this->well(well_id).segments;
if (segments.empty())
return {};
@ -997,14 +980,14 @@ int WellState::wellIndex(const std::string& wellName) const
int WellState::numSegments(const int well_id) const
{
const auto& segments = this->segments(well_id);
return segments.size();
const auto& ws = this->well(well_id);
return ws.segments.size();
}
int WellState::segmentNumber(const int well_id, const int seg_id) const
{
const auto& segments = this->segment_state[well_id];
return segments.segment_number()[seg_id];
const auto& ws = this->well(well_id);
return ws.segments.segment_number()[seg_id];
}
void WellState::updateWellsDefaultALQ( const std::vector<Well>& wells_ecl )
@ -1033,7 +1016,7 @@ void WellState::resetConnectionTransFactors(const int 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)) {
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 "
+ std::to_string(conn_index)

View File

@ -161,50 +161,6 @@ public:
return well_reservoir_rates_[well_index];
}
double& wellDissolvedGasRates(std::size_t well_index)
{
return well_dissolved_gas_rates_[well_index];
}
double& wellVaporizedOilRates(std::size_t well_index)
{
return well_vaporized_oil_rates_[well_index];
}
const SegmentState& segments(const std::size_t well_index) const {
return this->segment_state[well_index];
}
SegmentState& segments(const std::size_t well_index) {
return this->segment_state[well_index];
}
const SegmentState& segments(const std::string& wname) const {
return this->segment_state[wname];
}
SegmentState& segments(const std::string& wname) {
return this->segment_state[wname];
}
std::vector<double>& productivityIndex(std::size_t well_index) {
return this->productivity_index_[well_index];
}
const std::vector<double>& productivityIndex(std::size_t well_index) const {
return this->productivity_index_[well_index];
}
std::vector<double>& wellPotentials(std::size_t well_index) {
return this->well_potentials_[well_index];
}
const std::vector<double>& wellPotentials(std::size_t well_index) const {
return this->well_potentials_[well_index];
}
template<class Comm>
void communicateGroupRates(const Comm& comm);
@ -341,7 +297,9 @@ public:
return this->wells_[well_name];
}
bool has(const std::string& well_name) const {
return this->wells_.has(well_name);
}
private:
WellMapType wellMap_;
@ -351,11 +309,11 @@ private:
std::optional<GlobalWellInfo> global_well_info;
ALQState alq_state;
bool do_glift_optimization_;
PhaseUsage phase_usage_;
WellContainer<SingleWellState> wells_;
WellContainer<const ParallelWellInfo*> parallel_well_info_;
WellContainer<std::vector<double>> wellrates_;
PhaseUsage phase_usage_;
WellContainer<PerfData> perfdata;
// The well_rates variable is defined for all wells on all processors. The
@ -367,23 +325,6 @@ private:
// or voidage phase rates
WellContainer<std::vector<double>> well_reservoir_rates_;
// dissolved gas rates or solution gas production rates
// should be zero for injection wells
WellContainer<double> well_dissolved_gas_rates_;
// vaporized oil rates or solution oil producation rates
// should be zero for injection wells
WellContainer<double> well_vaporized_oil_rates_;
WellContainer<SegmentState> segment_state;
// Productivity Index
WellContainer<std::vector<double>> productivity_index_;
// Well potentials
WellContainer<std::vector<double>> well_potentials_;
data::Segment
reportSegmentResults(const PhaseUsage& pu,
const int well_id,

View File

@ -175,7 +175,8 @@ namespace {
}
const auto pressTop = 100.0 * wellID;
auto& segments = wstate.segments(wellID);
auto& ws = wstate.well(wellID);
auto& segments = ws.segments;
segments.pressure[0] = pressTop;
const auto& segSet = well.getSegments();
@ -215,7 +216,8 @@ namespace {
}
const auto rateTop = 1000.0 * wellID;
auto& segments = wstate.segments(wellID);
auto& ws = wstate.well(wellID);
auto& segments = ws.segments;
auto& segRates = segments.rates;
if (wat) { segRates[iw] = rateTop; }
@ -250,8 +252,9 @@ BOOST_AUTO_TEST_CASE(Linearisation)
std::vector<Opm::ParallelWellInfo> pinfos;
const auto wstate = buildWellState(setup, tstep, pinfos);
const auto& ws = wstate.well("PROD01");
BOOST_CHECK_EQUAL(wstate.segments("PROD01").size(), 6);
BOOST_CHECK_EQUAL(ws.segments.size(), 6);
const auto& wells = setup.sched.getWellsatEnd();
BOOST_CHECK_EQUAL(wells.size(), 2);
@ -468,9 +471,6 @@ BOOST_AUTO_TEST_CASE(TESTWellContainer) {
BOOST_CHECK_EQUAL(wc.size(), 0);
BOOST_CHECK_THROW(wc3.update("NO_SUCH_WELL", -1), std::exception);
BOOST_CHECK_THROW(wc3.update(100, -1), std::exception);
BOOST_CHECK(wc3.has("W2"));
BOOST_CHECK(!wc3.has("NO_SUCH_WELL"));
@ -515,9 +515,9 @@ BOOST_AUTO_TEST_CASE(TESTSegmentState2) {
std::vector<Opm::ParallelWellInfo> pinfo;
const auto wstate = buildWellState(setup, 0, pinfo);
const auto& well = setup.sched.getWell("PROD01", 0);
const auto& ws = wstate.well("PROD01");
BOOST_CHECK_THROW(wstate.segments(100), std::exception);
auto segments = wstate.segments(1); // PROD01 is well 1
auto segments = ws.segments;
BOOST_CHECK_EQUAL(segments.pressure.size(), well.getSegments().size());
segments.pressure_drop_friction[0] = 1;
@ -577,9 +577,9 @@ GAS
BOOST_AUTO_TEST_CASE(TestSingleWellState) {
Opm::SingleWellState ws1(true, 1);
Opm::SingleWellState ws2(true, 2);
Opm::SingleWellState ws3(false, 3);
Opm::SingleWellState ws1(true, 3, 1);
Opm::SingleWellState ws2(true, 3, 2);
Opm::SingleWellState ws3(false, 3, 3);
ws1.bhp = 100;
ws1.thp = 200;