mirror of
https://github.com/OPM/opm-simulators.git
synced 2026-09-05 04:40:19 -05:00
stop updating operability during iterations
This commit is contained in:
@@ -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_operabilty_;
|
||||||
|
// Whether to check well operability during iterations
|
||||||
|
bool check_well_operabilty_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_operabilty_ = EWOMS_GET_PARAM(TypeTag, bool, EnableWellOperabilityCheck);
|
||||||
|
check_well_operabilty_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
|
||||||
|
|||||||
@@ -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)) {
|
||||||
@@ -1397,31 +1397,35 @@ namespace Opm {
|
|||||||
const bool old_well_operable = well->isOperable();
|
const bool old_well_operable = well->isOperable();
|
||||||
well->checkWellOperability(ebosSimulator_, this->wellState(), deferred_logger);
|
well->checkWellOperability(ebosSimulator_, this->wellState(), deferred_logger);
|
||||||
|
|
||||||
if (!well->isOperable() ) continue;
|
if (well->isOperable()) {
|
||||||
|
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);
|
// There is no new well control change input within a report step,
|
||||||
// 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.
|
||||||
// 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
|
|
||||||
if (param_.solve_welleq_initially_) {
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// solve the well equation initially to improve the initial solution of the well model
|
||||||
|
if (param_.solve_welleq_initially_) {
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
} else if (well_operable && !old_well_operable) {
|
} else if (well_operable && !old_well_operable) {
|
||||||
deferred_logger.info(" well " + well->name() + " gets REVIVED at the beginning of the time step ");
|
deferred_logger.info(" well " + well->name() + " gets REVIVED at the beginning of the time step ");
|
||||||
|
|||||||
@@ -201,7 +201,6 @@ protected:
|
|||||||
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
|
||||||
|
|||||||
@@ -377,19 +377,23 @@ namespace Opm
|
|||||||
DeferredLogger& deferred_logger)
|
DeferredLogger& deferred_logger)
|
||||||
{
|
{
|
||||||
const bool old_well_operable = this->operability_status_.isOperable();
|
const bool old_well_operable = this->operability_status_.isOperable();
|
||||||
checkWellOperability(ebosSimulator, well_state, deferred_logger);
|
|
||||||
|
if (param_.check_well_operabilty_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_.isOperable();
|
||||||
if (!well_operable && old_well_operable) {
|
if (!well_operable && old_well_operable) {
|
||||||
if (this->well_ecl_.getAutomaticShutIn()) {
|
if (this->well_ecl_.getAutomaticShutIn()) {
|
||||||
@@ -454,8 +458,7 @@ namespace Opm
|
|||||||
DeferredLogger& deferred_logger)
|
DeferredLogger& deferred_logger)
|
||||||
{
|
{
|
||||||
|
|
||||||
const bool checkOperability = EWOMS_GET_PARAM(TypeTag, bool, EnableWellOperabilityCheck);
|
if (!param_.check_well_operabilty_) {
|
||||||
if (!checkOperability) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user