Xyce  6.1
N_TIA_StepErrorControl.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-2015 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_TIA_StepErrorControl.C,v $
27 //
28 // Purpose : This file contains the functions which define the
29 // time integration stepsize control algorithm.
30 //
31 // Special Notes :
32 //
33 // Creator : Buddy Watts
34 //
35 // Creation Date : 6/1/00
36 //
37 // Revision Information:
38 // ---------------------
39 //
40 // Revision Number: $Revision: 1.265 $
41 //
42 // Revision Date : $Date: 2015/04/17 20:32:13 $
43 //
44 // Current Owner : $Author: dgbaur $
45 //-----------------------------------------------------------------------------
46 
47 #include <Xyce_config.h>
48 
49 #include <iostream>
50 #include <sstream>
51 
52 #include <N_TIA_StepErrorControl.h>
53 
54 #include <N_ANP_AnalysisManager.h>
55 #include <N_ERH_ErrorMgr.h>
56 #include <N_LOA_Loader.h>
57 #include <N_PDS_Comm.h>
58 #include <N_PDS_Manager.h>
59 #include <N_PDS_Serial.h>
60 #include <N_PDS_MPI.h>
61 #include <N_TIA_DataStore.h>
62 #include <N_TIA_TIAParams.h>
64 #include <N_UTL_BreakPoint.h>
65 #include <N_UTL_Diagnostic.h>
66 #include <N_UTL_FeatureTest.h>
67 #include <N_UTL_Functors.h>
68 #include <N_UTL_MachDepParams.h>
69 #include <N_UTL_SaveIOSState.h>
70 
71 namespace Xyce {
72 namespace TimeIntg {
73 
74 //-----------------------------------------------------------------------------
75 // Function : StepErrorControl::StepErrorControl
76 // Purpose : Non-argument constructor.
77 // Special Notes :
78 // Scope : public
79 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
80 // Creation Date : 9/06/01
81 //-----------------------------------------------------------------------------
83  const std::string & netlist_filename,
84  Analysis::AnalysisManager & analysis_manager,
85  WorkingIntegrationMethod & working_integration_method,
86  const TIAParams & tia_params)
87  : analysisManager_(analysis_manager),
88  wimPtr_(working_integration_method),
89  netlistFilename_(netlist_filename),
90  startingTimeStep(1.0e-10),
91  currentTimeStep(1.0e-10),
92  lastAttemptedTimeStep(1.0e-10),
93  lastTimeStep(1.0e-10),
94  minTimeStep(0.0),
95  maxTimeStep(0.0),
96  maxTimeStepUser(1.0e+99),
97  maxTimeStepBP(0.0),
98  savedTimeStep(1.0e-10),
99  lastTime(0.0),
100  currentTime(0.0),
101  nextTime(0.0),
102  stopTime(0.0),
103  initialTime(0.0),
104  finalTime(0.0),
105  currentTimeStepRatio(0.0),
106  currentTimeStepSum(0.0),
107  pauseTime(0.0),
108  pauseSetAtZero(false),
109  lastTimeStepRatio(0.0),
110  lastTimeStepSum(0.0),
111  newtonConvergenceStatus(-1),
112  nIterations(0),
113  numberSuccessiveFailures(0),
114  stepAttemptStatus(true),
115  previousCallStepSuccessful(false),
116  estOverTol_(0.0),
117  TimeStepLimitedbyBP(false),
118  minStepPrecisionFac_(10.0),
119  newtonStepReduction_(0.25),
120  restartTimeStepScale_(0.005),
121  tolAimFac_(0.5),
122  // define "heuristic" StepSize and Error Control parameters.
123 
124  // new-DAE variables:
125  currentOrder_(1), // Current order of integration
126  oldOrder_(1), // previous order of integration
127  minOrder_(1), // minimum order = max(1,user option minord) - see below.
128  maxOrder_(5), // maximum order = min(5,user option maxord) - see below.
129  usedOrder_(1), // order used in current step (used after currentOrder_ is updated)
130  alphas_(-1.0), // $\alpha_s$ fixed-leading coefficient of this BDF method
131  alpha_(6,0.0), // $\alpha_j(n)=h_n/\psi_j(n)$ coefficient used in local error test
132  // note: $h_n$ = current step size, n = current time step
133  alpha0_(0.0), // $-\sum_{j=1}^k \alpha_j(n)$ coefficient used in local error test
134  cj_ (0.0), // $-\alpha_s/h_n$ coefficient used in local error test
135  ck_ (0.0), // local error coefficient gamma_[0] = 0; // $\gamma_j(n)=\sum_{l=1}^{j-1}1/\psi_l(n)$ coefficient used to
136  sigma_(6,0.0), // $\sigma_j(n) = \frac{h_n^j(j-1)!}{\psi_1(n)*\cdots *\psi_j(n)}$
137  gamma_(6,0.0), // calculate time derivative of history array for predictor
138  beta_(6,0.0), // coefficients used to evaluate predictor from history array
139  psi_(6,0.0), // $\psi_j(n) = t_n-t_{n-j}$ intermediary variable used to
140  // compute $\beta_j(n)$
141  numberOfSteps_(0), // number of total time integration steps taken
142  nef_(0),
143  usedStep_(0.0),
144  nscsco_(0),
145  Ek_(0.0),
146  Ekm1_(0.0),
147  Ekm2_(0.0),
148  Ekp1_(0.0),
149  Est_(0.0),
150  Tk_(0.0),
151  Tkm1_(0.0),
152  Tkm2_(0.0),
153  Tkp1_(0.0),
154  newOrder_(1),
155  initialPhase_(true),
156  h0_safety_(2.0),
157  h0_max_factor_(0.005), // New value, to match old-DAE.
158  //h0_max_factor_(0.0001), // this is the new-DAE equivalent of restartTimeStepScale_(0.005)
159  h_phase0_incr_(2.0),
160  h_max_inv_(0.0),
161  Tkm1_Tk_safety_(2.0),
162  Tkp1_Tk_safety_(0.5),
163  r_factor_(1.0),
164  r_safety_(2.0),
165  r_fudge_(0.0001),
166  //r_min_(0.125),
167  r_min_(0.25), // r_min_ is the same as the old-DAE variable, minFailStepFac_.
168  r_max_(0.9), // r_max_ is the same as the old-DAE variable, maxFailStepFac_.
169  r_hincr_test_(2.0),
170  r_hincr_(2.0),
171  max_LET_fail_(15),
172  breakPointLess_(Util::BreakPoint::defaultTolerance_),
173  breakPoints_(breakPointLess_),
174  currentPauseBP(breakPoints_.end())
175 {
176  setFromTIAParams(tia_params);
177 
178  setBreakPoint(Util::BreakPoint(tia_params.finalTime, Xyce::Util::BreakPoint::PAUSE), tia_params.initialTime);
179 }
180 
181 //-----------------------------------------------------------------------------
182 // Function : StepErrorControl::~StepErrorControl
183 // Purpose : destructor
184 // Special Notes :
185 // Scope : public
186 // Creator : Buddy Watts, SNL
187 // Creation Date : 6/01/00
188 //-----------------------------------------------------------------------------
189 
191 {}
192 
193 //-----------------------------------------------------------------------------
194 // Function : StepErrorControl::setFromTIAParams
195 // Purpose : This function copies stuff out of the tiaParams object into
196 // variables that are local to the step error control class.
197 // Special Notes :
198 // Scope : public
199 // Creator : Eric R. Keiter, SNL, Computational Sciences
200 // Creation Date : 09/06/01
201 //-----------------------------------------------------------------------------
202 bool
204  const TIAParams & tia_params)
205 {
206  startingTimeStep = tia_params.initialTimeStep;
207  currentTimeStep = tia_params.initialTimeStep;
208  initialTime = tia_params.initialTime;
209  finalTime = tia_params.finalTime;
210  currentTime = tia_params.initialTime;
211  nextTime = tia_params.initialTime;
212  lastTime = tia_params.initialTime;
213 
214  // if initial time steps are baloney, set then to a default value.
215  if (startingTimeStep <= 0.0) startingTimeStep = 1.0e-10;
216  if (currentTimeStep <= 0.0) currentTimeStep = 1.0e-10;
217 
218  if (tia_params.maxTimeStepGiven)
219  {
220  maxTimeStepUser = tia_params.maxTimeStep;
221  maxTimeStep = tia_params.maxTimeStep;
222  }
223  else
224  {
225  maxTimeStep = 0.1*(tia_params.finalTime-tia_params.initialTime);
226  }
227 
230 
231  initializeBreakPoints(tia_params.initialOutputTime, tia_params.initialTime, tia_params.finalTime);
232 
233  return true;
234 }
235 
236 //-----------------------------------------------------------------------------
237 // Function : StepErrorControl::resetAll
238 //
239 // Purpose : This function resets everything so that a transient loop
240 // can be started from the beginning.
241 //
242 // Special Notes : This function was needed for the .STEP capability.
243 //
244 // Scope : public
245 // Creator : Eric R. Keiter, SNL, Computational Sciences
246 // Creation Date : 11/04/03
247 //-----------------------------------------------------------------------------
248 bool
250  const TIAParams & tia_params)
251 {
252  startingTimeStep = tia_params.initialTimeStep;
253  currentTimeStep = tia_params.initialTimeStep;
254  initialTime = tia_params.initialTime;
255  finalTime = tia_params.finalTime;
256  currentTime = tia_params.initialTime;
257  lastTime = tia_params.initialTime;
258  nextTime = tia_params.initialTime;
259 
260  // if initial time steps are baloney, set then to a default value.
261  if (startingTimeStep <= 0.0) startingTimeStep = 1.0e-10;
262  if (currentTimeStep <= 0.0) currentTimeStep = 1.0e-10;
263 
264  if (tia_params.maxTimeStepGiven)
265  {
266  maxTimeStepUser = tia_params.maxTimeStep;
267  maxTimeStep = tia_params.maxTimeStep;
268  }
269  else
270  {
271  maxTimeStep = 0.1* (tia_params.finalTime - tia_params.initialTime);
272  }
273 
275 
276  initializeBreakPoints(tia_params.initialOutputTime, tia_params.initialTime, tia_params.finalTime);
277 
278  pauseSetAtZero = false;
279  pauseTime = 0.0;
280 
281  lastTimeStep = tia_params.initialTimeStep;
283 
284  currentTimeStepRatio = 1.0;
286 
290 
293  stepAttemptStatus = true;
294 
295  minTimeStep = 0.0;
296  estOverTol_ = 0.0;
297 
298  // need to set a pause breakpoint at the final time.
299  setBreakPoint(Util::BreakPoint(tia_params.finalTime ,Xyce::Util::BreakPoint::PAUSE), tia_params.initialTime);
300 
301  if (DEBUG_TIME && isActive(Diag::TIME_BREAKPOINTS))
302  {
303  Xyce::dout() << " after resetAll:" << std::endl;
304  printBreakPoints(Xyce::dout());
305  Xyce::dout() <<" currentPauseBP = " << currentPauseBP->value() << std::endl
306  << Xyce::section_divider << std::endl;
307  }
308 
309  return true;
310 }
311 
312 //-----------------------------------------------------------------------------
313 // Function : StepErrorControl::getEstOverTol
314 // Purpose : This function lets the controlling class (a transient
315 // analysis) get the estimated error over tol from the
316 // last step
317 // Special Notes :
318 // Scope : public
319 // Creator : Richard Schiek, Electrical and MEMS Modeling
320 // Creation Date : 01/23/09
321 //-----------------------------------------------------------------------------
323 {
324  return estOverTol_;
325 }
326 
327 //-----------------------------------------------------------------------------
328 // Function : StepErrorControl::setTimeStep
329 // Purpose :
330 // Special Notes :
331 // Scope : public
332 // Creator : Eric Keiter, SNL
333 // Creation Date : 08/09/09
334 //-----------------------------------------------------------------------------
335 void StepErrorControl::setTimeStep(double newTimeStep)
336 {
337  newTimeStep = std::max(newTimeStep, minTimeStep);
338  newTimeStep = std::min(newTimeStep, maxTimeStep);
339 
340  double nextTimePt = currentTime + newTimeStep;
341 
342  if (nextTimePt > stopTime)
343  {
344  nextTimePt = stopTime;
345  newTimeStep = stopTime - currentTime;
346  TimeStepLimitedbyBP = true;
347  }
348 
349  nextTime = nextTimePt;
350 
351  currentTimeStepRatio = newTimeStep/lastTimeStep;
352  currentTimeStepSum = newTimeStep + lastTimeStep;
353 
354  currentTimeStep = newTimeStep;
355 }
356 
357 //-----------------------------------------------------------------------------
358 // Function : StepErrorControl::updateStopTime
359 // Purpose : The "stop time" is either the next discontinuity point,
360 // a pause point, or the final time, whichever comes first.
361 // Special Notes :
362 // Scope : public
363 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
364 // Creation Date : 6/27/00
365 //-----------------------------------------------------------------------------
366 void
368  Parallel::Machine comm,
369  bool breakpoints_enabled,
370  double initial_time,
371  bool min_time_steps_breakpoint_given,
372  double min_time_steps_breakpoint)
373 {
374  double oldStopTime = stopTime;
375  double diffStopTime = 0.0;
376 
377  if (breakpoints_enabled)
378  {
379  // Find the first breakpoint equal to or larger than the
380  // current time.
381 
382  BreakPointSet::iterator itBP = std::upper_bound(breakPoints_.begin(), breakPoints_.end(), currentTime, breakPointLess_);
383 
384  stopTime = std::min(finalTime, itBP->value());
385 
386  // The breakpoint could be a pause breakpoint, in which case we might
387  // need to update the pauseTime:
388  if (itBP->bptype() == Xyce::Util::BreakPoint::PAUSE)
389  {
390  updatePauseTime(*itBP, initial_time);
391  }
392  stopTime = std::min(currentPauseBP->value(), stopTime);
393 
394  // if this is a breakpoint step, make sure the new stop
395  // time is for the next breakpoint, not the current one.
396  // This check is neccessary because of roundoff error.
397 
398  diffStopTime = fabs(stopTime-oldStopTime);
399  if (diffStopTime < breakPointLess_.tolerance_ &&
401  stopTime != pauseTime &&
402  stopTime != finalTime )
403  {
404  ++itBP;
405  stopTime = itBP->value();
406  }
407 
408  Parallel::AllReduce(comm, MPI_MIN, &stopTime, 1);
409  }
410  else
411  {
412  stopTime = std::min(pauseTime, finalTime);
413  }
414 
416  {
417  double time_to_stop = stopTime - currentTime;
418  if (min_time_steps_breakpoint_given && (min_time_steps_breakpoint > 0) )
419  {
420  maxTimeStepBP = time_to_stop/min_time_steps_breakpoint;
421  }
422  }
423 
424 
425  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
426  {
427  Xyce::dout() << std::endl
428  << " stopTime = " << stopTime << std::endl
429  << " pauseTime = " << pauseTime << std::endl
430  << " currentTime = " << currentTime << std::endl
431  << " oldStopTime = " << oldStopTime << std::endl
432  << " finalTime = " << finalTime << std::endl
433  << " maxTimeStepBP = " << maxTimeStepBP << std::endl
434  << " beginningIntegration = " << analysisManager_.getBeginningIntegrationFlag() << std::endl
435  << Xyce::section_divider << std::endl;
436  }
437 }
438 
439 //-----------------------------------------------------------------------------
440 // Function : StepErrorControl::findNextStopTime
441 // Purpose : Determine the next stop time, that comes immediately after
442 // the current one.
443 //
444 // Special Notes : Used by mixed-signal rollback.
445 //
446 // Scope : public
447 // Creator : Eric Keiter, SNL
448 // Creation Date : 4/9/09
449 //-----------------------------------------------------------------------------
450 double
452  Parallel::Machine comm,
453  bool breakpoints_enabled)
454 {
455  double nextStop = stopTime;
456 
457  if (breakpoints_enabled)
458  {
459  // Find the first breakpoint equal to or larger than the
460  // current time.
461 
462  BreakPointSet::iterator itBP = std::upper_bound(breakPoints_.begin(), breakPoints_.end(), currentTime, breakPointLess_);
463  ++itBP; // go to the next one.
464 
465  nextTime = std::min(finalTime, itBP->value());
466  nextTime = std::min(currentPauseBP->value(), nextTime);
467 
468  Parallel::AllReduce(comm, MPI_MIN, &nextTime, 1);
469  }
470  else
471  {
472  nextTime = std::min(pauseTime, finalTime);
473  }
474 
475  return nextStop;
476 }
477 
478 //-----------------------------------------------------------------------------
479 // Function : StepErrorControl::evaluateStepError
480 // Purpose :
481 // Special Notes :
482 // Scope : public
483 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
484 // Creation Date : 1/28/07
485 //-----------------------------------------------------------------------------
487  const Loader::Loader & loader,
488  const TIAParams & tia_params)
489 {
490  bool step_attempt_status( newtonConvergenceStatus >= 0);
491  bool sAStatus(false);
492  bool errorOptionStatus(true);
493  bool testTimeIntegrationError(false);
494 
495  // If we are running with constant step size, or are on the first pass
496  // through the transient loop, only base success on the Newton loop.
497  if (tia_params.newBPStepping)
498  {
499  if (currentTime == tia_params.initialTime)
500  {
501  testTimeIntegrationError = (analysisManager_.getStepNumber() >= 1 && !analysisManager_.getBeginningIntegrationFlag());
502  }
503  else
504  {
505  testTimeIntegrationError = (analysisManager_.getStepNumber() >= 1);
506  }
507  }
508  else
509  {
510  testTimeIntegrationError = (analysisManager_.getStepNumber() >= 1 && !analysisManager_.getBeginningIntegrationFlag());
511  }
512 
513  if (tia_params.testFirstStep)
514  {
515  testTimeIntegrationError = true;
516  }
517 
518  // if the step status is already false, don't do any more work.
519  if (!step_attempt_status)
520  {
521  testTimeIntegrationError = false;
522  }
523 
524 
525  if (testTimeIntegrationError)
526  {
527  // Needed for 2-level Solves:
529 
531 
532  if (estOverTol_ <= tia_params.errTolAcceptance)
533  {
534  sAStatus = true;
535  }
536  else
537  {
538  sAStatus = false;
539  }
540 
541  if (tia_params.timestepsReversal == true)
542  {
543  if (nIterations <= tia_params.NLmax)
544  errorOptionStatus = true;
545  else
546  errorOptionStatus = false;
547  }
548 
549  if (VERBOSE_TIME && tia_params.errorAnalysisOption == TimeIntg::NO_LOCAL_TRUNCATED_ESTIMATES)
550  {
551  Xyce::dout() << "ERROROPTION=1: DOREJECTSTEP = ";
552  if (tia_params.timestepsReversal == true)
553  {
554  Xyce::dout() << "1" << std::endl;
555  }
556  else
557  {
558  Xyce::dout() << "0" << std::endl;
559  }
560  }
561 
562  if ( tia_params.minTimeStepGiven && (currentTimeStep < tia_params.minTimeStep) )
563  {
564  // This step has dropped under the user specified min time step, so only
565  // test if the solver converged to accept the step.
566  // don't do the step_attempt_status && sAStatus;
567  if (DEBUG_TIME && isActive(Diag::TIME_ERROR))
568  {
569  Xyce::dout() << "Trying to skip time integrator error checks: " << currentTimeStep
570  << " newton status " << step_attempt_status << std::endl;
571  }
572  }
573 // else if (!tia_params.constantTimeStepFlag && ((tia_params.errorAnalysisOption == LOCAL_TRUNCATED_ESTIMATES)) )
574 // {
575 // step_attempt_status = step_attempt_status && sAStatus;
576 // }
577  else if (!tia_params.constantTimeStepFlag)
578  {
580  step_attempt_status = step_attempt_status && errorOptionStatus;
581  else
582  step_attempt_status = step_attempt_status && sAStatus;
583  }
584  }
585 
586  if (DEBUG_TIME && isActive(Diag::TIME_ERROR))
587  {
588  integrationStepReport(Xyce::dout(), step_attempt_status, sAStatus, testTimeIntegrationError, tia_params);
589  }
590  else if (VERBOSE_TIME)
591  {
592  terseIntegrationStepReport(Xyce::dout(), step_attempt_status, sAStatus, testTimeIntegrationError, tia_params);
593  }
594 
595  // Now that the status has been completely determined,
596  // set the class variable for step attempt
597  stepAttemptStatus = step_attempt_status;
598 }
599 
600 //-----------------------------------------------------------------------------
601 // Function : StepErrorControl::terseIntegrationStepReport_
602 // Purpose : This gives a one-line description of the step accept/reject.
603 // Special Notes :
604 // Scope : public
605 // Creator : Eric Keiter, SNL
606 // Creation Date : 01/27/07
607 //-----------------------------------------------------------------------------
608 void
610  std::ostream & os,
611  bool step_attempt_status,
612  bool sAStatus,
613  bool testedError,
614  const TIAParams & tia_params)
615 {
616  os << (DEBUG_TIME ? netlistFilename_ : "")
617  << " STEP STATUS: " << (step_attempt_status ? " success" : " fail")
618  << " Newton: " << newtonConvergenceStatus
619  << " estOverTol: " << estOverTol_ << (testedError && !tia_params.constantTimeStepFlag ? "" : " (not used for this step)") << std::endl;
620 }
621 
622 //-----------------------------------------------------------------------------
623 // Function : StepErrorControl::integrationStepReport_
624 // Purpose :
625 // Special Notes :
626 // Scope : public
627 // Creator : Eric Keiter, SNL
628 // Creation Date : 03/12/06
629 //-----------------------------------------------------------------------------
630 void StepErrorControl::integrationStepReport(std::ostream &os, bool step_attempt_status, bool sAStatus, bool testedError, const TIAParams &tia_params)
631 {
632  if (isActive(Diag::TIME_PARAMETERS))
633  {
634  os << "\n estOverTol = " << estOverTol_ << std::endl
635  << " error tolerance = " << tia_params.errTolAcceptance << std::endl
636  << std::endl
637  << "\nSTEP ATTEMPT STATUS:" << std::endl
638  << "NOTE:" << std::endl;
639 
640  if (!tia_params.constantTimeStepFlag &&
643  {
644  os << " We are running in variable stepsize mode " << std::endl
645  << " and we have NOT just passed a breakpoint. As such " << std::endl
646  << " for an integration step to succeed the " << std::endl
647  << " nonlinear solver must succeed AND the predictor" << std::endl
648  << " and corrector need to be close within a tolerance." << std::endl;
649 
651  {
652  os << "ADDENDUM: This is with erroption=1 so predictor-corrector is ignored for step error control." << std::endl;
653  }
654  }
655  else
656  {
657  os << " We are either running constant stepsize " << std::endl
658  << " or we just passed a breakpoint. As such " << std::endl
659  << " the only criteria we use in accepting/rejecting" << std::endl
660  << " an integration step is the nonlinear solver" << std::endl
661  << " success/failure." << std::endl;
662  }
663 
664  if (step_attempt_status)
665  {
666  os << "\n This has been a successful step:" << std::endl;
667  }
668  else
669  {
670  os << "\n This has NOT been a successful step:" << std::endl;
671  }
672 
673  if ( newtonConvergenceStatus > 0)
674  {
675  os << " - Newton solver succeded with return code " << newtonConvergenceStatus << std::endl << std::endl;
676  }
677  else
678  {
679  os << " - Newton solver failed with return code " << newtonConvergenceStatus << std::endl;
680  }
681 
682  if (testedError)
683  {
684  if (!tia_params.constantTimeStepFlag)
685  {
686  if (sAStatus)
687  {
688  os << " - predictor vs. corrector analysis succeeded." << std::endl;
689  }
690  else
691  {
692  os << " - predictor vs. corrector analysis failed." << std::endl;
693  }
694 
695  os << " (compare estOverTol with error tolerance above.)" << std::endl;
696  }
697  else
698  {
699  os << "If we had been using it << " << std::endl;
700 
701  if (sAStatus)
702  {
703  os << " - predictor vs. corrector analysis would have succeeded." << std::endl;
704  }
705  else
706  {
707  os << " - predictor vs. corrector analysis would have failed." << std::endl;
708  }
709 
710  os << " (compare estOverTol with error tolerance above.)" << std::endl;
711  }
712  }
713  else
714  {
715  os << " predictor vs. corrector was not tested" << std::endl;
716  }
717 
718  os << Xyce::section_divider << std::endl;
719  }
720 }
721 
722 //-----------------------------------------------------------------------------
723 // Function : StepErrorControl::initializeBreakPoints
724 // Purpose :
725 // Special Notes :
726 // Scope : public
727 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
728 // Creation Date : 06/11/01
729 //-----------------------------------------------------------------------------
730 bool
732  double initial_output_time,
733  double initial_time,
734  double final_time)
735 {
736  bool bsuccess = true;
737 
738  breakPoints_.clear ();
740 
741  // first breakpoint is the start time, last one is the final time.
742  setBreakPoint(initialTime, initial_time);
743 
744  // if initial_output_time is nonzero, then make it a breakpoint.
745  if (initial_output_time > initialTime && initial_output_time < finalTime)
746  {
747  setBreakPoint(initial_output_time, initial_time);
748  }
749 
750  // The final time needs to be the very last breakpoint.
751  setBreakPoint(Util::BreakPoint(final_time, Xyce::Util::BreakPoint::PAUSE), initial_time);
752 
754  {
755  BreakPointSet::iterator lastBP = breakPoints_.end();
756  --lastBP;
757  updatePauseTime(*lastBP, initialTime);
758  }
759 
760  return bsuccess;
761 }
762 
763 //-----------------------------------------------------------------------------
764 // Function : StepErrorControl::updateBreakPoints
765 // Purpose : Requests dynamic breakpoint information from the
766 // loader. Adds, subtracts from the breakpoints array.
767 // Special Notes :
768 // Scope : public
769 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
770 // Creation Date : 06/11/01
771 //-----------------------------------------------------------------------------
772 bool
774  const Loader::Loader & loader,
775  double initial_time)
776 {
777  bool bsuccess = true;
778 
779  if (DEBUG_TIME && isActive(Diag::TIME_BREAKPOINTS))
780  {
781  Xyce::dout() << std::endl
782  << Xyce::section_divider << std::endl
783  << " StepErrorControl::updateBreakPoints. time = " << currentTime << std::endl
784  << std::endl;
785  }
786 
787  std::vector<Util::BreakPoint> tmpBP;
788  tmpBP.clear ();
789 
790  loader.getBreakPoints(tmpBP);
791 
792  // debug outputs:
793  std::vector<Util::BreakPoint>::iterator iter;
794  std::vector<Util::BreakPoint>::iterator first = tmpBP.begin();
795  std::vector<Util::BreakPoint>::iterator last = tmpBP.end();
796 
797  // add any new breakpoints to the vector of breakpoints:
798  BreakPointSet::iterator itBP;
799  BreakPointSet::iterator itBP_2;
800  BreakPointSet::iterator firstBP = breakPoints_.begin();
801  BreakPointSet::iterator lastBP = breakPoints_.end();
802 
803  // Add new breakpoints to the set:
804  for (iter=first; iter!=last; ++iter)
805  {
806  if (iter->value() < finalTime && iter->value() > lastTime)
807  {
808  setBreakPoint(*iter, initial_time);
809  }
810  }
811 
812  if (DEBUG_TIME &&isActive(Diag::TIME_BREAKPOINTS))
813  {
814  firstBP = breakPoints_.begin();
815 
816  Xyce::dout() << netlistFilename_ << " breakPoints_ vector container, before any removals:" << std::endl;
817 
818  int i = 0;
819  for (itBP = firstBP; itBP != lastBP; ++i, ++itBP)
820  {
821  if (i==0)
822  {
823  Xyce::dout() << i << " " << itBP->value() << std::endl;
824  }
825  else
826  {
827  Xyce::dout() << i << " " << itBP->value() << " diff=" << (itBP->value()-itBP_2->value()) << std::endl;
828  }
829 
830  itBP_2 = itBP;
831  }
832  Xyce::dout() <<"" << std::endl;
833  }
834 
835  // Remove breakpoints which are now obsolete (old):
836  // LessThan<Util::BreakPoint,double> LessFunct;
837  // itBP_2 = std::lower_bound(firstBP,lastBP,lastTime,LessFunct);
838  itBP_2 = std::lower_bound(firstBP, lastBP, lastTime, breakPointLess_);
839  breakPoints_.erase(firstBP,itBP_2);
840 
841  // Remove breakpoints which are too close together.
842  // ERK. This is kind of ugly and can undoubtably be done
843  // in a much more elegant way using STL. Note that
844  // the value of "bpTol" is pulled out of my ear.
845 
846  // TVR: only need to do this if the BP tolerance has changed from what it
847  // was set to in the breakpoint class --- as things were inserted, near
848  // values were rejected if within tolerance. Only need to do this if the
849  // tolerance has gotten looser
850 
851  // TVR: Cannot use the STL "unique" function to accomplish this, because
852  // STL sets are designed to prevent changing the set elements after they're
853  // inserted. Have to do this by removing duplicate entries explicitly.
854 
855  double bpTol = 2.0 * minTimeStep;
856  if (bpTol != breakPointLess_.tolerance_)
857  {
858  // set the class's tolerance to this new one
859  breakPointLess_.tolerance_ = bpTol;
860  if (DEBUG_TIME && isActive(Diag::TIME_BREAKPOINTS))
861  {
862  Xyce::dout() << " bpTol = " << bpTol << std::endl;
863  Xyce::dout() << " Must now eliminate new duplicates " << std::endl;
864  }
865 
866  bool doneRemove = false;
867  while (!doneRemove)
868  {
869  doneRemove = true;
870  firstBP = breakPoints_.begin();
871  lastBP = breakPoints_.end();
872  int icount;
873  for (icount = 0, itBP=firstBP, itBP_2=firstBP;
874  itBP!=lastBP;
875  ++icount, ++itBP)
876  {
877  double diff = (itBP->value() - itBP_2->value());
878 
879  if (icount != 0)
880  {
881  if (fabs(diff) < bpTol)
882  {
883  // If both are simple, just toss the later one
884  if (itBP->bptype() == Xyce::Util::BreakPoint::SIMPLE &&
885  itBP_2->bptype() == Xyce::Util::BreakPoint::SIMPLE)
886  {
887  if (diff > 0.0)
888  breakPoints_.erase(itBP);
889  else
890  breakPoints_.erase(itBP_2);
891  }
892  else
893  {
894  // one of these breakpoints is not simple! Determine the
895  // overriding type, then set a breakpoint at the earliest time
896  // with the overriding type:
897  Xyce::Util::BreakPoint::Type overridingType = itBP->bptype();
898  double minTime=std::min(itBP->value(),itBP_2->value());
899 
900  // The following line will need to be changed if any other types
901  // besides SIMPLE_BREAKPOINT and PAUSE_BREAKPOINT are ever
902  // introduced and any more complex precedence is defined.
903  if (itBP_2->bptype() != Xyce::Util::BreakPoint::SIMPLE)
904  {
905  overridingType = itBP_2->bptype();
906  }
907  breakPoints_.erase(itBP);
908  breakPoints_.erase(itBP_2);
909  Util::BreakPoint tmpBP(minTime, overridingType);
910  breakPoints_.insert(tmpBP);
911  // and just to be very careful, make sure to update the pause
912  // time, lest the currentPauseBP iterator be confused.
913 
914  if (DEBUG_TIME && isActive(Diag::TIME_BREAKPOINTS))
915  Xyce::dout() << " Purging breakpoints, overriding with breakpoint of type " << tmpBP.bptype();
916 
917  updatePauseTime(tmpBP, initial_time);
918  }
919 
920  doneRemove = false;
921  break;
922  }
923  }
924  itBP_2 = itBP;
925  }
926  }
927  }
928 
929  if (DEBUG_TIME && isActive(Diag::TIME_BREAKPOINTS))
930  {
931  firstBP = breakPoints_.begin();
932 
933  Xyce::dout() << " breakPoints_ vector container after:" << std::endl;
934 
935  int i=0;
936  for (itBP=firstBP;itBP!=lastBP;++i,++itBP)
937  {
938  if (i==0)
939  {
940  Xyce::dout() << i << " " << itBP->value() << " type=" << itBP->bptype() << std::endl;
941  }
942  else
943  {
944  Xyce::dout() << i << " " << itBP->value() << " type=" << itBP->bptype() << " diff=" << (itBP->value()-itBP_2->value()) << std::endl;
945  }
946 
947  itBP_2 = itBP;
948  }
949 
950  Xyce::dout() << std::endl
951  << Xyce::section_divider << std::endl;
952  }
953 
954  return bsuccess;
955 }
956 
957 
958 //-----------------------------------------------------------------------------
959 // Function : StepErrorControl::updateMaxTimeStep
960 // Purpose : Requests dynamic time step information from the loader.
961 // Special Notes :
962 // Scope : public
963 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
964 // Creation Date : 08/01/01
965 //-----------------------------------------------------------------------------
966 bool
968  Parallel::Machine comm,
969  Loader::Loader & loader,
970  const TIAParams & tia_params,
971  double suggestedMaxTimeStep)
972 {
973  bool bsuccess = true;
974 
975  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
976  {
977  Xyce::dout() << Xyce::section_divider << std::endl
978  << " StepErrorControl::updateMaxTimeStep" << std::endl;
979  }
980 
981  double maxDevStep = 1.0e+99;
982  if (tia_params.useDeviceTimeStepMaxFlag)
983  {
984  maxDevStep = loader.getMaxTimeStepSize();
985  }
986 
987  if (tia_params.maxTimeStepGiven || tia_params.delmaxGiven)
988  {
989  maxTimeStep = std::min(tia_params.maxTimeStep, tia_params.delmax);
990  }
991  else
992  {
993  maxTimeStep = 0.1*(tia_params.finalTime-tia_params.initialTime);
994  }
995 
996  // if the default arg is not zero, then a suggested max time step was
997  // passed in. Test if it is feasible to use that at this time
998  if( suggestedMaxTimeStep > 0.0 )
999  {
1000  maxTimeStep = std::min( maxTimeStep, suggestedMaxTimeStep );
1001  }
1002 
1003  if ((maxTimeStepBP > 0.0) && (maxTimeStep > maxTimeStepBP))
1004  {
1006  }
1007 
1008  if (maxDevStep > 0.0)
1009  {
1010  maxTimeStep = std::min(maxTimeStep, maxDevStep);
1011  }
1012 
1013  if (tia_params.maxTimeStepGiven)
1014  {
1016  }
1017 
1018  Parallel::AllReduce(comm, MPI_MIN, &maxTimeStep, 1);
1019 
1020  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1021  {
1022  if (!tia_params.maxTimeStepGiven)
1023  {
1024  Xyce::dout() << " User did not specify a maximum time step." << std::endl;
1025  }
1026  else
1027  {
1028  Xyce::dout() << " User specified a maximum time step. = " << maxTimeStepUser << std::endl;
1029  }
1030 
1031  Xyce::dout() << " maxDevStep = " << maxDevStep << std::endl
1032  << " maxTimeStep = " << maxTimeStep << std::endl
1033  << Xyce::section_divider << std::endl;
1034  }
1035 
1036  if(maxTimeStep<=0.0)
1037  {
1038  const std::string msg = "Maximum Time step is invalid!\n";
1039  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1040  }
1041 
1042  return bsuccess;
1043 }
1044 
1045 //-----------------------------------------------------------------------------
1046 // Function : StepErrorControl::updateMinTimeStep
1047 // Purpose : Sets the minimum time step based on machine precision.
1048 // Special Notes :
1049 // Scope : public
1050 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
1051 // Creation Date : 08/02/01
1052 //-----------------------------------------------------------------------------
1054 {
1055  bool bsuccess = true;
1056 
1057  minTimeStep = currentTime*minStepPrecisionFac_*Util::MachineDependentParams::MachinePrecision();
1058 
1059  return bsuccess;
1060 }
1061 
1062 //-----------------------------------------------------------------------------
1063 // Function : StepErrorControl::setBreakPoint
1064 // Purpose : public method to set individual breakpoint
1065 // Special Notes :
1066 // Scope : public
1067 // Creator : Tom Russo, SNL, Component Information and Models
1068 // Creation Date : 04/30/04
1069 //-----------------------------------------------------------------------------
1071  const Util::BreakPoint & breakpoint,
1072  double initial_time)
1073 {
1074  if (breakpoint.bptype() == Xyce::Util::BreakPoint::SIMPLE)
1075  {
1076  breakPoints_.insert(breakpoint);
1077  }
1078  else
1079  {
1080  if (DEBUG_TIME && isActive(Diag::TIME_BREAKPOINTS))
1081  {
1082  Xyce::dout() << "In setBreakPoint, got non-simple breakpoint of type "
1083  << breakpoint.bptype() << " at time " << breakpoint.value() << std::endl;
1084  }
1085 
1086  // We're a pause breakpoint, and must override any simple breakpoint
1087  // at the same time.
1088  // erase any breakpoint that is the "same" time as this one
1089  breakPoints_.erase(breakpoint);
1090  // and put the new one in instead
1091  breakPoints_.insert(breakpoint);
1092  // force code to recalculate pause time NOW.
1093  updatePauseTime(breakpoint, initial_time);
1094  }
1095 }
1096 
1097 //-----------------------------------------------------------------------------
1098 // Function : StepErrorControl::setBreakPoint
1099 // Purpose : public method to set individual SIMPLE breakpoint
1100 // Special Notes :
1101 // Scope : public
1102 // Creator : Tom Russo, SNL, Component Information and Models
1103 // Creation Date : 04/30/04
1104 //-----------------------------------------------------------------------------
1106  double time)
1107 {
1108  breakPoints_.insert(time);
1109 }
1110 
1111 //-----------------------------------------------------------------------------
1112 // Function : StepErrorControl::updatePauseTime
1113 // Purpose : private method to recalculate pause time
1114 // Special Notes :
1115 // Scope : private
1116 // Creator : Tom Russo, SNL, Component Information and Models
1117 // Creation Date : 04/30/04
1118 //-----------------------------------------------------------------------------
1119 void
1121  Util::BreakPoint breakpoint,
1122  double initial_time)
1123 {
1124  // gotta handle case where pauseTime is still at its initial value of
1125  // 0.0, or we already passed the last pause time!
1126  // But we mustn't reset it if it's equal to the current time, because
1127  // that means we need to stop NOW and would overwrite that.
1128  //
1129  // If a pause break point is specifically set at 0, then
1130  // we shouldn't ignore that here. So set the pauseSetAtZero flag
1131  // here if needed.
1132  //
1133  // ERK: type>0 means breakpoint is "not simple", ie PAUSE breakpoint.
1134  if ((breakpoint.bptype() > 0) && (breakpoint.value() == 0.0))
1135  {
1136  pauseSetAtZero = true;
1137  }
1138 
1139  if (pauseTime < currentTime || ((pauseTime == initial_time) && !pauseSetAtZero))
1140  {
1141  pauseTime = breakpoint.value();
1142  }
1143  else
1144  {
1145  pauseTime = std::min(pauseTime, breakpoint.value());
1146  }
1147 
1148  // If we used this breakpoint for the pause time, save the iterator to this bp in
1149  // the list so we can use it later.
1150  if (pauseTime == breakpoint.value())
1151  {
1152  currentPauseBP = breakPoints_.find(breakpoint);
1153  if (DEBUG_TIME && isActive(Diag::TIME_BREAKPOINTS))
1154  {
1155  Xyce::dout() << "\n" << netlistFilename_
1156  << " UPDATING PAUSE TIME TO " << currentPauseBP->value()
1157  << " encountered breakpoint " << breakpoint.value() << " current time is "
1158  << currentTime << std::endl;
1159  }
1160  }
1161 }
1162 
1163 
1164 //-----------------------------------------------------------------------------
1165 // Function : StepErrorControl::simulationPaused
1166 // Purpose : public method to clear out breakpoint list and reset
1167 // pause time when pause time is reached
1168 // Special Notes : Need this method because the prior values get in the way
1169 // when we resume.
1170 // Scope : public
1171 // Creator : Tom Russo, SNL, Component Information and Models
1172 // Creation Date : 04/30/04
1173 //-----------------------------------------------------------------------------
1174 void
1176  double initial_time)
1177 {
1178  breakPoints_.erase(currentTime); // clear current breakpoint
1179  currentPauseBP = breakPoints_.end(); // make this invalid
1180  pauseTime = initial_time; // unset this
1181 }
1182 
1183 //-----------------------------------------------------------------------------
1184 // Function : StepErrorControl::printBreakPoints
1185 // Purpose :
1186 // Special Notes :
1187 // Scope : public
1188 // Creator : Eric Keiter, SNL
1189 // Creation Date : 10/17/05
1190 //-----------------------------------------------------------------------------
1191 void StepErrorControl::printBreakPoints (std::ostream & os) const
1192 {
1193  BreakPointSet::const_iterator itBP;
1194  BreakPointSet::const_iterator itBP2;
1195  BreakPointSet::const_iterator firstBP = breakPoints_.begin();
1196  BreakPointSet::const_iterator lastBP = breakPoints_.end();
1197 
1198  char tmp[128];
1199 
1200  int i;
1201  for (i=0, itBP=firstBP;itBP!=lastBP;++i,++itBP)
1202  {
1203  if (i==0)
1204  sprintf(tmp,"%4d %16.8e type=%d",i,itBP->value(),itBP->bptype());
1205  else
1206  sprintf(tmp,"%4d %16.8e type=%d diff=%16.8e", i, itBP->value(),
1207  itBP->bptype(),(itBP->value()-itBP2->value()));
1208 
1209  os << std::string(tmp);
1210  itBP2 = itBP;
1211  }
1212 }
1213 
1214 //-----------------------------------------------------------------------------
1215 // Function : StepErrorControl::restartDataSize
1216 // Purpose :
1217 // Special Notes : This gives the *total* size: both the base
1218 // StepErrorControl and the derived
1219 // StepErrorControlDAE, summed together.
1220 //
1221 // Don't sum them 2x!
1222 //
1223 // ERK: 6/20/2010:
1224 // There are no longer 2 distinct classes. The DAE version is
1225 // now part of the original, as one single class. The two
1226 // blocks of code in this function correspond to the original
1227 // class (first block), and the DAE class (second block).
1228 //
1229 // Scope : public
1230 // Creator : Eric R. Keiter, SNL
1231 // Creation Date : 07/27/06
1232 //-----------------------------------------------------------------------------
1234 {
1235  int totalSize = 0;
1236 
1237  // original set of vars:
1238  int numdoubles = 21;
1239  int numints = 9;
1240  int count = sizeof(double)*numdoubles;
1241  count += sizeof(int)*numints;
1242 
1243  // Must include the bp type now, not just the value
1244  count += sizeof(Util::BreakPoint)*breakPoints_.size();
1245 
1246  //overestimate buffer size for unpacked data
1247  // assumes there are fewer than 100 possible breakpoints types (i.e.
1248  // because the type can be represented by two ascii characters)
1249  if( !pack )
1250  { // 34
1251  count = 24*(numdoubles + numints + breakPoints_.size()) + 2*breakPoints_.size();
1252  }
1253 
1254  int baseClassSize = count;
1255 
1256  // another set of vars: (newDAE)
1257  numdoubles = 57;
1258  numints = 10;
1259 
1260  totalSize = baseClassSize;
1261  totalSize += sizeof(double) * numdoubles;
1262  totalSize += sizeof(int) * numints;
1263 
1264  //overestimate buffer size for unpacked data
1265  if ( !pack )
1266  {
1267  totalSize = baseClassSize + 24*(numdoubles+numints);
1268  }
1269 
1270  return totalSize;
1271 }
1272 //-----------------------------------------------------------------------------
1273 // Function : StepErrorControl::dumpRestartData
1274 // Purpose :
1275 // Special Notes : ERK: 6/20/2010:
1276 // There are no longer 2 distinct classes. The DAE version is
1277 // now part of the original, as one single class. The two
1278 // blocks of code in this function correspond to the original
1279 // class (first block), and the DAE class (second block).
1280 //
1281 // Scope : public
1282 // Creator : Eric R. Keiter, SNL
1283 // Creation Date : 7/28/06
1284 //-----------------------------------------------------------------------------
1286  char * buf,
1287  int bsize,
1288  int & pos,
1289  N_PDS_Comm * comm,
1290  bool pack)
1291 {
1292 
1293  // Set this variable up for later. Note that pos means different things
1294  // for packed vs. unpacked. For unpacked, it is the current index into
1295  // the buf array.
1296  int newPos = pos + getRestartDataSize(false);
1297 
1298  // if unpacked, initialize the buf array before calling the base class
1299  // function. At this point pos is zero, probably. The derived DAE
1300  // dataSize will be the size of the entire buf array, including the
1301  // base class size.
1302  if ( !pack )
1303  {
1304  for( int i = pos; i < (newPos); ++i) buf[i] = ' ';
1305  }
1306 
1307  if (DEBUG_RESTART)
1308  {
1309  Xyce::dout() << "TIA Restart Data DUMP! " << netlistFilename_ << "\n"
1310  << Xyce::section_divider << std::endl
1311  << "startingTimeStep: " << startingTimeStep << std::endl
1312  << "currentTimeStep: " << currentTimeStep << std::endl
1313  << "lastAttemptedTimeStep: " << lastAttemptedTimeStep << std::endl
1314  << "lastTimeStep: " << lastTimeStep << std::endl
1315  << "minTimeStep: " << minTimeStep << std::endl
1316  << "maxTimeStep: " << maxTimeStep << std::endl
1317  << "maxTimeStepUser: " << maxTimeStepUser << std::endl
1318  << "lastTime: " << lastTime << std::endl
1319  << "currentTime: " << currentTime << std::endl
1320  << "nextTime: " << nextTime << std::endl
1321  << "initialTime: " << initialTime << std::endl
1322  << "estOverTol_: " << estOverTol_ << std::endl
1323  << "breakpts: ";
1324 
1325  for (BreakPointSet::iterator iterSD = breakPoints_.begin(); iterSD != breakPoints_.end(); ++iterSD )
1326  Xyce::dout() << iterSD->value() << " ";
1327 
1328  Xyce::dout() << std::endl
1329  << "integMethod: " << analysisManager_.getIntegrationMethod() << std::endl
1330  << "stepNumber: " << analysisManager_.getStepNumber() << std::endl
1331  << "transStepNumber: " << analysisManager_.getTranStepNumber() << std::endl
1332  << "breakPointRestartNumber: " << analysisManager_.breakPointRestartStep << std::endl
1333  << Xyce::section_divider << std::endl << std::endl;
1334  }
1335 
1336  if( pack )
1337  {
1338  comm->pack( &startingTimeStep, 1, buf, bsize, pos );
1339  comm->pack( &currentTimeStep, 1, buf, bsize, pos );
1340  comm->pack( &lastAttemptedTimeStep, 1, buf, bsize, pos );
1341  comm->pack( &lastTimeStep, 1, buf, bsize, pos );
1342  comm->pack( &minTimeStep, 1, buf, bsize, pos );
1343  comm->pack( &maxTimeStep, 1, buf, bsize, pos );
1344  comm->pack( &maxTimeStepUser, 1, buf, bsize, pos );
1345  comm->pack( &lastTime, 1, buf, bsize, pos );
1346  comm->pack( &currentTime, 1, buf, bsize, pos );
1347  comm->pack( &nextTime, 1, buf, bsize, pos );
1348  comm->pack( &initialTime, 1, buf, bsize, pos );
1349  comm->pack( &currentTimeStepRatio, 1, buf, bsize, pos );
1350  comm->pack( &currentTimeStepSum, 1, buf, bsize, pos );
1351  comm->pack( &lastTimeStepRatio, 1, buf, bsize, pos );
1352  comm->pack( &lastTimeStepSum, 1, buf, bsize, pos );
1353  comm->pack( &newtonConvergenceStatus, 1, buf, bsize, pos );
1354  comm->pack( &numberSuccessiveFailures, 1, buf, bsize, pos );
1355  int flag = stepAttemptStatus;
1356  comm->pack( &flag, 1, buf, bsize, pos );
1357  comm->pack( &minStepPrecisionFac_, 1, buf, bsize, pos );
1358  comm->pack( &newtonStepReduction_, 1, buf, bsize, pos );
1359  comm->pack( &tolAimFac_, 1, buf, bsize, pos );
1360  comm->pack( &estOverTol_, 1, buf, bsize, pos );
1361  // Subtract one, because we won't write out the pause breakpoint at the
1362  // final time
1363  int size = breakPoints_.size() -1 ;
1364  BreakPointSet::iterator bpStart = breakPoints_.begin();
1365  BreakPointSet::iterator bpEnd = breakPoints_.end();
1366  comm->pack( &size, 1, buf, bsize, pos );
1367 
1368  double val;
1369  int bptype;
1370  for( BreakPointSet::iterator iterSD = bpStart;
1371  iterSD != bpEnd; ++iterSD)
1372  {
1373  val=iterSD->value();
1374  bptype=iterSD->bptype();
1375  if (!(bptype == Xyce::Util::BreakPoint::PAUSE && val == finalTime))
1376  {
1377  comm->pack( &(val), 1, buf, bsize, pos );
1378  comm->pack( &(bptype), 1, buf, bsize, pos );
1379  }
1380  }
1382  comm->pack( &im, 1, buf, bsize, pos );
1383  int sN = analysisManager_.getStepNumber();
1384  comm->pack( &sN, 1, buf, bsize, pos );
1385  int tSN = analysisManager_.getTranStepNumber();
1386  comm->pack( &tSN, 1, buf, bsize, pos );
1388  comm->pack( &bPRS, 1, buf, bsize, pos );
1389  int beginFlag = (analysisManager_.getBeginningIntegrationFlag())?1:0;
1390  comm->pack( &beginFlag, 1, buf, bsize, pos );
1391  }
1392  else
1393  {
1394  // count here will be the size for the base StepErrorControl
1395  // class *only*.
1396  int count = getRestartDataSize( false );
1397  int startIndex = pos;
1398 
1399  // Clobber any data in buf lest we leave garbage
1400  for( int i = startIndex; i < (startIndex+count); ++i) buf[i] = ' ';
1401 
1402  std::ostringstream ost;
1403  ost.width(24);ost.precision(16);ost.setf(std::ios::scientific);
1404  ost << startingTimeStep << " ";
1405  ost << currentTimeStep << " ";
1406  ost << lastAttemptedTimeStep << " ";
1407  ost << lastTimeStep << " ";
1408  ost << minTimeStep << " ";
1409  ost << maxTimeStep << " ";
1410  ost << maxTimeStepUser << " ";
1411  ost << lastTime << " ";
1412  ost << currentTime << " ";
1413  ost << nextTime << " ";
1414  ost << initialTime << " ";
1415  ost << currentTimeStepRatio << " ";
1416  ost << currentTimeStepSum << " ";
1417  ost << lastTimeStepRatio << " ";
1418  ost << lastTimeStepSum << " ";
1419  ost << newtonConvergenceStatus << " ";
1420  ost << numberSuccessiveFailures << " ";
1421  int flag = (stepAttemptStatus)?1:0;
1422  ost << flag << " ";
1423  ost << minStepPrecisionFac_ << " ";
1424  ost << newtonStepReduction_ << " ";
1425  ost << tolAimFac_ << " ";
1426  ost << estOverTol_ << " ";
1427  // Subtract one because we won't write out the pause breakpoint at the
1428  // final time
1429  int size = breakPoints_.size() - 1;
1430  ost << size << " ";
1431 
1432  BreakPointSet::iterator bpStart = breakPoints_.begin();
1433  BreakPointSet::iterator bpEnd = breakPoints_.end();
1434  for( BreakPointSet::iterator iterSD = bpStart;
1435  iterSD != bpEnd; ++iterSD )
1436  {
1437  if (!(iterSD->bptype() == Xyce::Util::BreakPoint::PAUSE && iterSD->value() == finalTime))
1438  {
1439  ost << iterSD->value() << " ";
1440  ost << iterSD->bptype() << " ";
1441  }
1442  }
1444  ost << im << " ";
1445  int sN = analysisManager_.getStepNumber();
1446  ost << sN << " ";
1447  int tSN = analysisManager_.getTranStepNumber();
1448  ost << tSN << " ";
1450  ost << bPRS << " ";
1451  int beginFlag = (analysisManager_.getBeginningIntegrationFlag())?1:0;
1452  ost << beginFlag << " ";
1453 
1454  std::string data( ost.str() );
1455  for( unsigned int i = 0; i < data.length(); ++i ) buf[startIndex+i] = data[i];
1456  // The line above copies the characters of the data string into buf,
1457  // but doesn't null-terminate buf.
1458  // it is essential to terminate the buffer with a null, or attempts
1459  // to construct a string object from it will get memory access problems.
1460  buf[startIndex+data.length()] = '\0';
1461  pos += data.length();
1462 
1463  if (DEBUG_RESTART)
1464  {
1465  std::string outputString(buf);
1466 
1467  Xyce::dout() << "StepErrorControl UNPACKED output buffer:" << std::endl
1468  << outputString << std::endl;
1469  }
1470  }
1471 
1472  if (DEBUG_RESTART)
1473  {
1474  Xyce::dout() << "TIA Restart Data DUMP (DAE)! " << netlistFilename_ << "\n"
1475  << Xyce::section_divider << std::endl<<std::endl
1476  << "alphas_ = " <<alphas_<<std::endl
1477  << "alpha0_ = " <<alpha0_<<std::endl
1478  << "cj_ = " <<cj_<<std::endl
1479  << "ck_ = " <<ck_<<std::endl
1480  << "usedStep_ = " <<usedStep_<<std::endl
1481  << "Ek_ = " <<Ek_<<std::endl
1482  << "Ekm1_ = " <<Ekm1_<<std::endl
1483  << "Ekm2_ = " <<Ekm2_<<std::endl
1484  << "Ekp1_ = " <<Ekp1_<<std::endl
1485  << "Est_ = " <<Est_<<std::endl
1486  << "Tk_ = " <<Tk_<<std::endl
1487  << "Tkm1_ = " <<Tkm1_<<std::endl
1488  << "Tkm2_ = " <<Tkm2_<<std::endl
1489  << "Tkp1_ = " <<Tkp1_<<std::endl
1490  << "h0_safety_ = " <<h0_safety_<<std::endl
1491  << "h0_max_factor_ = " <<h0_max_factor_<<std::endl
1492  << "h_phase0_incr_ = " <<h_phase0_incr_<<std::endl
1493  << "h_max_inv_ = " <<h_max_inv_<<std::endl
1494  << "Tkm1_Tk_safety_ = " <<Tkm1_Tk_safety_<<std::endl
1495  << "Tkp1_Tk_safety_ = " <<Tkp1_Tk_safety_<<std::endl
1496  << "r_factor_ = " <<r_factor_<<std::endl
1497  << "r_safety_ = " <<r_safety_<<std::endl
1498  << "r_fudge_ = " <<r_fudge_<<std::endl
1499  << "r_min_ = " <<r_min_<<std::endl
1500  << "r_max_ = " <<r_max_<<std::endl
1501  << "r_hincr_test_ = " <<r_hincr_test_<<std::endl
1502  << "r_hincr_ = " <<r_hincr_<<std::endl;
1503 
1504  for (int i=0;i<6;++i)
1505  {
1506  Xyce::dout() << " alpha_["<<i<<"] = " << alpha_[i]<<std::endl
1507  << " sigma_["<<i<<"] = " << sigma_[i]<<std::endl
1508  << " gamma_["<<i<<"] = " << gamma_[i]<<std::endl
1509  << " beta_["<<i<<"] = " << beta_[i]<<std::endl
1510  << " psi_["<<i<<"] = " << psi_[i]<<std::endl;
1511  }
1512 
1513  Xyce::dout() << Xyce::section_divider << std::endl << std::endl << std::endl;
1514  }
1515 
1516  if( pack )
1517  {
1518  // doubles:
1519  comm->pack( &alphas_ , 1, buf, bsize, pos );
1520  comm->pack( &alpha0_ , 1, buf, bsize, pos );
1521  comm->pack( &cj_ , 1, buf, bsize, pos );
1522  comm->pack( &ck_ , 1, buf, bsize, pos );
1523  comm->pack( &usedStep_ , 1, buf, bsize, pos );
1524  comm->pack( &Ek_ , 1, buf, bsize, pos );
1525  comm->pack( &Ekm1_ , 1, buf, bsize, pos );
1526  comm->pack( &Ekm2_ , 1, buf, bsize, pos );
1527  comm->pack( &Ekp1_ , 1, buf, bsize, pos );
1528  comm->pack( &Est_ , 1, buf, bsize, pos );
1529  comm->pack( &Tk_ , 1, buf, bsize, pos );
1530  comm->pack( &Tkm1_ , 1, buf, bsize, pos );
1531  comm->pack( &Tkm2_ , 1, buf, bsize, pos );
1532  comm->pack( &Tkp1_ , 1, buf, bsize, pos );
1533  comm->pack( &h0_safety_ , 1, buf, bsize, pos );
1534  comm->pack( &h0_max_factor_ , 1, buf, bsize, pos );
1535  comm->pack( &h_phase0_incr_ , 1, buf, bsize, pos );
1536  comm->pack( &h_max_inv_ , 1, buf, bsize, pos );
1537  comm->pack( &Tkm1_Tk_safety_ , 1, buf, bsize, pos );
1538  comm->pack( &Tkp1_Tk_safety_ , 1, buf, bsize, pos );
1539  comm->pack( &r_factor_ , 1, buf, bsize, pos );
1540  comm->pack( &r_safety_ , 1, buf, bsize, pos );
1541  comm->pack( &r_fudge_ , 1, buf, bsize, pos );
1542  comm->pack( &r_min_ , 1, buf, bsize, pos );
1543  comm->pack( &r_max_ , 1, buf, bsize, pos );
1544  comm->pack( &r_hincr_test_ , 1, buf, bsize, pos );
1545  comm->pack( &r_hincr_ , 1, buf, bsize, pos );
1546 
1547  // vectors of doubles:
1548  for (int i=0;i<6;++i)
1549  {
1550  comm->pack( &alpha_[i], 1, buf, bsize, pos );
1551  comm->pack( &sigma_[i], 1, buf, bsize, pos );
1552  comm->pack( &gamma_[i], 1, buf, bsize, pos );
1553  comm->pack( &beta_[i], 1, buf, bsize, pos );
1554  comm->pack( &psi_[i], 1, buf, bsize, pos );
1555  }
1556 
1557  // ints:
1558  comm->pack ( &currentOrder_, 1, buf, bsize, pos);
1559  comm->pack ( &oldOrder_, 1, buf, bsize, pos);
1560  comm->pack ( &maxOrder_, 1, buf, bsize, pos);
1561  comm->pack ( &minOrder_, 1, buf, bsize, pos);
1562  comm->pack ( &usedOrder_, 1, buf, bsize, pos);
1563  comm->pack ( &numberOfSteps_, 1, buf, bsize, pos);
1564  comm->pack ( &nef_, 1, buf, bsize, pos);
1565  comm->pack ( &nscsco_, 1, buf, bsize, pos);
1566  comm->pack ( &newOrder_, 1, buf, bsize, pos);
1567  comm->pack ( &max_LET_fail_, 1, buf, bsize, pos);
1568 
1569  // bools:
1570  int iP = (initialPhase_)?1:0;
1571  comm->pack ( &iP, 1, buf, bsize, pos);
1572  }
1573  else
1574  {
1575  std::ostringstream ost;
1576  ost.width(24);ost.precision(16);ost.setf(std::ios::scientific);
1577 
1578  // doubles:
1579  ost << alphas_ << " ";
1580  ost << alpha0_ << " ";
1581  ost << cj_ << " ";
1582  ost << ck_ << " ";
1583  ost << usedStep_ << " ";
1584  ost << Ek_ << " ";
1585  ost << Ekm1_ << " ";
1586  ost << Ekm2_ << " ";
1587  ost << Ekp1_ << " ";
1588  ost << Est_ << " ";
1589  ost << Tk_ << " ";
1590  ost << Tkm1_ << " ";
1591  ost << Tkm2_ << " ";
1592  ost << Tkp1_ << " ";
1593  ost << h0_safety_ << " ";
1594  ost << h0_max_factor_ << " ";
1595  ost << h_phase0_incr_ << " ";
1596  ost << h_max_inv_ << " ";
1597  ost << Tkm1_Tk_safety_ << " ";
1598  ost << Tkp1_Tk_safety_ << " ";
1599  ost << r_factor_ << " ";
1600  ost << r_safety_ << " ";
1601  ost << r_fudge_ << " ";
1602  ost << r_min_ << " ";
1603  ost << r_max_ << " ";
1604  ost << r_hincr_test_ << " ";
1605  ost << r_hincr_ << " ";
1606 
1607  // vectors of doubles:
1608  for (int i=0;i<6;++i)
1609  {
1610  ost << alpha_[i]<< " " ;
1611  ost << sigma_[i]<< " " ;
1612  ost << gamma_[i]<< " " ;
1613  ost << beta_[i]<< " " ;
1614  ost << psi_[i]<< " " ;
1615  }
1616 
1617  // ints:
1618  ost << currentOrder_ << " ";
1619  ost << oldOrder_ << " ";
1620  ost << maxOrder_ << " ";
1621  ost << minOrder_ << " ";
1622  ost << usedOrder_ << " ";
1623  ost << numberOfSteps_ << " ";
1624  ost << nef_ << " ";
1625  ost << nscsco_ << " ";
1626  ost << newOrder_ << " ";
1627  ost << max_LET_fail_ << " ";
1628 
1629  // bools:
1630  int iP = (initialPhase_)?1:0;
1631  ost << iP << " ";
1632 
1633  std::string data( ost.str() );
1634  for( unsigned int i = 0; i < data.length(); ++i ) buf[pos+i] = data[i];
1635  // null terminate buf, essential if buf is used as a string anywhere,
1636  // including in the string constructor below:
1637  buf[pos+data.length()] = '\0';
1638 
1639  if (DEBUG_RESTART) {
1640  std::string outputString(buf);
1641 
1642  Xyce::dout() << "StepErrorControlDAE UNPACKED output buffer:" << std::endl
1643  << outputString << std::endl;
1644  }
1645 
1646  pos = newPos;
1647  }
1648 
1649  return true;
1650 }
1651 
1652 //-----------------------------------------------------------------------------
1653 // Function : StepErrorControl::restoreRestartData
1654 // Purpose :
1655 // Special Notes : ERK: 6/20/2010:
1656 // There are no longer 2 distinct classes. The DAE version is
1657 // now part of the original, as one single class. The two
1658 // blocks of code in this function correspond to the original
1659 // class (first block), and the DAE class (second block).
1660 //
1661 // Scope : public
1662 // Creator : Eric R. Keiter, SNL
1663 // Creation Date : 7/28/06
1664 //-----------------------------------------------------------------------------
1666  char * buf,
1667  int bsize,
1668  int & pos,
1669  N_PDS_Comm * comm,
1670  bool pack,
1671  double & initial_time)
1672 {
1673  // original class variables:
1674  if( pack )
1675  {
1676  comm->unpack(buf, bsize, pos, &startingTimeStep, 1);
1677  comm->unpack(buf, bsize, pos, &currentTimeStep, 1);
1678  comm->unpack(buf, bsize, pos, &lastAttemptedTimeStep, 1);
1679  comm->unpack(buf, bsize, pos, &lastTimeStep, 1);
1680  comm->unpack(buf, bsize, pos, &minTimeStep, 1);
1681  comm->unpack(buf, bsize, pos, &maxTimeStep, 1);
1682  comm->unpack(buf, bsize, pos, &maxTimeStepUser, 1);
1683  comm->unpack(buf, bsize, pos, &lastTime, 1);
1684  comm->unpack(buf, bsize, pos, &currentTime, 1);
1685  comm->unpack(buf, bsize, pos, &nextTime, 1);
1686  comm->unpack(buf, bsize, pos, &initialTime, 1);
1687  comm->unpack(buf, bsize, pos, &currentTimeStepRatio, 1);
1688  comm->unpack(buf, bsize, pos, &currentTimeStepSum, 1);
1689  comm->unpack(buf, bsize, pos, &lastTimeStepRatio, 1);
1690  comm->unpack(buf, bsize, pos, &lastTimeStepSum, 1);
1691  comm->unpack(buf, bsize, pos, &newtonConvergenceStatus, 1);
1692  comm->unpack(buf, bsize, pos, &numberSuccessiveFailures, 1);
1693  int flag;
1694  comm->unpack(buf, bsize, pos, &flag, 1);
1695  stepAttemptStatus = flag;
1696  comm->unpack(buf, bsize, pos, &minStepPrecisionFac_, 1);
1697  comm->unpack(buf, bsize, pos, &newtonStepReduction_, 1);
1698  comm->unpack(buf, bsize, pos, &tolAimFac_, 1);
1699  comm->unpack(buf, bsize, pos, &estOverTol_, 1);
1700 
1701  double bpTol = 2.0 * minTimeStep;
1702  breakPointLess_.tolerance_ = bpTol;
1703  initial_time = initialTime;
1705  BreakPointSet tmpSet = breakPoints_;
1706  breakPoints_.clear();
1707  BreakPointSet::iterator iterSD;
1708  BreakPointSet::iterator firstSD = tmpSet.begin();
1709  BreakPointSet::iterator lastSD = tmpSet.end();
1710  for (iterSD = firstSD; iterSD != lastSD; ++iterSD)
1711  {
1712  if (iterSD->value() > currentTime)
1713  {
1714  breakPoints_.insert(*iterSD);
1715  if (iterSD->bptype() == Xyce::Util::BreakPoint::PAUSE)
1716  updatePauseTime(*iterSD, initialTime);
1717  }
1718  }
1719 
1720  int size;
1721  double val;
1722  int bptype;
1723  comm->unpack(buf, bsize, pos, &size, 1);
1724 
1725  for (int i = 0; i < size; ++i)
1726  {
1727  comm->unpack(buf, bsize, pos, &val, 1);
1728  comm->unpack(buf, bsize, pos, &bptype, 1);
1729  if (val > currentTime)
1730  {
1731  Util::BreakPoint TmpBP(val, bptype);
1732  breakPoints_.insert(TmpBP);
1733  if (TmpBP.bptype() == Xyce::Util::BreakPoint::PAUSE)
1734  {
1735  updatePauseTime(TmpBP, initialTime);
1736  }
1737  }
1738  }
1739 
1740  int im;
1741  comm->unpack(buf, bsize, pos, &im, 1);
1743  comm->unpack(buf, bsize, pos, &im, 1);
1745  comm->unpack(buf, bsize, pos, &im, 1);
1747  comm->unpack(buf, bsize, pos, &im, 1);
1749  comm->unpack(buf, bsize, pos, &im, 1);
1751  }
1752  else
1753  {
1754  std::string str1(buf);
1755  int length = str1.size() - pos;
1756  std::string str2(str1,pos,length);
1757 
1758  std::istringstream ist( str2 );
1759 
1760  // count here will be the size for the base StepErrorControl
1761  // class *only*.
1762 
1763  // THIS IS INCORRECT! restartDataSize returns the MAXIMUM the thing
1764  // is allowed to be, which allows for 24 characters for each integer
1765  // value in the output. This is almost always an overestimate, and
1766  // using it as a way of pointing to the next character after our
1767  // data is a sure-fire way to break downstream processing!
1768  // Instead, we'll use the tellg function from the stringstream to
1769  // return the offset after we read everything out.
1770  // int count = StepErrorControl::restartDataSize( false );
1771  // pos += count;
1772 
1773  ist >> startingTimeStep;
1774  ist >> currentTimeStep;
1775  ist >> lastAttemptedTimeStep;
1776  ist >> lastTimeStep;
1777  ist >> minTimeStep;
1778  ist >> maxTimeStep;
1779  ist >> maxTimeStepUser;
1780  ist >> lastTime;
1781  ist >> currentTime;
1782  ist >> nextTime;
1783  ist >> initialTime;
1784  ist >> currentTimeStepRatio;
1785  ist >> currentTimeStepSum;
1786  ist >> lastTimeStepRatio;
1787  ist >> lastTimeStepSum;
1788  ist >> newtonConvergenceStatus;
1789  ist >> numberSuccessiveFailures;
1790  int flag;
1791  ist >> flag;
1792  stepAttemptStatus = flag;
1793  ist >> minStepPrecisionFac_;
1794  ist >> newtonStepReduction_;
1795  ist >> tolAimFac_;
1796  ist >> estOverTol_;
1797 
1798  double bpTol = 2.0 * minTimeStep;
1799  breakPointLess_.tolerance_ = bpTol;
1800  initial_time = initialTime;
1802 
1803  BreakPointSet tmpSet = breakPoints_;
1804  breakPoints_.clear();
1805  BreakPointSet::iterator iterSD;
1806  BreakPointSet::iterator firstSD = tmpSet.begin();
1807  BreakPointSet::iterator lastSD = tmpSet.end();
1808  for (iterSD = firstSD; iterSD != lastSD; ++iterSD)
1809  {
1810  if (iterSD->value() > currentTime)
1811  {
1812  breakPoints_.insert(*iterSD);
1813  if (iterSD->bptype() == Xyce::Util::BreakPoint::PAUSE)
1814  updatePauseTime(*iterSD, initialTime);
1815  }
1816  }
1817 
1818  int size;
1819  double val;
1820  int bptype;
1821  ist >> size;
1822 
1823  for( int i = 0; i < size; ++i )
1824  {
1825  ist >> val;
1826  ist >> bptype;
1827  if (val > currentTime)
1828  {
1829  Util::BreakPoint TmpBP(val, bptype);
1830  breakPoints_.insert(TmpBP);
1831  if (TmpBP.bptype() == Xyce::Util::BreakPoint::PAUSE)
1832  {
1833  updatePauseTime(TmpBP, initialTime);
1834  }
1835  }
1836  }
1837 
1838  int tmpInt;
1839  ist >> tmpInt;
1841  ist >> tmpInt;
1843  ist >> tmpInt;
1845  ist >> tmpInt;
1847  ist >> tmpInt;
1849 
1850  pos += ist.tellg();
1851  }
1852 
1853  if (DEBUG_RESTART)
1854  {
1855  Xyce::dout() << "TIA Restart Data RESTORE! " << netlistFilename_ << "\n"
1856  << Xyce::section_divider << std::endl
1857  << "startingTimeStep: " << startingTimeStep << std::endl
1858  << "currentTimeStep: " << currentTimeStep << std::endl
1859  << "lastAttemptedTimeStep: " << lastAttemptedTimeStep << std::endl
1860  << "lastTimeStep: " << lastTimeStep << std::endl
1861  << "minTimeStep: " << minTimeStep << std::endl
1862  << "maxTimeStep: " << maxTimeStep << std::endl
1863  << "maxTimeStepUser: " << maxTimeStepUser << std::endl
1864  << "lastTime: " << lastTime << std::endl
1865  << "currentTime: " << currentTime << std::endl
1866  << "nextTime: " << nextTime << std::endl
1867  << "initialTime: " << initialTime << std::endl
1868  << "estOverTol_: " << estOverTol_ << std::endl
1869  << "breakpts: ";
1870  for (BreakPointSet::iterator iterSD = breakPoints_.begin();
1871  iterSD != breakPoints_.end(); ++iterSD)
1872  {
1873  Xyce::dout() << iterSD->value() << " " << iterSD->bptype() << std::endl;
1874  }
1875  Xyce::dout() << std::endl
1876  << "integMethod: " << analysisManager_.getIntegrationMethod() << std::endl
1877  << "stepNumber: " << analysisManager_.getStepNumber() << std::endl
1878  << "tranStepNumber: " << analysisManager_.getTranStepNumber() << std::endl
1879  << "breakPointRestartStep: " << analysisManager_.breakPointRestartStep << std::endl
1880  << Xyce::section_divider << std::endl << std::endl;
1881  }
1882 
1883  // DAE class variables:
1884  if( pack )
1885  {
1886  // doubles:
1887  comm->unpack(buf, bsize, pos, &alphas_ , 1);
1888  comm->unpack(buf, bsize, pos, &alpha0_ , 1);
1889  comm->unpack(buf, bsize, pos, &cj_ , 1);
1890  comm->unpack(buf, bsize, pos, &ck_ , 1);
1891  comm->unpack(buf, bsize, pos, &usedStep_ , 1);
1892  comm->unpack(buf, bsize, pos, &Ek_ , 1);
1893  comm->unpack(buf, bsize, pos, &Ekm1_ , 1);
1894  comm->unpack(buf, bsize, pos, &Ekm2_ , 1);
1895  comm->unpack(buf, bsize, pos, &Ekp1_ , 1);
1896  comm->unpack(buf, bsize, pos, &Est_ , 1);
1897  comm->unpack(buf, bsize, pos, &Tk_ , 1);
1898  comm->unpack(buf, bsize, pos, &Tkm1_ , 1);
1899  comm->unpack(buf, bsize, pos, &Tkm2_ , 1);
1900  comm->unpack(buf, bsize, pos, &Tkp1_ , 1);
1901  comm->unpack(buf, bsize, pos, &h0_safety_ , 1);
1902  comm->unpack(buf, bsize, pos, &h0_max_factor_ , 1);
1903  comm->unpack(buf, bsize, pos, &h_phase0_incr_ , 1);
1904  comm->unpack(buf, bsize, pos, &h_max_inv_ , 1);
1905  comm->unpack(buf, bsize, pos, &Tkm1_Tk_safety_ , 1);
1906  comm->unpack(buf, bsize, pos, &Tkp1_Tk_safety_ , 1);
1907  comm->unpack(buf, bsize, pos, &r_factor_ , 1);
1908  comm->unpack(buf, bsize, pos, &r_safety_ , 1);
1909  comm->unpack(buf, bsize, pos, &r_fudge_ , 1);
1910  comm->unpack(buf, bsize, pos, &r_min_ , 1);
1911  comm->unpack(buf, bsize, pos, &r_max_ , 1);
1912  comm->unpack(buf, bsize, pos, &r_hincr_test_ , 1);
1913  comm->unpack(buf, bsize, pos, &r_hincr_ , 1);
1914 
1915  // vectors of doubles:
1916  for (int i=0;i<6;++i)
1917  {
1918  comm->unpack(buf, bsize, pos, &alpha_[i], 1);
1919  comm->unpack(buf, bsize, pos, &sigma_[i], 1);
1920  comm->unpack(buf, bsize, pos, &gamma_[i], 1);
1921  comm->unpack(buf, bsize, pos, &beta_[i], 1);
1922  comm->unpack(buf, bsize, pos, &psi_[i], 1);
1923  }
1924 
1925  // ints:
1926  comm->unpack(buf, bsize, pos, &currentOrder_, 1);
1927  comm->unpack(buf, bsize, pos, &oldOrder_, 1);
1928  comm->unpack(buf, bsize, pos, &maxOrder_, 1);
1929  comm->unpack(buf, bsize, pos, &minOrder_, 1);
1930  comm->unpack(buf, bsize, pos, &usedOrder_, 1);
1931  comm->unpack(buf, bsize, pos, &numberOfSteps_, 1);
1932  comm->unpack(buf, bsize, pos, &nef_, 1);
1933  comm->unpack(buf, bsize, pos, &nscsco_, 1);
1934  comm->unpack(buf, bsize, pos, &newOrder_, 1);
1935  comm->unpack(buf, bsize, pos, &max_LET_fail_, 1);
1936 
1937  // bools:
1938  int iP;
1939  comm->unpack (buf, bsize, pos, &iP, 1);
1940  if (iP == 0) initialPhase_ = false;
1941  else initialPhase_ = true;
1942  }
1943  else
1944  {
1945  // want the string stream to only represent the new-DAE part of
1946  // the buf array.
1947  std::string str1(buf);
1948  int length = str1.size() - pos;
1949  std::string str2(str1,pos,length);
1950 
1951  std::istringstream ist( str2 );
1952 
1953  int count = getRestartDataSize(false);
1954  pos = count; // can update here, as pos isn't used after this.
1955 
1956  // doubles:
1957  ist >> alphas_;
1958  ist >> alpha0_;
1959  ist >> cj_;
1960  ist >> ck_;
1961  ist >> usedStep_;
1962  ist >> Ek_;
1963  ist >> Ekm1_;
1964  ist >> Ekm2_;
1965  ist >> Ekp1_;
1966  ist >> Est_;
1967  ist >> Tk_;
1968  ist >> Tkm1_;
1969  ist >> Tkm2_;
1970  ist >> Tkp1_;
1971  ist >> h0_safety_;
1972  ist >> h0_max_factor_;
1973  ist >> h_phase0_incr_;
1974  ist >> h_max_inv_;
1975  ist >> Tkm1_Tk_safety_;
1976  ist >> Tkp1_Tk_safety_;
1977  ist >> r_factor_;
1978  ist >> r_safety_;
1979  ist >> r_fudge_;
1980  ist >> r_min_;
1981  ist >> r_max_;
1982  ist >> r_hincr_test_;
1983  ist >> r_hincr_;
1984 
1985  // vectors of doubles:
1986  for (int i=0;i<6;++i)
1987  {
1988  ist >> alpha_[i];
1989  ist >> sigma_[i];
1990  ist >> gamma_[i];
1991  ist >> beta_[i];
1992  ist >> psi_[i];
1993  }
1994 
1995  // ints:
1996  ist >> currentOrder_;
1997  ist >> oldOrder_;
1998  ist >> maxOrder_;
1999  ist >> minOrder_;
2000  ist >> usedOrder_;
2001  ist >> numberOfSteps_;
2002  ist >> nef_;
2003  ist >> nscsco_;
2004  ist >> newOrder_;
2005  ist >> max_LET_fail_;
2006 
2007  // bools:
2008  int iP;
2009  ist >> iP;
2010  if (iP == 0) initialPhase_ = false;
2011  else initialPhase_ = true;
2012  }
2013 
2014  if (DEBUG_RESTART)
2015  {
2016 
2017  Xyce::dout() << "TIA Restart Data RESTORE (DAE)! " << netlistFilename_ << "\n"
2018  << Xyce::section_divider << std::endl<<std::endl
2019  << "alphas_ = " <<alphas_<<std::endl
2020  << "alpha0_ = " <<alpha0_<<std::endl
2021  << "cj_ = " <<cj_<<std::endl
2022  << "ck_ = " <<ck_<<std::endl
2023  << "usedStep_ = " <<usedStep_<<std::endl
2024  << "Ek_ = " <<Ek_<<std::endl
2025  << "Ekm1_ = " <<Ekm1_<<std::endl
2026  << "Ekm2_ = " <<Ekm2_<<std::endl
2027  << "Ekp1_ = " <<Ekp1_<<std::endl
2028  << "Est_ = " <<Est_<<std::endl
2029  << "Tk_ = " <<Tk_<<std::endl
2030  << "Tkm1_ = " <<Tkm1_<<std::endl
2031  << "Tkm2_ = " <<Tkm2_<<std::endl
2032  << "Tkp1_ = " <<Tkp1_<<std::endl
2033  << "h0_safety_ = " <<h0_safety_<<std::endl
2034  << "h0_max_factor_ = " <<h0_max_factor_<<std::endl
2035  << "h_phase0_incr_ = " <<h_phase0_incr_<<std::endl
2036  << "h_max_inv_ = " <<h_max_inv_<<std::endl
2037  << "Tkm1_Tk_safety_ = " <<Tkm1_Tk_safety_<<std::endl
2038  << "Tkp1_Tk_safety_ = " <<Tkp1_Tk_safety_<<std::endl
2039  << "r_factor_ = " <<r_factor_<<std::endl
2040  << "r_safety_ = " <<r_safety_<<std::endl
2041  << "r_fudge_ = " <<r_fudge_<<std::endl
2042  << "r_min_ = " <<r_min_<<std::endl
2043  << "r_max_ = " <<r_max_<<std::endl
2044  << "r_hincr_test_ = " <<r_hincr_test_<<std::endl
2045  << "r_hincr_ = " <<r_hincr_<<std::endl;
2046 
2047  for (int i=0;i<6;++i)
2048  {
2049  Xyce::dout() << " alpha_["<<i<<"] = " << alpha_[i]<<std::endl
2050  << " sigma_["<<i<<"] = " << sigma_[i]<<std::endl
2051  << " gamma_["<<i<<"] = " << gamma_[i]<<std::endl
2052  << " beta_["<<i<<"] = " << beta_[i]<<std::endl
2053  << " psi_["<<i<<"] = " << psi_[i]<<std::endl;
2054  }
2055 
2056  Xyce::dout() << Xyce::section_divider << std::endl << std::endl << std::endl;
2057  }
2058 
2059  return true;
2060 }
2061 
2062 //-----------------------------------------------------------------------------
2063 // Function : StepErrorControl::updateTwoLevelTimeInfo
2064 // Purpose :
2065 // Special Notes :
2066 // Scope : public
2067 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
2068 // Creation Date : 3/14/06
2069 //-----------------------------------------------------------------------------
2070 void
2072  Parallel::Machine comm,
2073  double tiInfonextTimeStep,
2074  double tiInfonextTime,
2075  int tiInfocurrentOrder,
2076  bool breakpoints_enabled,
2077  double initial_time,
2078  bool min_time_steps_breakpoint_given,
2079  double min_time_steps_breakpoint)
2080 {
2081  updateStopTime(comm, breakpoints_enabled, initial_time, min_time_steps_breakpoint_given, min_time_steps_breakpoint);
2082 
2083  // Need to get this right.
2084  if (previousCallStepSuccessful == true)
2085  {
2090  }
2091 
2092  // If the step needs to be adjusted:
2094  double newTimeStep = tiInfonextTimeStep;
2095  nextTime = tiInfonextTime;
2096  currentTimeStepRatio = newTimeStep/lastTimeStep;
2097  currentTimeStepSum = newTimeStep + lastTimeStep;
2098  currentTimeStep = newTimeStep;
2099  currentOrder_ = tiInfocurrentOrder;
2100 }
2101 
2102 //-----------------------------------------------------------------------------
2103 // Function : StepErrorControl::outputTimeInfo
2104 // Purpose :
2105 // Special Notes :
2106 // Scope : public
2107 // Creator : Todd Coffey, 1414
2108 // Creation Date : 03/04/08
2109 //-----------------------------------------------------------------------------
2110 
2111 void StepErrorControl::outputTimeInfo(std::ostream &os)
2112 {
2113  {
2114  Xyce::ios_flags_saver flagsave(os);
2115 
2116  os << " " << (DEBUG_TIME ? netlistFilename_ : " ") << " "
2117  << "Current,Next,Step: "
2118  << std::setw(DEBUG_TIME ? 14 : 16) << std::setprecision(Xyce::DEBUG_TIME ? 7 : 9)
2119  << currentTime << ", " << nextTime << ", " << currentTimeStep;
2120  }
2121 
2122  os << " ("<<numberOfSteps_<<") Used, Next Order: " << usedOrder_ << ", " << currentOrder_ << std::endl;
2123 }
2124 
2125 
2126 //-----------------------------------------------------------------------------
2127 // Function : StepErrorControl::isPauseTime
2128 // Purpose : public method to flag whether the current time is a pause
2129 // time
2130 // Special Notes : Need this method because the prior values get in the way
2131 // when we resume.
2132 // Scope : public
2133 // Creator : Tom Russo, SNL, Component Information and Models
2134 // Creation Date : 04/30/04
2135 //-----------------------------------------------------------------------------
2137 {
2138  // Check whether pauseTime == currentTime (to within bpTol).
2139  // If the pause time is equal to the final time, we are at the end, not
2140  // at a pause time.
2141  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
2142  {
2143  Xyce::dout() << "StepErrorControl::isPauseTime\n";
2144  Xyce::dout() << "currentPauseBP.value = " << currentPauseBP->value () << std::endl;
2145  Xyce::dout() << "final Time = " << finalTime << std::endl;
2146  Xyce::dout() << "current Time = " << currentTime << std::endl;
2147  }
2148 
2151 }
2152 
2153 //-----------------------------------------------------------------------------
2154 // Function : operator<<
2155 // Purpose : "<<" operator for step error control class.
2156 // Special Notes :
2157 // Scope : public
2158 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
2159 // Creation Date : 10/17/05
2160 //-----------------------------------------------------------------------------
2161 std::ostream & operator<<(std::ostream & os, const StepErrorControl & sec)
2162 {
2163  os << "\n\n-----------------------------------------" << std::endl
2164  << "\tStepErrorControl:\n"
2165  << "\t\tstartingTimeStep = " << sec.startingTimeStep << std::endl
2166  << "\t\tcurrentTimeStep = " << sec.currentTimeStep << std::endl
2167  << "\t\tlastAttemptedTimeStep = " << sec.lastAttemptedTimeStep << std::endl
2168  << "\t\tlastTimeStep = " << sec.lastTimeStep << std::endl
2169  << "\t\tminTimeStep = " << sec.minTimeStep << std::endl
2170  << "\t\tmaxTimeStep = " << sec.maxTimeStep << std::endl
2171  << "\t\tmaxTimeStepUser = " << sec.maxTimeStepUser << std::endl
2172  << "\t\tlastTime = " << sec.lastTime << std::endl
2173  << "\t\tcurrentTime = " << sec.currentTime << std::endl
2174  << "\t\tnextTime = " << sec.nextTime << std::endl
2175  << "\t\tstopTime = " << sec.stopTime << std::endl
2176  << "\t\tinitialTime = " << sec.initialTime << std::endl
2177  << "\t\tfinalTime = " << sec.finalTime << std::endl
2178  << std::endl
2179  << "\t\tBreak Points:" << std::endl;
2180 
2181  sec.printBreakPoints (os);
2182 
2183 
2184  os << Xyce::section_divider << std::endl
2185  << std::endl;
2186 
2187  return os;
2188 }
2189 
2190 } // namespace TimeIntg
2191 } // namespace Xyce
bool initializeBreakPoints(double start_time, double initial_time, double final_time)
double initialTimeStep
User specified initial time step.
bool dumpRestartData(char *buf, int bsize, int &pos, N_PDS_Comm *comm, bool pack)
void evaluateStepError(const Loader::Loader &loader, const TIAParams &tia_params)
Pure virtual class to augment a linear system.
int nIterations
Number of newton iterations.
int errorAnalysisOption
Error analysis option.
double finalTime
End time for simulation.
void updatePauseTime(Util::BreakPoint breakpoint, double initial_time)
bool resetAll(const TIAParams &tia_params)
bool setFromTIAParams(const TIAParams &tia_params)
double maxTimeStep
User specified maximum time step.
double minTimeStep
User specified minimum time step.
bool constantTimeStepFlag
Constant time step integration flag.
WorkingIntegrationMethod & wimPtr_
Analysis manager.
std::vector< TwoLevelError > innerErrorInfoVec
std::set< Util::BreakPoint, Util::BreakPointLess > BreakPointSet
void updateStopTime(Parallel::Machine comm, bool breakpoints_enabled, double initial_time, bool min_time_steps_breakpoint_given, double min_time_steps_breakpoint)
double findNextStopTimeDeprecated(Parallel::Machine comm, bool breakpoints_enabled)
bool restoreRestartData(char *buf, int bsize, int &pos, N_PDS_Comm *comm, bool pack, double &initial_time)
virtual double getMaxTimeStepSize()
Definition: N_LOA_Loader.h:279
StepErrorControl(const std::string &netlist_filename, Analysis::AnalysisManager &analysis_manager, WorkingIntegrationMethod &working_integration_method, const TIAParams &tia_params)
void updateTwoLevelTimeInfo(Parallel::Machine comm, double nextTimeStep, double nextTime, int currentOrder, bool breakpoints_enabled, double initial_time, bool min_time_steps_breakpoint_given, double min_time_steps_breakpoint)
std::ostream & operator<<(std::ostream &os, const StepErrorControl &sec)
double restartTimeStepScale
Time step is scaled coming out of a breakpoint (StepErrorControl)
void setBreakPoint(const Util::BreakPoint &breakpoint, double initial_time)
void simulationPaused(double initial_time)
Analysis::AnalysisManager & analysisManager_
double pauseTime
Time step value at which to "pause" the simulation.
AnalysisManager & analysisManager_
Definition: N_ANP_AC.C:960
double initialOutputTime
Time at which output starts (StepErrorControl)
bool pauseSetAtZero
Flag used to indicate that a pause was specifically set at time zero and thus should not be ignored...
double initialTime
Beginning time for the time integrator (StepErrorControl, integrators access from StepErrorControl) ...
void printBreakPoints(std::ostream &os) const
void integrationStepReport(std::ostream &os, bool step_attempt_status, bool sAStatus, bool testedError, const TIAParams &tia_params)
TimeIntg::DataStore * getDataStore()
bool useDeviceTimeStepMaxFlag
True if devices impose a time step maximum.
const std::string netlistFilename_
Working integration method.
bool updateMaxTimeStep(Parallel::Machine comm, Loader::Loader &loader, const TIAParams &tia_params, double suggestedMaxTimeStep=0.0)
void terseIntegrationStepReport(std::ostream &os, bool step_attempt_status, bool sAStatus, bool testedError, const TIAParams &tia_params)
virtual bool getInnerLoopErrorSums(std::vector< TimeIntg::TwoLevelError > &tleVec) const
Definition: N_LOA_Loader.h:300
bool getBlockAnalysisFlag() const
Return true if primary analysis is HB or MPDE.
bool updateBreakPoints(const Loader::Loader &loader, double initial_time)
virtual bool getBreakPoints(std::vector< Util::BreakPoint > &breakPointTimes) const
Definition: N_LOA_Loader.h:273