Merge pull request #3867 from totto82/avoid_error

avoid throw for nan residuals instead return well as unconverged
This commit is contained in:
Markus Blatt 2022-04-11 10:36:31 +02:00 committed by GitHub
commit c3679fb2ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 12 deletions

View File

@ -1619,9 +1619,9 @@ assemblePressureEq(const int seg,
} }
template<typename FluidSystem, typename Indices, typename Scalar> template<typename FluidSystem, typename Indices, typename Scalar>
std::vector<Scalar> std::pair<bool, std::vector<Scalar> >
MultisegmentWellEval<FluidSystem,Indices,Scalar>:: MultisegmentWellEval<FluidSystem,Indices,Scalar>::
getWellResiduals(const std::vector<Scalar>& B_avg, getFiniteWellResiduals(const std::vector<Scalar>& B_avg,
DeferredLogger& deferred_logger) const DeferredLogger& deferred_logger) const
{ {
assert(int(B_avg.size() ) == baseif_.numComponents()); assert(int(B_avg.size() ) == baseif_.numComponents());
@ -1638,8 +1638,9 @@ getWellResiduals(const std::vector<Scalar>& B_avg,
} }
} }
if (std::isnan(residual) || std::isinf(residual)) { if (std::isnan(residual) || std::isinf(residual)) {
OPM_DEFLOG_THROW(NumericalIssue, "nan or inf value for residal get for well " << baseif_.name() deferred_logger.debug("nan or inf value for residal get for well " + baseif_.name()
<< " segment " << seg << " eq_idx " << eq_idx, deferred_logger); + " segment " + std::to_string(seg) + " eq_idx " + std::to_string(eq_idx));
return {false, residuals};
} }
if (residual > residuals[eq_idx]) { if (residual > residuals[eq_idx]) {
@ -1652,12 +1653,13 @@ getWellResiduals(const std::vector<Scalar>& B_avg,
{ {
const double control_residual = std::abs(resWell_[0][numWellEq - 1]); const double control_residual = std::abs(resWell_[0][numWellEq - 1]);
if (std::isnan(control_residual) || std::isinf(control_residual)) { if (std::isnan(control_residual) || std::isinf(control_residual)) {
OPM_DEFLOG_THROW(NumericalIssue, "nan or inf value for control residal get for well " << baseif_.name(), deferred_logger); deferred_logger.debug("nan or inf value for control residal get for well " + baseif_.name());
return {false, residuals};
} }
residuals[numWellEq] = control_residual; residuals[numWellEq] = control_residual;
} }
return residuals; return {true, residuals};
} }
template<typename FluidSystem, typename Indices, typename Scalar> template<typename FluidSystem, typename Indices, typename Scalar>

View File

@ -199,7 +199,8 @@ protected:
EvalWell getWQTotal() const; EvalWell getWQTotal() const;
std::vector<Scalar> getWellResiduals(const std::vector<Scalar>& B_avg, std::pair<bool, std::vector<Scalar> >
getFiniteWellResiduals(const std::vector<Scalar>& B_avg,
DeferredLogger& deferred_logger) const; DeferredLogger& deferred_logger) const;
double getControlTolerance(const WellState& well_state, double getControlTolerance(const WellState& well_state,

View File

@ -1369,7 +1369,14 @@ namespace Opm
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;
const std::vector<Scalar> residuals0 = this->getWellResiduals(Base::B_avg_, deferred_logger);
{
// getWellFiniteResiduals returns false for nan/inf residuals
const auto& [isFinite, residuals] = this->getFiniteWellResiduals(Base::B_avg_, deferred_logger);
if(!isFinite)
return false;
}
std::vector<std::vector<Scalar> > residual_history; std::vector<std::vector<Scalar> > residual_history;
std::vector<double> measure_history; std::vector<double> measure_history;
int it = 0; int it = 0;
@ -1394,12 +1401,20 @@ namespace Opm
break; break;
} }
residual_history.push_back(this->getWellResiduals(Base::B_avg_, deferred_logger)); {
// getFinteWellResiduals returns false for nan/inf residuals
const auto& [isFinite, residuals] = this->getFiniteWellResiduals(Base::B_avg_, deferred_logger);
if (!isFinite)
return false;
residual_history.push_back(residuals);
measure_history.push_back(this->getResidualMeasureValue(well_state, measure_history.push_back(this->getResidualMeasureValue(well_state,
residual_history[it], residual_history[it],
this->param_.tolerance_wells_, this->param_.tolerance_wells_,
this->param_.tolerance_pressure_ms_wells_, this->param_.tolerance_pressure_ms_wells_,
deferred_logger) ); deferred_logger) );
}
bool is_oscillate = false; bool is_oscillate = false;
bool is_stagnate = false; bool is_stagnate = false;