mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-01-02 12:36:54 -06:00
Merge pull request #3485 from joakim-hove/single-well-state3
Single well state3
This commit is contained in:
commit
076c274352
@ -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...
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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]];
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user