From 86cab641194213f2d7a97babcc3a47cd21ae83a0 Mon Sep 17 00:00:00 2001
From: Lisa Julia Nebel <lisa_julia.nebel@tu-dresden.de>
Date: Mon, 30 Mar 2020 15:12:27 +0200
Subject: [PATCH] Continue with Trust-Region-Algorithm if IPOPT threw an error
 while solving, treat this case as an 'unsuccessful iteration'

---
 dune/gfe/riemanniantrsolver.cc | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/dune/gfe/riemanniantrsolver.cc b/dune/gfe/riemanniantrsolver.cc
index cd6febcc..1675873b 100644
--- a/dune/gfe/riemanniantrsolver.cc
+++ b/dune/gfe/riemanniantrsolver.cc
@@ -434,6 +434,7 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
 
         CorrectionType corr_global(rhs_global.size());
         corr_global = 0;
+        bool solved = true;
 
         if (rank==0)
         {
@@ -451,10 +452,16 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
             std::cout << "Solve quadratic problem..." << std::endl;
 
             Dune::Timer solutionTimer;
-            innerSolver_->solve();
+            try {
+                innerSolver_->solve();
+            } catch (Dune::Exception &e) {
+                std::cerr << "Error while solving: " << e << std::endl;
+                solved = false;
+                corr_global = 0;
+            }
             std::cout << "Solving the quadratic problem took " << solutionTimer.elapsed() << " seconds." << std::endl;
 
-            if (mgStep)
+            if (mgStep && solved)
                 corr_global = mgStep->getSol();
 
             //std::cout << "Correction: " << std::endl << corr_global << std::endl;
@@ -541,6 +548,10 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
 
 
         }
+        double energy = 0;
+        double modelDecrease = 0;
+        SolutionType newIterate = x_;
+        if (solved) {
 
         if (this->verbosity_ == NumProc::FULL)
             std::cout << "Infinity norm of the correction: " << corr.infinity_norm() << std::endl;
@@ -558,11 +569,9 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
         //   Check whether trust-region step can be accepted
         // ////////////////////////////////////////////////////
 
-        SolutionType newIterate = x_;
         for (size_t j=0; j<newIterate.size(); j++)
             newIterate[j] = TargetSpace::exp(newIterate[j], corr[j]);
 
-        double energy    = assembler_->computeEnergy(newIterate);
         energy = grid_->comm().sum(energy);
 
         // compute the model decrease
@@ -571,7 +580,6 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
         CorrectionType tmp(corr.size());
         tmp = 0;
         hessianMatrix_->umv(corr, tmp);
-        double modelDecrease = (rhs*corr) - 0.5 * (corr*tmp);
         modelDecrease = grid_->comm().sum(modelDecrease);
 
         double relativeModelDecrease = modelDecrease / std::fabs(energy);
@@ -582,8 +590,10 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
             std::cout << "Relative model decrease: " << relativeModelDecrease
                       << ",  functional decrease: " << (oldEnergy - energy)/energy << std::endl;
         }
+            energy  = assembler_->computeEnergy(newIterate);
 
         assert(modelDecrease >= 0);
+            modelDecrease = (rhs*corr) - 0.5 * (corr*tmp);
 
         if (energy >= oldEnergy and rank==0) {
             if (this->verbosity_ == NumProc::FULL)
@@ -605,7 +615,7 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
         // //////////////////////////////////////////////
         //   Check for acceptance of the step
         // //////////////////////////////////////////////
-        if ( (oldEnergy-energy) / modelDecrease > 0.9) {
+        if (solved && (oldEnergy-energy) / modelDecrease > 0.9) {
             // very successful iteration
 
             x_ = newIterate;
@@ -616,7 +626,7 @@ void RiemannianTrustRegionSolver<Basis,TargetSpace>::solve()
 
             recomputeGradientHessian = true;
 
-        } else if ( (oldEnergy-energy) / modelDecrease > 0.01
+        } else if (solved && (oldEnergy-energy) / modelDecrease > 0.01
                     || std::abs(oldEnergy-energy) < 1e-12) {
             // successful iteration
             x_ = newIterate;
-- 
GitLab