mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Add accessor functions to maintain WellState objects in well model
This commit is contained in:
parent
ee20d1c1c1
commit
405b9d2244
@ -33,6 +33,7 @@
|
|||||||
#include <opm/models/utils/propertysystem.hh>
|
#include <opm/models/utils/propertysystem.hh>
|
||||||
#include <opm/models/utils/alignedallocator.hh>
|
#include <opm/models/utils/alignedallocator.hh>
|
||||||
|
|
||||||
|
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
|
||||||
#include <opm/material/fluidstates/CompositionalFluidState.hpp>
|
#include <opm/material/fluidstates/CompositionalFluidState.hpp>
|
||||||
#include <opm/material/densead/Evaluation.hpp>
|
#include <opm/material/densead/Evaluation.hpp>
|
||||||
#include <opm/material/densead/Math.hpp>
|
#include <opm/material/densead/Math.hpp>
|
||||||
@ -1410,6 +1411,36 @@ protected:
|
|||||||
/ rhoWaterSurface;
|
/ rhoWaterSurface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WellStateFullyImplicitBlackoil& wellState() const
|
||||||
|
{
|
||||||
|
throw std::logic_error("wellState() method not implemented for class eclpeacemanwell");
|
||||||
|
}
|
||||||
|
|
||||||
|
WellStateFullyImplicitBlackoil& wellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("wellState() method not implemented for class eclpeacemanwell");
|
||||||
|
}
|
||||||
|
|
||||||
|
void commitWellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("commitWellState() method not implemented for class eclpeacemanwell");
|
||||||
|
}
|
||||||
|
|
||||||
|
void commitWellState(WellStateFullyImplicitBlackoil well_state)
|
||||||
|
{
|
||||||
|
throw std::logic_error("commitWellState() method not implemented for class eclpeacemanwell");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetWellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("resetWellState() method not implemented for class eclpeacemanwell");
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateNupcolWellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("updateNupcolWellState() method not implemented for class eclpeacemanwell");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updateEclWell(int, int)
|
updateEclWell(int, int)
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Events.hpp>
|
||||||
|
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellConnections.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
|
||||||
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
#include <opm/parser/eclipse/EclipseState/Schedule/TimeMap.hpp>
|
||||||
@ -619,6 +620,35 @@ public:
|
|||||||
// not implemented
|
// not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const WellStateFullyImplicitBlackoil& wellState() const
|
||||||
|
{
|
||||||
|
throw std::logic_error("wellState() method not implemented for class eclwellmanager");
|
||||||
|
}
|
||||||
|
|
||||||
|
WellStateFullyImplicitBlackoil& wellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("wellState() method not implemented for class eclwellmanager");
|
||||||
|
}
|
||||||
|
|
||||||
|
void commitWellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("commitWellState() method not implemented for class eclwellmanager");
|
||||||
|
}
|
||||||
|
|
||||||
|
void commitWellState(WellStateFullyImplicitBlackoil well_state)
|
||||||
|
{
|
||||||
|
throw std::logic_error("commitWellState() method not implemented for class eclwellmanager");
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetWellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("resetWellState() method not implemented for class eclwellmanager");
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateNupcolWellState()
|
||||||
|
{
|
||||||
|
throw std::logic_error("updateNupcolWellState() method not implemented for class eclwellmanager");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updateEclWell(int, int)
|
updateEclWell(int, int)
|
||||||
|
@ -215,14 +215,113 @@ namespace Opm {
|
|||||||
return grp_nwrk_values;
|
return grp_nwrk_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
The dynamic state of the well model is maintained with an instance
|
||||||
|
of the WellStateFullyImplicitBlackoil class. Currently we have
|
||||||
|
three different wellstate instances:
|
||||||
|
|
||||||
|
1. The currently active wellstate is in the active_well_state_
|
||||||
|
member. That is the state which is mutated by the simulator.
|
||||||
|
|
||||||
|
2. In the case timestep fails to converge and we must go back and
|
||||||
|
try again with a smaller timestep we need to recover the last
|
||||||
|
valid wellstate. This is maintained with the
|
||||||
|
last_valid_well_state_ member and the functions
|
||||||
|
commitWellState() and resetWellState().
|
||||||
|
|
||||||
|
3. For the NUPCOL functionality we should either use the
|
||||||
|
currently active wellstate or a wellstate frozen at max
|
||||||
|
nupcol iterations. This is handled with the member
|
||||||
|
nupcol_well_state_ and the initNupcolWellState() function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Immutable version of the currently active wellstate.
|
||||||
|
*/
|
||||||
|
const WellStateFullyImplicitBlackoil& wellState() const
|
||||||
|
{
|
||||||
|
return this->active_well_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Mutable version of the currently active wellstate.
|
||||||
|
*/
|
||||||
|
WellStateFullyImplicitBlackoil& wellState()
|
||||||
|
{
|
||||||
|
return this->active_well_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will return the last good wellstate. This is typcially used when
|
||||||
|
initializing a new report step where the Schedule object might
|
||||||
|
have introduced new wells. The wellstate returned by
|
||||||
|
prevWellState() must have been stored with the commitWellState()
|
||||||
|
function first.
|
||||||
|
*/
|
||||||
|
const WellStateFullyImplicitBlackoil& prevWellState() const
|
||||||
|
{
|
||||||
|
return this->last_valid_well_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will return the currently active nupcolWellState; must initialize
|
||||||
|
the internal nupcol wellstate with initNupcolWellState() first.
|
||||||
|
*/
|
||||||
|
const WellStateFullyImplicitBlackoil& nupcolWellState() const
|
||||||
|
{
|
||||||
|
return this->nupcol_well_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will assign the internal member last_valid_well_state_ to the
|
||||||
|
current value of the this->active_well_state_. The state stored
|
||||||
|
with storeWellState() can then subsequently be recovered with the
|
||||||
|
resetWellState() method.
|
||||||
|
*/
|
||||||
|
void commitWellState()
|
||||||
|
{
|
||||||
|
this->last_valid_well_state_ = this->active_well_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will store a copy of the input argument well_state in the
|
||||||
|
last_valid_well_state_ member, that state can then be recovered
|
||||||
|
with a subsequent call to resetWellState().
|
||||||
|
*/
|
||||||
|
void commitWellState(WellStateFullyImplicitBlackoil well_state)
|
||||||
|
{
|
||||||
|
this->last_valid_well_state_ = std::move(well_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will update the internal variable active_well_state_ to whatever
|
||||||
|
was stored in the last_valid_well_state_ member. This function
|
||||||
|
works in pair with commitWellState() which should be called first.
|
||||||
|
*/
|
||||||
|
void resetWellState()
|
||||||
|
{
|
||||||
|
this->active_well_state_ = this->last_valid_well_state_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Will store the current active wellstate in the nupcol_well_state_
|
||||||
|
member. This can then be subsequently retrieved with accessor
|
||||||
|
nupcolWellState().
|
||||||
|
*/
|
||||||
|
void updateNupcolWellState()
|
||||||
|
{
|
||||||
|
this->nupcol_well_state_ = this->active_well_state_;
|
||||||
|
}
|
||||||
|
|
||||||
Opm::data::Wells wellData() const
|
Opm::data::Wells wellData() const
|
||||||
{
|
{
|
||||||
auto wsrpt = well_state_
|
auto wsrpt = this->wellState().report(phase_usage_, Opm::UgGridHelpers::globalCell(grid()),
|
||||||
.report(phase_usage_, Opm::UgGridHelpers::globalCell(grid()),
|
[this](const int well_ndex) -> bool
|
||||||
[this](const int well_ndex) -> bool
|
{
|
||||||
{
|
return this->wasDynamicallyShutThisTimeStep(well_ndex);
|
||||||
return this->wasDynamicallyShutThisTimeStep(well_ndex);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
this->assignWellGuideRates(wsrpt);
|
this->assignWellGuideRates(wsrpt);
|
||||||
this->assignShutConnections(wsrpt);
|
this->assignShutConnections(wsrpt);
|
||||||
@ -247,13 +346,6 @@ namespace Opm {
|
|||||||
// Check if well equations is converged.
|
// Check if well equations is converged.
|
||||||
ConvergenceReport getWellConvergence(const std::vector<Scalar>& B_avg, const bool checkGroupConvergence = false) const;
|
ConvergenceReport getWellConvergence(const std::vector<Scalar>& B_avg, const bool checkGroupConvergence = false) const;
|
||||||
|
|
||||||
// return the internal well state, ignore the passed one.
|
|
||||||
// Used by the legacy code to make it compatible with the legacy well models.
|
|
||||||
const WellState& wellState(const WellState& well_state OPM_UNUSED) const;
|
|
||||||
|
|
||||||
// return the internal well state
|
|
||||||
const WellState& wellState() const;
|
|
||||||
|
|
||||||
const SimulatorReportSingle& lastReport() const;
|
const SimulatorReportSingle& lastReport() const;
|
||||||
|
|
||||||
void addWellContributions(SparseMatrixAdapter& jacobian) const
|
void addWellContributions(SparseMatrixAdapter& jacobian) const
|
||||||
@ -279,6 +371,8 @@ namespace Opm {
|
|||||||
double wellPI(const int well_index) const;
|
double wellPI(const int well_index) const;
|
||||||
double wellPI(const std::string& well_name) const;
|
double wellPI(const std::string& well_name) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Simulator& ebosSimulator_;
|
Simulator& ebosSimulator_;
|
||||||
|
|
||||||
@ -323,9 +417,6 @@ namespace Opm {
|
|||||||
|
|
||||||
WellInterfacePtr createWellForWellTest(const std::string& well_name, const int report_step, Opm::DeferredLogger& deferred_logger) const;
|
WellInterfacePtr createWellForWellTest(const std::string& well_name, const int report_step, Opm::DeferredLogger& deferred_logger) const;
|
||||||
|
|
||||||
WellState well_state_;
|
|
||||||
WellState previous_well_state_;
|
|
||||||
WellState well_state_nupcol_;
|
|
||||||
|
|
||||||
const ModelParameters param_;
|
const ModelParameters param_;
|
||||||
bool terminal_output_;
|
bool terminal_output_;
|
||||||
@ -526,6 +617,16 @@ namespace Opm {
|
|||||||
data::GroupData& gdata) const;
|
data::GroupData& gdata) const;
|
||||||
|
|
||||||
void computeWellTemperature();
|
void computeWellTemperature();
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
The various wellState members should be accessed and modified
|
||||||
|
through the accessor functions wellState(), prevWellState(),
|
||||||
|
commitWellState(), resetWellState(), nupcolWellState() and
|
||||||
|
updateNupcolWellState().
|
||||||
|
*/
|
||||||
|
WellState active_well_state_;
|
||||||
|
WellState last_valid_well_state_;
|
||||||
|
WellState nupcol_well_state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,11 +268,11 @@ namespace Opm {
|
|||||||
|
|
||||||
// handling MS well related
|
// handling MS well related
|
||||||
if (param_.use_multisegment_well_&& anyMSWellOpenLocal()) { // if we use MultisegmentWell model
|
if (param_.use_multisegment_well_&& anyMSWellOpenLocal()) { // if we use MultisegmentWell model
|
||||||
well_state_.initWellStateMSWell(wells_ecl_, phase_usage_, &previous_well_state_);
|
this->wellState().initWellStateMSWell(wells_ecl_, phase_usage_, &this->prevWellState());
|
||||||
}
|
}
|
||||||
|
|
||||||
const Group& fieldGroup = schedule().getGroup("FIELD", timeStepIdx);
|
const Group& fieldGroup = schedule().getGroup("FIELD", timeStepIdx);
|
||||||
WellGroupHelpers::setCmodeGroup(fieldGroup, schedule(), summaryState, timeStepIdx, well_state_);
|
WellGroupHelpers::setCmodeGroup(fieldGroup, schedule(), summaryState, timeStepIdx, this->wellState());
|
||||||
|
|
||||||
// Compute reservoir volumes for RESV controls.
|
// Compute reservoir volumes for RESV controls.
|
||||||
rateConverter_.reset(new RateConverterType (phase_usage_,
|
rateConverter_.reset(new RateConverterType (phase_usage_,
|
||||||
@ -289,8 +289,8 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the previous well state. This is used to restart failed steps.
|
// Store the current well state, to be able to recover in the case of failed iterations
|
||||||
previous_well_state_ = well_state_;
|
this->commitWellState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -305,8 +305,8 @@ namespace Opm {
|
|||||||
|
|
||||||
Opm::DeferredLogger local_deferredLogger;
|
Opm::DeferredLogger local_deferredLogger;
|
||||||
|
|
||||||
well_state_ = previous_well_state_;
|
this->resetWellState();
|
||||||
well_state_.disableGliftOptimization();
|
this->wellState().disableGliftOptimization();
|
||||||
updateAndCommunicateGroupData();
|
updateAndCommunicateGroupData();
|
||||||
const int reportStepIdx = ebosSimulator_.episodeIndex();
|
const int reportStepIdx = ebosSimulator_.episodeIndex();
|
||||||
const double simulationTime = ebosSimulator_.time();
|
const double simulationTime = ebosSimulator_.time();
|
||||||
@ -383,7 +383,7 @@ namespace Opm {
|
|||||||
// nonzero phase anyway.
|
// nonzero phase anyway.
|
||||||
for (auto& well : well_container_) {
|
for (auto& well : well_container_) {
|
||||||
if (well->isProducer()) {
|
if (well->isProducer()) {
|
||||||
well->updateWellStateRates(ebosSimulator_, well_state_, local_deferredLogger);
|
well->updateWellStateRates(ebosSimulator_, this->wellState(), local_deferredLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,9 +393,9 @@ namespace Opm {
|
|||||||
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
||||||
std::vector<double> pot(numPhases(), 0.0);
|
std::vector<double> pot(numPhases(), 0.0);
|
||||||
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
|
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
|
||||||
WellGroupHelpers::updateGuideRateForProductionGroups(fieldGroup, schedule(), phase_usage_, reportStepIdx, simulationTime, well_state_, comm, guideRate_.get(), pot);
|
WellGroupHelpers::updateGuideRateForProductionGroups(fieldGroup, schedule(), phase_usage_, reportStepIdx, simulationTime, this->wellState(), comm, guideRate_.get(), pot);
|
||||||
WellGroupHelpers::updateGuideRatesForInjectionGroups(fieldGroup, schedule(), summaryState, phase_usage_, reportStepIdx, well_state_, guideRate_.get(), local_deferredLogger);
|
WellGroupHelpers::updateGuideRatesForInjectionGroups(fieldGroup, schedule(), summaryState, phase_usage_, reportStepIdx, this->wellState(), guideRate_.get(), local_deferredLogger);
|
||||||
WellGroupHelpers::updateGuideRatesForWells(schedule(), phase_usage_, reportStepIdx, simulationTime, well_state_, comm, guideRate_.get());
|
WellGroupHelpers::updateGuideRatesForWells(schedule(), phase_usage_, reportStepIdx, simulationTime, this->wellState(), comm, guideRate_.get());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Compute initial well solution for new wells and injectors that change injection type i.e. WAG.
|
// Compute initial well solution for new wells and injectors that change injection type i.e. WAG.
|
||||||
@ -408,8 +408,8 @@ namespace Opm {
|
|||||||
const bool event = report_step_starts_ && events.hasEvent(well->name(), effective_events_mask);
|
const bool event = report_step_starts_ && events.hasEvent(well->name(), effective_events_mask);
|
||||||
if (event) {
|
if (event) {
|
||||||
try {
|
try {
|
||||||
well->calculateExplicitQuantities(ebosSimulator_, well_state_, local_deferredLogger);
|
well->calculateExplicitQuantities(ebosSimulator_, this->wellState(), local_deferredLogger);
|
||||||
well->solveWellEquation(ebosSimulator_, well_state_, local_deferredLogger);
|
well->solveWellEquation(ebosSimulator_, this->wellState(), local_deferredLogger);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
const std::string msg = "Compute initial well solution for new well " + well->name() + " failed. Continue with zero initial rates";
|
const std::string msg = "Compute initial well solution for new well " + well->name() + " failed. Continue with zero initial rates";
|
||||||
local_deferredLogger.warning("WELL_INITIAL_SOLVE_FAILED", msg);
|
local_deferredLogger.warning("WELL_INITIAL_SOLVE_FAILED", msg);
|
||||||
@ -483,7 +483,7 @@ namespace Opm {
|
|||||||
const WellTestConfig::Reason testing_reason = testWell.second;
|
const WellTestConfig::Reason testing_reason = testWell.second;
|
||||||
|
|
||||||
well->wellTesting(ebosSimulator_, simulationTime, timeStepIdx,
|
well->wellTesting(ebosSimulator_, simulationTime, timeStepIdx,
|
||||||
testing_reason, well_state_, wellTestState_, deferred_logger);
|
testing_reason, this->wellState(), wellTestState_, deferred_logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,7 +534,7 @@ namespace Opm {
|
|||||||
Opm::DeferredLogger local_deferredLogger;
|
Opm::DeferredLogger local_deferredLogger;
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
if (getPropValue<TypeTag, Properties::EnablePolymerMW>() && well->isInjector()) {
|
if (getPropValue<TypeTag, Properties::EnablePolymerMW>() && well->isInjector()) {
|
||||||
well->updateWaterThroughput(dt, well_state_);
|
well->updateWaterThroughput(dt, this->wellState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateWellTestState(simulationTime, wellTestState_);
|
updateWellTestState(simulationTime, wellTestState_);
|
||||||
@ -554,11 +554,11 @@ namespace Opm {
|
|||||||
|
|
||||||
// check group sales limits at the end of the timestep
|
// check group sales limits at the end of the timestep
|
||||||
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
|
const Group& fieldGroup = schedule().getGroup("FIELD", reportStepIdx);
|
||||||
checkGconsaleLimits(fieldGroup, well_state_, local_deferredLogger);
|
checkGconsaleLimits(fieldGroup, this->wellState(), local_deferredLogger);
|
||||||
|
|
||||||
this->calculateProductivityIndexValues(local_deferredLogger);
|
this->calculateProductivityIndexValues(local_deferredLogger);
|
||||||
|
|
||||||
previous_well_state_ = well_state_;
|
this->commitWellState();
|
||||||
|
|
||||||
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
|
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
|
||||||
if (terminal_output_) {
|
if (terminal_output_) {
|
||||||
@ -629,12 +629,11 @@ namespace Opm {
|
|||||||
const auto phaseUsage = phaseUsageFromDeck(eclState());
|
const auto phaseUsage = phaseUsageFromDeck(eclState());
|
||||||
const size_t numCells = Opm::UgGridHelpers::numCells(grid());
|
const size_t numCells = Opm::UgGridHelpers::numCells(grid());
|
||||||
const bool handle_ms_well = (param_.use_multisegment_well_ && anyMSWellOpenLocal());
|
const bool handle_ms_well = (param_.use_multisegment_well_ && anyMSWellOpenLocal());
|
||||||
well_state_.resize(wells_ecl_, local_parallel_well_info_, schedule(), handle_ms_well, numCells, phaseUsage, well_perf_data_, summaryState, globalNumWells); // Resize for restart step
|
this->wellState().resize(wells_ecl_, local_parallel_well_info_, schedule(), handle_ms_well, numCells, phaseUsage, well_perf_data_, summaryState, globalNumWells); // Resize for restart step
|
||||||
wellsToState(restartValues.wells, restartValues.grp_nwrk, phaseUsage, handle_ms_well, well_state_);
|
wellsToState(restartValues.wells, restartValues.grp_nwrk, phaseUsage, handle_ms_well, this->wellState());
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_well_state_ = well_state_;
|
this->commitWellState();
|
||||||
|
|
||||||
initial_step_ = false;
|
initial_step_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,9 +756,9 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state_.init(cellPressures, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx,
|
this->wellState().init(cellPressures, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx,
|
||||||
&previous_well_state_, phase_usage_, well_perf_data_,
|
&this->prevWellState(), phase_usage_, well_perf_data_,
|
||||||
summaryState, globalNumWells);
|
summaryState, globalNumWells);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -792,7 +791,7 @@ namespace Opm {
|
|||||||
// Due to ACTIONX the well might have been closed behind our back.
|
// Due to ACTIONX the well might have been closed behind our back.
|
||||||
if (well_ecl.getStatus() != Well::Status::SHUT) {
|
if (well_ecl.getStatus() != Well::Status::SHUT) {
|
||||||
this->closed_this_step_.insert(well_name);
|
this->closed_this_step_.insert(well_name);
|
||||||
well_state_.shutWell(w);
|
this->wellState().shutWell(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -802,13 +801,13 @@ namespace Opm {
|
|||||||
if (this->wellTestState_.hasWellClosed(well_name)) {
|
if (this->wellTestState_.hasWellClosed(well_name)) {
|
||||||
// TODO: more checking here, to make sure this standard more specific and complete
|
// TODO: more checking here, to make sure this standard more specific and complete
|
||||||
// maybe there is some WCON keywords will not open the well
|
// maybe there is some WCON keywords will not open the well
|
||||||
if (well_state_.effectiveEventsOccurred(w)) {
|
if (this->wellState().effectiveEventsOccurred(w)) {
|
||||||
if (wellTestState_.lastTestTime(well_name) == ebosSimulator_.time()) {
|
if (wellTestState_.lastTestTime(well_name) == ebosSimulator_.time()) {
|
||||||
// The well was shut this timestep, we are most likely retrying
|
// The well was shut this timestep, we are most likely retrying
|
||||||
// a timestep without the well in question, after it caused
|
// a timestep without the well in question, after it caused
|
||||||
// repeated timestep cuts. It should therefore not be opened,
|
// repeated timestep cuts. It should therefore not be opened,
|
||||||
// even if it was new or received new targets this report step.
|
// even if it was new or received new targets this report step.
|
||||||
well_state_.setEffectiveEventsOccurred(w, false);
|
this->wellState().setEffectiveEventsOccurred(w, false);
|
||||||
} else {
|
} else {
|
||||||
wellTestState_.openWell(well_name);
|
wellTestState_.openWell(well_name);
|
||||||
}
|
}
|
||||||
@ -823,11 +822,11 @@ namespace Opm {
|
|||||||
{
|
{
|
||||||
if (well_ecl.getAutomaticShutIn()) {
|
if (well_ecl.getAutomaticShutIn()) {
|
||||||
// shut wells are not added to the well container
|
// shut wells are not added to the well container
|
||||||
well_state_.shutWell(w);
|
this->wellState().shutWell(w);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// stopped wells are added to the container but marked as stopped
|
// stopped wells are added to the container but marked as stopped
|
||||||
well_state_.stopWell(w);
|
this->wellState().stopWell(w);
|
||||||
wellIsStopped = true;
|
wellIsStopped = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -874,13 +873,13 @@ namespace Opm {
|
|||||||
if (zero_rate_control) {
|
if (zero_rate_control) {
|
||||||
// Treat as shut, do not add to container.
|
// Treat as shut, do not add to container.
|
||||||
local_deferredLogger.info(" Well shut due to zero rate control and disallowing crossflow: " + well_ecl.name());
|
local_deferredLogger.info(" Well shut due to zero rate control and disallowing crossflow: " + well_ecl.name());
|
||||||
well_state_.shutWell(w);
|
this->wellState().shutWell(w);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (well_status == Well::Status::STOP) {
|
if (well_status == Well::Status::STOP) {
|
||||||
well_state_.stopWell(w);
|
this->wellState().stopWell(w);
|
||||||
wellIsStopped = true;
|
wellIsStopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,7 +947,7 @@ namespace Opm {
|
|||||||
this->numComponents(),
|
this->numComponents(),
|
||||||
this->numPhases(),
|
this->numPhases(),
|
||||||
wellID,
|
wellID,
|
||||||
this->well_state_.firstPerfIndex()[wellID],
|
this->wellState().firstPerfIndex()[wellID],
|
||||||
perf_data);
|
perf_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,15 +1020,15 @@ namespace Opm {
|
|||||||
|
|
||||||
if (param_.solve_welleq_initially_ && iterationIdx == 0) {
|
if (param_.solve_welleq_initially_ && iterationIdx == 0) {
|
||||||
for (auto& well : well_container_) {
|
for (auto& well : well_container_) {
|
||||||
well->solveWellEquation(ebosSimulator_, well_state_, local_deferredLogger);
|
well->solveWellEquation(ebosSimulator_, this->wellState(), local_deferredLogger);
|
||||||
}
|
}
|
||||||
updateWellControls(local_deferredLogger, /* check group controls */ false);
|
updateWellControls(local_deferredLogger, /* check group controls */ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
gliftDebug("assemble() : running assembleWellEq()..", local_deferredLogger);
|
gliftDebug("assemble() : running assembleWellEq()..", local_deferredLogger);
|
||||||
well_state_.enableGliftOptimization();
|
this->wellState().enableGliftOptimization();
|
||||||
assembleWellEq(dt, local_deferredLogger);
|
assembleWellEq(dt, local_deferredLogger);
|
||||||
well_state_.disableGliftOptimization();
|
this->wellState().disableGliftOptimization();
|
||||||
} catch (const std::runtime_error& e) {
|
} catch (const std::runtime_error& e) {
|
||||||
exc_type = ExceptionType::RUNTIME_ERROR;
|
exc_type = ExceptionType::RUNTIME_ERROR;
|
||||||
exc_msg = e.what();
|
exc_msg = e.what();
|
||||||
@ -1054,9 +1053,8 @@ namespace Opm {
|
|||||||
assembleWellEq(const double dt, Opm::DeferredLogger& deferred_logger)
|
assembleWellEq(const double dt, Opm::DeferredLogger& deferred_logger)
|
||||||
{
|
{
|
||||||
for (auto& well : well_container_) {
|
for (auto& well : well_container_) {
|
||||||
well->maybeDoGasLiftOptimization(
|
well->maybeDoGasLiftOptimization(this->wellState(), ebosSimulator_, deferred_logger);
|
||||||
well_state_, ebosSimulator_, deferred_logger);
|
well->assembleWellEq(ebosSimulator_, dt, this->wellState(), deferred_logger);
|
||||||
well->assembleWellEq(ebosSimulator_, dt, well_state_, deferred_logger);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1167,7 +1165,7 @@ namespace Opm {
|
|||||||
try {
|
try {
|
||||||
if (localWellsActive()) {
|
if (localWellsActive()) {
|
||||||
for (auto& well : well_container_) {
|
for (auto& well : well_container_) {
|
||||||
well->recoverWellSolutionAndUpdateWellState(x, well_state_, local_deferredLogger);
|
well->recoverWellSolutionAndUpdateWellState(x, this->wellState(), local_deferredLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const std::runtime_error& e) {
|
} catch (const std::runtime_error& e) {
|
||||||
@ -1251,7 +1249,7 @@ namespace Opm {
|
|||||||
ConvergenceReport local_report;
|
ConvergenceReport local_report;
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
if (well->isOperable() ) {
|
if (well->isOperable() ) {
|
||||||
local_report += well->getWellConvergence(well_state_, B_avg, local_deferredLogger);
|
local_report += well->getWellConvergence(this->wellState(), B_avg, local_deferredLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
|
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
|
||||||
@ -1292,7 +1290,7 @@ namespace Opm {
|
|||||||
{
|
{
|
||||||
// TODO: checking isOperable() ?
|
// TODO: checking isOperable() ?
|
||||||
for (auto& well : well_container_) {
|
for (auto& well : well_container_) {
|
||||||
well->calculateExplicitQuantities(ebosSimulator_, well_state_, deferred_logger);
|
well->calculateExplicitQuantities(ebosSimulator_, this->wellState(), deferred_logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1329,7 +1327,7 @@ namespace Opm {
|
|||||||
// Check wells' group constraints and communicate.
|
// Check wells' group constraints and communicate.
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
const auto mode = WellInterface<TypeTag>::IndividualOrGroup::Group;
|
const auto mode = WellInterface<TypeTag>::IndividualOrGroup::Group;
|
||||||
const bool changed = well->updateWellControl(ebosSimulator_, mode, well_state_, deferred_logger);
|
const bool changed = well->updateWellControl(ebosSimulator_, mode, this->wellState(), deferred_logger);
|
||||||
if (changed) {
|
if (changed) {
|
||||||
switched_wells.insert(well->name());
|
switched_wells.insert(well->name());
|
||||||
}
|
}
|
||||||
@ -1343,7 +1341,7 @@ namespace Opm {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto mode = WellInterface<TypeTag>::IndividualOrGroup::Individual;
|
const auto mode = WellInterface<TypeTag>::IndividualOrGroup::Individual;
|
||||||
well->updateWellControl(ebosSimulator_, mode, well_state_, deferred_logger);
|
well->updateWellControl(ebosSimulator_, mode, this->wellState(), deferred_logger);
|
||||||
}
|
}
|
||||||
updateAndCommunicateGroupData();
|
updateAndCommunicateGroupData();
|
||||||
|
|
||||||
@ -1364,7 +1362,7 @@ namespace Opm {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node_pressures_ = WellGroupHelpers::computeNetworkPressures(
|
node_pressures_ = WellGroupHelpers::computeNetworkPressures(
|
||||||
network, well_state_, *(vfp_properties_->getProd()), schedule(), reportStepIdx);
|
network, this->wellState(), *(vfp_properties_->getProd()), schedule(), reportStepIdx);
|
||||||
|
|
||||||
// Set the thp limits of wells
|
// Set the thp limits of wells
|
||||||
for (auto& well : well_container_) {
|
for (auto& well : well_container_) {
|
||||||
@ -1398,42 +1396,44 @@ namespace Opm {
|
|||||||
// This builds some necessary lookup structures, so it must be called
|
// This builds some necessary lookup structures, so it must be called
|
||||||
// before we copy to well_state_nupcol_.
|
// before we copy to well_state_nupcol_.
|
||||||
const auto& comm = ebosSimulator_.vanguard().grid().comm();
|
const auto& comm = ebosSimulator_.vanguard().grid().comm();
|
||||||
well_state_.updateGlobalIsGrup(schedule(), reportStepIdx, comm);
|
this->wellState().updateGlobalIsGrup(schedule(), reportStepIdx, comm);
|
||||||
|
|
||||||
if (iterationIdx < nupcol) {
|
if (iterationIdx < nupcol) {
|
||||||
well_state_nupcol_ = well_state_;
|
this->updateNupcolWellState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& well_state = this->wellState();
|
||||||
|
const auto& well_state_nupcol = this->nupcolWellState();
|
||||||
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
||||||
// the group target reduction rates needs to be update since wells may have swicthed to/from GRUP control
|
// the group target reduction rates needs to be update since wells may have swicthed to/from GRUP control
|
||||||
// Currently the group target reduction does not honor NUPCOL. TODO: is that true?
|
// Currently the group target reduction does not honor NUPCOL. TODO: is that true?
|
||||||
std::vector<double> groupTargetReduction(numPhases(), 0.0);
|
std::vector<double> groupTargetReduction(numPhases(), 0.0);
|
||||||
WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, phase_usage_, *guideRate_, well_state_nupcol_, well_state_, groupTargetReduction);
|
WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ false, phase_usage_, *guideRate_, well_state_nupcol, well_state, groupTargetReduction);
|
||||||
std::vector<double> groupTargetReductionInj(numPhases(), 0.0);
|
std::vector<double> groupTargetReductionInj(numPhases(), 0.0);
|
||||||
WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, phase_usage_, *guideRate_, well_state_nupcol_, well_state_, groupTargetReductionInj);
|
WellGroupHelpers::updateGroupTargetReduction(fieldGroup, schedule(), reportStepIdx, /*isInjector*/ true, phase_usage_, *guideRate_, well_state_nupcol, well_state, groupTargetReductionInj);
|
||||||
|
|
||||||
WellGroupHelpers::updateREINForGroups(fieldGroup, schedule(), reportStepIdx, phase_usage_, summaryState, well_state_nupcol_, well_state_);
|
WellGroupHelpers::updateREINForGroups(fieldGroup, schedule(), reportStepIdx, phase_usage_, summaryState, well_state_nupcol, well_state);
|
||||||
WellGroupHelpers::updateVREPForGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol_, well_state_);
|
WellGroupHelpers::updateVREPForGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state);
|
||||||
|
|
||||||
WellGroupHelpers::updateReservoirRatesInjectionGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol_, well_state_);
|
WellGroupHelpers::updateReservoirRatesInjectionGroups(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state);
|
||||||
WellGroupHelpers::updateGroupProductionRates(fieldGroup, schedule(), reportStepIdx, well_state_nupcol_, well_state_);
|
WellGroupHelpers::updateGroupProductionRates(fieldGroup, schedule(), reportStepIdx, well_state_nupcol, well_state);
|
||||||
|
|
||||||
// We use the rates from the privious time-step to reduce oscilations
|
// We use the rates from the privious time-step to reduce oscilations
|
||||||
WellGroupHelpers::updateWellRates(fieldGroup, schedule(), reportStepIdx, previous_well_state_, well_state_);
|
WellGroupHelpers::updateWellRates(fieldGroup, schedule(), reportStepIdx, this->prevWellState(), well_state);
|
||||||
|
|
||||||
// Set ALQ for off-process wells to zero
|
// Set ALQ for off-process wells to zero
|
||||||
for (const auto& wname : schedule().wellNames(reportStepIdx)) {
|
for (const auto& wname : schedule().wellNames(reportStepIdx)) {
|
||||||
const bool is_producer = schedule().getWell(wname, reportStepIdx).isProducer();
|
const bool is_producer = schedule().getWell(wname, reportStepIdx).isProducer();
|
||||||
const bool not_on_this_process = well_state_.wellMap().count(wname) == 0;
|
const bool not_on_this_process = well_state.wellMap().count(wname) == 0;
|
||||||
if (is_producer && not_on_this_process) {
|
if (is_producer && not_on_this_process) {
|
||||||
well_state_.setALQ(wname, 0.0);
|
well_state.setALQ(wname, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
well_state_.communicateGroupRates(comm);
|
well_state.communicateGroupRates(comm);
|
||||||
|
|
||||||
// compute wsolvent fraction for REIN wells
|
// compute wsolvent fraction for REIN wells
|
||||||
updateWsolvent(fieldGroup, schedule(), reportStepIdx, well_state_nupcol_);
|
updateWsolvent(fieldGroup, schedule(), reportStepIdx, well_state_nupcol);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1450,7 +1450,7 @@ namespace Opm {
|
|||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
const auto wasClosed = wellTestState.hasWellClosed(well->name());
|
const auto wasClosed = wellTestState.hasWellClosed(well->name());
|
||||||
|
|
||||||
well->updateWellTestState(well_state_, simulationTime, /*writeMessageToOPMLog=*/ true, wellTestState, local_deferredLogger);
|
well->updateWellTestState(this->wellState(), simulationTime, /*writeMessageToOPMLog=*/ true, wellTestState, local_deferredLogger);
|
||||||
|
|
||||||
if (!wasClosed && wellTestState.hasWellClosed(well->name())) {
|
if (!wasClosed && wellTestState.hasWellClosed(well->name())) {
|
||||||
this->closed_this_step_.insert(well->name());
|
this->closed_this_step_.insert(well->name());
|
||||||
@ -1475,7 +1475,7 @@ namespace Opm {
|
|||||||
const int np = numPhases();
|
const int np = numPhases();
|
||||||
well_potentials.resize(nw * np, 0.0);
|
well_potentials.resize(nw * np, 0.0);
|
||||||
|
|
||||||
auto well_state_copy = well_state_;
|
auto well_state = this->wellState();
|
||||||
|
|
||||||
const Opm::SummaryConfig& summaryConfig = ebosSimulator_.vanguard().summaryConfig();
|
const Opm::SummaryConfig& summaryConfig = ebosSimulator_.vanguard().summaryConfig();
|
||||||
const bool write_restart_file = ebosSimulator_.vanguard().schedule().write_rst_file(reportStepIdx);
|
const bool write_restart_file = ebosSimulator_.vanguard().schedule().write_rst_file(reportStepIdx);
|
||||||
@ -1494,7 +1494,7 @@ namespace Opm {
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
std::vector<double> potentials;
|
std::vector<double> potentials;
|
||||||
well->computeWellPotentials(ebosSimulator_, well_state_copy, potentials, deferred_logger);
|
well->computeWellPotentials(ebosSimulator_, well_state, potentials, deferred_logger);
|
||||||
// putting the sucessfully calculated potentials to the well_potentials
|
// putting the sucessfully calculated potentials to the well_potentials
|
||||||
for (int p = 0; p < np; ++p) {
|
for (int p = 0; p < np; ++p) {
|
||||||
well_potentials[well->indexOfWell() * np + p] = std::abs(potentials[p]);
|
well_potentials[well->indexOfWell() * np + p] = std::abs(potentials[p]);
|
||||||
@ -1519,7 +1519,7 @@ namespace Opm {
|
|||||||
terminal_output_);
|
terminal_output_);
|
||||||
|
|
||||||
// Store it in the well state
|
// Store it in the well state
|
||||||
well_state_.wellPotentials() = well_potentials;
|
this->wellState().wellPotentials() = well_potentials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1540,7 +1540,7 @@ namespace Opm {
|
|||||||
for (const auto& wellPtr : this->well_container_) {
|
for (const auto& wellPtr : this->well_container_) {
|
||||||
wellPtr->updateProductivityIndex(this->ebosSimulator_,
|
wellPtr->updateProductivityIndex(this->ebosSimulator_,
|
||||||
this->prod_index_calc_[wellPtr->indexOfWell()],
|
this->prod_index_calc_[wellPtr->indexOfWell()],
|
||||||
this->well_state_,
|
this->wellState(),
|
||||||
deferred_logger);
|
deferred_logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1558,15 +1558,15 @@ namespace Opm {
|
|||||||
std::string exc_msg;
|
std::string exc_msg;
|
||||||
try {
|
try {
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
well->checkWellOperability(ebosSimulator_, well_state_, deferred_logger);
|
well->checkWellOperability(ebosSimulator_, this->wellState(), deferred_logger);
|
||||||
}
|
}
|
||||||
// since the controls are all updated, we should update well_state accordingly
|
// since the controls are all updated, we should update well_state accordingly
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
const int w = well->indexOfWell();
|
const int w = well->indexOfWell();
|
||||||
if (!well->isOperable() ) continue;
|
if (!well->isOperable() ) continue;
|
||||||
|
|
||||||
if (well_state_.effectiveEventsOccurred(w) ) {
|
if (this->wellState().effectiveEventsOccurred(w) ) {
|
||||||
well->updateWellStateWithTarget(ebosSimulator_, well_state_, deferred_logger);
|
well->updateWellStateWithTarget(ebosSimulator_, this->wellState(), deferred_logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is no new well control change input within a report step,
|
// there is no new well control change input within a report step,
|
||||||
@ -1575,8 +1575,8 @@ namespace Opm {
|
|||||||
// we do not need to set it to false
|
// we do not need to set it to false
|
||||||
// TODO: we should do this at the end of the time step in case we will need it within
|
// TODO: we should do this at the end of the time step in case we will need it within
|
||||||
// this time step somewhere
|
// this time step somewhere
|
||||||
if (well_state_.effectiveEventsOccurred(w) ) {
|
if (this->wellState().effectiveEventsOccurred(w) ) {
|
||||||
well_state_.setEffectiveEventsOccurred(w, false);
|
this->wellState().setEffectiveEventsOccurred(w, false);
|
||||||
}
|
}
|
||||||
} // end of for (const auto& well : well_container_)
|
} // end of for (const auto& well : well_container_)
|
||||||
updatePrimaryVariables(deferred_logger);
|
updatePrimaryVariables(deferred_logger);
|
||||||
@ -1600,17 +1600,6 @@ namespace Opm {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
|
||||||
const typename BlackoilWellModel<TypeTag>::WellState&
|
|
||||||
BlackoilWellModel<TypeTag>::
|
|
||||||
wellState() const { return well_state_; }
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
|
||||||
const typename BlackoilWellModel<TypeTag>::WellState&
|
|
||||||
BlackoilWellModel<TypeTag>::
|
|
||||||
wellState(const WellState& well_state OPM_UNUSED) const { return wellState(); }
|
|
||||||
|
|
||||||
|
|
||||||
template<typename TypeTag>
|
template<typename TypeTag>
|
||||||
void
|
void
|
||||||
BlackoilWellModel<TypeTag>::
|
BlackoilWellModel<TypeTag>::
|
||||||
@ -1726,7 +1715,7 @@ namespace Opm {
|
|||||||
updatePrimaryVariables(Opm::DeferredLogger& deferred_logger)
|
updatePrimaryVariables(Opm::DeferredLogger& deferred_logger)
|
||||||
{
|
{
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
well->updatePrimaryVariables(well_state_, deferred_logger);
|
well->updatePrimaryVariables(this->wellState(), deferred_logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2103,7 +2092,7 @@ namespace Opm {
|
|||||||
const int reportStepIdx = ebosSimulator_.episodeIndex();
|
const int reportStepIdx = ebosSimulator_.episodeIndex();
|
||||||
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
||||||
const auto& comm = ebosSimulator_.vanguard().grid().comm();
|
const auto& comm = ebosSimulator_.vanguard().grid().comm();
|
||||||
const auto& well_state = well_state_;
|
const auto& well_state = this->wellState();
|
||||||
|
|
||||||
const auto controls = group.productionControls(summaryState);
|
const auto controls = group.productionControls(summaryState);
|
||||||
const Group::ProductionCMode& currentControl = well_state.currentProductionGroupControl(group.name());
|
const Group::ProductionCMode& currentControl = well_state.currentProductionGroupControl(group.name());
|
||||||
@ -2209,7 +2198,7 @@ namespace Opm {
|
|||||||
const int reportStepIdx = ebosSimulator_.episodeIndex();
|
const int reportStepIdx = ebosSimulator_.episodeIndex();
|
||||||
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
const auto& summaryState = ebosSimulator_.vanguard().summaryState();
|
||||||
const auto& comm = ebosSimulator_.vanguard().grid().comm();
|
const auto& comm = ebosSimulator_.vanguard().grid().comm();
|
||||||
const auto& well_state = well_state_;
|
const auto& well_state = this->wellState();
|
||||||
|
|
||||||
int phasePos;
|
int phasePos;
|
||||||
if (phase == Phase::GAS && phase_usage_.phase_used[BlackoilPhases::Vapour] )
|
if (phase == Phase::GAS && phase_usage_.phase_used[BlackoilPhases::Vapour] )
|
||||||
@ -2429,7 +2418,7 @@ namespace Opm {
|
|||||||
BlackoilWellModel<TypeTag>::
|
BlackoilWellModel<TypeTag>::
|
||||||
actionOnBrokenConstraints(const Group& group, const Group::ExceedAction& exceed_action, const Group::ProductionCMode& newControl, Opm::DeferredLogger& deferred_logger) {
|
actionOnBrokenConstraints(const Group& group, const Group::ExceedAction& exceed_action, const Group::ProductionCMode& newControl, Opm::DeferredLogger& deferred_logger) {
|
||||||
|
|
||||||
auto& well_state = well_state_;
|
auto& well_state = this->wellState();
|
||||||
const Group::ProductionCMode oldControl = well_state.currentProductionGroupControl(group.name());
|
const Group::ProductionCMode oldControl = well_state.currentProductionGroupControl(group.name());
|
||||||
|
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
@ -2482,7 +2471,7 @@ namespace Opm {
|
|||||||
void
|
void
|
||||||
BlackoilWellModel<TypeTag>::
|
BlackoilWellModel<TypeTag>::
|
||||||
actionOnBrokenConstraints(const Group& group, const Group::InjectionCMode& newControl, const Phase& controlPhase, Opm::DeferredLogger& deferred_logger) {
|
actionOnBrokenConstraints(const Group& group, const Group::InjectionCMode& newControl, const Phase& controlPhase, Opm::DeferredLogger& deferred_logger) {
|
||||||
auto& well_state = well_state_;
|
auto& well_state = this->wellState();
|
||||||
const Group::InjectionCMode oldControl = well_state.currentInjectionGroupControl(controlPhase, group.name());
|
const Group::InjectionCMode oldControl = well_state.currentInjectionGroupControl(controlPhase, group.name());
|
||||||
|
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
@ -2557,22 +2546,21 @@ namespace Opm {
|
|||||||
if (!skip && group.isInjectionGroup()) {
|
if (!skip && group.isInjectionGroup()) {
|
||||||
// Obtain rates for group.
|
// Obtain rates for group.
|
||||||
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
|
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
|
||||||
const double local_current_rate = WellGroupHelpers::sumWellRates(
|
const double local_current_rate = WellGroupHelpers::sumWellRates(group, schedule(), this->wellState(), reportStepIdx, phasePos, /* isInjector */ true);
|
||||||
group, schedule(), well_state_, reportStepIdx, phasePos, /* isInjector */ true);
|
|
||||||
// Sum over all processes
|
// Sum over all processes
|
||||||
rates[phasePos] = comm.sum(local_current_rate);
|
rates[phasePos] = comm.sum(local_current_rate);
|
||||||
}
|
}
|
||||||
const Phase all[] = { Phase::WATER, Phase::OIL, Phase::GAS };
|
const Phase all[] = { Phase::WATER, Phase::OIL, Phase::GAS };
|
||||||
for (Phase phase : all) {
|
for (Phase phase : all) {
|
||||||
// Check higher up only if under individual (not FLD) control.
|
// Check higher up only if under individual (not FLD) control.
|
||||||
const Group::InjectionCMode& currentControl = well_state_.currentInjectionGroupControl(phase, group.name());
|
const Group::InjectionCMode& currentControl = this->wellState().currentInjectionGroupControl(phase, group.name());
|
||||||
if (currentControl != Group::InjectionCMode::FLD) {
|
if (currentControl != Group::InjectionCMode::FLD) {
|
||||||
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
|
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
|
||||||
const std::pair<bool, double> changed = WellGroupHelpers::checkGroupConstraintsInj(
|
const std::pair<bool, double> changed = WellGroupHelpers::checkGroupConstraintsInj(
|
||||||
group.name(),
|
group.name(),
|
||||||
group.parent(),
|
group.parent(),
|
||||||
parentGroup,
|
parentGroup,
|
||||||
well_state_,
|
this->wellState(),
|
||||||
reportStepIdx,
|
reportStepIdx,
|
||||||
guideRate_.get(),
|
guideRate_.get(),
|
||||||
rates.data(),
|
rates.data(),
|
||||||
@ -2594,20 +2582,19 @@ namespace Opm {
|
|||||||
if (!skip && group.isProductionGroup()) {
|
if (!skip && group.isProductionGroup()) {
|
||||||
// Obtain rates for group.
|
// Obtain rates for group.
|
||||||
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
|
for (int phasePos = 0; phasePos < phase_usage_.num_phases; ++phasePos) {
|
||||||
const double local_current_rate = WellGroupHelpers::sumWellRates(
|
const double local_current_rate = WellGroupHelpers::sumWellRates(group, schedule(), this->wellState(), reportStepIdx, phasePos, /* isInjector */ false);
|
||||||
group, schedule(), well_state_, reportStepIdx, phasePos, /* isInjector */ false);
|
|
||||||
// Sum over all processes
|
// Sum over all processes
|
||||||
rates[phasePos] = -comm.sum(local_current_rate);
|
rates[phasePos] = -comm.sum(local_current_rate);
|
||||||
}
|
}
|
||||||
// Check higher up only if under individual (not FLD) control.
|
// Check higher up only if under individual (not FLD) control.
|
||||||
const Group::ProductionCMode& currentControl = well_state_.currentProductionGroupControl(group.name());
|
const Group::ProductionCMode& currentControl = this->wellState().currentProductionGroupControl(group.name());
|
||||||
if (currentControl != Group::ProductionCMode::FLD) {
|
if (currentControl != Group::ProductionCMode::FLD) {
|
||||||
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
|
const Group& parentGroup = schedule().getGroup(group.parent(), reportStepIdx);
|
||||||
const std::pair<bool, double> changed = WellGroupHelpers::checkGroupConstraintsProd(
|
const std::pair<bool, double> changed = WellGroupHelpers::checkGroupConstraintsProd(
|
||||||
group.name(),
|
group.name(),
|
||||||
group.parent(),
|
group.parent(),
|
||||||
parentGroup,
|
parentGroup,
|
||||||
well_state_,
|
this->wellState(),
|
||||||
reportStepIdx,
|
reportStepIdx,
|
||||||
guideRate_.get(),
|
guideRate_.get(),
|
||||||
rates.data(),
|
rates.data(),
|
||||||
@ -2654,7 +2641,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->well_state_.resetConnectionTransFactors(well_index, pd);
|
this->wellState().resetConnectionTransFactors(well_index, pd);
|
||||||
this->prod_index_calc_[well_index].reInit(well);
|
this->prod_index_calc_[well_index].reInit(well);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2691,7 +2678,7 @@ namespace Opm {
|
|||||||
{
|
{
|
||||||
const auto& pu = this->phase_usage_;
|
const auto& pu = this->phase_usage_;
|
||||||
const auto np = this->numPhases();
|
const auto np = this->numPhases();
|
||||||
const auto* pi = &this->well_state_.productivityIndex()[np*well_index + 0];
|
const auto* pi = &this->wellState().productivityIndex()[np*well_index + 0];
|
||||||
|
|
||||||
const auto preferred = this->wells_ecl_[well_index].getPreferredPhase();
|
const auto preferred = this->wells_ecl_[well_index].getPreferredPhase();
|
||||||
switch (preferred) { // Should really have LIQUID = OIL + WATER here too...
|
switch (preferred) { // Should really have LIQUID = OIL + WATER here too...
|
||||||
@ -2789,8 +2776,8 @@ namespace Opm {
|
|||||||
|
|
||||||
// Minimal well setup to compute PI/II values
|
// Minimal well setup to compute PI/II values
|
||||||
{
|
{
|
||||||
auto saved_previous_well_state = this->previous_well_state_;
|
auto saved_previous_well_state = this->prevWellState();
|
||||||
this->previous_well_state_ = this->well_state_;
|
this->commitWellState();
|
||||||
|
|
||||||
well_container_ = createWellContainer(timeStepIdx);
|
well_container_ = createWellContainer(timeStepIdx);
|
||||||
for (auto& well : well_container_) {
|
for (auto& well : well_container_) {
|
||||||
@ -2803,7 +2790,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->calculateProductivityIndexValues(local_deferredLogger);
|
this->calculateProductivityIndexValues(local_deferredLogger);
|
||||||
this->previous_well_state_ = std::move(saved_previous_well_state);
|
this->commitWellState(std::move(saved_previous_well_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto nw = this->numLocalWells();
|
const auto nw = this->numLocalWells();
|
||||||
@ -2998,7 +2985,7 @@ namespace Opm {
|
|||||||
// group tree (FIELD group).
|
// group tree (FIELD group).
|
||||||
|
|
||||||
for (const auto& wname : sched.wellNames(reportStepIdx)) {
|
for (const auto& wname : sched.wellNames(reportStepIdx)) {
|
||||||
if (! (this->well_state_.hasWellRates(wname) &&
|
if (! (this->wellState().hasWellRates(wname) &&
|
||||||
this->guideRate_->has(wname)))
|
this->guideRate_->has(wname)))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -3080,22 +3067,19 @@ namespace Opm {
|
|||||||
cgc.currentWaterInjectionConstraint =
|
cgc.currentWaterInjectionConstraint =
|
||||||
::Opm::Group::InjectionCMode::NONE;
|
::Opm::Group::InjectionCMode::NONE;
|
||||||
|
|
||||||
if (this->well_state_.hasProductionGroupControl(gname)) {
|
if (this->wellState().hasProductionGroupControl(gname)) {
|
||||||
cgc.currentProdConstraint = this->well_state_
|
cgc.currentProdConstraint = this->wellState().currentProductionGroupControl(gname);
|
||||||
.currentProductionGroupControl(gname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((grup_type == ::Opm::Group::GroupType::INJECTION) ||
|
if ((grup_type == ::Opm::Group::GroupType::INJECTION) ||
|
||||||
(grup_type == ::Opm::Group::GroupType::MIXED))
|
(grup_type == ::Opm::Group::GroupType::MIXED))
|
||||||
{
|
{
|
||||||
if (this->well_state_.hasInjectionGroupControl(::Opm::Phase::WATER, gname)) {
|
if (this->wellState().hasInjectionGroupControl(::Opm::Phase::WATER, gname)) {
|
||||||
cgc.currentWaterInjectionConstraint = this->well_state_
|
cgc.currentWaterInjectionConstraint = this->wellState().currentInjectionGroupControl(::Opm::Phase::WATER, gname);
|
||||||
.currentInjectionGroupControl(::Opm::Phase::WATER, gname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->well_state_.hasInjectionGroupControl(::Opm::Phase::GAS, gname)) {
|
if (this->wellState().hasInjectionGroupControl(::Opm::Phase::GAS, gname)) {
|
||||||
cgc.currentGasInjectionConstraint = this->well_state_
|
cgc.currentGasInjectionConstraint = this->wellState().currentInjectionGroupControl(::Opm::Phase::GAS, gname);
|
||||||
.currentInjectionGroupControl(::Opm::Phase::GAS, gname);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3110,7 +3094,7 @@ namespace Opm {
|
|||||||
assert (this->guideRate_ != nullptr);
|
assert (this->guideRate_ != nullptr);
|
||||||
|
|
||||||
const auto& wname = well.name();
|
const auto& wname = well.name();
|
||||||
if (! this->well_state_.hasWellRates(wname)) {
|
if (! this->wellState().hasWellRates(wname)) {
|
||||||
// No flow rates for 'wname' -- might be before well comes
|
// No flow rates for 'wname' -- might be before well comes
|
||||||
// online (e.g., for the initial condition before simulation
|
// online (e.g., for the initial condition before simulation
|
||||||
// starts).
|
// starts).
|
||||||
@ -3123,7 +3107,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto qs = WellGroupHelpers::
|
const auto qs = WellGroupHelpers::
|
||||||
getWellRateVector(this->well_state_, this->phase_usage_, wname);
|
getWellRateVector(this->wellState(), this->phase_usage_, wname);
|
||||||
|
|
||||||
this->getGuideRateValues(qs, well.isInjector(), wname, grval);
|
this->getGuideRateValues(qs, well.isInjector(), wname, grval);
|
||||||
|
|
||||||
@ -3161,7 +3145,7 @@ namespace Opm {
|
|||||||
|
|
||||||
const auto& gname = group.name();
|
const auto& gname = group.name();
|
||||||
|
|
||||||
if ( ! this->well_state_.hasProductionGroupRates(gname)) {
|
if ( ! this->wellState().hasProductionGroupRates(gname)) {
|
||||||
// No flow rates for production group 'gname' -- might be before group comes
|
// No flow rates for production group 'gname' -- might be before group comes
|
||||||
// online (e.g., for the initial condition before simulation
|
// online (e.g., for the initial condition before simulation
|
||||||
// starts).
|
// starts).
|
||||||
@ -3173,8 +3157,7 @@ namespace Opm {
|
|||||||
return grval;
|
return grval;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto qs = WellGroupHelpers::
|
const auto qs = WellGroupHelpers::getProductionGroupRateVector(this->wellState(), this->phase_usage_, gname);
|
||||||
getProductionGroupRateVector(this->well_state_, this->phase_usage_, gname);
|
|
||||||
|
|
||||||
const auto is_inj = false; // This procedure only applies to G*PGR.
|
const auto is_inj = false; // This procedure only applies to G*PGR.
|
||||||
this->getGuideRateValues(qs, is_inj, gname, grval);
|
this->getGuideRateValues(qs, is_inj, gname, grval);
|
||||||
@ -3273,7 +3256,7 @@ namespace Opm {
|
|||||||
cellInternalEnergy = fs.enthalpy(phaseIdx).value() - fs.pressure(phaseIdx).value() / fs.density(phaseIdx).value();
|
cellInternalEnergy = fs.enthalpy(phaseIdx).value() - fs.pressure(phaseIdx).value() / fs.density(phaseIdx).value();
|
||||||
cellBinv = fs.invB(phaseIdx).value();
|
cellBinv = fs.invB(phaseIdx).value();
|
||||||
cellDensity = fs.density(phaseIdx).value();
|
cellDensity = fs.density(phaseIdx).value();
|
||||||
perfPhaseRate = well_state_.perfPhaseRates()[connpos + perf*np + phaseIdx ];
|
perfPhaseRate = this->wellState().perfPhaseRates()[connpos + perf*np + phaseIdx ];
|
||||||
weight_factor += cellDensity * perfPhaseRate/cellBinv * cellInternalEnergy/cellTemperatures;
|
weight_factor += cellDensity * perfPhaseRate/cellBinv * cellInternalEnergy/cellTemperatures;
|
||||||
}
|
}
|
||||||
total_weight += weight_factor;
|
total_weight += weight_factor;
|
||||||
@ -3281,7 +3264,7 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
weighted_temperature = well_info.communication().sum(weighted_temperature);
|
weighted_temperature = well_info.communication().sum(weighted_temperature);
|
||||||
total_weight = well_info.communication().sum(total_weight);
|
total_weight = well_info.communication().sum(total_weight);
|
||||||
well_state_.temperature()[wellID] = weighted_temperature/total_weight;
|
this->wellState().temperature()[wellID] = weighted_temperature/total_weight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
Loading…
Reference in New Issue
Block a user