From eaa0ea6524ff7d797267de849740cbaec3338ce6 Mon Sep 17 00:00:00 2001 From: Dmitri Naumov <dmitri.naumov@ufz.de> Date: Thu, 28 Nov 2019 18:27:41 +0100 Subject: [PATCH] [NL] Throw exception in MFront, catch in NSolver. This causes the time step to fail and repeated if possible. --- MaterialLib/SolidModels/MFront/MFront.cpp | 5 +++- NumLib/Exceptions.h | 23 +++++++++++++++++++ NumLib/ODESolver/NonlinearSolver.cpp | 16 +++++++++++-- NumLib/ODESolver/TimeDiscretizedODESystem.cpp | 13 +++++++++-- 4 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 NumLib/Exceptions.h diff --git a/MaterialLib/SolidModels/MFront/MFront.cpp b/MaterialLib/SolidModels/MFront/MFront.cpp index f470c15f82c..b80e6fa879d 100644 --- a/MaterialLib/SolidModels/MFront/MFront.cpp +++ b/MaterialLib/SolidModels/MFront/MFront.cpp @@ -11,6 +11,8 @@ #include <MGIS/Behaviour/Integrate.hxx> +#include "NumLib/Exceptions.h" + namespace { /// Converts between OGSes and MFront's Kelvin vector indices. @@ -313,7 +315,8 @@ MFront<DisplacementDim>::integrateStress( auto const status = mgis::behaviour::integrate(v, _behaviour); if (status != 1) { - OGS_FATAL("Integration failed with status %i.", status); + throw NumLib::AssemblyException("MFront: integration failed with status" + + std::to_string(status) + "."); } KelvinVector sigma; diff --git a/NumLib/Exceptions.h b/NumLib/Exceptions.h new file mode 100644 index 00000000000..f171290957a --- /dev/null +++ b/NumLib/Exceptions.h @@ -0,0 +1,23 @@ +/** + * \file + * \copyright + * Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#pragma once + +#include <stdexcept> +#include <string> + +namespace NumLib +{ +struct AssemblyException : public std::runtime_error +{ + AssemblyException(std::string const& reason) + : std::runtime_error{"Error in process' assembly: " + reason} {}; +}; +} // namespace NumLib diff --git a/NumLib/ODESolver/NonlinearSolver.cpp b/NumLib/ODESolver/NonlinearSolver.cpp index afaf5db02dc..327bffe8427 100644 --- a/NumLib/ODESolver/NonlinearSolver.cpp +++ b/NumLib/ODESolver/NonlinearSolver.cpp @@ -15,9 +15,10 @@ #include "BaseLib/ConfigTree.h" #include "BaseLib/Error.h" #include "BaseLib/RunTime.h" +#include "ConvergenceCriterion.h" #include "MathLib/LinAlg/LinAlg.h" #include "NumLib/DOF/GlobalMatrixProviders.h" -#include "ConvergenceCriterion.h" +#include "NumLib/Exceptions.h" namespace NumLib { @@ -277,7 +278,18 @@ NonlinearSolverStatus NonlinearSolver<NonlinearSolverTag::Newton>::solve( BaseLib::RunTime time_assembly; time_assembly.start(); - sys.assemble(x, process_id); + try + { + sys.assemble(x, process_id); + } + catch (AssemblyException const& e) + { + ERR("Abort nonlinear iteration. Repeating timestep. Reason: %s", + e.what()); + error_norms_met = false; + iteration = _maxiter; + break; + } sys.getResidual(*x[process_id], res); sys.getJacobian(J); INFO("[time] Assembly took %g s.", time_assembly.elapsed()); diff --git a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp index d8e35b83ea6..cca51941325 100644 --- a/NumLib/ODESolver/TimeDiscretizedODESystem.cpp +++ b/NumLib/ODESolver/TimeDiscretizedODESystem.cpp @@ -13,6 +13,7 @@ #include "MathLib/LinAlg/ApplyKnownSolution.h" #include "MathLib/LinAlg/UnifiedMatrixSetters.h" #include "NumLib/IndexValueVector.h" +#include "NumLib/Exceptions.h" namespace detail { @@ -91,8 +92,16 @@ void TimeDiscretizedODESystem<ODESystemTag::FirstOrderImplicitQuasilinear, _Jac->setZero(); _ode.preAssemble(t, dt, x_curr); - _ode.assembleWithJacobian(t, dt, x_new_timestep, xdot, dxdot_dx, dx_dx, - process_id, *_M, *_K, *_b, *_Jac); + try + { + _ode.assembleWithJacobian(t, dt, x_new_timestep, xdot, dxdot_dx, dx_dx, + process_id, *_M, *_K, *_b, *_Jac); + } + catch (AssemblyException const&) + { + NumLib::GlobalVectorProvider::provider.releaseVector(xdot); + throw; + } LinAlg::finalizeAssembly(*_M); LinAlg::finalizeAssembly(*_K); -- GitLab