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