mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
shut/stop unsolvable wells
This commit is contained in:
parent
2dae87fb74
commit
b5e29684f2
@ -142,6 +142,10 @@ struct MaxNewtonIterationsWithInnerWellIterations {
|
||||
using type = UndefinedProperty;
|
||||
};
|
||||
template<class TypeTag, class MyTypeTag>
|
||||
struct ShutUnsolvableWells {
|
||||
using type = UndefinedProperty;
|
||||
};
|
||||
template<class TypeTag, class MyTypeTag>
|
||||
struct MaxInnerIterWells {
|
||||
using type = UndefinedProperty;
|
||||
};
|
||||
@ -251,6 +255,10 @@ struct MaxInnerIterWells<TypeTag, TTag::FlowModelParameters> {
|
||||
static constexpr int value = 50;
|
||||
};
|
||||
template<class TypeTag>
|
||||
struct ShutUnsolvableWells<TypeTag, TTag::FlowModelParameters> {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
template<class TypeTag>
|
||||
struct AlternativeWellRateInit<TypeTag, TTag::FlowModelParameters> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
@ -341,6 +349,9 @@ namespace Opm
|
||||
/// Maximum newton iterations with inner well iterations
|
||||
int max_niter_inner_well_iter_;
|
||||
|
||||
/// Whether to shut unsolvable well
|
||||
bool shut_unsolvable_wells_;
|
||||
|
||||
/// Maximum inner iteration number for standard wells
|
||||
int max_inner_iter_wells_;
|
||||
|
||||
@ -398,6 +409,7 @@ namespace Opm
|
||||
strict_inner_iter_ms_wells_ = EWOMS_GET_PARAM(TypeTag, int, StrictInnerIterMsWells);
|
||||
regularization_factor_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, RegularizationFactorMsw);
|
||||
max_niter_inner_well_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxNewtonIterationsWithInnerWellIterations);
|
||||
shut_unsolvable_wells_ = EWOMS_GET_PARAM(TypeTag, bool, ShutUnsolvableWells);
|
||||
max_inner_iter_wells_ = EWOMS_GET_PARAM(TypeTag, int, MaxInnerIterWells);
|
||||
maxSinglePrecisionTimeStep_ = EWOMS_GET_PARAM(TypeTag, Scalar, MaxSinglePrecisionDays) *24*60*60;
|
||||
max_strict_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxStrictIter);
|
||||
@ -430,6 +442,7 @@ namespace Opm
|
||||
EWOMS_REGISTER_PARAM(TypeTag, int, MaxInnerIterMsWells, "Maximum number of inner iterations for multi-segment wells");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, int, StrictInnerIterMsWells, "Number of inner iterations for multi-segment wells with strict tolerance");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, int, MaxNewtonIterationsWithInnerWellIterations, "Maximum newton iterations with inner well iterations");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, bool, ShutUnsolvableWells, "Shut unsolvable wells");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, int, MaxInnerIterWells, "Maximum number of inner iterations for standard wells");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, bool, AlternativeWellRateInit, "Use alternative well rate initialization procedure");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, Scalar, RegularizationFactorMsw, "Regularization factor for ms wells");
|
||||
|
@ -1262,6 +1262,7 @@ namespace Opm {
|
||||
std::string exc_msg;
|
||||
try {
|
||||
for (const auto& well : well_container_) {
|
||||
const bool old_well_operable = well->isOperable();
|
||||
well->checkWellOperability(ebosSimulator_, this->wellState(), deferred_logger);
|
||||
|
||||
if (!well->isOperable() ) continue;
|
||||
@ -1279,6 +1280,22 @@ namespace Opm {
|
||||
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);
|
||||
} catch (const std::runtime_error& e) {
|
||||
|
@ -340,6 +340,8 @@ protected:
|
||||
|
||||
void solveWellForTesting(const Simulator& ebosSimulator, WellState& well_state, const GroupState& group_state,
|
||||
DeferredLogger& deferred_logger);
|
||||
|
||||
bool shutUnsolvableWells() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ protected:
|
||||
// definition of the struct OperabilityStatus
|
||||
struct OperabilityStatus {
|
||||
bool isOperable() const {
|
||||
if (!operable_under_only_bhp_limit) {
|
||||
if (!operable_under_only_bhp_limit || !solvable) {
|
||||
return false;
|
||||
} else {
|
||||
return ( (isOperableUnderBHPLimit() || isOperableUnderTHPLimit()) );
|
||||
@ -197,6 +197,7 @@ protected:
|
||||
obey_thp_limit_under_bhp_limit = true;
|
||||
can_obtain_bhp_with_thp_limit = true;
|
||||
obey_bhp_limit_with_thp_limit = true;
|
||||
solvable = true;
|
||||
}
|
||||
|
||||
// whether the well can be operated under bhp limit
|
||||
@ -210,6 +211,8 @@ protected:
|
||||
bool can_obtain_bhp_with_thp_limit = true;
|
||||
// whether the well obey bhp limit when operated under thp limit
|
||||
bool obey_bhp_limit_with_thp_limit = true;
|
||||
// the well is solveable
|
||||
bool solvable = true;
|
||||
};
|
||||
|
||||
OperabilityStatus operability_status_;
|
||||
|
@ -342,12 +342,14 @@ namespace Opm
|
||||
const WellState well_state0 = well_state;
|
||||
const double dt = ebosSimulator.timeStepSize();
|
||||
const bool converged = iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger);
|
||||
if (converged) {
|
||||
deferred_logger.debug("Compute initial well solution for well " + this->name() + ". Converged");
|
||||
} else {
|
||||
if (!converged) {
|
||||
const int max_iter = param_.max_welleq_iter_;
|
||||
deferred_logger.debug("Compute initial well solution for well " + this->name() + ". Failed to converge in "
|
||||
+ 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;
|
||||
}
|
||||
}
|
||||
@ -363,13 +365,35 @@ namespace Opm
|
||||
const GroupState& group_state,
|
||||
DeferredLogger& deferred_logger)
|
||||
{
|
||||
|
||||
const bool old_well_operable = this->operability_status_.isOperable();
|
||||
checkWellOperability(ebosSimulator, well_state, deferred_logger);
|
||||
|
||||
// only use inner well iterations for the first newton iterations.
|
||||
const int iteration_idx = ebosSimulator.model().newtonMethod().numIterations();
|
||||
if (iteration_idx < param_.max_niter_inner_well_iter_) {
|
||||
this->iterateWellEquations(ebosSimulator, dt, well_state, group_state, deferred_logger);
|
||||
bool converged = true;
|
||||
if (iteration_idx < param_.max_niter_inner_well_iter_)
|
||||
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.
|
||||
if (!converged) {
|
||||
if (this->shutUnsolvableWells())
|
||||
this->operability_status_.solvable = false;
|
||||
}
|
||||
const bool well_operable = this->operability_status_.isOperable();
|
||||
if (!well_operable && old_well_operable) {
|
||||
if (this->well_ecl_.getAutomaticShutIn()) {
|
||||
deferred_logger.info(" well " + this->name() + " gets SHUT during iteration ");
|
||||
} else {
|
||||
if (!this->wellIsStopped()) {
|
||||
deferred_logger.info(" well " + this->name() + " gets STOPPED during iteration ");
|
||||
this->stopWell();
|
||||
changed_to_stopped_this_step_ = true;
|
||||
}
|
||||
}
|
||||
} else if (well_operable && !old_well_operable) {
|
||||
deferred_logger.info(" well " + this->name() + " gets REVIVED during iteration ");
|
||||
this->openWell();
|
||||
changed_to_stopped_this_step_ = false;
|
||||
}
|
||||
|
||||
const auto& summary_state = ebosSimulator.vanguard().summaryState();
|
||||
@ -498,27 +522,18 @@ namespace Opm
|
||||
return;
|
||||
}
|
||||
|
||||
const bool old_well_operable = this->operability_status_.isOperable();
|
||||
|
||||
updateWellOperability(ebos_simulator, well_state, deferred_logger);
|
||||
}
|
||||
|
||||
const bool well_operable = this->operability_status_.isOperable();
|
||||
|
||||
if (!well_operable && old_well_operable) {
|
||||
if (this->well_ecl_.getAutomaticShutIn()) {
|
||||
deferred_logger.info(" well " + this->name() + " gets SHUT during iteration ");
|
||||
} else {
|
||||
if (!this->wellIsStopped()) {
|
||||
deferred_logger.info(" well " + this->name() + " gets STOPPED during iteration ");
|
||||
this->stopWell();
|
||||
changed_to_stopped_this_step_ = true;
|
||||
}
|
||||
}
|
||||
} else if (well_operable && !old_well_operable) {
|
||||
deferred_logger.info(" well " + this->name() + " gets REVIVED during iteration ");
|
||||
this->openWell();
|
||||
changed_to_stopped_this_step_ = false;
|
||||
}
|
||||
template<typename TypeTag>
|
||||
bool
|
||||
WellInterface<TypeTag>::
|
||||
shutUnsolvableWells() const
|
||||
{
|
||||
bool shut_unsolvable_wells = param_.shut_unsolvable_wells_;
|
||||
// the well operability system currently works only for producers in prediction mode
|
||||
return shut_unsolvable_wells && !this->isInjector() && this->underPredictionMode();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user