HermesCommon  3.0
nonlinear_convergence_measurement.cpp
1 // This file is part of HermesCommon
2 //
3 // Copyright (c) 2009 hp-FEM group at the University of Nevada, Reno (UNR).
4 // Email: hpfem-group@unr.edu, home page: http://www.hpfem.org/.
5 //
6 // Hermes2D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published
8 // by the Free Software Foundation; either version 2 of the License,
9 // or (at your option) any later version.
10 //
11 // Hermes2D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with Hermes2D; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 
26 namespace Hermes
27 {
28  namespace Solvers
29  {
30  template<typename Scalar>
32  {
33  // get iteration.
34  unsigned int iteration = nonlinear_solver->get_current_iteration_number();
35 
36  const std::vector<double>& residual_norms = nonlinear_solver->get_parameter_value(nonlinear_solver->residual_norms());
37  const std::vector<double>& solution_norms = nonlinear_solver->get_parameter_value(nonlinear_solver->solution_norms());
38  const std::vector<double>& solution_change_norms = nonlinear_solver->get_parameter_value(nonlinear_solver->solution_change_norms());
39  int residual_norms_count = residual_norms.size();
40  int solution_norms_count = solution_norms.size();
41  int solution_change_norms_count = solution_change_norms.size();
42 
43  double initial_residual_norm = residual_norms[0];
44  double current_residual_norm = residual_norms.back();
45  double previous_residual_norm = iteration == 1 ? current_residual_norm : residual_norms[residual_norms_count - 2];
46 
47  double initial_solution_norm = solution_norms[0];
48  double previous_solution_norm = solution_norms[solution_norms_count - 2];
49  double current_solution_norm = solution_norms.back();
50  double current_solution_change_norm = solution_change_norms.back();
51 
52  bool converged;
53  if (nonlinear_solver->handleMultipleTolerancesAnd)
54  converged = true;
55  else
56  converged = false;
57 
58  double convergence_decision_value[NonlinearConvergenceMeasurementTypeCount];
59  convergence_decision_value[0] = ((previous_residual_norm - current_residual_norm) / previous_residual_norm);
60  convergence_decision_value[1] = (current_residual_norm / initial_residual_norm);
61  convergence_decision_value[2] = (current_residual_norm / previous_residual_norm);
62  convergence_decision_value[3] = current_residual_norm;
63  convergence_decision_value[4] = current_solution_change_norm;
64  convergence_decision_value[5] = (current_solution_change_norm / previous_solution_norm);
65 
66  for (int i = 0; i < NonlinearConvergenceMeasurementTypeCount; i++)
67  {
68  if (!nonlinear_solver->tolerance_set[i])
69  continue;
70 
71  if (i == 1 && iteration == 1)
72  {
73  if (nonlinear_solver->handleMultipleTolerancesAnd)
74  return false;
75  else
76  continue;
77  }
78 
79  bool converged_this_tolerance = (convergence_decision_value[i] < nonlinear_solver->tolerance[i]);
80  if (nonlinear_solver->handleMultipleTolerancesAnd)
81  converged = converged && converged_this_tolerance;
82  else
83  if (converged_this_tolerance)
84  return true;
85  }
86 
87  return converged;
88  }
89 
90  template class HERMES_API NonlinearConvergenceMeasurement < double > ;
91  template class HERMES_API NonlinearConvergenceMeasurement < std::complex<double> > ;
92  }
93 }
General namespace for the Hermes library.
bool tolerance_set[NonlinearConvergenceMeasurementTypeCount]
info about set tolerances.
int get_current_iteration_number()
Shortcut method for getting the current iteration.
static bool converged(NonlinearMatrixSolver< Scalar > *newtonSolver)
Convergence measurement function - returns converged true/false.
Newton's method for algebraic equations.
Base class for defining interface for nonlinear solvers.
nonlinear_convergence_measurement.
double tolerance[NonlinearConvergenceMeasurementTypeCount]
Tolerances for all NonlinearConvergenceMeasurementType numbered sequentially as the enum NonlinearCon...
const int NonlinearConvergenceMeasurementTypeCount