mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-26 01:01:00 -06:00
Add inner iterations for standard wells also
This commit is contained in:
parent
c1effde738
commit
fc45b1bd47
@ -136,8 +136,8 @@ public:
|
||||
EWOMS_HIDE_PARAM(TypeTag, UseMultisegmentWell);
|
||||
EWOMS_HIDE_PARAM(TypeTag, TolerancePressureMsWells);
|
||||
EWOMS_HIDE_PARAM(TypeTag, MaxPressureChangeMsWells);
|
||||
EWOMS_HIDE_PARAM(TypeTag, UseInnerIterationsMsWells);
|
||||
EWOMS_HIDE_PARAM(TypeTag, MaxInnerIterMsWells);
|
||||
EWOMS_HIDE_PARAM(TypeTag, UseInnerIterationsWells);
|
||||
EWOMS_HIDE_PARAM(TypeTag, MaxInnerIterWells);
|
||||
EWOMS_HIDE_PARAM(TypeTag, MaxSinglePrecisionDays);
|
||||
EWOMS_HIDE_PARAM(TypeTag, MaxStrictIter);
|
||||
EWOMS_HIDE_PARAM(TypeTag, SolveWelleqInitially);
|
||||
|
@ -29,6 +29,9 @@ BEGIN_PROPERTIES
|
||||
|
||||
NEW_TYPE_TAG(FlowModelParameters);
|
||||
|
||||
NEW_PROP_TAG(Scalar);
|
||||
NEW_PROP_TAG(EclDeckFileName);
|
||||
|
||||
NEW_PROP_TAG(DbhpMaxRel);
|
||||
NEW_PROP_TAG(DwellFractionMax);
|
||||
NEW_PROP_TAG(MaxResidualAllowed);
|
||||
@ -77,13 +80,8 @@ SET_SCALAR_PROP(FlowModelParameters, TolerancePressureMsWells, 0.01*1e5);
|
||||
SET_SCALAR_PROP(FlowModelParameters, MaxPressureChangeMsWells, 10*1e5);
|
||||
SET_BOOL_PROP(FlowModelParameters, UseInnerIterationsMsWells, true);
|
||||
SET_INT_PROP(FlowModelParameters, MaxInnerIterMsWells, 100);
|
||||
SET_INT_PROP(FlowModelParameters, StrictInnerIterMsWells, 40);
|
||||
SET_SCALAR_PROP(FlowModelParameters, RegularizationFactorMsw, 1);
|
||||
SET_BOOL_PROP(FlowModelParameters, EnableWellOperabilityCheck, true);
|
||||
|
||||
SET_SCALAR_PROP(FlowModelParameters, RelaxedFlowTolInnerIterMsw, 1);
|
||||
SET_SCALAR_PROP(FlowModelParameters, RelaxedPressureTolInnerIterMsw, 0.5e5);
|
||||
|
||||
// if openMP is available, determine the number threads per process automatically.
|
||||
#if _OPENMP
|
||||
SET_INT_PROP(FlowModelParameters, ThreadsPerProcess, -1);
|
||||
@ -120,12 +118,6 @@ namespace Opm
|
||||
double tolerance_well_control_;
|
||||
/// Tolerance for the pressure equations for multisegment wells
|
||||
double tolerance_pressure_ms_wells_;
|
||||
|
||||
/// Relaxed tolerance for the inner iteration for the MSW flow solution
|
||||
double relaxed_inner_tolerance_flow_ms_well_;
|
||||
/// Relaxed tolerance for the inner iteration for the MSW pressure solution
|
||||
double relaxed_inner_tolerance_pressure_ms_well_;
|
||||
|
||||
/// Maximum pressure change over an iteratio for ms wells
|
||||
double max_pressure_change_ms_wells_;
|
||||
|
||||
@ -135,12 +127,6 @@ namespace Opm
|
||||
/// Maximum inner iteration number for ms wells
|
||||
int max_inner_iter_ms_wells_;
|
||||
|
||||
/// Strict inner iteration number for ms wells
|
||||
int strict_inner_iter_ms_wells_;
|
||||
|
||||
/// Regularization factor for ms wells
|
||||
int regularization_factor_ms_wells_;
|
||||
|
||||
/// Maximum iteration number of the well equation solution
|
||||
int max_welleq_iter_;
|
||||
|
||||
@ -187,13 +173,9 @@ namespace Opm
|
||||
max_welleq_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxWelleqIter);
|
||||
use_multisegment_well_ = EWOMS_GET_PARAM(TypeTag, bool, UseMultisegmentWell);
|
||||
tolerance_pressure_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, TolerancePressureMsWells);
|
||||
relaxed_inner_tolerance_flow_ms_well_ = EWOMS_GET_PARAM(TypeTag, Scalar, RelaxedFlowTolInnerIterMsw);
|
||||
relaxed_inner_tolerance_pressure_ms_well_ = EWOMS_GET_PARAM(TypeTag, Scalar, RelaxedPressureTolInnerIterMsw);
|
||||
max_pressure_change_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, MaxPressureChangeMsWells);
|
||||
use_inner_iterations_ms_wells_ = EWOMS_GET_PARAM(TypeTag, bool, UseInnerIterationsMsWells);
|
||||
max_inner_iter_ms_wells_ = EWOMS_GET_PARAM(TypeTag, int, MaxInnerIterMsWells);
|
||||
strict_inner_iter_ms_wells_ = EWOMS_GET_PARAM(TypeTag, int, StrictInnerIterMsWells);
|
||||
regularization_factor_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, RegularizationFactorMsw);
|
||||
maxSinglePrecisionTimeStep_ = EWOMS_GET_PARAM(TypeTag, Scalar, MaxSinglePrecisionDays) *24*60*60;
|
||||
max_strict_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxStrictIter);
|
||||
solve_welleq_initially_ = EWOMS_GET_PARAM(TypeTag, bool, SolveWelleqInitially);
|
||||
@ -217,13 +199,9 @@ namespace Opm
|
||||
EWOMS_REGISTER_PARAM(TypeTag, int, MaxWelleqIter, "Maximum number of iterations to determine solution the well equations");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, bool, UseMultisegmentWell, "Use the well model for multi-segment wells instead of the one for single-segment wells");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, Scalar, TolerancePressureMsWells, "Tolerance for the pressure equations for multi-segment wells");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, Scalar, RelaxedFlowTolInnerIterMsw, "Relaxed tolerance for the inner iteration for the MSW flow solution");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, Scalar, RelaxedPressureTolInnerIterMsw, "Relaxed tolerance for the inner iteration for the MSW pressure solution");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, Scalar, MaxPressureChangeMsWells, "Maximum relative pressure change for a single iteration of the multi-segment well model");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, bool, UseInnerIterationsMsWells, "Use nested iterations for multi-segment wells");
|
||||
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, Scalar, RegularizationFactorMsw, "Regularization factor for ms wells");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, Scalar, MaxSinglePrecisionDays, "Maximum time step size where single precision floating point arithmetic can be used solving for the linear systems of equations");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, int, MaxStrictIter, "Maximum number of Newton iterations before relaxed tolerances are used for the CNV convergence criterion");
|
||||
EWOMS_REGISTER_PARAM(TypeTag, bool, SolveWelleqInitially, "Fully solve the well equations before each iteration of the reservoir model");
|
||||
|
@ -122,6 +122,14 @@ namespace Opm
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger) override;
|
||||
|
||||
virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
||||
const std::vector<Scalar>& B_avg,
|
||||
const double dt,
|
||||
const Well::InjectionControls& inj_controls,
|
||||
const Well::ProductionControls& prod_controls,
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger) override;
|
||||
|
||||
/// updating the well state based the current control mode
|
||||
virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
|
||||
WellState& well_state,
|
||||
@ -416,13 +424,6 @@ namespace Opm
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger);
|
||||
|
||||
void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
||||
const double dt,
|
||||
const Well::InjectionControls& inj_controls,
|
||||
const Well::ProductionControls& prod_controls,
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger);
|
||||
|
||||
virtual void wellTestingPhysical(const Simulator& simulator, const std::vector<double>& B_avg,
|
||||
const double simulation_time, const int report_step,
|
||||
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger) override;
|
||||
|
@ -262,13 +262,13 @@ namespace Opm
|
||||
const auto inj_controls = well_ecl_.isInjector() ? well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0);
|
||||
const auto prod_controls = well_ecl_.isProducer() ? well_ecl_.productionControls(summary_state) : Well::ProductionControls(0);
|
||||
|
||||
const bool use_inner_iterations = param_.use_inner_iterations_ms_wells_;
|
||||
const bool use_inner_iterations = param_.use_inner_iterations_wells_;
|
||||
if (use_inner_iterations) {
|
||||
|
||||
iterateWellEquations(ebosSimulator, B_avg, dt, inj_controls, prod_controls, well_state, deferred_logger);
|
||||
}
|
||||
|
||||
assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, deferred_logger);
|
||||
assembleWellEqWithoutIteration(ebosSimulator, B_avg, dt, inj_controls, prod_controls, well_state, deferred_logger);
|
||||
}
|
||||
|
||||
|
||||
@ -2383,7 +2383,7 @@ namespace Opm
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger)
|
||||
{
|
||||
const int max_iter_number = param_.max_inner_iter_ms_wells_;
|
||||
const int max_iter_number = param_.max_inner_iter_wells_;
|
||||
const WellState well_state0 = well_state;
|
||||
const std::vector<Scalar> residuals0 = getWellResiduals(B_avg);
|
||||
std::vector<std::vector<Scalar> > residual_history;
|
||||
@ -2397,7 +2397,7 @@ namespace Opm
|
||||
bool relax_convergence = false;
|
||||
for (; it < max_iter_number; ++it, ++debug_cost_counter_) {
|
||||
|
||||
assembleWellEqWithoutIteration(ebosSimulator, dt, inj_controls, prod_controls, well_state, deferred_logger);
|
||||
assembleWellEqWithoutIteration(ebosSimulator, B_avg, dt, inj_controls, prod_controls, well_state, deferred_logger);
|
||||
|
||||
const BVectorWell dx_well = mswellhelpers::invDXDirect(duneD_, resWell_);
|
||||
|
||||
@ -2491,6 +2491,7 @@ namespace Opm
|
||||
void
|
||||
MultisegmentWell<TypeTag>::
|
||||
assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
||||
const std::vector<Scalar>& /* B_avg */,
|
||||
const double dt,
|
||||
const Well::InjectionControls& inj_controls,
|
||||
const Well::ProductionControls& prod_controls,
|
||||
|
@ -172,6 +172,14 @@ namespace Opm
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger) override;
|
||||
|
||||
virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
||||
const std::vector<Scalar>& B_avg,
|
||||
const double dt,
|
||||
const Well::InjectionControls& inj_controls,
|
||||
const Well::ProductionControls& prod_controls,
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger) override;
|
||||
|
||||
virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger) const override;
|
||||
|
@ -509,15 +509,37 @@ namespace Opm
|
||||
}
|
||||
|
||||
|
||||
template<typename TypeTag>
|
||||
void
|
||||
StandardWell<TypeTag>::
|
||||
assembleWellEq(const Simulator& ebosSimulator,
|
||||
const std::vector<Scalar>& B_avg,
|
||||
const double dt,
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger)
|
||||
{
|
||||
const bool use_inner_iterations = param_.use_inner_iterations_wells_;
|
||||
const auto& summary_state = ebosSimulator.vanguard().summaryState();
|
||||
const auto inj_controls = well_ecl_.isInjector() ? well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0);
|
||||
const auto prod_controls = well_ecl_.isProducer() ? well_ecl_.productionControls(summary_state) : Well::ProductionControls(0);
|
||||
if (use_inner_iterations) {
|
||||
Base::solveWellEqUntilConverged(ebosSimulator, B_avg, well_state, deferred_logger);
|
||||
}
|
||||
assembleWellEqWithoutIteration(ebosSimulator, B_avg, dt, inj_controls, prod_controls, well_state, deferred_logger);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename TypeTag>
|
||||
void
|
||||
StandardWell<TypeTag>::
|
||||
assembleWellEq(const Simulator& ebosSimulator,
|
||||
assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
||||
const std::vector<Scalar>& /* B_avg */,
|
||||
const double dt,
|
||||
const Well::InjectionControls& /*inj_controls*/,
|
||||
const Well::ProductionControls& /*prod_controls*/,
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger)
|
||||
{
|
||||
|
@ -168,6 +168,15 @@ namespace Opm
|
||||
Opm::DeferredLogger& deferred_logger
|
||||
) = 0;
|
||||
|
||||
virtual void assembleWellEqWithoutIteration(const Simulator& ebosSimulator,
|
||||
const std::vector<Scalar>& B_avg,
|
||||
const double dt,
|
||||
const Well::InjectionControls& inj_controls,
|
||||
const Well::ProductionControls& prod_controls,
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger
|
||||
) = 0;
|
||||
|
||||
void updateWellTestState(const WellState& well_state,
|
||||
const double& simulationTime,
|
||||
const bool& writeMessageToOPMLog,
|
||||
|
@ -1289,13 +1289,15 @@ namespace Opm
|
||||
WellState& well_state,
|
||||
Opm::DeferredLogger& deferred_logger)
|
||||
{
|
||||
const int max_iter = param_.max_welleq_iter_;
|
||||
const int max_iter = param_.max_inner_iter_wells_;
|
||||
int it = 0;
|
||||
const double dt = 1.0; //not used for the well tests
|
||||
const double dt = ebosSimulator.timeStepSize();
|
||||
const auto& summary_state = ebosSimulator.vanguard().summaryState();
|
||||
const auto inj_controls = well_ecl_.isInjector() ? well_ecl_.injectionControls(summary_state) : Well::InjectionControls(0);
|
||||
const auto prod_controls = well_ecl_.isProducer() ? well_ecl_.productionControls(summary_state) : Well::ProductionControls(0);
|
||||
bool converged;
|
||||
WellState well_state0 = well_state;
|
||||
do {
|
||||
assembleWellEq(ebosSimulator, B_avg, dt, well_state, deferred_logger);
|
||||
assembleWellEqWithoutIteration(ebosSimulator, B_avg, dt, inj_controls, prod_controls, well_state, deferred_logger);
|
||||
|
||||
auto report = getWellConvergence(well_state, B_avg, deferred_logger);
|
||||
|
||||
@ -1369,7 +1371,7 @@ namespace Opm
|
||||
if (converged) {
|
||||
deferred_logger.debug("WellTest: Well equation for well " + name() + " converged");
|
||||
} else {
|
||||
const int max_iter = param_.max_welleq_iter_;
|
||||
const int max_iter = param_.max_inner_iter_wells_;
|
||||
deferred_logger.debug("WellTest: Well equation for well " +name() + " failed converging in "
|
||||
+ std::to_string(max_iter) + " iterations");
|
||||
well_state = well_state0;
|
||||
|
Loading…
Reference in New Issue
Block a user