Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-----------------------------------------------------------------------------
26 // Filename : $RCSfile: N_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.235 $
41 //
42 // Revision Date : $Date: 2014/08/06 22:26:43 $
43 //
44 // Current Owner : $Author: dgbaur $
45 //-----------------------------------------------------------------------------
46 
47 #include <Xyce_config.h>
48 
49 #include <iostream>
50 #include <sstream>
51 
52 #ifdef HAVE_CSTDIO
53 #include <cstdio>
54 #else
55 #include <stdio.h>
56 #endif
57 
58 #include <N_TIA_StepErrorControl.h>
59 
60 #include <N_ANP_AnalysisManager.h>
61 #include <N_ERH_ErrorMgr.h>
62 #include <N_IO_CmdParse.h>
63 #include <N_LOA_Loader.h>
64 #include <N_PDS_Comm.h>
65 #include <N_PDS_Manager.h>
66 #include <N_TIA_DataStore.h>
67 #include <N_TIA_TIAParams.h>
68 #include <N_TIA_TimeIntInfo.h>
70 #include <N_UTL_BreakPoint.h>
71 #include <N_UTL_Functors.h>
72 #include <N_UTL_SaveIOSState.h>
73 #include <N_UTL_Xyce.h>
74 
75 
76 //-----------------------------------------------------------------------------
77 // Function : N_TIA_StepErrorControl::N_TIA_StepErrorControl
78 // Purpose : Non-argument constructor.
79 // Special Notes :
80 // Scope : public
81 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
82 // Creation Date : 9/06/01
83 //-----------------------------------------------------------------------------
85  N_IO_CmdParse & cp,
86  N_ANP_AnalysisManager & anaManager,
87  N_TIA_TIAParams & tiaP)
88  :
89  startingTimeStep(1.0e-10),
90  currentTimeStep(1.0e-10),
91  lastAttemptedTimeStep(1.0e-10),
92  lastTimeStep(1.0e-10),
93  minTimeStep(0.0),
94  maxTimeStep(0.0),
95  maxTimeStepUser(1.0e+99),
96  maxTimeStepBP(0.0),
97  savedTimeStep(1.0e-10),
98  lastTime(0.0),
99  currentTime(0.0),
100  nextTime(0.0),
101  stopTime(0.0),
102  initialTime(0.0),
103  finalTime(0.0),
104  currentTimeStepRatio(0.0),
105  currentTimeStepSum(0.0),
106  lastTimeStepRatio(0.0),
107  lastTimeStepSum(0.0),
108  newtonConvergenceStatus(-1),
109  nIterations(0),
110  numberSuccessiveFailures(0),
111  stepAttemptStatus(true),
112  previousCallStepSuccessful(false),
113  estOverTol_(0.0),
114  initializeFlag_(false),
115  minStepPrecisionFac_(10.0),
116  newtonStepReduction_(0.25),
117  restartTimeStepScale_(0.005),
118  tolAimFac_(0.5),
119  tiaParams_(tiaP),
120  anaManager_(anaManager),
121  wimPtr_(NULL),
122  commandLine_(cp),
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 {
178  // make sure we initialize the iterator currentPauseBP to a valid but
179  // bad value until it is calulcated
181 
182  setTIAParams();
183  setBreakPoint(N_UTL_BreakPoint(tiaParams_.finalTime, Xyce::Util::PAUSE_BREAKPOINT));
184 
186 }
187 
188 //-----------------------------------------------------------------------------
189 // Function : N_TIA_StepErrorControl::~N_TIA_StepErrorControl
190 // Purpose : destructor
191 // Special Notes :
192 // Scope : public
193 // Creator : Buddy Watts, SNL
194 // Creation Date : 6/01/00
195 //-----------------------------------------------------------------------------
196 
198 {
199  return ;
200 }
201 
202 //-----------------------------------------------------------------------------
203 // Function : N_TIA_StepErrorControl::setTIAParams
204 // Purpose : This function copies stuff out of the tiaParams object into
205 // variables that are local to the step error control class.
206 // Special Notes :
207 // Scope : public
208 // Creator : Eric R. Keiter, SNL, Computational Sciences
209 // Creation Date : 09/06/01
210 //-----------------------------------------------------------------------------
212 {
220 
222  {
225  }
226  else
227  {
229  }
230 
231  initializeFlag_ = true;
232 
234 
235  // if initial time steps are baloney, set then to a default value.
236  if (startingTimeStep <= 0.0) startingTimeStep = 1.0e-10;
237  if (currentTimeStep <= 0.0) currentTimeStep = 1.0e-10;
238 
240 
241  // 12/15/06 tscoffe: The MPDE Manger calls resetAll and then setTIAParams.
242  // resetAll correctly sets up the currentPauseBP iterator, but setTIAParams
243  // did not. This little block of code should fix that.
244  if( anaManager_.getBlockAnalysisFlag() == true )
245  {
246  std::set<N_UTL_BreakPoint>::iterator lastBP = breakPoints_.end();
247  lastBP--;
248  updatePauseTime(*lastBP);
249  }
250 
252 
253  return true;
254 }
255 
256 
257 //-----------------------------------------------------------------------------
258 // Function : N_TIA_StepErrorControl::getEstOverTol
259 // Purpose : This function lets the controlling class (a transient
260 // analysis) get the estimated error over tol from the
261 // last step
262 // Special Notes :
263 // Scope : public
264 // Creator : Richard Schiek, Electrical and MEMS Modeling
265 // Creation Date : 01/23/09
266 //-----------------------------------------------------------------------------
268 {
269  return estOverTol_;
270 }
271 
272 
273 
274 //-----------------------------------------------------------------------------
275 // Function : N_TIA_StepErrorControl::getTranOPFlag
276 // Purpose : Get flag from analysis manager for DC op part of a
277 // transient run.
278 // Special Notes :
279 // Scope : public
280 // Creator : Richard Schiek, Electrical and MEMS Modeling
281 // Creation Date : 01/23/09
282 //-----------------------------------------------------------------------------
284 {
285  return anaManager_.getTranOPFlag();
286 }
287 
288 //-----------------------------------------------------------------------------
289 // Function : N_TIA_StepErrorControl::setTimeStep
290 // Purpose :
291 // Special Notes :
292 // Scope : public
293 // Creator : Eric Keiter, SNL
294 // Creation Date : 08/09/09
295 //-----------------------------------------------------------------------------
296 void N_TIA_StepErrorControl::setTimeStep(double newTimeStep)
297 {
298  newTimeStep = Xycemax(newTimeStep, minTimeStep);
299  newTimeStep = Xycemin(newTimeStep, maxTimeStep);
300 
301  double nextTimePt = currentTime + newTimeStep;
302 
303  if (nextTimePt > stopTime)
304  {
305  nextTimePt = stopTime;
306  newTimeStep = stopTime - currentTime;
308  }
309 
310  nextTime = nextTimePt;
311 
312  currentTimeStepRatio = newTimeStep/lastTimeStep;
313  currentTimeStepSum = newTimeStep + lastTimeStep;
314 
315  currentTimeStep = newTimeStep;
316 }
317 
318 //-----------------------------------------------------------------------------
319 // Function : N_TIA_StepErrorControl::resetAll
320 //
321 // Purpose : This function resets everything so that a transient loop
322 // can be started from the beginning.
323 //
324 // Special Notes : This function was needed for the .STEP capability.
325 //
326 // Scope : public
327 // Creator : Eric R. Keiter, SNL, Computational Sciences
328 // Creation Date : 11/04/03
329 //-----------------------------------------------------------------------------
331 {
332  // reset a bunch of variables.
333  tiaParams_.pauseSetAtZero = false;
334  tiaParams_.pauseTime = 0.0;
335 
340 
343 
347 
348  currentTimeStepRatio = 1.0;
350 
354 
357  stepAttemptStatus = true;
358 
359  minTimeStep = 0.0;
360  estOverTol_ = 0.0;
361 
363  {
366  }
367  else
368  {
370  }
371 
373 
374  // if initial time steps are baloney, set then to a default value.
375  if (startingTimeStep <= 0.0) startingTimeStep = 1.0e-10;
376  if (currentTimeStep <= 0.0) currentTimeStep = 1.0e-10;
377 
378 #ifdef Xyce_DEBUG_TIME
379  if (tiaParams_.debugLevel > 0)
380  {
381  Xyce::dout() << std::endl;
382  Xyce::dout() << Xyce::section_divider << std::endl;
383  Xyce::dout() <<
384  " N_TIA_StepErrorControl::resetAll" << std::endl;
385  Xyce::dout() <<
386  " before initializeBreakPoints " << std::endl;
387  printBreakPoints(Xyce::dout());
388  Xyce::dout() <<" currentPauseBP = " << currentPauseBP->value() << std::endl;
389 
390  }
391 #endif // Xyce_DEBUG_TIME
392 
394 
395 #ifdef Xyce_DEBUG_TIME
396  if (tiaParams_.debugLevel > 0)
397  {
398  Xyce::dout() <<
399  " after initializeBreakPoints " << std::endl;
400  printBreakPoints(Xyce::dout());
401  Xyce::dout() << " currentPauseBP = " << currentPauseBP->value() << std::endl;
402  }
403 #endif // Xyce_DEBUG_TIME
404 
405  // ERK: Note: always do this, not just for block solves?
406  //if( anaManager_.getBlockAnalysisFlag() == true ) // if MPDE or HB
407  //{
408  std::set<N_UTL_BreakPoint>::iterator lastBP = breakPoints_.end();
409  lastBP--;
410  updatePauseTime(*lastBP);
411  //}
412 
413  // need to set a pause breakpoint at the final time.
414  setBreakPoint(N_UTL_BreakPoint(tiaParams_.finalTime ,Xyce::Util::PAUSE_BREAKPOINT));
415 
416 #ifdef Xyce_DEBUG_TIME
417  if (tiaParams_.debugLevel > 0)
418  {
419  Xyce::dout() <<
420  " after updatePauseTime & setBreakPoint" << std::endl;
421  printBreakPoints(Xyce::dout());
422  Xyce::dout() <<" currentPauseBP = " << currentPauseBP->value() << std::endl;
423  Xyce::dout() << Xyce::section_divider << std::endl;
424  }
425 #endif // Xyce_DEBUG_TIME
426 
427  return true;
428 }
429 
430 //-----------------------------------------------------------------------------
431 // Function : N_TIA_StepErrorControl::initializeStepSizeVariables
432 // Purpose : Remainder of initialization for the StepSize Process.
433 // This should be called every time an integration start-up is
434 // needed -- such as at the beginning of integration and after
435 // a point of discontinuity is encountered, but not upon
436 // continuation from a saved solution state (i.e. a restart
437 // file).
438 // Special Notes :
439 // Scope : public
440 // Creator : Buddy Watts, SNL
441 // Creation Date : 6/01/00
442 //-----------------------------------------------------------------------------
444 {
445  double time_to_stop = stopTime - currentTime;
446 
447 #ifdef Xyce_VERBOSE_TIME
448  const std::string crMsg = "\n";
449  const std::string startMsg = ("* Initial Time Value:\t");
450  const std::string stopMsg = (" * Ending Time Value:\t");
451  const std::string secondsMsg = (" secs");
452  const std::string timeToStopMsg = (" * Time to Stop Value:\t");
453 
454  Xyce::dout() << crMsg + startMsg << currentTime << secondsMsg << std::endl
455  << stopMsg << stopTime << secondsMsg << std::endl
456  << timeToStopMsg << time_to_stop << secondsMsg << std::endl;
457 
458 #endif
459 
460  // At some point, we might want to consider computing an on-scale starting
461  // step-size based on local behavior of problem solution
462 
464  {
465  currentTimeStep = 0.1 * time_to_stop;
466  }
467  else
468  {
469  // The original of this was just:
470  currentTimeStep = restartTimeStepScale_ * time_to_stop;
471 
472  // This can cause problems in the cases of very steep pulsed sources,
473  // e.g. those with nanosecond scale rise and fall times. Then we get
474  // order picosecond timesteps after breakpoints, and this is often too
475  // bloody small.
476  // I (TVR) tried this but it is not smart enough to cover all cases.
477  // currentTimeStep = Xycemax(0.005*time_to_stop,5e-11);
478  }
479 
480  if (currentTime == initialTime || tiaParams_.constantStepSize)
481  {
483  }
484  else
485  {
487  }
488 
489 #ifdef Xyce_VERBOSE_TIME
490  const std::string stepMsg = (" * Initial Step Size: \t");
491 
492  Xyce::dout() << stepMsg <<
493  currentTimeStep << secondsMsg + crMsg << std::endl;
494 #endif // Xyce_VERBOSE_TIME
495 
496  currentTimeStepRatio = 1.0;
498 
502 
504  stepAttemptStatus = true;
505 
506  nextTime = currentTime + currentTimeStep;
507 
508  return;
509 }
510 
511 //-----------------------------------------------------------------------------
512 // Function : N_TIA_StepErrorControl::updateStopTime
513 // Purpose : The "stop time" is either the next discontinuity point,
514 // a pause point, or the final time, whichever comes first.
515 // Special Notes :
516 // Scope : public
517 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
518 // Creation Date : 6/27/00
519 //-----------------------------------------------------------------------------
521 {
522 
523 //#ifdef Xyce_MPDE
524  // 10/04/05 tscoffe: In MPDE mode, we need to set the final time, but
525  // StepErrorControl only reads finalTime from TIAParams at construction. So
526  // here, we're forcing it to reload it if its in MPDE mode.
527 // finalTime = tiaParams_.finalTime;
528 //#endif // Xyce_MPDE
529 
530  double oldStopTime = stopTime;
531  double diffStopTime(0.0);
532 
533  if (tiaParams_.bpEnable)
534  {
535  std::set<N_UTL_BreakPoint>::iterator itBP;
536  std::set<N_UTL_BreakPoint>::iterator firstBP = breakPoints_.begin();
537  std::set<N_UTL_BreakPoint>::iterator lastBP = breakPoints_.end();
538 
539  // Find the first breakpoint equal to or larger than the
540  // current time.
541 
542  itBP = upper_bound(firstBP,lastBP,N_UTL_BreakPoint(currentTime));
543 
544  stopTime = Xycemin(finalTime, itBP->value());
545 
546  // The breakpoint could be a pause breakpoint, in which case we might
547  // need to update the pauseTime:
548  if (itBP->bptype() == Xyce::Util::PAUSE_BREAKPOINT)
549  {
550  updatePauseTime(*itBP);
551  }
553 
554  // if this is a breakpoint step, make sure the new stop
555  // time is for the next breakpoint, not the current one.
556  // This check is neccessary because of roundoff error.
557 
558  diffStopTime = fabs(stopTime-oldStopTime);
559  if(diffStopTime < anaManager_.getBreakpointTol() &&
562  stopTime != finalTime )
563  {
564  ++itBP;
565  stopTime = itBP->value();
566  }
567 
568 #ifdef Xyce_PARALLEL_MPI
569  double sT = stopTime;
570  double mST;
571 
572  N_PDS_Comm &comm = anaManager_.getPDSComm();
573  // NOTE: This needs to be a minAll !
574  comm.minAll ( &sT, &mST, 1);
575  stopTime = mST;
576 #endif // Xyce_PARALLEL_MPI
577 
578  }
579  else
580  {
582  }
583 
585  {
586  double time_to_stop = stopTime - currentTime;
588  {
589  maxTimeStepBP = time_to_stop/tiaParams_.minTimeStepsBP;
590  }
591  }
592 
593 
594 #ifdef Xyce_DEBUG_TIME
595  if (tiaParams_.debugLevel >0)
596  {
597  Xyce::dout() << std::endl
598  << " stopTime = " << stopTime << std::endl
599  << " pauseTime = " << tiaParams_.pauseTime << std::endl
600  << " currentTime = " << currentTime << std::endl
601  << " oldStopTime = " << oldStopTime << std::endl
602  << " finalTime = " << finalTime << std::endl
603  << " maxTimeStepBP = " << maxTimeStepBP << std::endl
604  << " beginningIntegration = " << anaManager_.getBeginningIntegrationFlag() << std::endl
605  << Xyce::section_divider << std::endl;
606  }
607 #endif // Xyce_DEBUG_TIME
608 
609 }
610 
611 //-----------------------------------------------------------------------------
612 // Function : N_TIA_StepErrorControl::findNextStopTime
613 // Purpose : Determine the next stop time, that comes immediately after
614 // the current one.
615 //
616 // Special Notes : Used by mixed-signal rollback.
617 //
618 // Scope : public
619 // Creator : Eric Keiter, SNL
620 // Creation Date : 4/9/09
621 //-----------------------------------------------------------------------------
623 {
624  double nextStop=stopTime;
625 
626  if (tiaParams_.bpEnable)
627  {
628  std::set<N_UTL_BreakPoint>::iterator itBP;
629  std::set<N_UTL_BreakPoint>::iterator firstBP = breakPoints_.begin();
630  std::set<N_UTL_BreakPoint>::iterator lastBP = breakPoints_.end();
631 
632  // Find the first breakpoint equal to or larger than the
633  // current time.
634 
635  itBP = upper_bound(firstBP,lastBP,N_UTL_BreakPoint(currentTime));
636  itBP++; // go to the next one.
637 
638  nextTime = Xycemin(finalTime, itBP->value());
640 
641 #ifdef Xyce_PARALLEL_MPI
642  double nT = nextTime;
643  double mNT;
644 
645  N_PDS_Comm &comm = anaManager_.getPDSComm();
646  // NOTE: This needs to be a minAll !
647  comm.minAll ( &nT, &mNT, 1);
648  nextTime = mNT;
649 #endif // Xyce_PARALLEL_MPI
650 
651  }
652  else
653  {
655  }
656 
657  return nextStop;
658 }
659 
660 //-----------------------------------------------------------------------------
661 // Function : N_TIA_StepErrorControl::evaluateStepError
662 // Purpose :
663 // Special Notes :
664 // Scope : public
665 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
666 // Creation Date : 1/28/07
667 //-----------------------------------------------------------------------------
669 {
670  bool step_attempt_status( newtonConvergenceStatus >= 0);
671  bool sAStatus(false);
672  bool errorOptionStatus(true);
673  bool testTimeIntegrationError(false);
674 
675  // If we are running with constant step size, or are on the first pass
676  // through the transient loop, only base success on the Newton loop.
677 
678 // if (anaManager_.getIntegrationMethod() == 7 && tiaParams_.newLte == true)
679  if (tiaParams_.newBPStepping == true)
680  {
682  {
683  testTimeIntegrationError = (anaManager_.getStepNumber() >= 1 && !(anaManager_.getBeginningIntegrationFlag()));
684  }
685  else
686  {
687  testTimeIntegrationError = (anaManager_.getStepNumber() >= 1);
688  }
689  }
690  else
691  {
692  testTimeIntegrationError = (anaManager_.getStepNumber() >= 1 && !(anaManager_.getBeginningIntegrationFlag()));
693  }
694 
696  {
697  testTimeIntegrationError = true;
698  }
699 
700  // if the step status is already false, don't do any more work.
701  if (!step_attempt_status)
702  {
703  testTimeIntegrationError = false;
704  }
705 
706 
707  if (testTimeIntegrationError)
708  {
709  // Needed for 2-level Solves:
711 
713 
715  {
716  sAStatus = true;
717  }
718  else
719  {
720  sAStatus = false;
721  }
722 
723  if (tiaParams_.timestepsReversal == true)
724  {
726  errorOptionStatus = true;
727  else
728  errorOptionStatus = false;
729  }
730 #ifdef Xyce_VERBOSE_TIME
732  {
733  Xyce::dout() << "ERROROPTION=1: DOREJECTSTEP = ";
734  if (tiaParams_.timestepsReversal == true)
735  {
736  Xyce::dout() << "1" << std::endl;
737  }
738  else
739  {
740  Xyce::dout() << "0" << std::endl;
741  }
742  }
743 #endif // Xyce_VERBOSE_TIME
744 
746  {
747  // This step has dropped under the user specified min time step, so only
748  // test if the sovler converged to accept the step.
749  // don't do the step_attempt_status && sAStatus;
750 #ifdef Xyce_DEBUG_TIME
751  if (tiaParams_.debugLevel > 2)
752  {
753  Xyce::dout() << "Trying to skip time integrator error checks: " << currentTimeStep
754  << " newton status " << step_attempt_status << std::endl;
755  }
756 #endif
757  }
758 // else if (!(tiaParams_.constantStepSize) && ((tiaParams_.errorAnalysisOption == 0)) )
759 // {
760 // step_attempt_status = step_attempt_status && sAStatus;
761 // }
762  else if (!(tiaParams_.constantStepSize))
763  {
765  step_attempt_status = step_attempt_status && errorOptionStatus;
766  else
767  step_attempt_status = step_attempt_status && sAStatus;
768  }
769  }
770 
771 
772 #ifdef Xyce_VERBOSE_TIME
773 #ifdef Xyce_DEBUG_TIME
774  if (tiaParams_.debugLevel > 0)
775  {
776  integrationStepReport_(Xyce::dout(), step_attempt_status, sAStatus, testTimeIntegrationError);
777  }
778  else
779 #endif
780  {
781  terseIntegrationStepReport_(Xyce::lout(), step_attempt_status, sAStatus, testTimeIntegrationError);
782  }
783 #endif
784 
785  // Now that the status has been completely determined,
786  // set the class variable for step attempt
787  stepAttemptStatus = step_attempt_status;
788 }
789 
790 //-----------------------------------------------------------------------------
791 // Function : N_TIA_StepErrorControl::terseIntegrationStepReport_
792 // Purpose : This gives a one-line description of the step accept/reject.
793 // Special Notes :
794 // Scope : public
795 // Creator : Eric Keiter, SNL
796 // Creation Date : 01/27/07
797 //-----------------------------------------------------------------------------
798 void N_TIA_StepErrorControl::terseIntegrationStepReport_(std::ostream &os, bool step_attempt_status, bool sAStatus, bool testedError)
799 {
800  os << (Xyce::DEBUG_TIME ? commandLine_.getArgumentValue("netlist") : "")
801  << " STEP STATUS: " << (step_attempt_status ? " success" : " fail")
802  << " Newton: " << newtonConvergenceStatus
803  << " estOverTol: " << estOverTol_ << (testedError && !(tiaParams_.constantStepSize) ? "" : " (not used for this step)") << std::endl;
804 }
805 
806 //-----------------------------------------------------------------------------
807 // Function : N_TIA_StepErrorControl::integrationStepReport_
808 // Purpose :
809 // Special Notes :
810 // Scope : public
811 // Creator : Eric Keiter, SNL
812 // Creation Date : 03/12/06
813 //-----------------------------------------------------------------------------
814 void N_TIA_StepErrorControl::integrationStepReport_(std::ostream &os, bool step_attempt_status, bool sAStatus, bool testedError)
815 {
816  if (tiaParams_.debugLevel > 0)
817  {
818  os << "\n estOverTol = " << estOverTol_ << std::endl
819  << " error tolerance = " << tiaParams_.errTolAcceptance << std::endl
820  << std::endl
821  << "\nSTEP ATTEMPT STATUS:" << std::endl
822  << "NOTE:" << std::endl;
823 
824  if (!(tiaParams_.constantStepSize) &&
825  anaManager_.getStepNumber() >= 1 &&
827  {
828  os << " We are running in variable stepsize mode " << std::endl
829  << " and we have NOT just passed a breakpoint. As such " << std::endl
830  << " for an integration step to succeed the " << std::endl
831  << " nonlinear solver must succeed AND the predictor" << std::endl
832  << " and corrector need to be close within a tolerance." << std::endl;
833 
835  {
836  os << "ADDENDUM: This is with erroption=1 so predictor-corrector is ignored for step error control." << std::endl;
837  }
838  }
839  else
840  {
841  os << " We are either running constant stepsize " << std::endl
842  << " or we just passed a breakpoint. As such " << std::endl
843  << " the only criteria we use in accepting/rejecting" << std::endl
844  << " an integration step is the nonlinear solver" << std::endl
845  << " success/failure." << std::endl;
846  }
847 
848  if (step_attempt_status)
849  {
850  os << "\n This has been a successful step:" << std::endl;
851  }
852  else
853  {
854  os << "\n This has NOT been a successful step:" << std::endl;
855  }
856 
857  if ( newtonConvergenceStatus > 0)
858  {
859  os << " - Newton solver succeded with return code " << newtonConvergenceStatus << std::endl << std::endl;
860  }
861  else
862  {
863  os << " - Newton solver failed with return code " << newtonConvergenceStatus << std::endl;
864  }
865 
866  if (testedError)
867  {
869  {
870  if (sAStatus)
871  {
872  os << " - predictor vs. corrector analysis succeeded." << std::endl;
873  }
874  else
875  {
876  os << " - predictor vs. corrector analysis failed." << std::endl;
877  }
878 
879  os << " (compare estOverTol with error tolerance above.)" << std::endl;
880  }
881  else
882  {
883  os << "If we had been using it << " << std::endl;
884 
885  if (sAStatus)
886  {
887  os << " - predictor vs. corrector analysis would have succeeded." << std::endl;
888  }
889  else
890  {
891  os << " - predictor vs. corrector analysis would have failed." << std::endl;
892  }
893 
894  os << " (compare estOverTol with error tolerance above.)" << std::endl;
895  }
896  }
897  else
898  {
899  os << " predictor vs. corrector was not tested" << std::endl;
900  }
901 
902  os << Xyce::section_divider << std::endl;
903  } // end of debugLevel if statement
904 }
905 
906 //-----------------------------------------------------------------------------
907 // Function : N_TIA_StepErrorControl::initializeBreakPoints
908 // Purpose :
909 // Special Notes :
910 // Scope : public
911 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
912 // Creation Date : 06/11/01
913 //-----------------------------------------------------------------------------
915 {
916  bool bsuccess = true;
917 
918  breakPoints_.clear ();
919  // if currentPauseBP was set, it is now invalid so set it to a safe but
920  // invalid value until it is calulcated
922 
923  // first breakpoint is the start time, last one is the final time.
925 
926  // if tStart is nonzero, then make it a breakpoint.
927  if (tiaParams_.tStart > initialTime &&
929  {
931  }
932 
933  // The final time needs to be the very last breakpoint.
934  //setBreakPoint(finalTime);
935  setBreakPoint(N_UTL_BreakPoint(tiaParams_.finalTime ,Xyce::Util::PAUSE_BREAKPOINT));
936 
937  // Now add in the user break points. NOT DONE YET.
938  //vector<double> ;
939  //tiaParams_.userSpecBreakPoints;
940 
941 
942  // other breakpoints will later be added/removed dynamically over the
943  // course of the transient simulation in calls to the loader.
944 
945  return bsuccess;
946 }
947 
948 //-----------------------------------------------------------------------------
949 // Function : N_TIA_StepErrorControl::updateBreakPoints
950 // Purpose : Requests dynamic breakpoint information from the
951 // loader. Adds, subtracts from the breakpoints array.
952 // Special Notes :
953 // Scope : public
954 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
955 // Creation Date : 06/11/01
956 //-----------------------------------------------------------------------------
958 {
959  bool bsuccess = true;
960 
961 #ifdef Xyce_DEBUG_TIME
962  if (tiaParams_.debugLevel >0)
963  {
964  Xyce::dout() << std::endl
965  << Xyce::section_divider << std::endl
966  << " N_TIA_StepErrorControl::updateBreakPoints. time = " << currentTime << std::endl
967  << std::endl;
968  }
969 #endif
970 
971  std::vector<N_UTL_BreakPoint> tmpBP;
972  tmpBP.clear ();
973 
974  anaManager_.getLoader().getBreakPoints(tmpBP);
975 
976  // debug outputs:
977  std::vector<N_UTL_BreakPoint>::iterator iter;
978  std::vector<N_UTL_BreakPoint>::iterator first = tmpBP.begin();
979  std::vector<N_UTL_BreakPoint>::iterator last = tmpBP.end();
980 
981  // add any new breakpoints to the vector of breakpoints:
982  std::set<N_UTL_BreakPoint>::iterator itBP;
983  std::set<N_UTL_BreakPoint>::iterator itBP_2;
984  std::set<N_UTL_BreakPoint>::iterator firstBP = breakPoints_.begin();
985  std::set<N_UTL_BreakPoint>::iterator lastBP = breakPoints_.end();
986 
987  // Add new breakpoints to the set:
988  for (iter=first; iter!=last; ++iter)
989  {
990  if (iter->value() < finalTime && iter->value() > lastTime)
991  {
992  setBreakPoint(*iter);
993  }
994  }
995 
996 #ifdef Xyce_DEBUG_TIME
997  char tmp[128];
998  int i;
999  if (tiaParams_.debugLevel >0)
1000  {
1001  firstBP = breakPoints_.begin();
1002 
1003  std::string netListFile = commandLine_.getArgumentValue("netlist");
1004  std::string msg = netListFile + " breakPoints_ vector container, before any removals:";
1005 
1006  Xyce::dout() <<msg << std::endl;
1007 
1008  for (i=0, itBP=firstBP;itBP!=lastBP;++i,++itBP)
1009  {
1010  if (i==0)
1011  {
1012  sprintf(tmp,"%4d %16.8e",i,itBP->value());
1013  }
1014  else
1015  {
1016  sprintf(tmp,"%4d %16.8e diff=%16.8e", i, itBP->value(),(itBP->value()-itBP_2->value()));
1017  }
1018 
1019  Xyce::dout() <<tmp << std::endl;
1020  itBP_2 = itBP;
1021  }
1022  Xyce::dout() <<"" << std::endl;
1023  }
1024 #endif
1025 
1026  // Remove breakpoints which are now obsolete (old):
1027  LessThan<N_UTL_BreakPoint,double> LessFunct;
1028  itBP_2 = lower_bound(firstBP,lastBP,lastTime,LessFunct);
1029  breakPoints_.erase(firstBP,itBP_2);
1030 
1031  // Remove breakpoints which are too close together.
1032  // ERK. This is kind of ugly and can undoubtably be done
1033  // in a much more elegant way using STL. Note that
1034  // the value of "bpTol" is pulled out of my ear.
1035 
1036  // TVR: only need to do this if the BP tolerance has changed from what it
1037  // was set to in the breakpoint class --- as things were inserted, near
1038  // values were rejected if within tolerance. Only need to do this if the
1039  // tolerance has gotten looser
1040 
1041  // TVR: Cannot use the STL "unique" function to accomplish this, because
1042  // STL sets are designed to prevent changing the set elements after they're
1043  // inserted. Have to do this by removing duplicate entries explicitly.
1044 
1045  double bpTol = 2.0 * minTimeStep;
1046  if (bpTol != anaManager_.getBreakpointTol())
1047  {
1048  // set the class's tolerance to this new one
1050 #ifdef Xyce_DEBUG_TIME
1051  if (tiaParams_.debugLevel >0)
1052  {
1053  Xyce::dout() << " bpTol = " << bpTol << std::endl;
1054  Xyce::dout() << " Must now eliminate new duplicates " << std::endl;
1055  }
1056 #endif
1057 
1058  bool doneRemove = false;
1059  while (!doneRemove)
1060  {
1061  doneRemove = true;
1062  firstBP = breakPoints_.begin();
1063  lastBP = breakPoints_.end();
1064  int icount;
1065  for (icount = 0, itBP=firstBP, itBP_2=firstBP;
1066  itBP!=lastBP;
1067  ++icount, ++itBP)
1068  {
1069  double diff = (itBP->value() - itBP_2->value());
1070 
1071  if (icount != 0)
1072  {
1073  if (fabs(diff) < bpTol)
1074  {
1075  // If both are simple, just toss the later one
1076  if (itBP->bptype() == Xyce::Util::SIMPLE_BREAKPOINT &&
1077  itBP_2->bptype() == Xyce::Util::SIMPLE_BREAKPOINT)
1078  {
1079  if (diff > 0.0)
1080  breakPoints_.erase(itBP);
1081  else
1082  breakPoints_.erase(itBP_2);
1083  }
1084  else
1085  {
1086  // one of these breakpoints is not simple! Determine the
1087  // overriding type, then set a breakpoint at the earliest time
1088  // with the overriding type:
1089  Xyce::Util::BreakpointType overridingType = itBP->bptype();
1090  double minTime=Xycemin(itBP->value(),itBP_2->value());
1091 
1092  // The following line will need to be changed if any other types
1093  // besides SIMPLE_BREAKPOINT and PAUSE_BREAKPOINT are ever
1094  // introduced and any more complex precedence is defined.
1095  if (itBP_2->bptype() != Xyce::Util::SIMPLE_BREAKPOINT)
1096  {
1097  overridingType = itBP_2->bptype();
1098  }
1099  breakPoints_.erase(itBP);
1100  breakPoints_.erase(itBP_2);
1101  N_UTL_BreakPoint tmpBP(minTime,overridingType);
1102  breakPoints_.insert(tmpBP);
1103  // and just to be very careful, make sure to update the pause
1104  // time, lest the currentPauseBP iterator be confused.
1105 #ifdef Xyce_DEBUG_TIME
1106  Xyce::dout() << " Purging breakpoints, overriding with breakpoint of type " << tmpBP.bptype();
1107 #endif
1108  updatePauseTime(tmpBP);
1109  }
1110 
1111  doneRemove = false;
1112  break;
1113  }
1114  }
1115  itBP_2 = itBP;
1116  }
1117  }
1118  }
1119 
1120 #ifdef Xyce_DEBUG_TIME
1121  if (tiaParams_.debugLevel >0)
1122  {
1123  firstBP = breakPoints_.begin();
1124 
1125  Xyce::dout() <<
1126  " breakPoints_ vector container after:" << std::endl;
1127 
1128  for (i=0, itBP=firstBP;itBP!=lastBP;++i,++itBP)
1129  {
1130  if (i==0)
1131  {
1132  sprintf(tmp,"%4d %16.8e type=%d",i,itBP->value(),itBP->bptype());
1133  }
1134  else
1135  {
1136  sprintf(tmp,"%4d %16.8e type=%d diff=%16.8e", i, itBP->value(),
1137  itBP->bptype(),(itBP->value()-itBP_2->value()));
1138  }
1139 
1140  Xyce::dout() <<tmp << std::endl;
1141  itBP_2 = itBP;
1142  }
1143 
1144  Xyce::dout() <<"" << std::endl;
1145  Xyce::dout() <<Xyce::section_divider << std::endl;
1146  }
1147 #endif
1148 
1149  return bsuccess;
1150 }
1151 
1152 
1153 //-----------------------------------------------------------------------------
1154 // Function : N_TIA_StepErrorControl::updateMaxTimeStep
1155 // Purpose : Requests dynamic time step information from the loader.
1156 // Special Notes :
1157 // Scope : public
1158 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1159 // Creation Date : 08/01/01
1160 //-----------------------------------------------------------------------------
1161 bool N_TIA_StepErrorControl::updateMaxTimeStep(double suggestedMaxTimeStep)
1162 {
1163  bool bsuccess = true;
1164 
1165 #ifdef Xyce_DEBUG_TIME
1166  if (tiaParams_.debugLevel >0)
1167  {
1168  Xyce::dout() << Xyce::section_divider << std::endl;
1169  Xyce::dout() <<
1170  " N_TIA_StepErrorControl::updateMaxTimeStep" << std::endl;
1171  }
1172 #endif
1173 
1174  double maxDevStep = 1.0e+99;
1176  {
1177  maxDevStep = anaManager_.getLoader().getMaxTimeStepSize();
1178  }
1179 
1181  {
1183  }
1184  else
1185  {
1187  }
1188 
1189  // if the default arg is not zero, then a suggested max time step was
1190  // passed in. Test if it is feasible to use that at this time
1191  if( suggestedMaxTimeStep > 0.0 )
1192  {
1193  maxTimeStep = Xycemin( maxTimeStep, suggestedMaxTimeStep );
1194  }
1195 
1196  if ((maxTimeStepBP > 0.0) && (maxTimeStep > maxTimeStepBP))
1197  {
1199  }
1200 
1201  if (maxDevStep > 0.0)
1202  {
1203  maxTimeStep = Xycemin(maxTimeStep, maxDevStep);
1204  }
1205 
1207  {
1209  }
1210 
1211 #ifdef Xyce_PARALLEL_MPI
1212  double mTS = maxTimeStep;
1213  double mMTS;
1214 
1215  N_PDS_Comm &comm = anaManager_.getPDSComm();
1216 
1217  comm.minAll ( &mTS, &mMTS, 1);
1218 
1219  maxTimeStep = mMTS;
1220 #endif
1221 
1222 #ifdef Xyce_DEBUG_TIME
1223  if (tiaParams_.debugLevel >0)
1224  {
1226  {
1227  Xyce::dout() <<
1228  " User did not specify a maximum time step." << std::endl;
1229  }
1230  else
1231  {
1232  Xyce::dout() <<
1233  " User specified a maximum time step. = " << maxTimeStepUser << std::endl;
1234  }
1235 
1236  Xyce::dout() <<
1237  " maxDevStep = " << maxDevStep << std::endl;
1238  Xyce::dout() <<
1239  " maxTimeStep = " << maxTimeStep << std::endl;
1240  Xyce::dout() <<Xyce::section_divider << std::endl;
1241  }
1242 #endif
1243 
1244  if(maxTimeStep<=0.0)
1245  {
1246  const std::string msg = "Maximum Time step is invalid!\n";
1247  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1248  }
1249 
1250  return bsuccess;
1251 }
1252 
1253 //-----------------------------------------------------------------------------
1254 // Function : N_TIA_StepErrorControl::updateMinTimeStep
1255 // Purpose : Sets the minimum time step based on machine precision.
1256 // Special Notes :
1257 // Scope : public
1258 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
1259 // Creation Date : 08/02/01
1260 //-----------------------------------------------------------------------------
1262 {
1263  bool bsuccess = true;
1264 
1266  N_UTL_MachineDependentParams::MachinePrecision();
1267 
1268  return bsuccess;
1269 }
1270 
1271 //-----------------------------------------------------------------------------
1272 // Function : N_TIA_StepErrorControl::setBreakPoint
1273 // Purpose : public method to set individual breakpoint
1274 // Special Notes :
1275 // Scope : public
1276 // Creator : Tom Russo, SNL, Component Information and Models
1277 // Creation Date : 04/30/04
1278 //-----------------------------------------------------------------------------
1279 void N_TIA_StepErrorControl::setBreakPoint(const N_UTL_BreakPoint &theBP)
1280 {
1281  if (theBP.bptype() == Xyce::Util::SIMPLE_BREAKPOINT)
1282  {
1283  breakPoints_.insert(theBP);
1284  }
1285  else
1286  {
1287 #ifdef Xyce_DEBUG_TIME
1288  if (tiaParams_.debugLevel > 0)
1289  {
1290  Xyce::dout() << "In setBreakPoint, got non-simple breakpoint of type "
1291  << theBP.bptype() << " at time " << theBP.value() << std::endl;
1292  }
1293 #endif
1294  // We're a pause breakpoint, and must override any simple breakpoint
1295  // at the same time.
1296  // erase any breakpoint that is the "same" time as this one
1297  breakPoints_.erase(theBP);
1298  // and put the new one in instead
1299  breakPoints_.insert(theBP);
1300  // force code to recalculate pause time NOW.
1301  updatePauseTime(theBP);
1302  }
1303 }
1304 
1305 //-----------------------------------------------------------------------------
1306 // Function : N_TIA_StepErrorControl::setBreakPoint
1307 // Purpose : public method to set individual SIMPLE breakpoint
1308 // Special Notes :
1309 // Scope : public
1310 // Creator : Tom Russo, SNL, Component Information and Models
1311 // Creation Date : 04/30/04
1312 //-----------------------------------------------------------------------------
1314 {
1315  breakPoints_.insert(theBP);
1316 }
1317 
1318 //-----------------------------------------------------------------------------
1319 // Function : N_TIA_StepErrorControl::updatePauseTime
1320 // Purpose : private method to recalculate pause time
1321 // Special Notes :
1322 // Scope : private
1323 // Creator : Tom Russo, SNL, Component Information and Models
1324 // Creation Date : 04/30/04
1325 //-----------------------------------------------------------------------------
1327 {
1328  // gotta handle case where pauseTime is still at its initial value of
1329  // 0.0, or we already passed the last pause time!
1330  // But we mustn't reset it if it's equal to the current time, because
1331  // that means we need to stop NOW and would overwrite that.
1332  //
1333  // If a pause break point is specifically set at 0, then
1334  // we shouldn't ignore that here. So set the pauseSetAtZero flag
1335  // here if needed.
1336  //
1337  // ERK: type>0 means breakpoint is "not simple", ie PAUSE breakpoint.
1338  if ((BP.bptype() > 0) && (BP.value() == 0.0))
1339  {
1340  tiaParams_.pauseSetAtZero = true;
1341  }
1342 
1345  {
1346  tiaParams_.pauseTime = BP.value();
1347  }
1348  else
1349  {
1351  }
1352 
1353  // If we used this BP for the pause time, save the iterator to this bp in
1354  // the list so we can use it later.
1355  if (tiaParams_.pauseTime == BP.value())
1356  {
1357  currentPauseBP = breakPoints_.find(BP);
1358 #ifdef Xyce_DEBUG_TIME
1359  if (tiaParams_.debugLevel > 0)
1360  {
1361  Xyce::dout() << "\n" << commandLine_.getArgumentValue("netlist")
1362  << " UPDATING PAUSE TIME TO " << currentPauseBP->value()
1363  << " encountered breakpoint " << BP.value() << " current time is "
1364  << currentTime << std::endl;
1365  }
1366 #endif
1367  }
1368 
1369 }
1370 
1371 
1372 //-----------------------------------------------------------------------------
1373 // Function : N_TIA_StepErrorControl::simulationPaused
1374 // Purpose : public method to clear out breakpoint list and reset
1375 // pause time when pause time is reached
1376 // Special Notes : Need this method because the prior values get in the way
1377 // when we resume.
1378 // Scope : public
1379 // Creator : Tom Russo, SNL, Component Information and Models
1380 // Creation Date : 04/30/04
1381 //-----------------------------------------------------------------------------
1383 {
1384  breakPoints_.erase(currentTime); // clear current breakpoint
1385  tiaParams_.pauseTime = tiaParams_.initialTime; // unset this
1386  currentPauseBP = breakPoints_.end(); // make this invalid
1387 }
1388 
1389 //-----------------------------------------------------------------------------
1390 // Function : N_TIA_StepErrorControl::printBreakPoints
1391 // Purpose :
1392 // Special Notes :
1393 // Scope : public
1394 // Creator : Eric Keiter, SNL
1395 // Creation Date : 10/17/05
1396 //-----------------------------------------------------------------------------
1397 void N_TIA_StepErrorControl::printBreakPoints (std::ostream & os) const
1398 {
1399  std::set<N_UTL_BreakPoint>::const_iterator itBP;
1400  std::set<N_UTL_BreakPoint>::const_iterator itBP2;
1401  std::set<N_UTL_BreakPoint>::const_iterator firstBP = breakPoints_.begin();
1402  std::set<N_UTL_BreakPoint>::const_iterator lastBP = breakPoints_.end();
1403 
1404  char tmp[128];
1405 
1406  int i;
1407  for (i=0, itBP=firstBP;itBP!=lastBP;++i,++itBP)
1408  {
1409  if (i==0)
1410  sprintf(tmp,"%4d %16.8e type=%d",i,itBP->value(),itBP->bptype());
1411  else
1412  sprintf(tmp,"%4d %16.8e type=%d diff=%16.8e", i, itBP->value(),
1413  itBP->bptype(),(itBP->value()-itBP2->value()));
1414 
1415  os << std::string(tmp);
1416  itBP2 = itBP;
1417  }
1418 }
1419 
1420 //-----------------------------------------------------------------------------
1421 // Function : N_TIA_StepErrorControl::restartDataSize
1422 // Purpose :
1423 // Special Notes : This gives the *total* size: both the base
1424 // N_TIA_StepErrorControl and the derived
1425 // N_TIA_StepErrorControlDAE, summed together.
1426 //
1427 // Don't sum them 2x!
1428 //
1429 // ERK: 6/20/2010:
1430 // There are no longer 2 distinct classes. The DAE version is
1431 // now part of the original, as one single class. The two
1432 // blocks of code in this function correspond to the original
1433 // class (first block), and the DAE class (second block).
1434 //
1435 // Scope : public
1436 // Creator : Eric R. Keiter, SNL
1437 // Creation Date : 07/27/06
1438 //-----------------------------------------------------------------------------
1440 {
1441  int totalSize = 0;
1442 
1443  // original set of vars:
1444  int numdoubles = 21;
1445  int numints = 9;
1446  int count = sizeof(double) * (numdoubles);
1447  count += sizeof(int) * numints;
1448 
1449  // Must include the bp type now, not just the value
1450  count += sizeof(N_UTL_BreakPoint)*breakPoints_.size();
1451 
1452  //overestimate buffer size for unpacked data
1453  // assumes there are fewer than 100 possible breakpoints types (i.e.
1454  // because the type can be represented by two ascii characters)
1455  if( !pack )
1456  { // 34
1457  count = 24*((numdoubles+numints) + (breakPoints_.size()))
1458  + 2*(breakPoints_.size());
1459  }
1460 
1461  int baseClassSize = count;
1462 
1463  // another set of vars: (newDAE)
1464  numdoubles = 57;
1465  numints = 10;
1466 
1467  totalSize = baseClassSize;
1468  totalSize += sizeof(double) * numdoubles;
1469  totalSize += sizeof(int) * numints;
1470 
1471  //overestimate buffer size for unpacked data
1472  if ( !pack )
1473  {
1474  totalSize = baseClassSize + 24*(numdoubles+numints);
1475  }
1476 
1477  return totalSize;
1478 }
1479 //-----------------------------------------------------------------------------
1480 // Function : N_TIA_StepErrorControl::dumpRestartData
1481 // Purpose :
1482 // Special Notes : ERK: 6/20/2010:
1483 // There are no longer 2 distinct classes. The DAE version is
1484 // now part of the original, as one single class. The two
1485 // blocks of code in this function correspond to the original
1486 // class (first block), and the DAE class (second block).
1487 //
1488 // Scope : public
1489 // Creator : Eric R. Keiter, SNL
1490 // Creation Date : 7/28/06
1491 //-----------------------------------------------------------------------------
1493  (char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack )
1494 {
1495 
1496  // Set this variable up for later. Note that pos means different things
1497  // for packed vs. unpacked. For unpacked, it is the current index into
1498  // the buf array.
1499  int newPos = pos + N_TIA_StepErrorControl::restartDataSize(false);
1500 
1501  // if unpacked, initialize the buf array before calling the base class
1502  // function. At this point pos is zero, probably. The derived DAE
1503  // dataSize will be the size of the entire buf array, including the
1504  // base class size.
1505  if ( !pack )
1506  {
1507  for( int i = pos; i < (newPos); ++i) buf[i] = ' ';
1508  }
1509 
1510 #ifdef Xyce_DEBUG_RESTART
1511  std::string netListFile = commandLine_.getArgumentValue("netlist");
1512  Xyce::dout() << "TIA Restart Data DUMP! " << netListFile << "\n";
1513  Xyce::dout() << Xyce::section_divider << std::endl;
1514  Xyce::dout() << "startingTimeStep: " << startingTimeStep << std::endl;
1515  Xyce::dout() << "currentTimeStep: " << currentTimeStep << std::endl;
1516  Xyce::dout() << "lastAttemptedTimeStep: " << lastAttemptedTimeStep << std::endl;
1517  Xyce::dout() << "lastTimeStep: " << lastTimeStep << std::endl;
1518  Xyce::dout() << "minTimeStep: " << minTimeStep << std::endl;
1519  Xyce::dout() << "maxTimeStep: " << maxTimeStep << std::endl;
1520  Xyce::dout() << "maxTimeStepUser: " << maxTimeStepUser << std::endl;
1521  Xyce::dout() << "lastTime: " << lastTime << std::endl;
1522  Xyce::dout() << "currentTime: " << currentTime << std::endl;
1523  Xyce::dout() << "nextTime: " << nextTime << std::endl;
1524  Xyce::dout() << "initialTime: " << initialTime << std::endl;
1525  Xyce::dout() << "estOverTol_: " << estOverTol_ << std::endl;
1526  Xyce::dout() << "breakpts: ";
1527 
1528  for (std::set<N_UTL_BreakPoint>::iterator iterSD = breakPoints_.begin();
1529  iterSD != breakPoints_.end(); ++iterSD )
1530  Xyce::dout() << iterSD->value() << " ";
1531  Xyce::dout() << std::endl;
1532  Xyce::dout() << "integMethod: " << anaManager_.getIntegrationMethod() << std::endl;
1533  Xyce::dout() << "stepNumber: " << anaManager_.getStepNumber() << std::endl;
1534  Xyce::dout() << "transStepNumber: " << anaManager_.getTranStepNumber() << std::endl;
1535  Xyce::dout() << "breakPointRestartNumber: " << anaManager_.breakPointRestartStep << std::endl;
1536  Xyce::dout() << Xyce::section_divider << std::endl << std::endl;
1537 #endif
1538  if( pack )
1539  {
1540  comm->pack( &startingTimeStep, 1, buf, bsize, pos );
1541  comm->pack( &currentTimeStep, 1, buf, bsize, pos );
1542  comm->pack( &lastAttemptedTimeStep, 1, buf, bsize, pos );
1543  comm->pack( &lastTimeStep, 1, buf, bsize, pos );
1544  comm->pack( &minTimeStep, 1, buf, bsize, pos );
1545  comm->pack( &maxTimeStep, 1, buf, bsize, pos );
1546  comm->pack( &maxTimeStepUser, 1, buf, bsize, pos );
1547  comm->pack( &lastTime, 1, buf, bsize, pos );
1548  comm->pack( &currentTime, 1, buf, bsize, pos );
1549  comm->pack( &nextTime, 1, buf, bsize, pos );
1550  comm->pack( &initialTime, 1, buf, bsize, pos );
1551  comm->pack( &currentTimeStepRatio, 1, buf, bsize, pos );
1552  comm->pack( &currentTimeStepSum, 1, buf, bsize, pos );
1553  comm->pack( &lastTimeStepRatio, 1, buf, bsize, pos );
1554  comm->pack( &lastTimeStepSum, 1, buf, bsize, pos );
1555  comm->pack( &newtonConvergenceStatus, 1, buf, bsize, pos );
1556  comm->pack( &numberSuccessiveFailures, 1, buf, bsize, pos );
1557  int flag = stepAttemptStatus;
1558  comm->pack( &flag, 1, buf, bsize, pos );
1559  comm->pack( &minStepPrecisionFac_, 1, buf, bsize, pos );
1560  comm->pack( &newtonStepReduction_, 1, buf, bsize, pos );
1561  comm->pack( &tolAimFac_, 1, buf, bsize, pos );
1562  comm->pack( &estOverTol_, 1, buf, bsize, pos );
1563  // Subtract one, because we won't write out the pause breakpoint at the
1564  // final time
1565  int size = breakPoints_.size() -1 ;
1566  std::set<N_UTL_BreakPoint>::iterator bpStart = breakPoints_.begin();
1567  std::set<N_UTL_BreakPoint>::iterator bpEnd = breakPoints_.end();
1568  comm->pack( &size, 1, buf, bsize, pos );
1569 
1570  double val;
1571  int bptype;
1572  for( std::set<N_UTL_BreakPoint>::iterator iterSD = bpStart;
1573  iterSD != bpEnd; ++iterSD)
1574  {
1575  val=iterSD->value();
1576  bptype=iterSD->bptype();
1577  if (!(bptype == Xyce::Util::PAUSE_BREAKPOINT && val == finalTime))
1578  {
1579  comm->pack( &(val), 1, buf, bsize, pos );
1580  comm->pack( &(bptype), 1, buf, bsize, pos );
1581  }
1582  }
1583  int im = anaManager_.getIntegrationMethod();
1584  comm->pack( &im, 1, buf, bsize, pos );
1585  int sN = anaManager_.getStepNumber();
1586  comm->pack( &sN, 1, buf, bsize, pos );
1587  int tSN = anaManager_.getTranStepNumber();
1588  comm->pack( &tSN, 1, buf, bsize, pos );
1589  int bPRS = anaManager_.breakPointRestartStep;
1590  comm->pack( &bPRS, 1, buf, bsize, pos );
1591  int beginFlag = (anaManager_.getBeginningIntegrationFlag())?1:0;
1592  comm->pack( &beginFlag, 1, buf, bsize, pos );
1593  }
1594  else
1595  {
1596  // count here will be the size for the base N_TIA_StepErrorControl
1597  // class *only*.
1598  int count = N_TIA_StepErrorControl::restartDataSize( false );
1599  int startIndex = pos;
1600 
1601  // Clobber any data in buf lest we leave garbage
1602  for( int i = startIndex; i < (startIndex+count); ++i) buf[i] = ' ';
1603 
1604  std::ostringstream ost;
1605  ost.width(24);ost.precision(16);ost.setf(std::ios::scientific);
1606  ost << startingTimeStep << " ";
1607  ost << currentTimeStep << " ";
1608  ost << lastAttemptedTimeStep << " ";
1609  ost << lastTimeStep << " ";
1610  ost << minTimeStep << " ";
1611  ost << maxTimeStep << " ";
1612  ost << maxTimeStepUser << " ";
1613  ost << lastTime << " ";
1614  ost << currentTime << " ";
1615  ost << nextTime << " ";
1616  ost << initialTime << " ";
1617  ost << currentTimeStepRatio << " ";
1618  ost << currentTimeStepSum << " ";
1619  ost << lastTimeStepRatio << " ";
1620  ost << lastTimeStepSum << " ";
1621  ost << newtonConvergenceStatus << " ";
1622  ost << numberSuccessiveFailures << " ";
1623  int flag = (stepAttemptStatus)?1:0;
1624  ost << flag << " ";
1625  ost << minStepPrecisionFac_ << " ";
1626  ost << newtonStepReduction_ << " ";
1627  ost << tolAimFac_ << " ";
1628  ost << estOverTol_ << " ";
1629  // Subtract one because we won't write out the pause breakpoint at the
1630  // final time
1631  int size = breakPoints_.size() - 1;
1632  ost << size << " ";
1633 
1634  std::set<N_UTL_BreakPoint>::iterator bpStart = breakPoints_.begin();
1635  std::set<N_UTL_BreakPoint>::iterator bpEnd = breakPoints_.end();
1636  for( std::set<N_UTL_BreakPoint>::iterator iterSD = bpStart;
1637  iterSD != bpEnd; ++iterSD )
1638  {
1639  if (!(iterSD->bptype() == Xyce::Util::PAUSE_BREAKPOINT &&
1640  iterSD->value() == finalTime))
1641  {
1642  ost << iterSD->value() << " ";
1643  ost << iterSD->bptype() << " ";
1644  }
1645  }
1646  int im = anaManager_.getIntegrationMethod();
1647  ost << im << " ";
1648  int sN = anaManager_.getStepNumber();
1649  ost << sN << " ";
1650  int tSN = anaManager_.getTranStepNumber();
1651  ost << tSN << " ";
1652  int bPRS = anaManager_.breakPointRestartStep;
1653  ost << bPRS << " ";
1654  int beginFlag = (anaManager_.getBeginningIntegrationFlag())?1:0;
1655  ost << beginFlag << " ";
1656 
1657  std::string data( ost.str() );
1658  for( unsigned int i = 0; i < data.length(); ++i ) buf[startIndex+i] = data[i];
1659  // The line above copies the characters of the data string into buf,
1660  // but doesn't null-terminate buf.
1661  // it is essential to terminate the buffer with a null, or attempts
1662  // to construct a string object from it will get memory access problems.
1663  buf[startIndex+data.length()] = '\0';
1664  pos += data.length();
1665 
1666 #ifdef Xyce_DEBUG_RESTART
1667  std::string outputString(buf);
1668 
1669  Xyce::dout() << "StepErrorControl UNPACKED output buffer:" << std::endl;
1670  Xyce::dout() << outputString << std::endl;
1671 #endif
1672  }
1673 
1674 #ifdef Xyce_DEBUG_RESTART
1675  Xyce::dout() << "TIA Restart Data DUMP (DAE)! " << netListFile << "\n";
1676  Xyce::dout() << Xyce::section_divider << std::endl<<std::endl;
1677  Xyce::dout() << "alphas_ = " <<alphas_<<std::endl;
1678  Xyce::dout() << "alpha0_ = " <<alpha0_<<std::endl;
1679  Xyce::dout() << "cj_ = " <<cj_<<std::endl;
1680  Xyce::dout() << "ck_ = " <<ck_<<std::endl;
1681  Xyce::dout() << "usedStep_ = " <<usedStep_<<std::endl;
1682  Xyce::dout() << "Ek_ = " <<Ek_<<std::endl;
1683  Xyce::dout() << "Ekm1_ = " <<Ekm1_<<std::endl;
1684  Xyce::dout() << "Ekm2_ = " <<Ekm2_<<std::endl;
1685  Xyce::dout() << "Ekp1_ = " <<Ekp1_<<std::endl;
1686  Xyce::dout() << "Est_ = " <<Est_<<std::endl;
1687  Xyce::dout() << "Tk_ = " <<Tk_<<std::endl;
1688  Xyce::dout() << "Tkm1_ = " <<Tkm1_<<std::endl;
1689  Xyce::dout() << "Tkm2_ = " <<Tkm2_<<std::endl;
1690  Xyce::dout() << "Tkp1_ = " <<Tkp1_<<std::endl;
1691  Xyce::dout() << "h0_safety_ = " <<h0_safety_<<std::endl;
1692  Xyce::dout() << "h0_max_factor_ = " <<h0_max_factor_<<std::endl;
1693  Xyce::dout() << "h_phase0_incr_ = " <<h_phase0_incr_<<std::endl;
1694  Xyce::dout() << "h_max_inv_ = " <<h_max_inv_<<std::endl;
1695  Xyce::dout() << "Tkm1_Tk_safety_ = " <<Tkm1_Tk_safety_<<std::endl;
1696  Xyce::dout() << "Tkp1_Tk_safety_ = " <<Tkp1_Tk_safety_<<std::endl;
1697  Xyce::dout() << "r_factor_ = " <<r_factor_<<std::endl;
1698  Xyce::dout() << "r_safety_ = " <<r_safety_<<std::endl;
1699  Xyce::dout() << "r_fudge_ = " <<r_fudge_<<std::endl;
1700  Xyce::dout() << "r_min_ = " <<r_min_<<std::endl;
1701  Xyce::dout() << "r_max_ = " <<r_max_<<std::endl;
1702  Xyce::dout() << "r_hincr_test_ = " <<r_hincr_test_<<std::endl;
1703  Xyce::dout() << "r_hincr_ = " <<r_hincr_<<std::endl;
1704 
1705  for (int i=0;i<6;++i)
1706  {
1707  Xyce::dout() << " alpha_["<<i<<"] = " << alpha_[i]<<std::endl;
1708  Xyce::dout() << " sigma_["<<i<<"] = " << sigma_[i]<<std::endl;
1709  Xyce::dout() << " gamma_["<<i<<"] = " << gamma_[i]<<std::endl;
1710  Xyce::dout() << " beta_["<<i<<"] = " << beta_[i]<<std::endl;
1711  Xyce::dout() << " psi_["<<i<<"] = " << psi_[i]<<std::endl;
1712  }
1713 
1714  Xyce::dout() << Xyce::section_divider << std::endl << std::endl << std::endl;
1715 #endif
1716 
1717  if( pack )
1718  {
1719  // doubles:
1720  comm->pack( &alphas_ , 1, buf, bsize, pos );
1721  comm->pack( &alpha0_ , 1, buf, bsize, pos );
1722  comm->pack( &cj_ , 1, buf, bsize, pos );
1723  comm->pack( &ck_ , 1, buf, bsize, pos );
1724  comm->pack( &usedStep_ , 1, buf, bsize, pos );
1725  comm->pack( &Ek_ , 1, buf, bsize, pos );
1726  comm->pack( &Ekm1_ , 1, buf, bsize, pos );
1727  comm->pack( &Ekm2_ , 1, buf, bsize, pos );
1728  comm->pack( &Ekp1_ , 1, buf, bsize, pos );
1729  comm->pack( &Est_ , 1, buf, bsize, pos );
1730  comm->pack( &Tk_ , 1, buf, bsize, pos );
1731  comm->pack( &Tkm1_ , 1, buf, bsize, pos );
1732  comm->pack( &Tkm2_ , 1, buf, bsize, pos );
1733  comm->pack( &Tkp1_ , 1, buf, bsize, pos );
1734  comm->pack( &h0_safety_ , 1, buf, bsize, pos );
1735  comm->pack( &h0_max_factor_ , 1, buf, bsize, pos );
1736  comm->pack( &h_phase0_incr_ , 1, buf, bsize, pos );
1737  comm->pack( &h_max_inv_ , 1, buf, bsize, pos );
1738  comm->pack( &Tkm1_Tk_safety_ , 1, buf, bsize, pos );
1739  comm->pack( &Tkp1_Tk_safety_ , 1, buf, bsize, pos );
1740  comm->pack( &r_factor_ , 1, buf, bsize, pos );
1741  comm->pack( &r_safety_ , 1, buf, bsize, pos );
1742  comm->pack( &r_fudge_ , 1, buf, bsize, pos );
1743  comm->pack( &r_min_ , 1, buf, bsize, pos );
1744  comm->pack( &r_max_ , 1, buf, bsize, pos );
1745  comm->pack( &r_hincr_test_ , 1, buf, bsize, pos );
1746  comm->pack( &r_hincr_ , 1, buf, bsize, pos );
1747 
1748  // vectors of doubles:
1749  for (int i=0;i<6;++i)
1750  {
1751  comm->pack( &alpha_[i], 1, buf, bsize, pos );
1752  comm->pack( &sigma_[i], 1, buf, bsize, pos );
1753  comm->pack( &gamma_[i], 1, buf, bsize, pos );
1754  comm->pack( &beta_[i], 1, buf, bsize, pos );
1755  comm->pack( &psi_[i], 1, buf, bsize, pos );
1756  }
1757 
1758  // ints:
1759  comm->pack ( &currentOrder_, 1, buf, bsize, pos);
1760  comm->pack ( &oldOrder_, 1, buf, bsize, pos);
1761  comm->pack ( &maxOrder_, 1, buf, bsize, pos);
1762  comm->pack ( &minOrder_, 1, buf, bsize, pos);
1763  comm->pack ( &usedOrder_, 1, buf, bsize, pos);
1764  comm->pack ( &numberOfSteps_, 1, buf, bsize, pos);
1765  comm->pack ( &nef_, 1, buf, bsize, pos);
1766  comm->pack ( &nscsco_, 1, buf, bsize, pos);
1767  comm->pack ( &newOrder_, 1, buf, bsize, pos);
1768  comm->pack ( &max_LET_fail_, 1, buf, bsize, pos);
1769 
1770  // bools:
1771  int iP = (initialPhase_)?1:0;
1772  comm->pack ( &iP, 1, buf, bsize, pos);
1773  }
1774  else
1775  {
1776  std::ostringstream ost;
1777  ost.width(24);ost.precision(16);ost.setf(std::ios::scientific);
1778 
1779  // doubles:
1780  ost << alphas_ << " ";
1781  ost << alpha0_ << " ";
1782  ost << cj_ << " ";
1783  ost << ck_ << " ";
1784  ost << usedStep_ << " ";
1785  ost << Ek_ << " ";
1786  ost << Ekm1_ << " ";
1787  ost << Ekm2_ << " ";
1788  ost << Ekp1_ << " ";
1789  ost << Est_ << " ";
1790  ost << Tk_ << " ";
1791  ost << Tkm1_ << " ";
1792  ost << Tkm2_ << " ";
1793  ost << Tkp1_ << " ";
1794  ost << h0_safety_ << " ";
1795  ost << h0_max_factor_ << " ";
1796  ost << h_phase0_incr_ << " ";
1797  ost << h_max_inv_ << " ";
1798  ost << Tkm1_Tk_safety_ << " ";
1799  ost << Tkp1_Tk_safety_ << " ";
1800  ost << r_factor_ << " ";
1801  ost << r_safety_ << " ";
1802  ost << r_fudge_ << " ";
1803  ost << r_min_ << " ";
1804  ost << r_max_ << " ";
1805  ost << r_hincr_test_ << " ";
1806  ost << r_hincr_ << " ";
1807 
1808  // vectors of doubles:
1809  for (int i=0;i<6;++i)
1810  {
1811  ost << alpha_[i]<< " " ;
1812  ost << sigma_[i]<< " " ;
1813  ost << gamma_[i]<< " " ;
1814  ost << beta_[i]<< " " ;
1815  ost << psi_[i]<< " " ;
1816  }
1817 
1818  // ints:
1819  ost << currentOrder_ << " ";
1820  ost << oldOrder_ << " ";
1821  ost << maxOrder_ << " ";
1822  ost << minOrder_ << " ";
1823  ost << usedOrder_ << " ";
1824  ost << numberOfSteps_ << " ";
1825  ost << nef_ << " ";
1826  ost << nscsco_ << " ";
1827  ost << newOrder_ << " ";
1828  ost << max_LET_fail_ << " ";
1829 
1830  // bools:
1831  int iP = (initialPhase_)?1:0;
1832  ost << iP << " ";
1833 
1834  std::string data( ost.str() );
1835  for( unsigned int i = 0; i < data.length(); ++i ) buf[pos+i] = data[i];
1836  // null terminate buf, essential if buf is used as a string anywhere,
1837  // including in the string constructor below:
1838  buf[pos+data.length()] = '\0';
1839 
1840 #ifdef Xyce_DEBUG_RESTART
1841  std::string outputString(buf);
1842 
1843  Xyce::dout() << "StepErrorControlDAE UNPACKED output buffer:" << std::endl;
1844  Xyce::dout() << outputString << std::endl;
1845 #endif
1846  pos = newPos;
1847  }
1848 
1849  return true;
1850 }
1851 
1852 //-----------------------------------------------------------------------------
1853 // Function : N_TIA_StepErrorControl::restoreRestartData
1854 // Purpose :
1855 // Special Notes : ERK: 6/20/2010:
1856 // There are no longer 2 distinct classes. The DAE version is
1857 // now part of the original, as one single class. The two
1858 // blocks of code in this function correspond to the original
1859 // class (first block), and the DAE class (second block).
1860 //
1861 // Scope : public
1862 // Creator : Eric R. Keiter, SNL
1863 // Creation Date : 7/28/06
1864 //-----------------------------------------------------------------------------
1866  (char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack)
1867 {
1868 
1869  // original class variables:
1870  if( pack )
1871  {
1872  comm->unpack(buf, bsize, pos, &startingTimeStep, 1);
1873  comm->unpack(buf, bsize, pos, &currentTimeStep, 1);
1874  comm->unpack(buf, bsize, pos, &lastAttemptedTimeStep, 1);
1875  comm->unpack(buf, bsize, pos, &lastTimeStep, 1);
1876  comm->unpack(buf, bsize, pos, &minTimeStep, 1);
1877  comm->unpack(buf, bsize, pos, &maxTimeStep, 1);
1878  comm->unpack(buf, bsize, pos, &maxTimeStepUser, 1);
1879  comm->unpack(buf, bsize, pos, &lastTime, 1);
1880  comm->unpack(buf, bsize, pos, &currentTime, 1);
1881  comm->unpack(buf, bsize, pos, &nextTime, 1);
1882  comm->unpack(buf, bsize, pos, &initialTime, 1);
1883  comm->unpack(buf, bsize, pos, &currentTimeStepRatio, 1);
1884  comm->unpack(buf, bsize, pos, &currentTimeStepSum, 1);
1885  comm->unpack(buf, bsize, pos, &lastTimeStepRatio, 1);
1886  comm->unpack(buf, bsize, pos, &lastTimeStepSum, 1);
1887  comm->unpack(buf, bsize, pos, &newtonConvergenceStatus, 1);
1888  comm->unpack(buf, bsize, pos, &numberSuccessiveFailures, 1);
1889  int flag;
1890  comm->unpack(buf, bsize, pos, &flag, 1);
1891  stepAttemptStatus = flag;
1892  comm->unpack(buf, bsize, pos, &minStepPrecisionFac_, 1);
1893  comm->unpack(buf, bsize, pos, &newtonStepReduction_, 1);
1894  comm->unpack(buf, bsize, pos, &tolAimFac_, 1);
1895  comm->unpack(buf, bsize, pos, &estOverTol_, 1);
1896 
1897  double bpTol = 2.0 * minTimeStep;
1898  anaManager_.setBreakpointTol(bpTol);
1899  tiaParams_.initialTime=initialTime;
1900  tiaParams_.pauseTime=initialTime;
1901  std::set<N_UTL_BreakPoint> tmpSet = breakPoints_;
1902  breakPoints_.clear();
1903  std::set<N_UTL_BreakPoint>::iterator iterSD;
1904  std::set<N_UTL_BreakPoint>::iterator firstSD = tmpSet.begin();
1905  std::set<N_UTL_BreakPoint>::iterator lastSD = tmpSet.end();
1906  for (iterSD = firstSD; iterSD != lastSD; ++iterSD)
1907  {
1908  if (iterSD->value() > currentTime)
1909  {
1910  breakPoints_.insert(*iterSD);
1911  if (iterSD->bptype() == Xyce::Util::PAUSE_BREAKPOINT)
1912  updatePauseTime(*iterSD);
1913  }
1914  }
1915 
1916  int size;
1917  double val;
1918  int bptype;
1919  N_UTL_BreakPoint TmpBP;
1920  comm->unpack(buf, bsize, pos, &size, 1);
1921 
1922  for (int i = 0; i < size; ++i)
1923  {
1924  comm->unpack(buf, bsize, pos, &val, 1);
1925  comm->unpack(buf, bsize, pos, &bptype, 1);
1926  if (val > currentTime)
1927  {
1928  TmpBP.set(val,bptype);
1929  breakPoints_.insert(TmpBP);
1930  if (TmpBP.bptype() == Xyce::Util::PAUSE_BREAKPOINT)
1931  {
1932  updatePauseTime(TmpBP);
1933  }
1934  }
1935  }
1936 
1937  int im;
1938  comm->unpack(buf, bsize, pos, &im, 1);
1939  anaManager_.setIntegrationMethod(im);
1940  comm->unpack(buf, bsize, pos, &im, 1);
1941  anaManager_.setStepNumber(im);
1942  comm->unpack(buf, bsize, pos, &im, 1);
1943  anaManager_.setTranStepNumber(im);
1944  comm->unpack(buf, bsize, pos, &im, 1);
1945  anaManager_.breakPointRestartStep = im;
1946  comm->unpack(buf, bsize, pos, &im, 1);
1947  anaManager_.setBeginningIntegrationFlag(im==1);
1948  }
1949  else
1950  {
1951  std::string str1(buf);
1952  int length = str1.size() - pos;
1953  std::string str2(str1,pos,length);
1954 
1955  std::istringstream ist( str2 );
1956 
1957  // count here will be the size for the base N_TIA_StepErrorControl
1958  // class *only*.
1959 
1960  // THIS IS INCORRECT! restartDataSize returns the MAXIMUM the thing
1961  // is allowed to be, which allows for 24 characters for each integer
1962  // value in the output. This is almost always an overestimate, and
1963  // using it as a way of pointing to the next character after our
1964  // data is a sure-fire way to break downstream processing!
1965  // Instead, we'll use the tellg function from the stringstream to
1966  // return the offset after we read everything out.
1967  // int count = N_TIA_StepErrorControl::restartDataSize( false );
1968  // pos += count;
1969 
1970  ist >> startingTimeStep;
1971  ist >> currentTimeStep;
1972  ist >> lastAttemptedTimeStep;
1973  ist >> lastTimeStep;
1974  ist >> minTimeStep;
1975  ist >> maxTimeStep;
1976  ist >> maxTimeStepUser;
1977  ist >> lastTime;
1978  ist >> currentTime;
1979  ist >> nextTime;
1980  ist >> initialTime;
1981  ist >> currentTimeStepRatio;
1982  ist >> currentTimeStepSum;
1983  ist >> lastTimeStepRatio;
1984  ist >> lastTimeStepSum;
1985  ist >> newtonConvergenceStatus;
1986  ist >> numberSuccessiveFailures;
1987  int flag;
1988  ist >> flag;
1989  stepAttemptStatus = flag;
1990  ist >> minStepPrecisionFac_;
1991  ist >> newtonStepReduction_;
1992  ist >> tolAimFac_;
1993  ist >> estOverTol_;
1994 
1995  double bpTol = 2.0 * minTimeStep;
1996  anaManager_.setBreakpointTol(bpTol);
1997  tiaParams_.initialTime=initialTime;
1998  tiaParams_.pauseTime=initialTime;
1999 
2000  std::set<N_UTL_BreakPoint> tmpSet = breakPoints_;
2001  breakPoints_.clear();
2002  std::set<N_UTL_BreakPoint>::iterator iterSD;
2003  std::set<N_UTL_BreakPoint>::iterator firstSD = tmpSet.begin();
2004  std::set<N_UTL_BreakPoint>::iterator lastSD = tmpSet.end();
2005  for (iterSD = firstSD; iterSD != lastSD; ++iterSD)
2006  {
2007  if (iterSD->value() > currentTime)
2008  {
2009  breakPoints_.insert(*iterSD);
2010  if (iterSD->bptype() == Xyce::Util::PAUSE_BREAKPOINT)
2011  updatePauseTime(*iterSD);
2012  }
2013  }
2014 
2015  int size;
2016  double val;
2017  int bptype;
2018  N_UTL_BreakPoint TmpBP;
2019  ist >> size;
2020 
2021  for( int i = 0; i < size; ++i )
2022  {
2023  ist >> val;
2024  ist >> bptype;
2025  if (val > currentTime)
2026  {
2027  TmpBP.set(val,bptype);
2028  breakPoints_.insert( TmpBP );
2029  if (TmpBP.bptype() == Xyce::Util::PAUSE_BREAKPOINT)
2030  {
2031  updatePauseTime(TmpBP);
2032  }
2033  }
2034  }
2035 
2036  int tmpInt;
2037  ist >> tmpInt;
2038  anaManager_.setIntegrationMethod(tmpInt);
2039  ist >> tmpInt;
2040  anaManager_.setStepNumber(tmpInt);
2041  ist >> tmpInt;
2042  anaManager_.setTranStepNumber(tmpInt);
2043  ist >> tmpInt;
2044  anaManager_.breakPointRestartStep = tmpInt;
2045  ist >> tmpInt;
2046  anaManager_.setBeginningIntegrationFlag(tmpInt==1);
2047 
2048  pos += ist.tellg();
2049  }
2050 
2051 #ifdef Xyce_DEBUG_RESTART
2052  std::string netListFile = commandLine_.getArgumentValue("netlist");
2053  Xyce::dout() << "TIA Restart Data RESTORE! " << netListFile << "\n";
2054  Xyce::dout() << Xyce::section_divider << std::endl;
2055  Xyce::dout() << "startingTimeStep: " << startingTimeStep << std::endl;
2056  Xyce::dout() << "currentTimeStep: " << currentTimeStep << std::endl;
2057  Xyce::dout() << "lastAttemptedTimeStep: " << lastAttemptedTimeStep << std::endl;
2058  Xyce::dout() << "lastTimeStep: " << lastTimeStep << std::endl;
2059  Xyce::dout() << "minTimeStep: " << minTimeStep << std::endl;
2060  Xyce::dout() << "maxTimeStep: " << maxTimeStep << std::endl;
2061  Xyce::dout() << "maxTimeStepUser: " << maxTimeStepUser << std::endl;
2062  Xyce::dout() << "lastTime: " << lastTime << std::endl;
2063  Xyce::dout() << "currentTime: " << currentTime << std::endl;
2064  Xyce::dout() << "nextTime: " << nextTime << std::endl;
2065  Xyce::dout() << "initialTime: " << initialTime << std::endl;
2066  Xyce::dout() << "estOverTol_: " << estOverTol_ << std::endl;
2067  Xyce::dout() << "breakpts: ";
2068  for (std::set<N_UTL_BreakPoint>::iterator iterSD = breakPoints_.begin();
2069  iterSD != breakPoints_.end(); ++iterSD)
2070  {
2071  Xyce::dout() << iterSD->value() << " " << iterSD->bptype() << std::endl;
2072  }
2073  Xyce::dout() << std::endl;
2074  Xyce::dout() << "integMethod: " << anaManager_.getIntegrationMethod() << std::endl;
2075  Xyce::dout() << "stepNumber: " << anaManager_.getStepNumber() << std::endl;
2076  Xyce::dout() << "tranStepNumber: " << anaManager_.getTranStepNumber() << std::endl;
2077  Xyce::dout() << "breakPointRestartStep: " << anaManager_.breakPointRestartStep <<
2078  std::endl;
2079  Xyce::dout() << Xyce::section_divider << std::endl << std::endl;
2080 #endif
2081 
2082  // DAE class variables:
2083  if( pack )
2084  {
2085  // doubles:
2086  comm->unpack(buf, bsize, pos, &alphas_ , 1);
2087  comm->unpack(buf, bsize, pos, &alpha0_ , 1);
2088  comm->unpack(buf, bsize, pos, &cj_ , 1);
2089  comm->unpack(buf, bsize, pos, &ck_ , 1);
2090  comm->unpack(buf, bsize, pos, &usedStep_ , 1);
2091  comm->unpack(buf, bsize, pos, &Ek_ , 1);
2092  comm->unpack(buf, bsize, pos, &Ekm1_ , 1);
2093  comm->unpack(buf, bsize, pos, &Ekm2_ , 1);
2094  comm->unpack(buf, bsize, pos, &Ekp1_ , 1);
2095  comm->unpack(buf, bsize, pos, &Est_ , 1);
2096  comm->unpack(buf, bsize, pos, &Tk_ , 1);
2097  comm->unpack(buf, bsize, pos, &Tkm1_ , 1);
2098  comm->unpack(buf, bsize, pos, &Tkm2_ , 1);
2099  comm->unpack(buf, bsize, pos, &Tkp1_ , 1);
2100  comm->unpack(buf, bsize, pos, &h0_safety_ , 1);
2101  comm->unpack(buf, bsize, pos, &h0_max_factor_ , 1);
2102  comm->unpack(buf, bsize, pos, &h_phase0_incr_ , 1);
2103  comm->unpack(buf, bsize, pos, &h_max_inv_ , 1);
2104  comm->unpack(buf, bsize, pos, &Tkm1_Tk_safety_ , 1);
2105  comm->unpack(buf, bsize, pos, &Tkp1_Tk_safety_ , 1);
2106  comm->unpack(buf, bsize, pos, &r_factor_ , 1);
2107  comm->unpack(buf, bsize, pos, &r_safety_ , 1);
2108  comm->unpack(buf, bsize, pos, &r_fudge_ , 1);
2109  comm->unpack(buf, bsize, pos, &r_min_ , 1);
2110  comm->unpack(buf, bsize, pos, &r_max_ , 1);
2111  comm->unpack(buf, bsize, pos, &r_hincr_test_ , 1);
2112  comm->unpack(buf, bsize, pos, &r_hincr_ , 1);
2113 
2114  // vectors of doubles:
2115  for (int i=0;i<6;++i)
2116  {
2117  comm->unpack(buf, bsize, pos, &alpha_[i], 1);
2118  comm->unpack(buf, bsize, pos, &sigma_[i], 1);
2119  comm->unpack(buf, bsize, pos, &gamma_[i], 1);
2120  comm->unpack(buf, bsize, pos, &beta_[i], 1);
2121  comm->unpack(buf, bsize, pos, &psi_[i], 1);
2122  }
2123 
2124  // ints:
2125  comm->unpack(buf, bsize, pos, &currentOrder_, 1);
2126  comm->unpack(buf, bsize, pos, &oldOrder_, 1);
2127  comm->unpack(buf, bsize, pos, &maxOrder_, 1);
2128  comm->unpack(buf, bsize, pos, &minOrder_, 1);
2129  comm->unpack(buf, bsize, pos, &usedOrder_, 1);
2130  comm->unpack(buf, bsize, pos, &numberOfSteps_, 1);
2131  comm->unpack(buf, bsize, pos, &nef_, 1);
2132  comm->unpack(buf, bsize, pos, &nscsco_, 1);
2133  comm->unpack(buf, bsize, pos, &newOrder_, 1);
2134  comm->unpack(buf, bsize, pos, &max_LET_fail_, 1);
2135 
2136  // bools:
2137  int iP;
2138  comm->unpack (buf, bsize, pos, &iP, 1);
2139  if (iP == 0) initialPhase_ = false;
2140  else initialPhase_ = true;
2141  }
2142  else
2143  {
2144  // want the string stream to only represent the new-DAE part of
2145  // the buf array.
2146  std::string str1(buf);
2147  int length = str1.size() - pos;
2148  std::string str2(str1,pos,length);
2149 
2150  std::istringstream ist( str2 );
2151 
2152  int count = N_TIA_StepErrorControl::restartDataSize(false);
2153  pos = count; // can update here, as pos isn't used after this.
2154 
2155  // doubles:
2156  ist >> alphas_;
2157  ist >> alpha0_;
2158  ist >> cj_;
2159  ist >> ck_;
2160  ist >> usedStep_;
2161  ist >> Ek_;
2162  ist >> Ekm1_;
2163  ist >> Ekm2_;
2164  ist >> Ekp1_;
2165  ist >> Est_;
2166  ist >> Tk_;
2167  ist >> Tkm1_;
2168  ist >> Tkm2_;
2169  ist >> Tkp1_;
2170  ist >> h0_safety_;
2171  ist >> h0_max_factor_;
2172  ist >> h_phase0_incr_;
2173  ist >> h_max_inv_;
2174  ist >> Tkm1_Tk_safety_;
2175  ist >> Tkp1_Tk_safety_;
2176  ist >> r_factor_;
2177  ist >> r_safety_;
2178  ist >> r_fudge_;
2179  ist >> r_min_;
2180  ist >> r_max_;
2181  ist >> r_hincr_test_;
2182  ist >> r_hincr_;
2183 
2184  // vectors of doubles:
2185  for (int i=0;i<6;++i)
2186  {
2187  ist >> alpha_[i];
2188  ist >> sigma_[i];
2189  ist >> gamma_[i];
2190  ist >> beta_[i];
2191  ist >> psi_[i];
2192  }
2193 
2194  // ints:
2195  ist >> currentOrder_;
2196  ist >> oldOrder_;
2197  ist >> maxOrder_;
2198  ist >> minOrder_;
2199  ist >> usedOrder_;
2200  ist >> numberOfSteps_;
2201  ist >> nef_;
2202  ist >> nscsco_;
2203  ist >> newOrder_;
2204  ist >> max_LET_fail_;
2205 
2206  // bools:
2207  int iP;
2208  ist >> iP;
2209  if (iP == 0) initialPhase_ = false;
2210  else initialPhase_ = true;
2211  }
2212 
2213 #ifdef Xyce_DEBUG_RESTART
2214  Xyce::dout() << "TIA Restart Data RESTORE (DAE)! " << netListFile << "\n";
2215  Xyce::dout() << Xyce::section_divider << std::endl<<std::endl;
2216  Xyce::dout() << "alphas_ = " <<alphas_<<std::endl;
2217  Xyce::dout() << "alpha0_ = " <<alpha0_<<std::endl;
2218  Xyce::dout() << "cj_ = " <<cj_<<std::endl;
2219  Xyce::dout() << "ck_ = " <<ck_<<std::endl;
2220  Xyce::dout() << "usedStep_ = " <<usedStep_<<std::endl;
2221  Xyce::dout() << "Ek_ = " <<Ek_<<std::endl;
2222  Xyce::dout() << "Ekm1_ = " <<Ekm1_<<std::endl;
2223  Xyce::dout() << "Ekm2_ = " <<Ekm2_<<std::endl;
2224  Xyce::dout() << "Ekp1_ = " <<Ekp1_<<std::endl;
2225  Xyce::dout() << "Est_ = " <<Est_<<std::endl;
2226  Xyce::dout() << "Tk_ = " <<Tk_<<std::endl;
2227  Xyce::dout() << "Tkm1_ = " <<Tkm1_<<std::endl;
2228  Xyce::dout() << "Tkm2_ = " <<Tkm2_<<std::endl;
2229  Xyce::dout() << "Tkp1_ = " <<Tkp1_<<std::endl;
2230  Xyce::dout() << "h0_safety_ = " <<h0_safety_<<std::endl;
2231  Xyce::dout() << "h0_max_factor_ = " <<h0_max_factor_<<std::endl;
2232  Xyce::dout() << "h_phase0_incr_ = " <<h_phase0_incr_<<std::endl;
2233  Xyce::dout() << "h_max_inv_ = " <<h_max_inv_<<std::endl;
2234  Xyce::dout() << "Tkm1_Tk_safety_ = " <<Tkm1_Tk_safety_<<std::endl;
2235  Xyce::dout() << "Tkp1_Tk_safety_ = " <<Tkp1_Tk_safety_<<std::endl;
2236  Xyce::dout() << "r_factor_ = " <<r_factor_<<std::endl;
2237  Xyce::dout() << "r_safety_ = " <<r_safety_<<std::endl;
2238  Xyce::dout() << "r_fudge_ = " <<r_fudge_<<std::endl;
2239  Xyce::dout() << "r_min_ = " <<r_min_<<std::endl;
2240  Xyce::dout() << "r_max_ = " <<r_max_<<std::endl;
2241  Xyce::dout() << "r_hincr_test_ = " <<r_hincr_test_<<std::endl;
2242  Xyce::dout() << "r_hincr_ = " <<r_hincr_<<std::endl;
2243 
2244  for (int i=0;i<6;++i)
2245  {
2246  Xyce::dout() << " alpha_["<<i<<"] = " << alpha_[i]<<std::endl;
2247  Xyce::dout() << " sigma_["<<i<<"] = " << sigma_[i]<<std::endl;
2248  Xyce::dout() << " gamma_["<<i<<"] = " << gamma_[i]<<std::endl;
2249  Xyce::dout() << " beta_["<<i<<"] = " << beta_[i]<<std::endl;
2250  Xyce::dout() << " psi_["<<i<<"] = " << psi_[i]<<std::endl;
2251  }
2252 
2253  Xyce::dout() << Xyce::section_divider << std::endl << std::endl << std::endl;
2254 #endif
2255 
2256  return true;
2257 }
2258 
2259 //-----------------------------------------------------------------------------
2260 // Function : N_TIA_StepErrorControl::updateTwoLevelTimeInfo
2261 // Purpose :
2262 // Special Notes :
2263 // Scope : public
2264 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
2265 // Creation Date : 3/14/06
2266 //-----------------------------------------------------------------------------
2268 {
2269  updateStopTime();
2270 
2271  // Need to get this right.
2272  if (previousCallStepSuccessful == true)
2273  {
2278  }
2279 
2280  // If the step needs to be adjusted:
2282  double newTimeStep = tiInfo.nextTimeStep;
2283  nextTime = tiInfo.nextTime;
2284  currentTimeStepRatio = newTimeStep/lastTimeStep;
2285  currentTimeStepSum = newTimeStep + lastTimeStep;
2286  currentTimeStep = newTimeStep;
2287  currentOrder_ = tiInfo.currentOrder;
2288 }
2289 
2290 //-----------------------------------------------------------------------------
2291 // Function : N_TIA_StepErrorControl::outputTimeInfo
2292 // Purpose :
2293 // Special Notes :
2294 // Scope : public
2295 // Creator : Todd Coffey, 1414
2296 // Creation Date : 03/04/08
2297 //-----------------------------------------------------------------------------
2298 
2300 {
2301  {
2302  Xyce::ios_flags_saver flagsave(os);
2303 
2304  os << " " << (Xyce::DEBUG_TIME ? commandLine_.getArgumentValue("netlist") : " ") << " "
2305  << "Current,Next,Step: "
2306  << std::setw(Xyce::DEBUG_TIME ? 14 : 16) << std::setprecision(Xyce::DEBUG_TIME ? 7 : 9)
2307  << currentTime << ", " << nextTime << ", " << currentTimeStep;
2308  }
2309 
2310  os << " ("<<numberOfSteps_<<") Used, Next Order: " << usedOrder_ << ", " << currentOrder_ << std::endl;
2311 }
2312 
2313 
2314 //-----------------------------------------------------------------------------
2315 // Function : N_TIA_StepErrorControl::isPauseTime
2316 // Purpose : public method to flag whether the current time is a pause
2317 // time
2318 // Special Notes : Need this method because the prior values get in the way
2319 // when we resume.
2320 // Scope : public
2321 // Creator : Tom Russo, SNL, Component Information and Models
2322 // Creation Date : 04/30/04
2323 //-----------------------------------------------------------------------------
2325 {
2326  // Check whether pauseTime == currentTime (to within bpTol).
2327  // If the pause time is equal to the final time, we are at the end, not
2328  // at a pause time.
2329 #ifdef Xyce_DEBUG_TIME
2330  if (tiaParams_.debugLevel >0)
2331  {
2332  Xyce::dout() << "N_TIA_StepErrorControl::isPauseTime\n";
2333  Xyce::dout() << "currentPauseBP.value = " << currentPauseBP->value () << std::endl;
2334  Xyce::dout() << "final Time = " << finalTime << std::endl;
2335  Xyce::dout() << "current Time = " << currentTime << std::endl;
2336  }
2337 #endif
2338  return ( !(*currentPauseBP == finalTime) &&
2340 }
2341 
2342 //-----------------------------------------------------------------------------
2343 // Function : operator<<
2344 // Purpose : "<<" operator for step error control class.
2345 // Special Notes :
2346 // Scope : public
2347 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
2348 // Creation Date : 10/17/05
2349 //-----------------------------------------------------------------------------
2350 std::ostream & operator<<(std::ostream & os, const N_TIA_StepErrorControl & sec)
2351 {
2352  os << "\n\n-----------------------------------------" << std::endl
2353  << "\tStepErrorControl:\n"
2354  << "\t\tstartingTimeStep = " << sec.startingTimeStep << std::endl
2355  << "\t\tcurrentTimeStep = " << sec.currentTimeStep << std::endl
2356  << "\t\tlastAttemptedTimeStep = " << sec.lastAttemptedTimeStep << std::endl
2357  << "\t\tlastTimeStep = " << sec.lastTimeStep << std::endl
2358  << "\t\tminTimeStep = " << sec.minTimeStep << std::endl
2359  << "\t\tmaxTimeStep = " << sec.maxTimeStep << std::endl
2360  << "\t\tmaxTimeStepUser = " << sec.maxTimeStepUser << std::endl
2361  << "\t\tlastTime = " << sec.lastTime << std::endl
2362  << "\t\tcurrentTime = " << sec.currentTime << std::endl
2363  << "\t\tnextTime = " << sec.nextTime << std::endl
2364  << "\t\tstopTime = " << sec.stopTime << std::endl
2365  << "\t\tinitialTime = " << sec.initialTime << std::endl
2366  << "\t\tfinalTime = " << sec.finalTime << std::endl
2367  << std::endl
2368  << "\t\tBreak Points:" << std::endl;
2369 
2370  sec.printBreakPoints (os);
2371 
2372 
2373  os << Xyce::section_divider << std::endl;
2374  os << std::endl;
2375 
2376  return os;
2377 }
2378