diff --git a/MaterialLib/SolidModels/MFront/MFront.cpp b/MaterialLib/SolidModels/MFront/MFront.cpp index f470c15f82cec681bb460a21250e5393bd46908e..b80e6fa879d9c6550ebea93f5f59ea0ed7739c2c 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 0000000000000000000000000000000000000000..f171290957a789380d37fd7ab998679ee0260158 --- /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 afaf5db02dcdc1314a3766b31fd09f113bd9ac52..327bffe8427de6c5001d409aa2bd14858456c4d1 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 d8e35b83ea6714fdbaad5b1927ff2b49ee596173..cca519413258d54ec549f3e8f352865e30461854 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);