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