Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_NLS_NOX_StagnationTest.C
Go to the documentation of this file.
1 //-------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_NLS_NOX_StagnationTest.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator :
33 //
34 // Creation Date :
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.10 $
40 //
41 // Revision Date : $Date: 2014/02/24 23:49:25 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 /* DEBUG: missing standard header */
47 
48 
49 #include <Xyce_config.h>
50 
51 
52 #include "N_NLS_NOX_StagnationTest.h" // class definition
53 #include "NOX_Common.H"
54 #include "NOX_Solver_Generic.H"
55 #include "NOX_Abstract_Group.H"
56 
57 N_NLS_NOX::Stagnation::Stagnation(int maxSteps_, double tolerance_) :
58  maxSteps(maxSteps_),
59  numSteps(0),
60  lastIteration(-1),
61  tolerance(tolerance_),
62  convRate(1.0),
63  minConvRate(1.0),
64  normFInit(1.0),
65  status(NOX::StatusTest::Unconverged)
66 {
67 
68 }
69 
71 {
72 
73 }
74 
75 NOX::StatusTest::StatusType
76 N_NLS_NOX::Stagnation::checkStatus(const NOX::Solver::Generic& problem)
77 {
78  status = NOX::StatusTest::Unconverged;
79 
80  // First time through we don't do anything but reset the counters
81  int niters = problem.getNumIterations();
82  if (niters == 0) {
83  numSteps = 0;
84  lastIteration = 0;
85  convRate = 1.0;
86  //minConvRate = 1.0; // Don't reset this. Xyce solver never does.
87  normFInit = problem.getSolutionGroup().getNormF();
88  return NOX::StatusTest::Unconverged;
89  }
90 
91  // Make sure we have not already counted the last nonlinear iteration.
92  // This protects against multiple calls to checkStatus() in between
93  // nonlinear iterations.
94  bool isCounted = false;
95  if (niters == lastIteration) {
96  isCounted = true;
97  }
98  else
99  lastIteration = niters;
100 
101  // Compute the convergenc rate and set counter appropriately
102  if (!isCounted) {
103 
104  convRate = problem.getSolutionGroup().getNormF() /
105  problem.getPreviousSolutionGroup().getNormF();
106 
107  if (fabs(convRate - 1.0) <= tolerance) {
108 
109  if ((numSteps == 0) || (convRate < minConvRate))
110  minConvRate = convRate;
111 
112  ++numSteps ;
113  }
114  else
115  numSteps = 0;
116 
117  }
118 
119  if (numSteps >= maxSteps) {
120 
121  double initConvRate = problem.getSolutionGroup().getNormF()/normFInit;
122 
123  if ((initConvRate <= 0.9) && (minConvRate <= 1.0)) {
124  status = NOX::StatusTest::Converged;
125  }
126  else
127  status = NOX::StatusTest::Failed;
128 
129  }
130 
131  return status;
132 }
133 
134 NOX::StatusTest::StatusType N_NLS_NOX::Stagnation::getStatus() const
135 {
136  return status;
137 }
138 
139 std::ostream& N_NLS_NOX::Stagnation::print(std::ostream& stream, int indent) const
140 {
141  for (int j = 0; j < indent; ++j )
142  stream << ' ';
143  stream << status;
144  stream << "Stagnation Count = " << numSteps << " = " << maxSteps << "\n";
145 
146  for (int j = 0; j < indent; ++j )
147  stream << ' ';
148  stream << " (convergence rate = " << convRate << ")";
149 
150  if (status == NOX::StatusTest::Converged) {
151  stream << "\n (Near Convergence!)" << std::endl;
152  }
153 
154  stream << std::endl;
155  return stream;
156 }
157 
158 
160 {
161  return maxSteps;
162 }
163 
165 {
166  return numSteps;
167 }
168 
170 {
171  return tolerance;
172 }
173 
175 {
176  return convRate;
177 }
178