Merge pull request #3539 from totto82/wellOperIter

stop updating operability during iterations
This commit is contained in:
Tor Harald Sandve 2021-09-30 10:26:26 +02:00 committed by GitHub
commit 986930850f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 63 additions and 74 deletions

View File

@ -107,7 +107,10 @@ template<class TypeTag, class MyTypeTag>
struct EnableWellOperabilityCheck { struct EnableWellOperabilityCheck {
using type = UndefinedProperty; using type = UndefinedProperty;
}; };
template<class TypeTag, class MyTypeTag>
struct EnableWellOperabilityCheckIter {
using type = UndefinedProperty;
};
// parameters for multisegment wells // parameters for multisegment wells
template<class TypeTag, class MyTypeTag> template<class TypeTag, class MyTypeTag>
struct TolerancePressureMsWells { struct TolerancePressureMsWells {
@ -284,6 +287,10 @@ struct EnableWellOperabilityCheck<TypeTag, TTag::FlowModelParameters> {
static constexpr bool value = true; static constexpr bool value = true;
}; };
template<class TypeTag> template<class TypeTag>
struct EnableWellOperabilityCheckIter<TypeTag, TTag::FlowModelParameters> {
static constexpr bool value = false;
};
template<class TypeTag>
struct RelaxedWellFlowTol<TypeTag, TTag::FlowModelParameters> { struct RelaxedWellFlowTol<TypeTag, TTag::FlowModelParameters> {
using type = GetPropType<TypeTag, Scalar>; using type = GetPropType<TypeTag, Scalar>;
static constexpr type value = 1; static constexpr type value = 1;
@ -398,6 +405,12 @@ namespace Opm
// Whether to add influences of wells between cells to the matrix and preconditioner matrix // Whether to add influences of wells between cells to the matrix and preconditioner matrix
bool matrix_add_well_contributions_; bool matrix_add_well_contributions_;
// Whether to check well operability
bool check_well_operability_;
// Whether to check well operability during iterations
bool check_well_operability_iter_;
/// Construct from user parameters or defaults. /// Construct from user parameters or defaults.
BlackoilModelParametersEbos() BlackoilModelParametersEbos()
{ {
@ -429,6 +442,8 @@ namespace Opm
update_equations_scaling_ = EWOMS_GET_PARAM(TypeTag, bool, UpdateEquationsScaling); update_equations_scaling_ = EWOMS_GET_PARAM(TypeTag, bool, UpdateEquationsScaling);
use_update_stabilization_ = EWOMS_GET_PARAM(TypeTag, bool, UseUpdateStabilization); use_update_stabilization_ = EWOMS_GET_PARAM(TypeTag, bool, UseUpdateStabilization);
matrix_add_well_contributions_ = EWOMS_GET_PARAM(TypeTag, bool, MatrixAddWellContributions); matrix_add_well_contributions_ = EWOMS_GET_PARAM(TypeTag, bool, MatrixAddWellContributions);
check_well_operability_ = EWOMS_GET_PARAM(TypeTag, bool, EnableWellOperabilityCheck);
check_well_operability_iter_ = EWOMS_GET_PARAM(TypeTag, bool, EnableWellOperabilityCheckIter);
deck_file_name_ = EWOMS_GET_PARAM(TypeTag, std::string, EclDeckFileName); deck_file_name_ = EWOMS_GET_PARAM(TypeTag, std::string, EclDeckFileName);
} }
@ -466,6 +481,7 @@ namespace Opm
EWOMS_REGISTER_PARAM(TypeTag, bool, UseUpdateStabilization, "Try to detect and correct oscillations or stagnation during the Newton method"); EWOMS_REGISTER_PARAM(TypeTag, bool, UseUpdateStabilization, "Try to detect and correct oscillations or stagnation during the Newton method");
EWOMS_REGISTER_PARAM(TypeTag, bool, MatrixAddWellContributions, "Explicitly specify the influences of wells between cells in the Jacobian and preconditioner matrices"); EWOMS_REGISTER_PARAM(TypeTag, bool, MatrixAddWellContributions, "Explicitly specify the influences of wells between cells in the Jacobian and preconditioner matrices");
EWOMS_REGISTER_PARAM(TypeTag, bool, EnableWellOperabilityCheck, "Enable the well operability checking"); EWOMS_REGISTER_PARAM(TypeTag, bool, EnableWellOperabilityCheck, "Enable the well operability checking");
EWOMS_REGISTER_PARAM(TypeTag, bool, EnableWellOperabilityCheckIter, "Enable the well operability checking during iterations");
} }
}; };
} // namespace Opm } // namespace Opm

View File

@ -1136,7 +1136,7 @@ namespace Opm {
ConvergenceReport local_report; ConvergenceReport local_report;
const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations(); const int iterationIdx = ebosSimulator_.model().newtonMethod().numIterations();
for (const auto& well : well_container_) { for (const auto& well : well_container_) {
if (well->isOperable() ) { if (well->isOperableAndSolvable() ) {
local_report += well->getWellConvergence(this->wellState(), B_avg, local_deferredLogger, iterationIdx > param_.strict_outer_iter_wells_ ); local_report += well->getWellConvergence(this->wellState(), B_avg, local_deferredLogger, iterationIdx > param_.strict_outer_iter_wells_ );
} }
} }
@ -1178,7 +1178,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::
calculateExplicitQuantities(DeferredLogger& deferred_logger) const calculateExplicitQuantities(DeferredLogger& deferred_logger) const
{ {
// TODO: checking isOperable() ? // TODO: checking isOperableAndSolvable() ?
for (auto& well : well_container_) { for (auto& well : well_container_) {
well->calculateExplicitQuantities(ebosSimulator_, this->wellState(), deferred_logger); well->calculateExplicitQuantities(ebosSimulator_, this->wellState(), deferred_logger);
} }
@ -1285,7 +1285,7 @@ namespace Opm {
for (const auto& well : well_container_) { for (const auto& well : well_container_) {
const auto& wname = well->name(); const auto& wname = well->name();
const auto wasClosed = wellTestState.hasWellClosed(wname); const auto wasClosed = wellTestState.hasWellClosed(wname);
well->checkWellOperability(ebosSimulator_, this->wellState(), local_deferredLogger);
well->updateWellTestState(this->wellState().well(wname), simulationTime, /*writeMessageToOPMLog=*/ true, wellTestState, local_deferredLogger); well->updateWellTestState(this->wellState().well(wname), simulationTime, /*writeMessageToOPMLog=*/ true, wellTestState, local_deferredLogger);
if (!wasClosed && wellTestState.hasWellClosed(wname)) { if (!wasClosed && wellTestState.hasWellClosed(wname)) {
@ -1394,11 +1394,6 @@ namespace Opm {
prepareTimeStep(DeferredLogger& deferred_logger) prepareTimeStep(DeferredLogger& deferred_logger)
{ {
for (const auto& well : well_container_) { for (const auto& well : well_container_) {
const bool old_well_operable = well->isOperable();
well->checkWellOperability(ebosSimulator_, this->wellState(), deferred_logger);
if (!well->isOperable() ) continue;
auto& events = this->wellState().well(well->indexOfWell()).events; auto& events = this->wellState().well(well->indexOfWell()).events;
if (events.hasEvent(WellState::event_mask)) { if (events.hasEvent(WellState::event_mask)) {
well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), deferred_logger); well->updateWellStateWithTarget(ebosSimulator_, this->groupState(), this->wellState(), deferred_logger);
@ -1406,36 +1401,16 @@ namespace Opm {
// so next time step, the well does not consider to have effective events anymore. // so next time step, the well does not consider to have effective events anymore.
events.clearEvent(WellState::event_mask); events.clearEvent(WellState::event_mask);
} }
// solve the well equation initially to improve the initial solution of the well model // solve the well equation initially to improve the initial solution of the well model
if (param_.solve_welleq_initially_) { if (param_.solve_welleq_initially_) {
well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), deferred_logger); well->solveWellEquation(ebosSimulator_, this->wellState(), this->groupState(), deferred_logger);
} }
}
const bool well_operable = well->isOperable();
if (!well_operable && old_well_operable) {
const Well& well_ecl = getWellEcl(well->name());
if (well_ecl.getAutomaticShutIn()) {
deferred_logger.info(" well " + well->name() + " gets SHUT at the beginning of the time step ");
} else {
if (!well->wellIsStopped()) {
deferred_logger.info(" well " + well->name() + " gets STOPPED at the beginning of the time step ");
well->stopWell();
}
}
} else if (well_operable && !old_well_operable) {
deferred_logger.info(" well " + well->name() + " gets REVIVED at the beginning of the time step ");
well->openWell();
}
} // end of for (const auto& well : well_container_)
updatePrimaryVariables(deferred_logger); updatePrimaryVariables(deferred_logger);
} }
template<typename TypeTag> template<typename TypeTag>
void void
BlackoilWellModel<TypeTag>:: BlackoilWellModel<TypeTag>::

View File

@ -439,7 +439,7 @@ updatePrimaryVariables(const WellState& well_state) const
// TODO: to test using rate conversion coefficients to see if it will be better than // TODO: to test using rate conversion coefficients to see if it will be better than
// this default one // this default one
if (!baseif_.isOperable() && !baseif_.wellIsStopped()) return; if (!baseif_.isOperableAndSolvable() && !baseif_.wellIsStopped()) return;
const Well& well = baseif_.wellEcl(); const Well& well = baseif_.wellEcl();
@ -510,7 +510,7 @@ void
MultisegmentWellEval<FluidSystem,Indices,Scalar>:: MultisegmentWellEval<FluidSystem,Indices,Scalar>::
recoverSolutionWell(const BVector& x, BVectorWell& xw) const recoverSolutionWell(const BVector& x, BVectorWell& xw) const
{ {
if (!baseif_.isOperable() && !baseif_.wellIsStopped()) return; if (!baseif_.isOperableAndSolvable() && !baseif_.wellIsStopped()) return;
BVectorWell resWell = resWell_; BVectorWell resWell = resWell_;
// resWell = resWell - B * x // resWell = resWell - B * x

View File

@ -183,7 +183,7 @@ namespace Opm
MultisegmentWell<TypeTag>:: MultisegmentWell<TypeTag>::
apply(const BVector& x, BVector& Ax) const apply(const BVector& x, BVector& Ax) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
if ( this->param_.matrix_add_well_contributions_ ) if ( this->param_.matrix_add_well_contributions_ )
{ {
@ -210,7 +210,7 @@ namespace Opm
MultisegmentWell<TypeTag>:: MultisegmentWell<TypeTag>::
apply(BVector& r) const apply(BVector& r) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
// invDrw_ = duneD^-1 * resWell_ // invDrw_ = duneD^-1 * resWell_
const BVectorWell invDrw = mswellhelpers::applyUMFPack(this->duneD_, this->duneDSolver_, this->resWell_); const BVectorWell invDrw = mswellhelpers::applyUMFPack(this->duneD_, this->duneDSolver_, this->resWell_);
@ -227,7 +227,7 @@ namespace Opm
WellState& well_state, WellState& well_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
BVectorWell xw(1); BVectorWell xw(1);
this->recoverSolutionWell(x, xw); this->recoverSolutionWell(x, xw);
@ -484,7 +484,7 @@ namespace Opm
MultisegmentWell<TypeTag>:: MultisegmentWell<TypeTag>::
solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger) solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger)
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
// We assemble the well equations, then we check the convergence, // We assemble the well equations, then we check the convergence,
// which is why we do not put the assembleWellEq here. // which is why we do not put the assembleWellEq here.
@ -578,7 +578,7 @@ namespace Opm
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const double relaxation_factor) const const double relaxation_factor) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
const double dFLimit = this->param_.dwell_fraction_max_; const double dFLimit = this->param_.dwell_fraction_max_;
const double max_pressure_change = this->param_.max_pressure_change_ms_wells_; const double max_pressure_change = this->param_.max_pressure_change_ms_wells_;
@ -1336,7 +1336,7 @@ namespace Opm
const GroupState& group_state, const GroupState& group_state,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
if (!this->isOperable() && !this->wellIsStopped()) return true; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return true;
const int max_iter_number = this->param_.max_inner_iter_ms_wells_; const int max_iter_number = this->param_.max_inner_iter_ms_wells_;
const WellState well_state0 = well_state; const WellState well_state0 = well_state;
@ -1460,7 +1460,7 @@ namespace Opm
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
// update the upwinding segments // update the upwinding segments
this->updateUpwindingSegments(); this->updateUpwindingSegments();

View File

@ -250,7 +250,7 @@ updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_log
static constexpr int Oil = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Oil; static constexpr int Oil = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Oil;
static constexpr int Water = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Water; static constexpr int Water = WellInterfaceIndices<FluidSystem,Indices,Scalar>::Water;
if (!baseif_.isOperable() && !baseif_.wellIsStopped()) return; if (!baseif_.isOperableAndSolvable() && !baseif_.wellIsStopped()) return;
const int well_index = baseif_.indexOfWell(); const int well_index = baseif_.indexOfWell();
const int np = baseif_.numPhases(); const int np = baseif_.numPhases();

View File

@ -397,7 +397,7 @@ namespace Opm
{ {
// TODO: only_wells should be put back to save some computation // TODO: only_wells should be put back to save some computation
// for example, the matrices B C does not need to update if only_wells // for example, the matrices B C does not need to update if only_wells
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
// clear all entries // clear all entries
this->duneB_ = 0.0; this->duneB_ = 0.0;
@ -852,7 +852,7 @@ namespace Opm
WellState& well_state, WellState& well_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
updatePrimaryVariablesNewton(dwells, well_state); updatePrimaryVariablesNewton(dwells, well_state);
@ -1517,7 +1517,7 @@ namespace Opm
StandardWell<TypeTag>:: StandardWell<TypeTag>::
solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger) solveEqAndUpdateWellState(WellState& well_state, DeferredLogger& deferred_logger)
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
// We assemble the well equations, then we check the convergence, // We assemble the well equations, then we check the convergence,
// which is why we do not put the assembleWellEq here. // which is why we do not put the assembleWellEq here.
@ -1552,7 +1552,7 @@ namespace Opm
StandardWell<TypeTag>:: StandardWell<TypeTag>::
apply(const BVector& x, BVector& Ax) const apply(const BVector& x, BVector& Ax) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
if (this->param_.matrix_add_well_contributions_) if (this->param_.matrix_add_well_contributions_)
{ {
@ -1583,7 +1583,7 @@ namespace Opm
StandardWell<TypeTag>:: StandardWell<TypeTag>::
apply(BVector& r) const apply(BVector& r) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
assert( this->invDrw_.size() == this->invDuneD_.N() ); assert( this->invDrw_.size() == this->invDuneD_.N() );
@ -1598,7 +1598,7 @@ namespace Opm
StandardWell<TypeTag>:: StandardWell<TypeTag>::
recoverSolutionWell(const BVector& x, BVectorWell& xw) const recoverSolutionWell(const BVector& x, BVectorWell& xw) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
BVectorWell resWell = this->resWell_; BVectorWell resWell = this->resWell_;
// resWell = resWell - B * x // resWell = resWell - B * x
@ -1618,7 +1618,7 @@ namespace Opm
WellState& well_state, WellState& well_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
BVectorWell xw(1); BVectorWell xw(1);
xw[0].resize(this->numWellEq_); xw[0].resize(this->numWellEq_);
@ -1903,7 +1903,7 @@ namespace Opm
updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) const updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_logger) const
{ {
this->StdWellEval::updatePrimaryVariables(well_state, deferred_logger); this->StdWellEval::updatePrimaryVariables(well_state, deferred_logger);
if (!this->isOperable() && !this->wellIsStopped()) return; if (!this->isOperableAndSolvable() && !this->wellIsStopped()) return;
// other primary variables related to polymer injection // other primary variables related to polymer injection
if constexpr (Base::has_polymermw) { if constexpr (Base::has_polymermw) {

View File

@ -352,7 +352,7 @@ void WellInterfaceGeneric::updateWellTestStatePhysical(const double simulation_t
WellTestState& well_test_state, WellTestState& well_test_state,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
if (!isOperable()) { if (!isOperableAndSolvable()) {
if (well_test_state.hasWellClosed(name(), WellTestConfig::Reason::ECONOMIC) || if (well_test_state.hasWellClosed(name(), WellTestConfig::Reason::ECONOMIC) ||
well_test_state.hasWellClosed(name(), WellTestConfig::Reason::PHYSICAL) ) { well_test_state.hasWellClosed(name(), WellTestConfig::Reason::PHYSICAL) ) {
// Already closed, do nothing. // Already closed, do nothing.
@ -368,9 +368,9 @@ void WellInterfaceGeneric::updateWellTestStatePhysical(const double simulation_t
} }
} }
bool WellInterfaceGeneric::isOperable() const bool WellInterfaceGeneric::isOperableAndSolvable() const
{ {
return operability_status_.isOperable(); return operability_status_.isOperableAndSolvable();
} }
double WellInterfaceGeneric::getALQ(const WellState& well_state) const double WellInterfaceGeneric::getALQ(const WellState& well_state) const

View File

@ -82,7 +82,7 @@ public:
bool underPredictionMode() const; bool underPredictionMode() const;
// whether the well is operable // whether the well is operable
bool isOperable() const; bool isOperableAndSolvable() const;
void initCompletions(); void initCompletions();
void closeCompletions(WellTestState& wellTestState); void closeCompletions(WellTestState& wellTestState);
@ -180,7 +180,7 @@ protected:
// definition of the struct OperabilityStatus // definition of the struct OperabilityStatus
struct OperabilityStatus { struct OperabilityStatus {
bool isOperable() const { bool isOperableAndSolvable() const {
if (!operable_under_only_bhp_limit || !solvable) { if (!operable_under_only_bhp_limit || !solvable) {
return false; return false;
} else { } else {
@ -196,12 +196,11 @@ protected:
return can_obtain_bhp_with_thp_limit && obey_bhp_limit_with_thp_limit; return can_obtain_bhp_with_thp_limit && obey_bhp_limit_with_thp_limit;
} }
void reset() { void resetOperability() {
operable_under_only_bhp_limit = true; operable_under_only_bhp_limit = true;
obey_thp_limit_under_bhp_limit = true; obey_thp_limit_under_bhp_limit = true;
can_obtain_bhp_with_thp_limit = true; can_obtain_bhp_with_thp_limit = true;
obey_bhp_limit_with_thp_limit = true; obey_bhp_limit_with_thp_limit = true;
solvable = true;
} }
// whether the well can be operated under bhp limit // whether the well can be operated under bhp limit

View File

@ -246,7 +246,7 @@ namespace Opm
} }
updateWellOperability(simulator, well_state_copy, deferred_logger); updateWellOperability(simulator, well_state_copy, deferred_logger);
if ( !this->isOperable() ) { if ( !this->isOperableAndSolvable() ) {
const auto msg = fmt::format("WTEST: Well {} is not operable (physical)", this->name()); const auto msg = fmt::format("WTEST: Well {} is not operable (physical)", this->name());
deferred_logger.debug(msg); deferred_logger.debug(msg);
return; return;
@ -346,7 +346,7 @@ namespace Opm
const GroupState& group_state, const GroupState& group_state,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
if (!this->isOperable()) if (!this->isOperableAndSolvable())
return; return;
// keep a copy of the original well state // keep a copy of the original well state
@ -357,10 +357,6 @@ namespace Opm
const int max_iter = param_.max_welleq_iter_; const int max_iter = param_.max_welleq_iter_;
deferred_logger.debug("Compute initial well solution for well " + this->name() + ". Failed to converge in " deferred_logger.debug("Compute initial well solution for well " + this->name() + ". Failed to converge in "
+ std::to_string(max_iter) + " iterations"); + std::to_string(max_iter) + " iterations");
// the well operability system currently works only for producers in prediction mode
if (this->shutUnsolvableWells())
this->operability_status_.solvable = false;
well_state = well_state0; well_state = well_state0;
} }
} }
@ -376,21 +372,25 @@ namespace Opm
const GroupState& group_state, const GroupState& group_state,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
const bool old_well_operable = this->operability_status_.isOperable(); const bool old_well_operable = this->operability_status_.isOperableAndSolvable();
checkWellOperability(ebosSimulator, well_state, deferred_logger);
if (param_.check_well_operability_iter_)
checkWellOperability(ebosSimulator, well_state, deferred_logger);
// only use inner well iterations for the first newton iterations. // only use inner well iterations for the first newton iterations.
const int iteration_idx = ebosSimulator.model().newtonMethod().numIterations(); const int iteration_idx = ebosSimulator.model().newtonMethod().numIterations();
bool converged = true; if (iteration_idx < param_.max_niter_inner_well_iter_) {
if (iteration_idx < param_.max_niter_inner_well_iter_) this->operability_status_.solvable = true;
converged = this->iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger); bool converged = this->iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger);
// unsolvable wells are treated as not operable and will not be solved for in this iteration. // unsolvable wells are treated as not operable and will not be solved for in this iteration.
if (!converged) { if (!converged) {
if (this->shutUnsolvableWells()) if (this->shutUnsolvableWells())
this->operability_status_.solvable = false; this->operability_status_.solvable = false;
}
} }
const bool well_operable = this->operability_status_.isOperable();
const bool well_operable = this->operability_status_.isOperableAndSolvable();
if (!well_operable && old_well_operable) { if (!well_operable && old_well_operable) {
if (this->well_ecl_.getAutomaticShutIn()) { if (this->well_ecl_.getAutomaticShutIn()) {
deferred_logger.info(" well " + this->name() + " gets SHUT during iteration "); deferred_logger.info(" well " + this->name() + " gets SHUT during iteration ");
@ -454,8 +454,7 @@ namespace Opm
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
const bool checkOperability = EWOMS_GET_PARAM(TypeTag, bool, EnableWellOperabilityCheck); if (!param_.check_well_operability_) {
if (!checkOperability) {
return; return;
} }
@ -497,7 +496,7 @@ namespace Opm
const WellState& well_state, const WellState& well_state,
DeferredLogger& deferred_logger) DeferredLogger& deferred_logger)
{ {
this->operability_status_.reset(); this->operability_status_.resetOperability();
auto current_control = well_state.well(this->index_of_well_).production_cmode; auto current_control = well_state.well(this->index_of_well_).production_cmode;
// Operability checking is not free // Operability checking is not free