Skip to content

Commit

Permalink
Add the option to throw an exception on MLMG failure rather than abor…
Browse files Browse the repository at this point in the history
…ting (#3424)


Co-authored-by: Weiqun Zhang <WeiqunZhang@lbl.gov>
  • Loading branch information
cgilet and WeiqunZhang committed Jul 14, 2023
1 parent 2a555f8 commit 500e5fc
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 11 deletions.
32 changes: 32 additions & 0 deletions Docs/sphinx_documentation/source/LinearSolvers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,38 @@ Available choices are
:cpp:`LPInfo::setConsolidationStrategy(int)`, to give control over how this
process works.


:cpp:`MLMG::setThrowException(bool)` controls whether multigrid failure results
in aborting (default) or throwing an exception, whereby control will return to the calling
application. The application code must catch the exception:

.. highlight:: c++

::

try {
mlmg.solve(...);
} catch (const MLMG::error& e) {
Print()<<e.what()<<std::endl; //Prints description of error

// Do something else...
}

Note that exceptions that are not caught are passed up the calling chain so that
application codes using specialized solvers relying on MLMG can still catch the exception.
For example, using AMReX-Hydro's :cpp:`NodalProjector`

.. highlight:: c++

::

try {
nodal_projector.project(...);
} catch (const MLMG::error& e) {
// Do something else...
}


Boundary Stencils for Cell-Centered Solvers
===========================================

Expand Down
42 changes: 31 additions & 11 deletions Src/LinearSolvers/MLMG/AMReX_MLMG.H
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class MLMGT
{
public:

class error
: public std::runtime_error
{
public :
using std::runtime_error::runtime_error;
};

template <typename T> friend class MLCGSolverT;

using FAB = typename MF::fab_type;
Expand Down Expand Up @@ -104,6 +111,7 @@ public:
*/
void apply (const Vector<MF*>& out, const Vector<MF*>& in);

void setThrowException (bool t) noexcept { throw_exception = t; }
void setVerbose (int v) noexcept { verbose = v; }
void setMaxIter (int n) noexcept { max_iters = n; }
void setMaxFmgIter (int n) noexcept { max_fmg_iters = n; }
Expand Down Expand Up @@ -211,7 +219,9 @@ public:

private:

bool throw_exception = false;
int verbose = 1;

int max_iters = 200;
int do_fixed_number_of_iters = 0;

Expand Down Expand Up @@ -453,16 +463,21 @@ MLMGT<MF>::solve (const Vector<AMF*>& a_sol, const Vector<AMF const*>& a_rhs,
}
break;
} else {
if (composite_norminf > RT(1.e20)*max_norm)
{
if (verbose > 0) {
amrex::Print() << "MLMG: Failing to converge after " << iter+1 << " iterations."
<< " resid, resid/" << norm_name << " = "
<< composite_norminf << ", "
<< composite_norminf/max_norm << "\n";
}
amrex::Abort("MLMG failing so lets stop here");
}
if (composite_norminf > RT(1.e20)*max_norm)
{
if (verbose > 0) {
amrex::Print() << "MLMG: Failing to converge after " << iter+1 << " iterations."
<< " resid, resid/" << norm_name << " = "
<< composite_norminf << ", "
<< composite_norminf/max_norm << "\n";
}

if ( throw_exception ) {
throw error("MLMG blew up.");
} else {
amrex::Abort("MLMG failing so lets stop here");
}
}
}
}

Expand All @@ -473,7 +488,12 @@ MLMGT<MF>::solve (const Vector<AMF*>& a_sol, const Vector<AMF const*>& a_rhs,
<< composite_norminf << ", "
<< composite_norminf/max_norm << "\n";
}
amrex::Abort("MLMG failed");

if ( throw_exception ) {
throw error("MLMG failed to converge.");
} else {
amrex::Abort("MLMG failed.");
}
}
timer[iter_time] = amrex::second() - iter_start_time;
}
Expand Down

0 comments on commit 500e5fc

Please sign in to comment.