Add trivial class SingleWellState with bhp and thp

This commit is contained in:
Joakim Hove 2021-08-03 20:05:14 +02:00
parent 3d3e9cca1b
commit a54daf75e8
15 changed files with 194 additions and 67 deletions

View File

@ -70,6 +70,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/wells/ParallelWellInfo.cpp
opm/simulators/wells/PerfData.cpp
opm/simulators/wells/SegmentState.cpp
opm/simulators/wells/SingleWellState.cpp
opm/simulators/wells/StandardWellEval.cpp
opm/simulators/wells/StandardWellGeneric.cpp
opm/simulators/wells/TargetCalculator.cpp
@ -307,6 +308,7 @@ list (APPEND PUBLIC_HEADER_FILES
opm/simulators/wells/PerforationData.hpp
opm/simulators/wells/RateConverter.hpp
opm/simulators/utils/readDeck.hpp
opm/simulators/wells/SingleWellState.hpp
opm/simulators/wells/TargetCalculator.hpp
opm/simulators/wells/WellConnectionAuxiliaryModule.hpp
opm/simulators/wells/WellState.hpp

View File

@ -172,8 +172,9 @@ loadRestartData(const data::Wells& rst_wells,
for( const auto& wm : well_state.wellMap() ) {
const auto well_index = wm.second[ 0 ];
const auto& rst_well = rst_wells.at( wm.first );
well_state.update_thp(well_index, rst_well.thp);
well_state.update_bhp(well_index, rst_well.bhp);
auto& ws = well_state.well(well_index);
ws.bhp = rst_well.bhp;
ws.thp = rst_well.thp;
well_state.update_temperature(well_index, rst_well.temperature);
if (rst_well.current_control.isProducer) {

View File

@ -1474,7 +1474,8 @@ updateThp(WellState& well_state,
// When there is no vaild VFP table provided, we set the thp to be zero.
if (!baseif_.isVFPActive(deferred_logger) || baseif_.wellIsStopped()) {
well_state.update_thp(baseif_.indexOfWell(), 0.);
auto& well = well_state.well(baseif_.indexOfWell());
well.thp = 0;
return;
}
@ -1492,9 +1493,9 @@ updateThp(WellState& well_state,
rates[ Gas ] = well_state.wellRates(baseif_.indexOfWell())[pu.phase_pos[ Gas ] ];
}
const double bhp = well_state.bhp(baseif_.indexOfWell());
well_state.update_thp(baseif_.indexOfWell(), this->calculateThpFromBhp(rates, bhp, rho, deferred_logger));
auto& well = well_state.well(baseif_.indexOfWell());
const double bhp = well.bhp;
well.thp = this->calculateThpFromBhp(rates, bhp, rho, deferred_logger);
}
template<typename FluidSystem, typename Indices, typename Scalar>
@ -1614,6 +1615,7 @@ 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& segment_rates = segments.rates;
auto& segment_pressure = segments.pressure;
@ -1658,7 +1660,7 @@ updateWellStateFromPrimaryVariables(WellState& well_state,
// update the segment pressure
segment_pressure[seg] = primary_variables_[seg][SPres];
if (seg == 0) { // top segment
well_state.update_bhp(baseif_.indexOfWell(), segment_pressure[seg]);
well.bhp = segment_pressure[seg];
}
}
updateThp(well_state, rho, deferred_logger);

View File

@ -136,8 +136,9 @@ void
MultisegmentWellGeneric<Scalar>::
scaleSegmentPressuresWithBhp(WellState& well_state) const
{
auto& well = well_state.well(baseif_.indexOfWell());
auto& segments = well_state.segments(baseif_.indexOfWell());
auto bhp = well_state.bhp(baseif_.indexOfWell());
const auto bhp = well.bhp;
segments.scale_pressure(bhp);
}

View File

@ -340,6 +340,7 @@ namespace Opm
// store a copy of the well state, we don't want to update the real well state
WellState well_state_copy = ebosSimulator.problem().wellModel().wellState();
const auto& group_state = ebosSimulator.problem().wellModel().groupState();
auto& ws = well_state_copy.well(this->index_of_well_);
// Get the current controls.
const auto& summary_state = ebosSimulator.vanguard().summaryState();
@ -358,7 +359,7 @@ namespace Opm
prod_controls.bhp_limit = bhp;
well_state_copy.currentProductionControl(index_of_well_, Well::ProducerCMode::BHP);
}
well_state_copy.update_bhp(well_copy.index_of_well_, bhp);
ws.bhp = bhp;
well_copy.scaleSegmentPressuresWithBhp(well_state_copy);
// initialized the well rates with the potentials i.e. the well rates based on bhp

View File

@ -0,0 +1,43 @@
/*
Copyright 2021 Equinor ASA
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <opm/simulators/wells/SingleWellState.hpp>
namespace Opm {
void SingleWellState::init_timestep(const SingleWellState& other) {
this->bhp = other.bhp;
this->thp = other.thp;
}
void SingleWellState::shut() {
this->bhp = 0;
this->thp = 0;
}
void SingleWellState::stop() {
this->thp = 0;
}
}

View File

@ -0,0 +1,42 @@
/*
Copyright 2021 Equinor ASA
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_SINGLE_WELL_STATE_HEADER_INCLUDED
#define OPM_SINGLE_WELL_STATE_HEADER_INCLUDED
namespace Opm {
class SingleWellState {
public:
double bhp{0};
double thp{0};
void init_timestep(const SingleWellState& other);
void shut();
void stop();
};
}
#endif

View File

@ -255,7 +255,7 @@ updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_log
const int well_index = baseif_.indexOfWell();
const int np = baseif_.numPhases();
const auto& pu = baseif_.phaseUsage();
const auto& well = well_state.well(well_index);
// the weighted total well rate
double total_well_rate = 0.0;
for (int p = 0; p < np; ++p) {
@ -339,7 +339,7 @@ updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_log
// BHP
primary_variables_[Bhp] = well_state.bhp(baseif_.indexOfWell());
primary_variables_[Bhp] = well.bhp;
}
template<class FluidSystem, class Indices, class Scalar>
@ -553,10 +553,11 @@ updateThp(WellState& well_state,
static constexpr int Gas = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Gas;
static constexpr int Oil = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Oil;
static constexpr int Water = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Water;
auto& well = well_state.well(baseif_.indexOfWell());
// When there is no vaild VFP table provided, we set the thp to be zero.
if (!baseif_.isVFPActive(deferred_logger) || baseif_.wellIsStopped()) {
well_state.update_thp(baseif_.indexOfWell(), 0);
well.thp = 0;
return;
}
@ -574,13 +575,12 @@ updateThp(WellState& well_state,
rates[ Gas ] = well_state.wellRates(baseif_.indexOfWell())[pu.phase_pos[ Gas ] ];
}
const double bhp = well_state.bhp(baseif_.indexOfWell());
const double bhp = well.bhp;
well_state.update_thp(baseif_.indexOfWell(),
this->calculateThpFromBhp(well_state,
rates,
bhp,
deferred_logger));
well.thp = this->calculateThpFromBhp(well_state,
rates,
bhp,
deferred_logger);
}
template<class FluidSystem, class Indices, class Scalar>
@ -652,7 +652,8 @@ updateWellStateFromPrimaryVariables(WellState& well_state,
F[pu.phase_pos[Gas]] += F_solvent;
}
well_state.update_bhp(baseif_.indexOfWell(), primary_variables_[Bhp]);
auto& well = well_state.well(baseif_.indexOfWell());
well.bhp = primary_variables_[Bhp];
// calculate the phase rates based on the primary variables
// for producers, this is not a problem, while not sure for injectors here

View File

@ -547,6 +547,7 @@ namespace Opm
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_);
if constexpr (has_polymer && Base::has_polymermw) {
if (this->isInjector()) {
// Store the original water flux computed from the reservoir quantities.
@ -694,7 +695,7 @@ namespace Opm
}
// Store the perforation pressure for later usage.
perf_data.pressure[perf] = well_state.bhp(this->index_of_well_) + this->perf_pressure_diffs_[perf];
perf_data.pressure[perf] = ws.bhp + this->perf_pressure_diffs_[perf];
}
@ -1156,7 +1157,7 @@ namespace Opm
const WellState& well_state,
DeferredLogger& deferred_logger)
{
const double bhp = well_state.bhp(index_of_well_);
const double bhp = well_state.well(index_of_well_).bhp;
std::vector<double> well_rates;
computeWellRatesWithBhp(ebos_simulator, bhp, well_rates, deferred_logger);
@ -1211,6 +1212,7 @@ namespace Opm
b_perf.resize(nperf * num_components_);
surf_dens_perf.resize(nperf * num_components_);
const int w = index_of_well_;
const auto& ws = well_state.well(this->index_of_well_);
const bool waterPresent = FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx);
const bool oilPresent = FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx);
@ -1224,7 +1226,7 @@ namespace Opm
// Compute the average pressure in each well block
const auto& perf_press = well_state.perfData(w).pressure;
auto p_above = this->parallel_well_info_.communicateAboveValues(well_state.bhp(w),
auto p_above = this->parallel_well_info_.communicateAboveValues(ws.bhp,
perf_press.data(),
nperf);
@ -1681,6 +1683,7 @@ namespace Opm
// to replace the original one
WellState well_state_copy = ebosSimulator.problem().wellModel().wellState();
const auto& group_state = ebosSimulator.problem().wellModel().groupState();
auto& ws = well_state_copy.well(this->index_of_well_);
// Set current control to bhp, and bhp value in state, modify bhp limit in control object.
if (well_ecl_.isInjector()) {
@ -1688,7 +1691,7 @@ namespace Opm
} else {
well_state_copy.currentProductionControl(index_of_well_, Well::ProducerCMode::BHP);
}
well_state_copy.update_bhp(index_of_well_, bhp);
ws.bhp = bhp;
const double dt = ebosSimulator.timeStepSize();
bool converged = this->iterateWellEquations(ebosSimulator, dt, well_state_copy, group_state, deferred_logger);

View File

@ -61,20 +61,22 @@ public:
return this->m_data.size();
}
void add(const std::string& name, T&& value) {
T& add(const std::string& name, T&& value) {
if (index_map.count(name) != 0)
throw std::logic_error("An object with name: " + name + " already exists in container");
this->index_map.emplace(name, this->m_data.size());
this->m_data.push_back(std::forward<T>(value));
return this->m_data.back();
}
void add(const std::string& name, const T& value) {
T& add(const std::string& name, const T& value) {
if (index_map.count(name) != 0)
throw std::logic_error("An object with name: " + name + " already exists in container");
this->index_map.emplace(name, this->m_data.size());
this->m_data.push_back(value);
return this->m_data.back();
}
bool has(const std::string& name) const {

View File

@ -91,10 +91,11 @@ activeProductionConstraint(const WellState& well_state,
const int well_index = this->index_of_well_;
const auto controls = this->well_ecl_.productionControls(summaryState);
auto currentControl = well_state.currentProductionControl(well_index);
auto& ws = well_state.well(well_index);
if (controls.hasControl(Well::ProducerCMode::BHP) && currentControl != Well::ProducerCMode::BHP) {
const double bhp_limit = controls.bhp_limit;
double current_bhp = well_state.bhp(well_index);
double current_bhp = ws.bhp;
if (bhp_limit > current_bhp)
return Well::ProducerCMode::BHP;
}
@ -164,7 +165,7 @@ activeProductionConstraint(const WellState& well_state,
if (controls.hasControl(Well::ProducerCMode::THP) && currentControl != Well::ProducerCMode::THP) {
const auto& thp = getTHPConstraint(summaryState);
double current_thp = well_state.thp(well_index);
double current_thp = ws.thp;
if (thp > current_thp)
return Well::ProducerCMode::THP;
}
@ -181,6 +182,7 @@ activeInjectionConstraint(const WellState& well_state,
{
const PhaseUsage& pu = this->phaseUsage();
const int well_index = this->index_of_well_;
const auto& ws = well_state.well(well_index);
const auto controls = this->well_ecl_.injectionControls(summaryState);
auto currentControl = well_state.currentInjectionControl(well_index);
@ -188,7 +190,7 @@ activeInjectionConstraint(const WellState& well_state,
if (controls.hasControl(Well::InjectorCMode::BHP) && currentControl != Well::InjectorCMode::BHP)
{
const auto& bhp = controls.bhp_limit;
double current_bhp = well_state.bhp(well_index);
double current_bhp = ws.bhp;
if (bhp < current_bhp)
return Well::InjectorCMode::BHP;
}
@ -241,7 +243,7 @@ activeInjectionConstraint(const WellState& well_state,
if (controls.hasControl(Well::InjectorCMode::THP) && currentControl != Well::InjectorCMode::THP)
{
const auto& thp = getTHPConstraint(summaryState);
double current_thp = well_state.thp(well_index);
double current_thp = ws.thp;
if (thp < current_thp)
return Well::InjectorCMode::THP;
}

View File

@ -599,6 +599,7 @@ namespace Opm
// only bhp and wellRates are used to initilize the primaryvariables for standard wells
const auto& well = this->well_ecl_;
const int well_index = this->index_of_well_;
auto& ws = well_state.well(well_index);
const auto& pu = this->phaseUsage();
const int np = well_state.numPhases();
const auto& summaryState = ebos_simulator.vanguard().summaryState();
@ -608,7 +609,7 @@ namespace Opm
for (int p = 0; p<np; ++p) {
well_state.wellRates(well_index)[p] = 0.0;
}
well_state.update_thp(well_index, 0.0);
ws.thp = 0;
return;
}
@ -663,7 +664,7 @@ namespace Opm
rates[p] = well_state.wellRates(well_index)[p];
}
double bhp = this->calculateBhpFromThp(well_state, rates, well, summaryState, this->getRefDensity(), deferred_logger);
well_state.update_bhp(well_index, bhp);
ws.bhp = bhp;
// if the total rates are negative or zero
// we try to provide a better intial well rate
@ -678,7 +679,7 @@ namespace Opm
}
case Well::InjectorCMode::BHP:
{
well_state.update_bhp(well_index, controls.bhp_limit);
ws.bhp = controls.bhp_limit;
double total_rate = 0.0;
for (int p = 0; p<np; ++p) {
total_rate += well_state.wellRates(well_index)[p];
@ -864,7 +865,7 @@ namespace Opm
}
case Well::ProducerCMode::BHP:
{
well_state.update_bhp(well_index, controls.bhp_limit);
ws.bhp = controls.bhp_limit;
double total_rate = 0.0;
for (int p = 0; p<np; ++p) {
total_rate -= well_state.wellRates(well_index)[p];
@ -886,7 +887,7 @@ namespace Opm
rates[p] = well_state.wellRates(well_index)[p];
}
double bhp = this->calculateBhpFromThp(well_state, rates, well, summaryState, this->getRefDensity(), deferred_logger);
well_state.update_bhp(well_index, bhp);
ws.bhp = bhp;
// if the total rates are negative or zero
// we try to provide a better intial well rate

View File

@ -44,12 +44,11 @@ void WellState::base_init(const std::vector<double>& cellPressures,
this->status_.clear();
this->parallel_well_info_.clear();
this->wellrates_.clear();
this->bhp_.clear();
this->thp_.clear();
this->temperature_.clear();
this->segment_state.clear();
this->well_potentials_.clear();
this->productivity_index_.clear();
this->wells_.clear();
{
// const int nw = wells->number_of_wells;
const int nw = wells_ecl.size();
@ -92,6 +91,7 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
const auto& pu = this->phase_usage_;
const int np = pu.num_phases;
auto& ws = this->wells_.add(well.name(), SingleWellState{});
this->status_.add(well.name(), Well::Status::OPEN);
this->parallel_well_info_.add(well.name(), well_info);
this->wellrates_.add(well.name(), std::vector<double>(np, 0));
@ -99,8 +99,6 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
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->bhp_.add(well.name(), 0.0);
this->thp_.add(well.name(), 0.0);
this->productivity_index_.add(well.name(), std::vector<double>(np, 0));
if ( well.isInjector() )
this->temperature_.add(well.name(), well.injectionControls(summary_state).temperature);
@ -136,9 +134,9 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
// applicable, otherwise assign equal to
// first perforation cell pressure.
if (is_bhp) {
bhp_[w] = bhp_limit;
ws.bhp = bhp_limit;
} else {
bhp_[w] = global_pressure;
ws.bhp = global_pressure;
}
} else if (is_grup) {
// Well under group control.
@ -148,7 +146,7 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
// the well is an injector or producer)
// pressure in first perforation cell.
const double safety_factor = well.isInjector() ? 1.01 : 0.99;
bhp_[w] = safety_factor * global_pressure;
ws.bhp = safety_factor * global_pressure;
} else {
// Open well, under own control:
// 1. Rates: initialize well rates to match
@ -206,10 +204,10 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
// the well is an injector or producer)
// pressure in first perforation cell.
if (is_bhp) {
bhp_[w] = bhp_limit;
ws.bhp = bhp_limit;
} else {
const double safety_factor = well.isInjector() ? 1.01 : 0.99;
bhp_[w] = safety_factor * global_pressure;
ws.bhp = safety_factor * global_pressure;
}
}
@ -219,7 +217,7 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
: prod_controls.hasControl(Well::ProducerCMode::THP);
const double thp_limit = well.isInjector() ? inj_controls.thp_limit : prod_controls.thp_limit;
if (has_thp) {
thp_[w] = thp_limit;
ws.thp = thp_limit;
}
}
@ -356,11 +354,17 @@ void WellState::init(const std::vector<double>& cellPressures,
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);
new_well.init_timestep(prev_well);
if (prevState->status_[oldIndex] == Well::Status::SHUT) {
// Well was shut in previous state, do not use its values.
continue;
@ -371,12 +375,6 @@ void WellState::init(const std::vector<double>& cellPressures,
continue;
}
// bhp
this->update_bhp( newIndex, prevState->bhp( oldIndex ));
// thp
this->update_thp( newIndex, prevState->thp( oldIndex ));
// If new target is set using WCONPROD, WCONINJE etc. we use the new control
if (!this->events_[w].hasEvent(WellState::event_mask)) {
current_injection_controls_[ newIndex ] = prevState->currentInjectionControl(oldIndex);
@ -436,7 +434,7 @@ void WellState::init(const std::vector<double>& cellPressures,
: well.productionControls(summary_state).hasControl(Well::ProducerCMode::THP);
if (!has_thp) {
this->update_thp(w, 0.0);
new_well.thp = 0;
}
}
}
@ -512,6 +510,7 @@ WellState::report(const int* globalCellIdxMap,
{
continue;
}
const auto& ws = this->well(well_index);
const auto& reservoir_rates = this->well_reservoir_rates_[well_index];
const auto& well_potentials = this->well_potentials_[well_index];
@ -519,8 +518,8 @@ WellState::report(const int* globalCellIdxMap,
const auto& wv = this->wellRates(well_index);
data::Well well;
well.bhp = this->bhp(well_index);
well.thp = this->thp( well_index );
well.bhp = ws.bhp;
well.thp = ws.thp;
well.temperature = this->temperature( well_index );
if( pu.phase_used[BlackoilPhases::Aqua] ) {
@ -680,6 +679,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
// what we do here, is to set the segment rates and perforation rates
for (int w = 0; w < nw; ++w) {
const auto& well_ecl = wells_ecl[w];
auto& ws = this->well(w);
if ( well_ecl.isMultiSegment() ) {
const WellSegments& segment_set = well_ecl.getSegments();
@ -748,7 +748,7 @@ void WellState::initWellStateMSWell(const std::vector<Well>& wells_ecl,
{
// top segment is always the first one, and its pressure is the well bhp
auto& segment_pressure = this->segments(w).pressure;
segment_pressure[0] = bhp(w);
segment_pressure[0] = ws.bhp;
const auto& perf_press = perf_data.pressure;
for (int seg = 1; seg < well_nseg; ++seg) {
if ( !segment_perforations[seg].empty() ) {
@ -842,15 +842,16 @@ double WellState::brineWellRate(const int w) const
void WellState::stopWell(int well_index)
{
auto& ws = this->well(well_index);
ws.stop();
this->status_[well_index] = Well::Status::STOP;
this->thp_[well_index] = 0;
}
void WellState::shutWell(int well_index)
{
auto& ws = this->well(well_index);
ws.shut();
this->status_[well_index] = Well::Status::SHUT;
this->thp_[well_index] = 0;
this->bhp_[well_index] = 0;
const int np = numPhases();
this->wellrates_[well_index].assign(np, 0);

View File

@ -22,6 +22,7 @@
#define OPM_WELLSTATEFULLYIMPLICITBLACKOIL_HEADER_INCLUDED
#include <opm/simulators/wells/ALQState.hpp>
#include <opm/simulators/wells/SingleWellState.hpp>
#include <opm/simulators/wells/GlobalWellInfo.hpp>
#include <opm/simulators/wells/SegmentState.hpp>
#include <opm/simulators/wells/WellContainer.hpp>
@ -309,14 +310,6 @@ public:
return this->phase_usage_;
}
/// One bhp pressure per well.
void update_bhp(std::size_t well_index, double value) { bhp_[well_index] = value; }
double bhp(std::size_t well_index) const { return bhp_[well_index]; }
/// One thp pressure per well.
void update_thp(std::size_t well_index, double value) { thp_[well_index] = value; }
double thp(std::size_t well_index) const { return thp_[well_index]; }
/// One temperature per well.
void update_temperature(std::size_t well_index, double value) { temperature_[well_index] = value; }
double temperature(std::size_t well_index) const { return temperature_[well_index]; }
@ -352,6 +345,23 @@ public:
return this->is_producer_[well_index];
}
const SingleWellState& well(std::size_t well_index) const {
return this->wells_[well_index];
}
const SingleWellState& well(const std::string& well_name) const {
return this->wells_[well_name];
}
SingleWellState& well(std::size_t well_index) {
return this->wells_[well_index];
}
SingleWellState& well(const std::string& well_name) {
return this->wells_[well_name];
}
private:
WellMapType wellMap_;
@ -362,10 +372,9 @@ private:
ALQState alq_state;
bool do_glift_optimization_;
WellContainer<SingleWellState> wells_;
WellContainer<Well::Status> status_;
WellContainer<const ParallelWellInfo*> parallel_well_info_;
WellContainer<double> bhp_;
WellContainer<double> thp_;
WellContainer<double> temperature_;
WellContainer<std::vector<double>> wellrates_;
PhaseUsage phase_usage_;

View File

@ -26,6 +26,7 @@
#include <opm/simulators/wells/GlobalWellInfo.hpp>
#include <opm/simulators/wells/ParallelWellInfo.hpp>
#include <opm/simulators/wells/WellState.hpp>
#include <opm/simulators/wells/SingleWellState.hpp>
#include <opm/simulators/wells/SegmentState.hpp>
#include <opm/simulators/wells/WellContainer.hpp>
#include <opm/simulators/wells/PerfData.hpp>
@ -575,5 +576,20 @@ GAS
}
BOOST_AUTO_TEST_CASE(TestSingleWellState) {
Opm::SingleWellState ws1;
Opm::SingleWellState ws2;
ws1.bhp = 100;
ws1.thp = 200;
ws2.init_timestep(ws1);
BOOST_CHECK_EQUAL(ws2.bhp, ws1.bhp);
BOOST_CHECK_EQUAL(ws2.thp, ws1.thp);
}
BOOST_AUTO_TEST_SUITE_END()