Merge pull request #4531 from GitPaean/trying_to_gurantee_zero_rate

making sure zero rate controlled production wells have zero rate in the simulation results
This commit is contained in:
Bård Skaflestad 2023-03-27 20:34:24 +02:00 committed by GitHub
commit 88e5b235b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 155 additions and 95 deletions

View File

@ -1324,7 +1324,8 @@ namespace Opm {
OPM_BEGIN_PARALLEL_TRY_CATCH();
{
for (auto& well : well_container_) {
well->recoverWellSolutionAndUpdateWellState(x, this->wellState(), local_deferredLogger);
const auto& summary_state = ebosSimulator_.vanguard().summaryState();
well->recoverWellSolutionAndUpdateWellState(summary_state, x, this->wellState(), local_deferredLogger);
}
}
@ -1659,7 +1660,8 @@ namespace Opm {
auto& events = this->wellState().well(well->indexOfWell()).events;
if (events.hasEvent(WellState::event_mask)) {
well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), deferred_logger);
well->updatePrimaryVariables(this->wellState(), deferred_logger);
const auto& summary_state = ebosSimulator_.vanguard().summaryState();
well->updatePrimaryVariables(summary_state, this->wellState(), deferred_logger);
well->initPrimaryVariablesEvaluation();
// There is no new well control change input within a report step,
// so next time step, the well does not consider to have effective events anymore.
@ -1733,7 +1735,8 @@ namespace Opm {
updatePrimaryVariables(DeferredLogger& deferred_logger)
{
for (const auto& well : well_container_) {
well->updatePrimaryVariables(this->wellState(), deferred_logger);
const auto& summary_state = ebosSimulator_.vanguard().summaryState();
well->updatePrimaryVariables(summary_state, this->wellState(), deferred_logger);
}
}

View File

@ -108,7 +108,8 @@ namespace Opm
/// using the solution x to recover the solution xw for wells and applying
/// xw to update Well State
void recoverWellSolutionAndUpdateWellState(const BVector& x,
void recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
const BVector& x,
WellState& well_state,
DeferredLogger& deferred_logger) override;
@ -118,9 +119,9 @@ namespace Opm
std::vector<double>& well_potentials,
DeferredLogger& deferred_logger) override;
void updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) override;
virtual void solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger) override; // const?
void updatePrimaryVariables(const SummaryState& summary_state,
const WellState& well_state,
DeferredLogger& deferred_logger) override;
virtual void calculateExplicitQuantities(const Simulator& ebosSimulator,
const WellState& well_state,
@ -171,7 +172,8 @@ namespace Opm
mutable int debug_cost_counter_ = 0;
// updating the well_state based on well solution dwells
void updateWellState(const BVectorWell& dwells,
void updateWellState(const SummaryState& summary_state,
const BVectorWell& dwells,
WellState& well_state,
DeferredLogger& deferred_logger,
const double relaxation_factor = 1.0);

View File

@ -34,6 +34,7 @@
#include <opm/simulators/wells/MultisegmentWellPrimaryVariables.hpp>
#include <opm/simulators/wells/WellAssemble.hpp>
#include <opm/simulators/wells/WellBhpThpCalculator.hpp>
#include <opm/simulators/wells/WellHelpers.hpp>
#include <opm/simulators/wells/WellInterfaceIndices.hpp>
#include <opm/simulators/wells/WellState.hpp>
@ -163,7 +164,7 @@ assembleControlEq(const WellState& well_state,
bhp_from_thp,
control_eq,
deferred_logger);
} else if (rateControlWithZeroTarget(well_state.well(well_.indexOfWell()).production_cmode, prod_controls)) {
} else if (wellhelpers::rateControlWithZeroTarget(well_state.well(well_.indexOfWell()).production_cmode, prod_controls)) {
// Production mode, zero target. Treat as STOP.
control_eq = primary_variables.getWQTotal();
} else {

View File

@ -64,7 +64,7 @@ init()
template<class FluidSystem, class Indices, class Scalar>
void MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::
update(const WellState& well_state)
update(const WellState& well_state, const bool zero_rate_target)
{
static constexpr int Water = BlackoilPhases::Aqua;
static constexpr int Gas = BlackoilPhases::Vapour;
@ -104,6 +104,9 @@ update(const WellState& well_state)
}
}
value_[seg][WQTotal] = total_seg_rate;
if (zero_rate_target && seg == 0) {
value_[seg][WQTotal] = 0;
}
if (std::abs(total_seg_rate) > 0.) {
if (has_wfrac_variable) {
const int water_pos = pu.phase_pos[Water];
@ -152,6 +155,7 @@ void MultisegmentWellPrimaryVariables<FluidSystem,Indices,Scalar>::
updateNewton(const BVectorWell& dwells,
const double relaxation_factor,
const double dFLimit,
const bool zero_rate_target,
const double max_pressure_change)
{
const std::vector<std::array<double, numWellEq>> old_primary_variables = value_;
@ -193,6 +197,10 @@ updateNewton(const BVectorWell& dwells,
}
}
}
if (zero_rate_target) {
value_[0][WQTotal] = 0.;
}
}
template<class FluidSystem, class Indices, class Scalar>

View File

@ -88,12 +88,13 @@ public:
void init();
//! \brief Copy values from well state.
void update(const WellState& well_state);
void update(const WellState& well_state, const bool zero_rate_target);
//! \brief Update values from newton update vector.
void updateNewton(const BVectorWell& dwells,
const double relaxation_factor,
const double DFLimit,
const bool zero_rate_target,
const double max_pressure_change);
//! \brief Copy values to well state.

View File

@ -148,9 +148,12 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
updatePrimaryVariables(const WellState& well_state, DeferredLogger& /* deferred_logger */)
updatePrimaryVariables(const SummaryState& summary_state,
const WellState& well_state,
DeferredLogger& /* deferred_logger */)
{
this->primary_variables_.update(well_state);
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
this->primary_variables_.update(well_state, zero_rate_target);
}
@ -240,7 +243,8 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
recoverWellSolutionAndUpdateWellState(const BVector& x,
recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
const BVector& x,
WellState& well_state,
DeferredLogger& deferred_logger)
{
@ -250,7 +254,7 @@ namespace Opm
BVectorWell xw(1);
this->linSys_.recoverSolutionWell(x, xw);
updateWellState(xw, well_state, deferred_logger);
updateWellState(summary_state, xw, well_state, deferred_logger);
}
@ -525,24 +529,6 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger)
{
if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
// We assemble the well equations, then we check the convergence,
// which is why we do not put the assembleWellEq here.
const BVectorWell dx_well = this->linSys_.solve();
updateWellState(dx_well, well_state, deferred_logger);
}
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
@ -619,7 +605,8 @@ namespace Opm
template <typename TypeTag>
void
MultisegmentWell<TypeTag>::
updateWellState(const BVectorWell& dwells,
updateWellState(const SummaryState& summary_state,
const BVectorWell& dwells,
WellState& well_state,
DeferredLogger& deferred_logger,
const double relaxation_factor)
@ -628,9 +615,11 @@ namespace Opm
const double dFLimit = this->param_.dwell_fraction_max_;
const double max_pressure_change = this->param_.max_pressure_change_ms_wells_;
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
this->primary_variables_.updateNewton(dwells,
relaxation_factor,
dFLimit,
zero_rate_target,
max_pressure_change);
this->primary_variables_.copyToWellState(*this, getRefDensity(),
@ -649,7 +638,8 @@ namespace Opm
const WellState& well_state,
DeferredLogger& deferred_logger)
{
updatePrimaryVariables(well_state, deferred_logger);
const auto& summary_state = ebosSimulator.vanguard().summaryState();
updatePrimaryVariables(summary_state, well_state, deferred_logger);
initPrimaryVariablesEvaluation();
computePerfCellPressDiffs(ebosSimulator);
computeInitialSegmentFluids(ebosSimulator);
@ -1492,7 +1482,8 @@ namespace Opm
this->regularize_ = true;
deferred_logger.debug(sstr.str());
}
updateWellState(dx_well, well_state, deferred_logger, relaxation_factor);
const auto& summary_state = ebosSimulator.vanguard().summaryState();
updateWellState(summary_state, dx_well, well_state, deferred_logger, relaxation_factor);
initPrimaryVariablesEvaluation();
}

View File

@ -156,7 +156,8 @@ namespace Opm
/// using the solution x to recover the solution xw for wells and applying
/// xw to update Well State
void recoverWellSolutionAndUpdateWellState(const BVector& x,
void recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
const BVector& x,
WellState& well_state,
DeferredLogger& deferred_logger) override;
@ -166,9 +167,13 @@ namespace Opm
std::vector<double>& well_potentials,
DeferredLogger& deferred_logger) /* const */ override;
void updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) override;
void updatePrimaryVariables(const SummaryState& summary_state,
const WellState& well_state,
DeferredLogger& deferred_logger) override;
virtual void solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger) override;
void solveEqAndUpdateWellState(const SummaryState& summary_state,
WellState& well_state,
DeferredLogger& deferred_logger);
virtual void calculateExplicitQuantities(const Simulator& ebosSimulator,
const WellState& well_state,
@ -252,7 +257,8 @@ namespace Opm
bool regularize_;
// updating the well_state based on well solution dwells
void updateWellState(const BVectorWell& dwells,
void updateWellState(const SummaryState& summary_state,
const BVectorWell& dwells,
WellState& well_state,
DeferredLogger& deferred_logger);
@ -359,7 +365,7 @@ namespace Opm
DeferredLogger& deferred_logger) const;
void updatePrimaryVariablesNewton(const BVectorWell& dwells,
const WellState& well_state,
const bool zero_rate_target,
DeferredLogger& deferred_logger);
void updateWellStateFromPrimaryVariables(WellState& well_state, DeferredLogger& deferred_logger) const;

View File

@ -143,7 +143,7 @@ assembleControlEq(const WellState& well_state,
bhp_from_thp,
control_eq,
deferred_logger);
} else if (rateControlWithZeroTarget(well_state.well(well_.indexOfWell()).production_cmode, prod_controls)) {
} else if (wellhelpers::rateControlWithZeroTarget(well_state.well(well_.indexOfWell()).production_cmode, prod_controls)) {
// Production mode, zero target. Treat as STOP.
control_eq = primary_variables.eval(PrimaryVariables::WQTotal);
} else {

View File

@ -81,7 +81,7 @@ Scalar relaxationFactorRate(const Scalar old_value,
const Scalar original_total_rate = old_value;
const Scalar possible_update_total_rate = old_value - newton_update;
// 0.8 here is a experimental value, which remains to be optimized
// 0.8 here is an experimental value, which remains to be optimized
// if the original rate is zero or possible_update_total_rate is zero, relaxation_factor will
// always be 1.0, more thoughts might be needed.
if (original_total_rate * possible_update_total_rate < 0.) { // sign changed
@ -121,7 +121,9 @@ resize(const int numWellEq)
template<class FluidSystem, class Indices, class Scalar>
void StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::
update(const WellState& well_state, DeferredLogger& deferred_logger)
update(const WellState& well_state,
const bool zero_rate_target,
DeferredLogger& deferred_logger)
{
static constexpr int Water = BlackoilPhases::Aqua;
static constexpr int Oil = BlackoilPhases::Liquid;
@ -158,6 +160,9 @@ update(const WellState& well_state, DeferredLogger& deferred_logger)
}
} else {
value_[WQTotal] = total_well_rate;
if (zero_rate_target) {
value_[WQTotal] = 0.;
}
}
if (std::abs(total_well_rate) > 0.) {
@ -240,6 +245,7 @@ updatePolyMW(const WellState& well_state)
template<class FluidSystem, class Indices, class Scalar>
void StandardWellPrimaryVariables<FluidSystem,Indices,Scalar>::
updateNewton(const BVectorWell& dwells,
const bool zero_rate_target,
[[maybe_unused]] const double dFLimit,
const double dBHPLimit)
{
@ -275,6 +281,10 @@ updateNewton(const BVectorWell& dwells,
// updating the total rates Q_t
value_[WQTotal] = value_[WQTotal] - dwells[0][WQTotal] * relaxation_factor_rate;
if (zero_rate_target) {
value_[WQTotal] = 0.;
}
// TODO: here, we make sure it is zero for zero rated wells
// updating the bottom hole pressure
const int sign1 = dwells[0][Bhp] > 0 ? 1: -1;

View File

@ -101,13 +101,16 @@ public:
int numWellEq() const { return numWellEq_; }
//! \brief Copy values from well state.
void update(const WellState& well_state, DeferredLogger& deferred_logger);
void update(const WellState& well_state,
const bool zero_rate_target,
DeferredLogger& deferred_logger);
//! \brief Copy polymer molecular weigt values from well state.
void updatePolyMW(const WellState& well_state);
//! \brief Update values from newton update vector.
void updateNewton(const BVectorWell& dwells,
const bool zero_rate_target,
const double dFLimit,
const double dBHPLimit);

View File

@ -993,13 +993,15 @@ namespace Opm
template<typename TypeTag>
void
StandardWell<TypeTag>::
updateWellState(const BVectorWell& dwells,
updateWellState(const SummaryState& summary_state,
const BVectorWell& dwells,
WellState& well_state,
DeferredLogger& deferred_logger)
{
if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
updatePrimaryVariablesNewton(dwells, well_state, deferred_logger);
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
updatePrimaryVariablesNewton(dwells, zero_rate_target, deferred_logger);
updateWellStateFromPrimaryVariables(well_state, deferred_logger);
Base::calculateReservoirRates(well_state.well(this->index_of_well_));
@ -1013,12 +1015,12 @@ namespace Opm
void
StandardWell<TypeTag>::
updatePrimaryVariablesNewton(const BVectorWell& dwells,
const WellState& /* well_state */,
const bool zero_rate_target,
DeferredLogger& deferred_logger)
{
const double dFLimit = this->param_.dwell_fraction_max_;
const double dBHPLimit = this->param_.dbhp_max_rel_;
this->primary_variables_.updateNewton(dwells, dFLimit, dBHPLimit);
this->primary_variables_.updateNewton(dwells, zero_rate_target, dFLimit, dBHPLimit);
// for the water velocity and skin pressure
if constexpr (Base::has_polymermw) {
@ -1581,7 +1583,9 @@ namespace Opm
template<typename TypeTag>
void
StandardWell<TypeTag>::
solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger)
solveEqAndUpdateWellState(const SummaryState& summary_state,
WellState& well_state,
DeferredLogger& deferred_logger)
{
if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
@ -1591,7 +1595,7 @@ namespace Opm
dx_well[0].resize(this->primary_variables_.numWellEq());
this->linSys_.solve( dx_well);
updateWellState(dx_well, well_state, deferred_logger);
updateWellState(summary_state, dx_well, well_state, deferred_logger);
}
@ -1605,7 +1609,8 @@ namespace Opm
const WellState& well_state,
DeferredLogger& deferred_logger)
{
updatePrimaryVariables(well_state, deferred_logger);
const auto& summary_state = ebosSimulator.vanguard().summaryState();
updatePrimaryVariables(summary_state, well_state, deferred_logger);
initPrimaryVariablesEvaluation();
computeWellConnectionPressures(ebosSimulator, well_state, deferred_logger);
this->computeAccumWell();
@ -1648,7 +1653,8 @@ namespace Opm
template<typename TypeTag>
void
StandardWell<TypeTag>::
recoverWellSolutionAndUpdateWellState(const BVector& x,
recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
const BVector& x,
WellState& well_state,
DeferredLogger& deferred_logger)
{
@ -1658,7 +1664,7 @@ namespace Opm
xw[0].resize(this->primary_variables_.numWellEq());
this->linSys_.recoverSolutionWell(x, xw);
updateWellState(xw, well_state, deferred_logger);
updateWellState(summary_state, xw, well_state, deferred_logger);
}
@ -1754,7 +1760,7 @@ namespace Opm
" potentials are computed based on unconverged solution";
deferred_logger.debug(msg);
}
well_copy.updatePrimaryVariables(well_state_copy, deferred_logger);
well_copy.updatePrimaryVariables(summary_state, well_state_copy, deferred_logger);
well_copy.computeWellConnectionPressures(ebosSimulator, well_state_copy, deferred_logger);
well_copy.initPrimaryVariablesEvaluation();
well_copy.computeWellRatesWithBhp(ebosSimulator, bhp, well_flux, deferred_logger);
@ -1970,11 +1976,14 @@ namespace Opm
template<typename TypeTag>
void
StandardWell<TypeTag>::
updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger)
updatePrimaryVariables(const SummaryState& summary_state,
const WellState& well_state,
DeferredLogger& deferred_logger)
{
if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
this->primary_variables_.update(well_state, deferred_logger);
const bool zero_rate_target = this->wellUnderZeroProductionRateControl(summary_state, well_state);
this->primary_variables_.update(well_state, zero_rate_target, deferred_logger);
// other primary variables related to polymer injection
if constexpr (Base::has_polymermw) {
@ -2511,7 +2520,8 @@ namespace Opm
}
++it;
solveEqAndUpdateWellState(well_state, deferred_logger);
const auto& summary_state = ebosSimulator.vanguard().summaryState();
solveEqAndUpdateWellState(summary_state, well_state, deferred_logger);
// TODO: when this function is used for well testing purposes, will need to check the controls, so that we will obtain convergence
// under the most restrictive control. Based on this converged results, we can check whether to re-open the well. Either we refactor

View File

@ -43,32 +43,6 @@
namespace Opm
{
bool rateControlWithZeroTarget(const Well::ProducerCMode mode,
const Well::ProductionControls& controls)
{
switch (mode) {
case Well::ProducerCMode::ORAT:
return controls.oil_rate == 0.0;
case Well::ProducerCMode::WRAT:
return controls.water_rate == 0.0;
case Well::ProducerCMode::GRAT:
return controls.gas_rate == 0.0;
case Well::ProducerCMode::LRAT:
return controls.liquid_rate == 0.0;
case Well::ProducerCMode::CRAT:
// Unsupported, will cause exception elsewhere, treat as nonzero target here.
return false;
case Well::ProducerCMode::RESV:
if (controls.prediction_mode) {
return controls.resv_rate == 0.0;
} else {
return controls.water_rate == 0.0 && controls.oil_rate == 0.0 && controls.gas_rate == 0.0;
}
default:
return false;
}
}
template<class FluidSystem>
WellAssemble<FluidSystem>::
WellAssemble(const WellInterfaceFluidSystem<FluidSystem>& well)

View File

@ -44,10 +44,6 @@ class WellState;
class WellInjectionControls;
class WellProductionControls;
/// Helper to avoid singular control equations.
bool rateControlWithZeroTarget(const WellProducerCMode mode,
const WellProductionControls& controls);
template<class FluidSystem>
class WellAssemble {
static constexpr int Water = BlackoilPhases::Aqua;

View File

@ -25,6 +25,9 @@
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/input/eclipse/Schedule/Well/WellProductionControls.hpp>
#include <opm/input/eclipse/Schedule/Well/WellEnums.hpp>
#include <opm/simulators/wells/ParallelWellInfo.hpp>
#include <fmt/format.h>
@ -168,6 +171,33 @@ DenseMatrix transposeDenseDynMatrix(const DenseMatrix& M)
return tmp;
}
bool rateControlWithZeroTarget(const WellProducerCMode& mode,
const WellProductionControls& controls)
{
switch (mode) {
case WellProducerCMode::ORAT:
return controls.oil_rate == 0.0;
case WellProducerCMode::WRAT:
return controls.water_rate == 0.0;
case WellProducerCMode::GRAT:
return controls.gas_rate == 0.0;
case WellProducerCMode::LRAT:
return controls.liquid_rate == 0.0;
case WellProducerCMode::CRAT:
// Unsupported, will cause exception elsewhere, treat as nonzero target here.
return false;
case WellProducerCMode::RESV:
if (controls.prediction_mode) {
return controls.resv_rate == 0.0;
} else {
return controls.water_rate == 0.0 && controls.oil_rate == 0.0 && controls.gas_rate == 0.0;
}
default:
return false;
}
}
template class ParallelStandardWellB<double>;
template<int Dim> using Vec = Dune::BlockVector<Dune::FieldVector<double,Dim>>;

View File

@ -31,6 +31,8 @@
namespace Opm {
class ParallelWellInfo;
enum class WellProducerCMode;
class WellProductionControls;
namespace wellhelpers {
@ -83,6 +85,10 @@ void sumDistributedWellEntries(Dune::DynamicMatrix<Scalar>& mat,
template <class DenseMatrix>
DenseMatrix transposeDenseDynMatrix(const DenseMatrix& M);
/// Helper to check whether the well is under zero production rate control
bool rateControlWithZeroTarget(const WellProducerCMode& mode,
const WellProductionControls& controls);
} // namespace wellhelpers
} // namespace Opm

View File

@ -156,8 +156,6 @@ public:
virtual ConvergenceReport getWellConvergence(const WellState& well_state, const std::vector<double>& B_avg, DeferredLogger& deferred_logger, const bool relax_tolerance) const = 0;
virtual void solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger) = 0;
void assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state,
@ -180,7 +178,8 @@ public:
/// using the solution x to recover the solution xw for wells and applying
/// xw to update Well State
virtual void recoverWellSolutionAndUpdateWellState(const BVector& x,
virtual void recoverWellSolutionAndUpdateWellState(const SummaryState& summary_state,
const BVector& x,
WellState& well_state,
DeferredLogger& deferred_logger) = 0;
@ -212,7 +211,9 @@ public:
const GroupState& group_state,
DeferredLogger& deferred_logger) /* const */;
virtual void updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) = 0;
virtual void updatePrimaryVariables(const SummaryState& summary_state,
const WellState& well_state,
DeferredLogger& deferred_logger) = 0;
virtual void calculateExplicitQuantities(const Simulator& ebosSimulator,
const WellState& well_state,
@ -359,7 +360,8 @@ protected:
Eval getPerfCellPressure(const FluidState& fs) const;
bool wellUnderZeroProductionRateControl(const SummaryState& summary_state,
const WellState& well_state) const;
};
}

View File

@ -26,6 +26,7 @@
#include <opm/simulators/wells/GroupState.hpp>
#include <opm/simulators/wells/TargetCalculator.hpp>
#include <opm/simulators/wells/WellBhpThpCalculator.hpp>
#include <opm/simulators/wells/WellHelpers.hpp>
#include <dune/common/version.hh>
@ -244,7 +245,7 @@ namespace Opm
this->well_control_log_.push_back(from);
updateWellStateWithTarget(ebos_simulator, group_state, well_state, deferred_logger);
updatePrimaryVariables(well_state, deferred_logger);
updatePrimaryVariables(summaryState, well_state, deferred_logger);
}
return changed;
@ -269,7 +270,8 @@ namespace Opm
updateWellStateWithTarget(simulator, group_state, well_state_copy, deferred_logger);
calculateExplicitQuantities(simulator, well_state_copy, deferred_logger);
updatePrimaryVariables(well_state_copy, deferred_logger);
const auto& summary_state = simulator.vanguard().summaryState();
updatePrimaryVariables(summary_state, well_state_copy, deferred_logger);
initPrimaryVariablesEvaluation();
if (this->isProducer()) {
@ -1128,4 +1130,19 @@ namespace Opm
return fs.pressure(FluidSystem::gasPhaseIdx);
}
}
template<typename TypeTag>
bool WellInterface<TypeTag>::wellUnderZeroProductionRateControl(const SummaryState& summary_state,
const WellState& well_state) const
{
if (this->wellIsStopped()) return true;
bool zero_rate_target = false;
if (this->well_ecl_.isProducer()) {
const auto prod_controls = this->well_ecl_.productionControls(summary_state);
zero_rate_target = wellhelpers::rateControlWithZeroTarget(well_state.well(this->index_of_well_).production_cmode, prod_controls);
}
return zero_rate_target;
}
} // namespace Opm