Merge pull request #3512 from totto82/relaxStw

add option for relaxed convergence for stw
This commit is contained in:
Tor Harald Sandve 2021-09-15 07:56:12 +02:00 committed by GitHub
commit 8e9a43c29b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 38 deletions

View File

@ -122,19 +122,19 @@ struct MaxInnerIterMsWells {
using type = UndefinedProperty; using type = UndefinedProperty;
}; };
template<class TypeTag, class MyTypeTag> template<class TypeTag, class MyTypeTag>
struct StrictInnerIterMsWells { struct StrictInnerIterWells {
using type = UndefinedProperty; using type = UndefinedProperty;
}; };
template<class TypeTag, class MyTypeTag> template<class TypeTag, class MyTypeTag>
struct StrictOuterIterMsWells { struct RelaxedWellFlowTol {
using type = UndefinedProperty; using type = UndefinedProperty;
}; };
template<class TypeTag, class MyTypeTag> template<class TypeTag, class MyTypeTag>
struct RelaxedFlowTolInnerIterMsw { struct StrictOuterIterWells {
using type = UndefinedProperty; using type = UndefinedProperty;
}; };
template<class TypeTag, class MyTypeTag> template<class TypeTag, class MyTypeTag>
struct RelaxedPressureTolInnerIterMsw { struct RelaxedPressureTolMsw {
using type = UndefinedProperty; using type = UndefinedProperty;
}; };
template<class TypeTag, class MyTypeTag> template<class TypeTag, class MyTypeTag>
@ -267,11 +267,11 @@ struct AlternativeWellRateInit<TypeTag, TTag::FlowModelParameters> {
static constexpr bool value = true; static constexpr bool value = true;
}; };
template<class TypeTag> template<class TypeTag>
struct StrictOuterIterMsWells<TypeTag, TTag::FlowModelParameters> { struct StrictOuterIterWells<TypeTag, TTag::FlowModelParameters> {
static constexpr int value = 99; static constexpr int value = 99;
}; };
template<class TypeTag> template<class TypeTag>
struct StrictInnerIterMsWells<TypeTag, TTag::FlowModelParameters> { struct StrictInnerIterWells<TypeTag, TTag::FlowModelParameters> {
static constexpr int value = 40; static constexpr int value = 40;
}; };
template<class TypeTag> template<class TypeTag>
@ -284,12 +284,12 @@ struct EnableWellOperabilityCheck<TypeTag, TTag::FlowModelParameters> {
static constexpr bool value = true; static constexpr bool value = true;
}; };
template<class TypeTag> template<class TypeTag>
struct RelaxedFlowTolInnerIterMsw<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;
}; };
template<class TypeTag> template<class TypeTag>
struct RelaxedPressureTolInnerIterMsw<TypeTag, TTag::FlowModelParameters> { struct RelaxedPressureTolMsw<TypeTag, TTag::FlowModelParameters> {
using type = GetPropType<TypeTag, Scalar>; using type = GetPropType<TypeTag, Scalar>;
static constexpr type value = 0.5e5; static constexpr type value = 0.5e5;
}; };
@ -336,11 +336,11 @@ namespace Opm
double tolerance_well_control_; double tolerance_well_control_;
/// Tolerance for the pressure equations for multisegment wells /// Tolerance for the pressure equations for multisegment wells
double tolerance_pressure_ms_wells_; double tolerance_pressure_ms_wells_;
/// Relaxed tolerance for for the well flow residual
double relaxed_tolerance_flow_well_;
/// Relaxed tolerance for the inner iteration for the MSW flow solution /// Relaxed tolerance for the MSW pressure solution
double relaxed_inner_tolerance_flow_ms_well_; double relaxed_tolerance_pressure_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 /// Maximum pressure change over an iteratio for ms wells
double max_pressure_change_ms_wells_; double max_pressure_change_ms_wells_;
@ -348,11 +348,11 @@ namespace Opm
/// Maximum inner iteration number for ms wells /// Maximum inner iteration number for ms wells
int max_inner_iter_ms_wells_; int max_inner_iter_ms_wells_;
/// Strict inner iteration number for ms wells /// Strict inner iteration number for wells
int strict_inner_iter_ms_wells_; int strict_inner_iter_wells_;
/// Newton iteration where ms wells are stricly convergent /// Newton iteration where wells are stricly convergent
int strict_outer_iter_ms_wells_; int strict_outer_iter_wells_;
/// Regularization factor for ms wells /// Regularization factor for ms wells
int regularization_factor_ms_wells_; int regularization_factor_ms_wells_;
@ -413,12 +413,12 @@ namespace Opm
max_welleq_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxWelleqIter); max_welleq_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxWelleqIter);
use_multisegment_well_ = EWOMS_GET_PARAM(TypeTag, bool, UseMultisegmentWell); use_multisegment_well_ = EWOMS_GET_PARAM(TypeTag, bool, UseMultisegmentWell);
tolerance_pressure_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, TolerancePressureMsWells); tolerance_pressure_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, TolerancePressureMsWells);
relaxed_inner_tolerance_flow_ms_well_ = EWOMS_GET_PARAM(TypeTag, Scalar, RelaxedFlowTolInnerIterMsw); relaxed_tolerance_flow_well_ = EWOMS_GET_PARAM(TypeTag, Scalar, RelaxedWellFlowTol);
relaxed_inner_tolerance_pressure_ms_well_ = EWOMS_GET_PARAM(TypeTag, Scalar, RelaxedPressureTolInnerIterMsw); relaxed_tolerance_pressure_ms_well_ = EWOMS_GET_PARAM(TypeTag, Scalar, RelaxedPressureTolMsw);
max_pressure_change_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, MaxPressureChangeMsWells); max_pressure_change_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, MaxPressureChangeMsWells);
max_inner_iter_ms_wells_ = EWOMS_GET_PARAM(TypeTag, int, MaxInnerIterMsWells); max_inner_iter_ms_wells_ = EWOMS_GET_PARAM(TypeTag, int, MaxInnerIterMsWells);
strict_inner_iter_ms_wells_ = EWOMS_GET_PARAM(TypeTag, int, StrictInnerIterMsWells); strict_inner_iter_wells_ = EWOMS_GET_PARAM(TypeTag, int, StrictInnerIterWells);
strict_outer_iter_ms_wells_ = EWOMS_GET_PARAM(TypeTag, int, StrictOuterIterMsWells); strict_outer_iter_wells_ = EWOMS_GET_PARAM(TypeTag, int, StrictOuterIterWells);
regularization_factor_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, RegularizationFactorMsw); regularization_factor_ms_wells_ = EWOMS_GET_PARAM(TypeTag, Scalar, RegularizationFactorMsw);
max_niter_inner_well_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxNewtonIterationsWithInnerWellIterations); max_niter_inner_well_iter_ = EWOMS_GET_PARAM(TypeTag, int, MaxNewtonIterationsWithInnerWellIterations);
shut_unsolvable_wells_ = EWOMS_GET_PARAM(TypeTag, bool, ShutUnsolvableWells); shut_unsolvable_wells_ = EWOMS_GET_PARAM(TypeTag, bool, ShutUnsolvableWells);
@ -448,12 +448,12 @@ namespace Opm
EWOMS_REGISTER_PARAM(TypeTag, int, MaxWelleqIter, "Maximum number of iterations to determine solution the well equations"); 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, 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, 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, RelaxedWellFlowTol, "Relaxed tolerance for the well flow residual");
EWOMS_REGISTER_PARAM(TypeTag, Scalar, RelaxedPressureTolInnerIterMsw, "Relaxed tolerance for the inner iteration for the MSW pressure solution"); EWOMS_REGISTER_PARAM(TypeTag, Scalar, RelaxedPressureTolMsw, "Relaxed tolerance 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, Scalar, MaxPressureChangeMsWells, "Maximum relative pressure change for a single iteration of the multi-segment well model");
EWOMS_REGISTER_PARAM(TypeTag, int, MaxInnerIterMsWells, "Maximum number of inner 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, int, StrictInnerIterWells, "Number of inner well iterations with strict tolerance");
EWOMS_REGISTER_PARAM(TypeTag, int, StrictOuterIterMsWells, "Number of newton iterations for which multi-segment wells are checked with strict tolerance"); EWOMS_REGISTER_PARAM(TypeTag, int, StrictOuterIterWells, "Number of newton iterations for which wells are checked with strict tolerance");
EWOMS_REGISTER_PARAM(TypeTag, int, MaxNewtonIterationsWithInnerWellIterations, "Maximum newton iterations with inner well iterations"); 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, bool, ShutUnsolvableWells, "Shut unsolvable wells");
EWOMS_REGISTER_PARAM(TypeTag, int, MaxInnerIterWells, "Maximum number of inner iterations for standard wells"); EWOMS_REGISTER_PARAM(TypeTag, int, MaxInnerIterWells, "Maximum number of inner iterations for standard wells");

View File

@ -1181,7 +1181,7 @@ namespace Opm {
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->isOperable() ) {
local_report += well->getWellConvergence(this->wellState(), B_avg, local_deferredLogger, iterationIdx > param_.strict_outer_iter_ms_wells_ ); local_report += well->getWellConvergence(this->wellState(), B_avg, local_deferredLogger, iterationIdx > param_.strict_outer_iter_wells_ );
} }
} }
DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger); DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);

View File

@ -168,9 +168,9 @@ namespace Opm
deferred_logger, deferred_logger,
this->param_.max_residual_allowed_, this->param_.max_residual_allowed_,
this->param_.tolerance_wells_, this->param_.tolerance_wells_,
this->param_.relaxed_inner_tolerance_flow_ms_well_, this->param_.relaxed_tolerance_flow_well_,
this->param_.tolerance_pressure_ms_wells_, this->param_.tolerance_pressure_ms_wells_,
this->param_.relaxed_inner_tolerance_pressure_ms_well_, this->param_.relaxed_tolerance_pressure_ms_well_,
relax_tolerance); relax_tolerance);
} }
@ -1314,7 +1314,7 @@ namespace Opm
const BVectorWell dx_well = mswellhelpers::applyUMFPack(this->duneD_, this->duneDSolver_, this->resWell_); const BVectorWell dx_well = mswellhelpers::applyUMFPack(this->duneD_, this->duneDSolver_, this->resWell_);
if (it > this->param_.strict_inner_iter_ms_wells_) if (it > this->param_.strict_inner_iter_wells_)
relax_convergence = true; relax_convergence = true;
const auto report = getWellConvergence(well_state, Base::B_avg_, deferred_logger, relax_convergence); const auto report = getWellConvergence(well_state, Base::B_avg_, deferred_logger, relax_convergence);
@ -1379,7 +1379,7 @@ namespace Opm
std::ostringstream sstr; std::ostringstream sstr;
sstr << " Well " << this->name() << " converged in " << it << " inner iterations."; sstr << " Well " << this->name() << " converged in " << it << " inner iterations.";
if (relax_convergence) if (relax_convergence)
sstr << " (A relaxed tolerance was used after "<< this->param_.strict_inner_iter_ms_wells_ << " iterations)"; sstr << " (A relaxed tolerance was used after "<< this->param_.strict_inner_iter_wells_ << " iterations)";
deferred_logger.debug(sstr.str()); deferred_logger.debug(sstr.str());
} else { } else {
std::ostringstream sstr; std::ostringstream sstr;

View File

@ -772,8 +772,10 @@ ConvergenceReport
StandardWellEval<FluidSystem,Indices,Scalar>:: StandardWellEval<FluidSystem,Indices,Scalar>::
getWellConvergence(const WellState& well_state, getWellConvergence(const WellState& well_state,
const std::vector<double>& B_avg, const std::vector<double>& B_avg,
const double tol_wells,
const double maxResidualAllowed, const double maxResidualAllowed,
const double tol_wells,
const double relaxed_tolerance_flow,
const bool relax_tolerance,
std::vector<double>& res, std::vector<double>& res,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
@ -807,7 +809,9 @@ getWellConvergence(const WellState& well_state,
report.setWellFailed({type, CR::Severity::NotANumber, compIdx, baseif_.name()}); report.setWellFailed({type, CR::Severity::NotANumber, compIdx, baseif_.name()});
} else if (well_flux_residual[compIdx] > maxResidualAllowed) { } else if (well_flux_residual[compIdx] > maxResidualAllowed) {
report.setWellFailed({type, CR::Severity::TooLarge, compIdx, baseif_.name()}); report.setWellFailed({type, CR::Severity::TooLarge, compIdx, baseif_.name()});
} else if (well_flux_residual[compIdx] > tol_wells) { } else if (!relax_tolerance && well_flux_residual[compIdx] > tol_wells) {
report.setWellFailed({type, CR::Severity::Normal, compIdx, baseif_.name()});
} else if (well_flux_residual[compIdx] > relaxed_tolerance_flow) {
report.setWellFailed({type, CR::Severity::Normal, compIdx, baseif_.name()}); report.setWellFailed({type, CR::Severity::Normal, compIdx, baseif_.name()});
} }
} }

View File

@ -148,8 +148,10 @@ protected:
ConvergenceReport getWellConvergence(const WellState& well_state, ConvergenceReport getWellConvergence(const WellState& well_state,
const std::vector<double>& B_avg, const std::vector<double>& B_avg,
const double tol_wells,
const double maxResidualAllowed, const double maxResidualAllowed,
const double tol_wells,
const double relaxed_tolerance_flow,
const bool relax_tolerance,
std::vector<double>& res, std::vector<double>& res,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;

View File

@ -1323,20 +1323,19 @@ namespace Opm
getWellConvergence(const WellState& well_state, getWellConvergence(const WellState& well_state,
const std::vector<double>& B_avg, const std::vector<double>& B_avg,
DeferredLogger& deferred_logger, DeferredLogger& deferred_logger,
const bool /*relax_tolerance*/) const const bool relax_tolerance) const
{ {
// the following implementation assume that the polymer is always after the w-o-g phases // the following implementation assume that the polymer is always after the w-o-g phases
// For the polymer, energy and foam cases, there is one more mass balance equations of reservoir than wells // For the polymer, energy and foam cases, there is one more mass balance equations of reservoir than wells
assert((int(B_avg.size()) == this->num_components_) || has_polymer || has_energy || has_foam || has_brine || has_zFraction); assert((int(B_avg.size()) == this->num_components_) || has_polymer || has_energy || has_foam || has_brine || has_zFraction);
const double tol_wells = this->param_.tolerance_wells_;
const double maxResidualAllowed = this->param_.max_residual_allowed_;
std::vector<double> res; std::vector<double> res;
ConvergenceReport report = this->StdWellEval::getWellConvergence(well_state, ConvergenceReport report = this->StdWellEval::getWellConvergence(well_state,
B_avg, B_avg,
tol_wells, this->param_.max_residual_allowed_,
maxResidualAllowed, this->param_.tolerance_wells_,
this->param_.relaxed_tolerance_flow_well_,
relax_tolerance,
res, res,
deferred_logger); deferred_logger);
checkConvergenceExtraEqs(res, report); checkConvergenceExtraEqs(res, report);