Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_NLS_LOCA_StepSizeControl.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_LOCA_StepSizeControl.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.7 $
40 //
41 // Revision Date : $Date: 2014/08/07 23:08:54 $
42 //
43 // Current Owner : $Author: dgbaur $
44 //-------------------------------------------------------------------------
45 
46 /* DEBUG: missing standard header */
47 
48 
49 #include <Xyce_config.h>
50 
51 
52 
54 
55 #include "LOCA_Continuation_ExtendedGroup.H"
56 #include "LOCA_Stepper.H"
57 #include "NOX_Solver_Generic.H"
58 #include "LOCA_Utils.H"
59 #include "LOCA_MultiContinuation_AbstractStrategy.H"
60 #include "LOCA_MultiContinuation_ExtendedVector.H"
61 #include "LOCA_NewStepper.H"
62 
63 namespace N_NLS_LOCA {
64 
66  maxStepSize(0.0),
67  minStepSize(0.0),
68  agrValue(0.0)
69 {
70 
71 }
72 
74 {
75 }
76 
77 NOX::Abstract::Group::ReturnType
78 StepSizeControl::reset(NOX::Parameter::List& params)
79 {
80  maxStepSize = params.getParameter("Max Step Size", 1.0e+12);
81  minStepSize = params.getParameter("Min Step Size", 1.0e-12);
82  startStepSize = params.getParameter("Initial Step Size", 1.0);
83  failedFactor = params.getParameter("Failed Step Reduction Factor", 0.5);
84  successFactor = params.getParameter("Successful Step Increase Factor", 1.26);
85  prevStepSize = 0.0;
86  isFirstStep = true;
87  agrValue = params.getParameter("Aggressiveness", 0.0);
88 
89  return NOX::Abstract::Group::Ok;
90 }
91 
92 NOX::Abstract::Group::ReturnType
94  LOCA::Continuation::ExtendedGroup& curGroup,
95  const LOCA::Continuation::ExtendedVector& predictor,
96  const NOX::Solver::Generic& solver,
97  const LOCA::Abstract::Iterator::StepStatus& stepStatus,
98  const LOCA::Stepper& stepper,
99  double& stepSize)
100 {
101  // If this is the first step, set step size to initial value
102  if (isFirstStep) {
103  double dpds = predictor.getParam();
104  if (dpds != 0.0) {
105  startStepSize /= dpds;
106  maxStepSize /= dpds;
107  minStepSize /= dpds;
108  }
109  isFirstStep = false;
110  stepSize = startStepSize;
111  prevStepSize = 0.0;
112  }
113  else {
114 
115  // A failed nonlinear solve cuts the step size in half
116  if (stepStatus == LOCA::Abstract::Iterator::Unsuccessful) {
117  stepSize *= failedFactor;
118  }
119  else {
120 
121  double ds_ratio = curGroup.getStepSizeScaleFactor();
122  startStepSize *= ds_ratio;
123  maxStepSize *= ds_ratio;
124  minStepSize *= ds_ratio;
125 
126  // Get maximum number of nonlinear iterations from stepper parameters
127  const NOX::Parameter::List& p = LOCA::Utils::getSublist("Stepper");
128  double maxNonlinearSteps
129  = static_cast<double>(p.getParameter("Max Nonlinear Iterations", 15));
130 
131  // Get number of nonlinear iterations in last step
132  double numNonlinearSteps =
133  static_cast<double>(solver.getNumIterations());
134 
135  // Save successful stepsize as previous
136  prevStepSize = stepSize;
137 
138  // adapive step size control
139  double factor = (maxNonlinearSteps - numNonlinearSteps)
140  / (maxNonlinearSteps);
141 
142  stepSize *= (1.0 + agrValue * factor * factor);
143 
144  stepSize *= ds_ratio;
145  }
146  }
147 
148  // Clip step size to be within prescribed bounds
149  NOX::Abstract::Group::ReturnType res = clipStepSize(stepSize);
150 
151  return res;
152 }
153 
154 NOX::Abstract::Group::ReturnType
156  LOCA::MultiContinuation::AbstractStrategy& curGroup,
157  const LOCA::MultiContinuation::ExtendedVector& predictor,
158  const NOX::Solver::Generic& solver,
159  const LOCA::Abstract::Iterator::StepStatus& stepStatus,
160  const LOCA::NewStepper& stepper,
161  double& stepSize)
162 {
163  // If this is the first step, set step size to initial value
164  if (isFirstStep) {
165  double dpds = predictor.getScalar(0);
166  if (dpds != 0.0) {
167  startStepSize /= dpds;
168  maxStepSize /= dpds;
169  minStepSize /= dpds;
170  }
171  isFirstStep = false;
172  stepSize = startStepSize;
173  prevStepSize = 0.0;
174  }
175  else {
176 
177  // A failed nonlinear solve cuts the step size in half
178  if (stepStatus == LOCA::Abstract::Iterator::Unsuccessful) {
179  stepSize *= failedFactor;
180  }
181  else {
182 
183  double ds_ratio = curGroup.getStepSizeScaleFactor();
184  startStepSize *= ds_ratio;
185  maxStepSize *= ds_ratio;
186  minStepSize *= ds_ratio;
187 
188  // Get maximum number of nonlinear iterations from stepper parameters
189  const NOX::Parameter::List& p = LOCA::Utils::getSublist("Stepper");
190  double maxNonlinearSteps
191  = static_cast<double>(p.getParameter("Max Nonlinear Iterations", 15));
192 
193  // Get number of nonlinear iterations in last step
194  double numNonlinearSteps =
195  static_cast<double>(solver.getNumIterations());
196 
197  // Save successful stepsize as previous
198  prevStepSize = stepSize;
199 
200  // adapive step size control
201  double factor = (maxNonlinearSteps - numNonlinearSteps)
202  / (maxNonlinearSteps);
203 
204  stepSize *= (1.0 + agrValue * factor * factor);
205 
206  stepSize *= ds_ratio;
207  }
208  }
209 
210  // Clip step size to be within prescribed bounds
211  NOX::Abstract::Group::ReturnType res = clipStepSize(stepSize);
212 
213  return res;
214 }
215 
216 
217 NOX::Abstract::Group::ReturnType
219 {
220  NOX::Abstract::Group::ReturnType res = NOX::Abstract::Group::Ok;
221 
222  // Compute sign of step size
223  double signStep = 1.0;
224  if (stepSize < 0.0)
225  signStep = -1.0;
226 
227  // Clip the step size if above the bounds
228  if (fabs(stepSize) > maxStepSize)
229  stepSize = signStep*maxStepSize;
230 
231  // Clip step size at minimum, signal for failed run
232  if (fabs(stepSize) < minStepSize) {
233  res = NOX::Abstract::Group::Failed;
234  stepSize = signStep*minStepSize;
235  if (LOCA::Utils::doPrint(LOCA::Utils::Error)) {
236  cout << "\n\tStep size reached minimum step size bound"
237  << endl;
238  }
239  }
240 
241  return res;
242 }
243 
244 double
246  return prevStepSize;
247 }
248 
249 double
251  return startStepSize;
252 }
253 
254 } // namespace N_NLS_LOCA