mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #866 from atgeirr/convergence-failure-not-error
Convergence failure classification, fix for parallel logging
This commit is contained in:
commit
1edbc9f238
@ -1939,16 +1939,28 @@ namespace detail {
|
||||
if (std::isnan(mass_balance_residual[idx])
|
||||
|| std::isnan(CNV[idx])
|
||||
|| (idx < np && std::isnan(well_flux_residual[idx]))) {
|
||||
OPM_THROW(Opm::NumericalProblem, "NaN residual for phase " << materialName(idx));
|
||||
const auto msg = std::string("NaN residual for phase ") + materialName(idx);
|
||||
if (terminal_output_) {
|
||||
OpmLog::problem(msg);
|
||||
}
|
||||
OPM_THROW_NOLOG(Opm::NumericalProblem, msg);
|
||||
}
|
||||
if (mass_balance_residual[idx] > maxResidualAllowed()
|
||||
|| CNV[idx] > maxResidualAllowed()
|
||||
|| (idx < np && well_flux_residual[idx] > maxResidualAllowed())) {
|
||||
OPM_THROW(Opm::NumericalProblem, "Too large residual for phase " << materialName(idx));
|
||||
const auto msg = std::string("Too large residual for phase ") + materialName(idx);
|
||||
if (terminal_output_) {
|
||||
OpmLog::problem(msg);
|
||||
}
|
||||
OPM_THROW_NOLOG(Opm::NumericalProblem, msg);
|
||||
}
|
||||
}
|
||||
if (std::isnan(residualWell) || residualWell > maxWellResidualAllowed) {
|
||||
OPM_THROW(Opm::NumericalProblem, "NaN or too large residual for well control equation");
|
||||
const auto msg = std::string("NaN or too large residual for well control equation");
|
||||
if (terminal_output_) {
|
||||
OpmLog::problem(msg);
|
||||
}
|
||||
OPM_THROW_NOLOG(Opm::NumericalProblem, msg);
|
||||
}
|
||||
|
||||
return converged;
|
||||
@ -2004,10 +2016,18 @@ namespace detail {
|
||||
// if one of the residuals is NaN, throw exception, so that the solver can be restarted
|
||||
for (int idx = 0; idx < np; ++idx) {
|
||||
if (std::isnan(well_flux_residual[idx])) {
|
||||
OPM_THROW(Opm::NumericalProblem, "NaN residual for phase " << materialName(idx));
|
||||
const auto msg = std::string("NaN residual for phase ") + materialName(idx);
|
||||
if (terminal_output_) {
|
||||
OpmLog::problem(msg);
|
||||
}
|
||||
OPM_THROW_NOLOG(Opm::NumericalProblem, msg);
|
||||
}
|
||||
if (well_flux_residual[idx] > maxResidualAllowed()) {
|
||||
OPM_THROW(Opm::NumericalProblem, "Too large residual for phase " << materialName(idx));
|
||||
const auto msg = std::string("Too large residual for phase ") + materialName(idx);
|
||||
if (terminal_output_) {
|
||||
OpmLog::problem(msg);
|
||||
}
|
||||
OPM_THROW_NOLOG(Opm::NumericalProblem, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,7 @@ namespace Opm
|
||||
fluidprops_.reset(new BlackoilPropsAdFromDeck(*deck_, *eclipse_state_, material_law_manager_, grid));
|
||||
|
||||
// Rock compressibility.
|
||||
rock_comp_.reset(new RockCompressibility(*deck_, *eclipse_state_));
|
||||
rock_comp_.reset(new RockCompressibility(*deck_, *eclipse_state_, output_cout_));
|
||||
|
||||
// Gravity.
|
||||
assert(UgGridHelpers::dimensions(grid) == 3);
|
||||
|
@ -174,6 +174,7 @@ namespace Opm
|
||||
const boost::any& parallelInformation_arg=boost::any())
|
||||
: iterations_( 0 ),
|
||||
parallelInformation_(parallelInformation_arg),
|
||||
isIORank_(isIORank(parallelInformation_arg)),
|
||||
parameters_( param )
|
||||
{
|
||||
}
|
||||
@ -487,7 +488,11 @@ namespace Opm
|
||||
|
||||
// Check for failure of linear solver.
|
||||
if (!parameters_.ignoreConvergenceFailure_ && !result.converged) {
|
||||
OPM_THROW(LinearSolverProblem, "Convergence failure for linear solver.");
|
||||
const std::string msg("Convergence failure for linear solver.");
|
||||
if (isIORank_) {
|
||||
OpmLog::problem(msg);
|
||||
}
|
||||
OPM_THROW_NOLOG(LinearSolverProblem, msg);
|
||||
}
|
||||
|
||||
// Copy solver output to dx.
|
||||
@ -509,6 +514,7 @@ namespace Opm
|
||||
protected:
|
||||
mutable int iterations_;
|
||||
boost::any parallelInformation_;
|
||||
bool isIORank_;
|
||||
|
||||
NewtonIterationBlackoilInterleavedParameters parameters_;
|
||||
}; // end NewtonIterationBlackoilInterleavedImpl
|
||||
@ -658,7 +664,9 @@ namespace Opm
|
||||
|
||||
// Check for failure of linear solver.
|
||||
if (!result.converged) {
|
||||
OPM_THROW(LinearSolverProblem, "Convergence failure for linear solver in computePressureIncrement().");
|
||||
const std::string msg("Convergence failure for linear solver in computePressureIncrement().");
|
||||
OpmLog::problem(msg);
|
||||
OPM_THROW_NOLOG(LinearSolverProblem, msg);
|
||||
}
|
||||
|
||||
// Copy solver output to dx.
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <opm/autodiff/NewtonIterationUtilities.hpp>
|
||||
#include <opm/autodiff/AutoDiffHelpers.hpp>
|
||||
#include <opm/core/linalg/ParallelIstlInformation.hpp>
|
||||
#include <opm/common/ErrorMacros.hpp>
|
||||
|
||||
#include <opm/common/utility/platform_dependent/disable_warnings.h>
|
||||
@ -288,5 +289,24 @@ namespace Opm
|
||||
|
||||
|
||||
|
||||
|
||||
/// Return true if this is a serial run, or rank zero on an MPI run.
|
||||
bool isIORank(const boost::any& parallel_info)
|
||||
{
|
||||
#if HAVE_MPI
|
||||
if (parallel_info.type() == typeid(ParallelISTLInformation)) {
|
||||
const ParallelISTLInformation& info =
|
||||
boost::any_cast<const ParallelISTLInformation&>(parallel_info);
|
||||
return info.communicator().rank() == 0;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static_cast<void>(parallel_info); // Suppress unused argument warning.
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define OPM_NEWTONITERATIONUTILITIES_HEADER_INCLUDED
|
||||
|
||||
#include <opm/autodiff/AutoDiffBlock.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Opm
|
||||
@ -58,6 +59,8 @@ namespace Opm
|
||||
Eigen::SparseMatrix<double, Eigen::RowMajor>& A,
|
||||
AutoDiffBlock<double>::V& b);
|
||||
|
||||
/// Return true if this is a serial run, or rank zero on an MPI run.
|
||||
bool isIORank(const boost::any& parallel_info);
|
||||
|
||||
} // namespace Opm
|
||||
|
||||
|
@ -277,7 +277,7 @@ namespace Opm
|
||||
/** \brief Whether this process does write to disk */
|
||||
bool isIORank () const
|
||||
{
|
||||
parallelOutput_->isIORank();
|
||||
return parallelOutput_->isIORank();
|
||||
}
|
||||
|
||||
void restore(SimulatorTimerInterface& timer,
|
||||
|
Loading…
Reference in New Issue
Block a user