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.227 $
41 //
42 // Revision Date : $Date: 2014/02/24 23:49:27 $
43 //
44 // Current Owner : $Author: tvrusso $
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_ANP_AnalysisManager.h>
60 #include <N_TIA_StepErrorControl.h>
61 #include <N_TIA_TIAParams.h>
62 #include <N_TIA_TimeIntInfo.h>
63 
64 #include <N_UTL_Xyce.h>
65 #include <N_UTL_BreakPoint.h>
66 #include <N_UTL_Functors.h>
67 #include <N_UTL_SaveIOSState.h>
68 
69 #include <N_PDS_Comm.h>
70 
71 #include <N_ERH_ErrorMgr.h>
72 
73 #include <N_IO_CmdParse.h>
74 
75 //-----------------------------------------------------------------------------
76 // Function : N_TIA_StepErrorControl::N_TIA_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  N_IO_CmdParse & cp,
85  N_ANP_AnalysisManager & anaManager,
86  N_TIA_TIAParams & tiaP)
87  :
88  startingTimeStep(1.0e-10),
89  currentTimeStep(1.0e-10),
90  lastAttemptedTimeStep(1.0e-10),
91  lastTimeStep(1.0e-10),
92  minTimeStep(0.0),
93  maxTimeStep(0.0),
94  maxTimeStepUser(1.0e+99),
95  maxTimeStepBP(0.0),
96  savedTimeStep(1.0e-10),
97  lastTime(0.0),
98  currentTime(0.0),
99  nextTime(0.0),
100  stopTime(0.0),
101  initialTime(0.0),
102  finalTime(0.0),
103  currentTimeStepRatio(0.0),
104  currentTimeStepSum(0.0),
105  lastTimeStepRatio(0.0),
106  lastTimeStepSum(0.0),
107  newtonConvergenceStatus(-1),
108  nIterations(0),
109  numberSuccessiveFailures(0),
110  stepAttemptStatus(true),
111  previousCallStepSuccessful(false),
112  estOverTol_(0.0),
113  initializeFlag_(false),
114  minStepPrecisionFac_(10.0),
115  newtonStepReduction_(0.25),
116  restartTimeStepScale_(0.005),
117  tolAimFac_(0.5),
118  tiaParams_(tiaP),
119  anaManager_(anaManager),
120  wimPtr_(NULL),
121  loader_( *(anaManager_.loaderPtr) ),
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" << 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" << 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( << std::endl & 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  }
552  stopTime = Xycemin(currentPauseBP->value(), stopTime);
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_.pdsMgrPtr->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());
639  nextTime = Xycemin(currentPauseBP->value(), nextTime);
640 
641 #ifdef Xyce_PARALLEL_MPI
642  double nT = nextTime;
643  double mNT;
644 
645  N_PDS_Comm * comm = anaManager_.pdsMgrPtr->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 #ifdef Xyce_EXTDEV
710  // Needed for 2-level Solves:
711  loader_.getInnerLoopErrorSums (anaManager_.getTIADataStore()->innerErrorInfoVec);
712 #endif
713 
715 
717  {
718  sAStatus = true;
719  }
720  else
721  {
722  sAStatus = false;
723  }
724 
725  if (tiaParams_.timestepsReversal == true)
726  {
728  errorOptionStatus = true;
729  else
730  errorOptionStatus = false;
731  }
732 #ifdef Xyce_VERBOSE_TIME
734  {
735  Xyce::dout() << "ERROROPTION=1: DOREJECTSTEP = ";
736  if (tiaParams_.timestepsReversal == true)
737  {
738  Xyce::dout() << "1" << std::endl;
739  }
740  else
741  {
742  Xyce::dout() << "0" << std::endl;
743  }
744  }
745 #endif // Xyce_VERBOSE_TIME
746 
748  {
749  // This step has dropped under the user specified min time step, so only
750  // test if the sovler converged to accept the step.
751  // don't do the step_attempt_status && sAStatus;
752 #ifdef Xyce_DEBUG_TIME
753  if (tiaParams_.debugLevel > 2)
754  {
755  Xyce::dout() << "Trying to skip time integrator error checks: " << currentTimeStep
756  << " newton status " << step_attempt_status << std::endl;
757  }
758 #endif
759  }
760 // else if (!(tiaParams_.constantStepSize) && ((tiaParams_.errorAnalysisOption == 0)) )
761 // {
762 // step_attempt_status = step_attempt_status && sAStatus;
763 // }
764  else if (!(tiaParams_.constantStepSize))
765  {
767  step_attempt_status = step_attempt_status && errorOptionStatus;
768  else
769  step_attempt_status = step_attempt_status && sAStatus;
770  }
771  }
772 
773 
774 #ifdef Xyce_VERBOSE_TIME
775 #ifdef Xyce_DEBUG_TIME
776  if (tiaParams_.debugLevel > 0)
777  {
778  integrationStepReport_(Xyce::dout(), step_attempt_status, sAStatus, testTimeIntegrationError);
779  }
780  else
781 #endif
782  {
783  terseIntegrationStepReport_(Xyce::lout(), step_attempt_status, sAStatus, testTimeIntegrationError);
784  }
785 #endif
786 
787  // Now that the status has been completely determined,
788  // set the class variable for step attempt
789  stepAttemptStatus = step_attempt_status;
790 }
791 
792 //-----------------------------------------------------------------------------
793 // Function : N_TIA_StepErrorControl::terseIntegrationStepReport_
794 // Purpose : This gives a one-line description of the step accept/reject.
795 // Special Notes :
796 // Scope : public
797 // Creator : Eric Keiter, SNL
798 // Creation Date : 01/27/07
799 //-----------------------------------------------------------------------------
800 void N_TIA_StepErrorControl::terseIntegrationStepReport_(std::ostream &os, bool step_attempt_status, bool sAStatus, bool testedError)
801 {
802  os << (Xyce::DEBUG_TIME ? commandLine_.getArgumentValue("netlist") : "")
803  << " STEP STATUS: " << (step_attempt_status ? " success" : " fail")
804  << " Newton: " << newtonConvergenceStatus
805  << " estOverTol: " << estOverTol_ << (testedError && !(tiaParams_.constantStepSize) ? "" : " (not used for this step)") << std::endl;
806 }
807 
808 //-----------------------------------------------------------------------------
809 // Function : N_TIA_StepErrorControl::integrationStepReport_
810 // Purpose :
811 // Special Notes :
812 // Scope : public
813 // Creator : Eric Keiter, SNL
814 // Creation Date : 03/12/06
815 //-----------------------------------------------------------------------------
816 void N_TIA_StepErrorControl::integrationStepReport_(std::ostream &os, bool step_attempt_status, bool sAStatus, bool testedError)
817 {
818  if (tiaParams_.debugLevel > 0)
819  {
820  os << "\n estOverTol = " << estOverTol_ << std::endl
821  << " error tolerance = " << tiaParams_.errTolAcceptance << std::endl
822  << std::endl
823  << "\nSTEP ATTEMPT STATUS:" << std::endl
824  << "NOTE:" << std::endl;
825 
826  if (!(tiaParams_.constantStepSize) &&
827  anaManager_.getStepNumber() >= 1 &&
829  {
830  os << " We are running in variable stepsize mode << " << std::endl
831  << " and we have NOT just passed a breakpoint. As such << " << std::endl
832  << " for an integration step to succeed << the " << std::endl
833  << " nonlinear solver must succeed << AND the predictor" << std::endl
834  << " and corrector need to be close within a tolerance." << std::endl;
835 
837  {
838  os << "ADDENDUM: This is with erroption=1 so predictor-corrector is ignored for step error control." << std::endl;
839  }
840  }
841  else
842  {
843  os << " We are either running constant stepsize << " << std::endl
844  << " or we just passed a breakpoint. As such << " << std::endl
845  << " the only criteria we use in accepting/rejecting" << std::endl
846  << " an integration step is the nonlinear solver" << std::endl
847  << " success/failure." << std::endl;
848  }
849 
850  if (step_attempt_status)
851  {
852  os << "\n This has been a successful step:" << std::endl;
853  }
854  else
855  {
856  os << "\n This has NOT been a successful step:" << std::endl;
857  }
858 
859  if ( newtonConvergenceStatus > 0)
860  {
861  os << " - Newton solver succeded with return code " << newtonConvergenceStatus << std::endl << std::endl;
862  }
863  else
864  {
865  os << " - Newton solver failed with return code " << newtonConvergenceStatus << std::endl;
866  }
867 
868  if (testedError)
869  {
871  {
872  if (sAStatus)
873  {
874  os << " - predictor vs. corrector analysis succeeded." << std::endl;
875  }
876  else
877  {
878  os << " - predictor vs. corrector analysis failed." << std::endl;
879  }
880 
881  os << " (compare estOverTol with error tolerance << above. << std::endl" << std::endl;
882  }
883  else
884  {
885  os << "If we had been using it << " << std::endl;
886 
887  if (sAStatus)
888  {
889  os << " - predictor vs. corrector analysis would have succeeded." << std::endl;
890  }
891  else
892  {
893  os << " - predictor vs. corrector analysis would have failed." << std::endl;
894  }
895 
896  os << " (compare estOverTol with error tolerance << above. << std::endl" << std::endl;
897  }
898  }
899  else
900  {
901  os << " predictor vs. corrector was not tested" << std::endl;
902  }
903 
904  os << Xyce::section_divider << std::endl;
905  } // end of debugLevel if statement
906 }
907 
908 //-----------------------------------------------------------------------------
909 // Function : N_TIA_StepErrorControl::initializeBreakPoints
910 // Purpose :
911 // Special Notes :
912 // Scope : public
913 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
914 // Creation Date : 06/11/01
915 //-----------------------------------------------------------------------------
917 {
918  bool bsuccess = true;
919 
920  breakPoints_.clear ();
921  // if currentPauseBP was set, it is now invalid so set it to a safe but
922  // invalid value until it is calulcated
924 
925  // first breakpoint is the start time, last one is the final time.
927 
928  // if tStart is nonzero, then make it a breakpoint.
929  if (tiaParams_.tStart > initialTime &&
931  {
933  }
934 
935  // The final time needs to be the very last breakpoint.
936  //setBreakPoint(finalTime);
937  setBreakPoint(N_UTL_BreakPoint(tiaParams_.finalTime ,Xyce::Util::PAUSE_BREAKPOINT));
938 
939  // Now add in the user break points. NOT DONE YET.
940  //vector<double> ;
941  //tiaParams_.userSpecBreakPoints;
942 
943 
944  // other breakpoints will later be added/removed dynamically over the
945  // course of the transient simulation in calls to the loader.
946 
947  return bsuccess;
948 }
949 
950 //-----------------------------------------------------------------------------
951 // Function : N_TIA_StepErrorControl::updateBreakPoints
952 // Purpose : Requests dynamic breakpoint information from the
953 // loader. Adds, subtracts from the breakpoints array.
954 // Special Notes :
955 // Scope : public
956 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
957 // Creation Date : 06/11/01
958 //-----------------------------------------------------------------------------
960 {
961  bool bsuccess = true;
962 
963 #ifdef Xyce_DEBUG_TIME
964  if (tiaParams_.debugLevel >0)
965  {
966  Xyce::dout() << std::endl
967  << Xyce::section_divider << std::endl
968  << " N_TIA_StepErrorControl::updateBreakPoints. time = " << currentTime << std::endl
969  << std::endl;
970  }
971 #endif
972 
973  std::vector<N_UTL_BreakPoint> tmpBP;
974  tmpBP.clear ();
975 
976  loader_.getBreakPoints(tmpBP);
977 
978  // debug outputs:
979  std::vector<N_UTL_BreakPoint>::iterator iter;
980  std::vector<N_UTL_BreakPoint>::iterator first = tmpBP.begin();
981  std::vector<N_UTL_BreakPoint>::iterator last = tmpBP.end();
982 
983  // add any new breakpoints to the vector of breakpoints:
984  std::set<N_UTL_BreakPoint>::iterator itBP;
985  std::set<N_UTL_BreakPoint>::iterator itBP_2;
986  std::set<N_UTL_BreakPoint>::iterator firstBP = breakPoints_.begin();
987  std::set<N_UTL_BreakPoint>::iterator lastBP = breakPoints_.end();
988 
989  // Add new breakpoints to the set:
990  for (iter=first; iter!=last; ++iter)
991  {
992  if (iter->value() < finalTime && iter->value() > lastTime)
993  {
994  setBreakPoint(*iter);
995  }
996  }
997 
998 #ifdef Xyce_DEBUG_TIME
999  char tmp[128];
1000  int i;
1001  if (tiaParams_.debugLevel >0)
1002  {
1003  firstBP = breakPoints_.begin();
1004 
1005  std::string netListFile = commandLine_.getArgumentValue("netlist");
1006  std::string msg = netListFile + " breakPoints_ vector container, before any removals:";
1007 
1008  Xyce::dout() <<msg << std::endl;
1009 
1010  for (i=0, itBP=firstBP;itBP!=lastBP;++i,++itBP)
1011  {
1012  if (i==0)
1013  {
1014  sprintf(tmp,"%4d %16.8e",i,itBP->value());
1015  }
1016  else
1017  {
1018  sprintf(tmp,"%4d %16.8e diff=%16.8e", i, itBP->value(),(itBP->value()-itBP_2->value()));
1019  }
1020 
1021  Xyce::dout() <<tmp << std::endl;
1022  itBP_2 = itBP;
1023  }
1024  Xyce::dout() <<"" << std::endl;
1025  }
1026 #endif
1027 
1028  // Remove breakpoints which are now obsolete (old):
1029  LessThan<N_UTL_BreakPoint,double> LessFunct;
1030  itBP_2 = lower_bound(firstBP,lastBP,lastTime,LessFunct);
1031  breakPoints_.erase(firstBP,itBP_2);
1032 
1033  // Remove breakpoints which are too close together.
1034  // ERK. This is kind of ugly and can undoubtably be done
1035  // in a much more elegant way using STL. Note that
1036  // the value of "bpTol" is pulled out of my ear.
1037 
1038  // TVR: only need to do this if the BP tolerance has changed from what it
1039  // was set to in the breakpoint class --- as things were inserted, near
1040  // values were rejected if within tolerance. Only need to do this if the
1041  // tolerance has gotten looser
1042 
1043  // TVR: Cannot use the STL "unique" function to accomplish this, because
1044  // STL sets are designed to prevent changing the set elements after they're
1045  // inserted. Have to do this by removing duplicate entries explicitly.
1046 
1047  double bpTol = 2.0 * minTimeStep;
1048  if (bpTol != anaManager_.getBreakpointTol())
1049  {
1050  // set the class's tolerance to this new one
1052 #ifdef Xyce_DEBUG_TIME
1053  if (tiaParams_.debugLevel >0)
1054  {
1055  Xyce::dout() << " bpTol = " << bpTol << std::endl;
1056  Xyce::dout() << " Must now eliminate new duplicates " << std::endl;
1057  }
1058 #endif
1059 
1060  bool doneRemove = false;
1061  while (!doneRemove)
1062  {
1063  doneRemove = true;
1064  firstBP = breakPoints_.begin();
1065  lastBP = breakPoints_.end();
1066  int icount;
1067  for (icount = 0, itBP=firstBP, itBP_2=firstBP;
1068  itBP!=lastBP;
1069  ++icount, ++itBP)
1070  {
1071  double diff = (itBP->value() - itBP_2->value());
1072 
1073  if (icount != 0)
1074  {
1075  if (fabs(diff) < bpTol)
1076  {
1077  // If both are simple, just toss the later one
1078  if (itBP->bptype() == Xyce::Util::SIMPLE_BREAKPOINT &&
1079  itBP_2->bptype() == Xyce::Util::SIMPLE_BREAKPOINT)
1080  {
1081  if (diff > 0.0)
1082  breakPoints_.erase(itBP);
1083  else
1084  breakPoints_.erase(itBP_2);
1085  }
1086  else
1087  {
1088  // one of these breakpoints is not simple! Determine the
1089  // overriding type, then set a breakpoint at the earliest time
1090  // with the overriding type:
1091  Xyce::Util::BreakpointType overridingType = itBP->bptype();
1092  double minTime=Xycemin(itBP->value(),itBP_2->value());
1093 
1094  // The following line will need to be changed if any other types
1095  // besides SIMPLE_BREAKPOINT and PAUSE_BREAKPOINT are ever
1096  // introduced and any more complex precedence is defined.
1097  if (itBP_2->bptype() != Xyce::Util::SIMPLE_BREAKPOINT)
1098  {
1099  overridingType = itBP_2->bptype();
1100  }
1101  breakPoints_.erase(itBP);
1102  breakPoints_.erase(itBP_2);
1103  N_UTL_BreakPoint tmpBP(minTime,overridingType);
1104  breakPoints_.insert(tmpBP);
1105  // and just to be very careful, make sure to update the pause
1106  // time, lest the currentPauseBP iterator be confused.
1107 #ifdef Xyce_DEBUG_TIME
1108  Xyce::dout() << " Purging breakpoints, overriding with breakpoint of type " << tmpBP.bptype();
1109 #endif
1110  updatePauseTime(tmpBP);
1111  }
1112 
1113  doneRemove = false;
1114  break;
1115  }
1116  }
1117  itBP_2 = itBP;
1118  }
1119  }
1120  }
1121 
1122 #ifdef Xyce_DEBUG_TIME
1123  if (tiaParams_.debugLevel >0)
1124  {
1125  firstBP = breakPoints_.begin();
1126 
1127  Xyce::dout() <<
1128  " breakPoints_ vector container << after:" << std::endl;
1129 
1130  for (i=0, itBP=firstBP;itBP!=lastBP;++i,++itBP)
1131  {
1132  if (i==0)
1133  {
1134  sprintf(tmp,"%4d %16.8e type=%d",i,itBP->value(),itBP->bptype());
1135  }
1136  else
1137  {
1138  sprintf(tmp,"%4d %16.8e type=%d diff=%16.8e", i, itBP->value(),
1139  itBP->bptype(),(itBP->value()-itBP_2->value()));
1140  }
1141 
1142  Xyce::dout() <<tmp << std::endl;
1143  itBP_2 = itBP;
1144  }
1145 
1146  Xyce::dout() <<"" << std::endl;
1147  Xyce::dout() <<Xyce::section_divider << std::endl;
1148  }
1149 #endif
1150 
1151  return bsuccess;
1152 }
1153 
1154 
1155 //-----------------------------------------------------------------------------
1156 // Function : N_TIA_StepErrorControl::updateMaxTimeStep
1157 // Purpose : Requests dynamic time step information from the loader.
1158 // Special Notes :
1159 // Scope : public
1160 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1161 // Creation Date : 08/01/01
1162 //-----------------------------------------------------------------------------
1163 bool N_TIA_StepErrorControl::updateMaxTimeStep(double suggestedMaxTimeStep)
1164 {
1165  bool bsuccess = true;
1166 
1167 #ifdef Xyce_DEBUG_TIME
1168  if (tiaParams_.debugLevel >0)
1169  {
1170  Xyce::dout() << Xyce::section_divider << std::endl;
1171  Xyce::dout() <<
1172  " N_TIA_StepErrorControl::updateMaxTimeStep" << std::endl;
1173  }
1174 #endif
1175 
1176  double maxDevStep = 1.0e+99;
1178  {
1179  maxDevStep = loader_.getMaxTimeStepSize();
1180  }
1181 
1183  {
1185  }
1186  else
1187  {
1189  }
1190 
1191  // if the default arg is not zero, then a suggested max time step was
1192  // passed in. Test if it is feasible to use that at this time
1193  if( suggestedMaxTimeStep > 0.0 )
1194  {
1195  maxTimeStep = Xycemin( maxTimeStep, suggestedMaxTimeStep );
1196  }
1197 
1198  if ((maxTimeStepBP > 0.0) && (maxTimeStep > maxTimeStepBP))
1199  {
1201  }
1202 
1203  if (maxDevStep > 0.0)
1204  {
1205  maxTimeStep = Xycemin(maxTimeStep, maxDevStep);
1206  }
1207 
1209  {
1211  }
1212 
1213 #ifdef Xyce_PARALLEL_MPI
1214  double mTS = maxTimeStep;
1215  double mMTS;
1216 
1217  N_PDS_Comm * comm = anaManager_.pdsMgrPtr->getPDSComm();
1218 
1219  comm->minAll ( &mTS, &mMTS, 1);
1220 
1221  maxTimeStep = mMTS;
1222 #endif
1223 
1224 #ifdef Xyce_DEBUG_TIME
1225  if (tiaParams_.debugLevel >0)
1226  {
1228  {
1229  Xyce::dout() <<
1230  " User did not specify a maximum time step." << std::endl;
1231  }
1232  else
1233  {
1234  Xyce::dout() <<
1235  " User specified a maximum time step. = " << maxTimeStepUser << std::endl;
1236  }
1237 
1238  Xyce::dout() <<
1239  " maxDevStep = " << maxDevStep << std::endl;
1240  Xyce::dout() <<
1241  " maxTimeStep = " << maxTimeStep << std::endl;
1242  Xyce::dout() <<Xyce::section_divider << std::endl;
1243  }
1244 #endif
1245 
1246  if(maxTimeStep<=0.0)
1247  {
1248  const std::string msg = "Maximum Time step is invalid!\n";
1249  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1250  }
1251 
1252  return bsuccess;
1253 }
1254 
1255 //-----------------------------------------------------------------------------
1256 // Function : N_TIA_StepErrorControl::updateMinTimeStep
1257 // Purpose : Sets the minimum time step based on machine precision.
1258 // Special Notes :
1259 // Scope : public
1260 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
1261 // Creation Date : 08/02/01
1262 //-----------------------------------------------------------------------------
1264 {
1265  bool bsuccess = true;
1266 
1268  N_UTL_MachineDependentParams::MachinePrecision();
1269 
1270  return bsuccess;
1271 }
1272 
1273 //-----------------------------------------------------------------------------
1274 // Function : N_TIA_StepErrorControl::setBreakPoint
1275 // Purpose : public method to set individual breakpoint
1276 // Special Notes :
1277 // Scope : public
1278 // Creator : Tom Russo, SNL, Component Information and Models
1279 // Creation Date : 04/30/04
1280 //-----------------------------------------------------------------------------
1281 void N_TIA_StepErrorControl::setBreakPoint(N_UTL_BreakPoint theBP)
1282 {
1283  if (theBP.bptype() == Xyce::Util::SIMPLE_BREAKPOINT)
1284  {
1285  breakPoints_.insert(theBP);
1286  }
1287  else
1288  {
1289 #ifdef Xyce_DEBUG_TIME
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  {
1350  tiaParams_.pauseTime = Xycemin(tiaParams_.pauseTime, BP.value());
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  Xyce::dout() << "\n" << commandLine_.getArgumentValue("netlist")
1360  << " UPDATING PAUSE TIME TO " << currentPauseBP->value()
1361  << " encountered breakpoint " << BP.value() << " current time is "
1362  << currentTime << std::endl;
1363 #endif
1364  }
1365 
1366 }
1367 
1368 
1369 //-----------------------------------------------------------------------------
1370 // Function : N_TIA_StepErrorControl::simulationPaused
1371 // Purpose : public method to clear out breakpoint list and reset
1372 // pause time when pause time is reached
1373 // Special Notes : Need this method because the prior values get in the way
1374 // when we resume.
1375 // Scope : public
1376 // Creator : Tom Russo, SNL, Component Information and Models
1377 // Creation Date : 04/30/04
1378 //-----------------------------------------------------------------------------
1380 {
1381  breakPoints_.erase(currentTime); // clear current breakpoint
1382  tiaParams_.pauseTime = tiaParams_.initialTime; // unset this
1383  currentPauseBP = breakPoints_.end(); // make this invalid
1384 }
1385 
1386 //-----------------------------------------------------------------------------
1387 // Function : N_TIA_StepErrorControl::printBreakPoints
1388 // Purpose :
1389 // Special Notes :
1390 // Scope : public
1391 // Creator : Eric Keiter, SNL
1392 // Creation Date : 10/17/05
1393 //-----------------------------------------------------------------------------
1394 void N_TIA_StepErrorControl::printBreakPoints (std::ostream & os) const
1395 {
1396  std::set<N_UTL_BreakPoint>::const_iterator itBP;
1397  std::set<N_UTL_BreakPoint>::const_iterator itBP2;
1398  std::set<N_UTL_BreakPoint>::const_iterator firstBP = breakPoints_.begin();
1399  std::set<N_UTL_BreakPoint>::const_iterator lastBP = breakPoints_.end();
1400 
1401  char tmp[128];
1402 
1403  int i;
1404  for (i=0, itBP=firstBP;itBP!=lastBP;++i,++itBP)
1405  {
1406  if (i==0)
1407  sprintf(tmp,"%4d %16.8e type=%d",i,itBP->value(),itBP->bptype());
1408  else
1409  sprintf(tmp,"%4d %16.8e type=%d diff=%16.8e", i, itBP->value(),
1410  itBP->bptype(),(itBP->value()-itBP2->value()));
1411 
1412  os << std::string(tmp);
1413  itBP2 = itBP;
1414  }
1415 }
1416 
1417 //-----------------------------------------------------------------------------
1418 // Function : N_TIA_StepErrorControl::restartDataSize
1419 // Purpose :
1420 // Special Notes : This gives the *total* size: both the base
1421 // N_TIA_StepErrorControl and the derived
1422 // N_TIA_StepErrorControlDAE, summed together.
1423 //
1424 // Don't sum them 2x!
1425 //
1426 // ERK: 6/20/2010:
1427 // There are no longer 2 distinct classes. The DAE version is
1428 // now part of the original, as one single class. The two
1429 // blocks of code in this function correspond to the original
1430 // class (first block), and the DAE class (second block).
1431 //
1432 // Scope : public
1433 // Creator : Eric R. Keiter, SNL
1434 // Creation Date : 07/27/06
1435 //-----------------------------------------------------------------------------
1437 {
1438  int totalSize = 0;
1439 
1440  // original set of vars:
1441  int numdoubles = 21;
1442  int numints = 9;
1443  int count = sizeof(double) * (numdoubles);
1444  count += sizeof(int) * numints;
1445 
1446  // Must include the bp type now, not just the value
1447  count += sizeof(N_UTL_BreakPoint)*breakPoints_.size();
1448 
1449  //overestimate buffer size for unpacked data
1450  // assumes there are fewer than 100 possible breakpoints types (i.e.
1451  // because the type can be represented by two ascii characters)
1452  if( !pack )
1453  { // 34
1454  count = 24*((numdoubles+numints) + (breakPoints_.size()))
1455  + 2*(breakPoints_.size());
1456  }
1457 
1458  int baseClassSize = count;
1459 
1460  // another set of vars: (newDAE)
1461  numdoubles = 57;
1462  numints = 10;
1463 
1464  totalSize = baseClassSize;
1465  totalSize += sizeof(double) * numdoubles;
1466  totalSize += sizeof(int) * numints;
1467 
1468  //overestimate buffer size for unpacked data
1469  if ( !pack )
1470  {
1471  totalSize = baseClassSize + 24*(numdoubles+numints);
1472  }
1473 
1474  return totalSize;
1475 }
1476 //-----------------------------------------------------------------------------
1477 // Function : N_TIA_StepErrorControl::dumpRestartData
1478 // Purpose :
1479 // Special Notes : ERK: 6/20/2010:
1480 // There are no longer 2 distinct classes. The DAE version is
1481 // now part of the original, as one single class. The two
1482 // blocks of code in this function correspond to the original
1483 // class (first block), and the DAE class (second block).
1484 //
1485 // Scope : public
1486 // Creator : Eric R. Keiter, SNL
1487 // Creation Date : 7/28/06
1488 //-----------------------------------------------------------------------------
1490  (char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack )
1491 {
1492 
1493  // Set this variable up for later. Note that pos means different things
1494  // for packed vs. unpacked. For unpacked, it is the current index into
1495  // the buf array.
1496  int newPos = pos + N_TIA_StepErrorControl::restartDataSize(false);
1497 
1498  // if unpacked, initialize the buf array before calling the base class
1499  // function. At this point pos is zero, probably. The derived DAE
1500  // dataSize will be the size of the entire buf array, including the
1501  // base class size.
1502  if ( !pack )
1503  {
1504  for( int i = pos; i < (newPos); ++i) buf[i] = ' ';
1505  }
1506 
1507 #ifdef Xyce_DEBUG_RESTART
1508  std::string netListFile = commandLine_.getArgumentValue("netlist");
1509  Xyce::dout() << "TIA Restart Data DUMP! " << netListFile << "\n";
1510  Xyce::dout() << Xyce::section_divider << std::endl;
1511  Xyce::dout() << "startingTimeStep: " << startingTimeStep << std::endl;
1512  Xyce::dout() << "currentTimeStep: " << currentTimeStep << std::endl;
1513  Xyce::dout() << "lastAttemptedTimeStep: " << lastAttemptedTimeStep << std::endl;
1514  Xyce::dout() << "lastTimeStep: " << lastTimeStep << std::endl;
1515  Xyce::dout() << "minTimeStep: " << minTimeStep << std::endl;
1516  Xyce::dout() << "maxTimeStep: " << maxTimeStep << std::endl;
1517  Xyce::dout() << "maxTimeStepUser: " << maxTimeStepUser << std::endl;
1518  Xyce::dout() << "lastTime: " << lastTime << std::endl;
1519  Xyce::dout() << "currentTime: " << currentTime << std::endl;
1520  Xyce::dout() << "nextTime: " << nextTime << std::endl;
1521  Xyce::dout() << "initialTime: " << initialTime << std::endl;
1522  Xyce::dout() << "estOverTol_: " << estOverTol_ << std::endl;
1523  Xyce::dout() << "breakpts: ";
1524 
1525  for (std::set<N_UTL_BreakPoint>::iterator iterSD = breakPoints_.begin();
1526  iterSD != breakPoints_.end(); ++iterSD )
1527  Xyce::dout() << iterSD->value() << " ";
1528  Xyce::dout() << std::endl;
1529  Xyce::dout() << "integMethod: " << anaManager_.getIntegrationMethod() << std::endl;
1530  Xyce::dout() << "stepNumber: " << anaManager_.getStepNumber() << std::endl;
1531  Xyce::dout() << "transStepNumber: " << anaManager_.getTranStepNumber() << std::endl;
1532  Xyce::dout() << "breakPointRestartNumber: " << anaManager_.breakPointRestartStep << std::endl;
1533  Xyce::dout() << Xyce::section_divider << std::endl << std::endl;
1534 #endif
1535  if( pack )
1536  {
1537  comm->pack( &startingTimeStep, 1, buf, bsize, pos );
1538  comm->pack( &currentTimeStep, 1, buf, bsize, pos );
1539  comm->pack( &lastAttemptedTimeStep, 1, buf, bsize, pos );
1540  comm->pack( &lastTimeStep, 1, buf, bsize, pos );
1541  comm->pack( &minTimeStep, 1, buf, bsize, pos );
1542  comm->pack( &maxTimeStep, 1, buf, bsize, pos );
1543  comm->pack( &maxTimeStepUser, 1, buf, bsize, pos );
1544  comm->pack( &lastTime, 1, buf, bsize, pos );
1545  comm->pack( &currentTime, 1, buf, bsize, pos );
1546  comm->pack( &nextTime, 1, buf, bsize, pos );
1547  comm->pack( &initialTime, 1, buf, bsize, pos );
1548  comm->pack( &currentTimeStepRatio, 1, buf, bsize, pos );
1549  comm->pack( &currentTimeStepSum, 1, buf, bsize, pos );
1550  comm->pack( &lastTimeStepRatio, 1, buf, bsize, pos );
1551  comm->pack( &lastTimeStepSum, 1, buf, bsize, pos );
1552  comm->pack( &newtonConvergenceStatus, 1, buf, bsize, pos );
1553  comm->pack( &numberSuccessiveFailures, 1, buf, bsize, pos );
1554  int flag = stepAttemptStatus;
1555  comm->pack( &flag, 1, buf, bsize, pos );
1556  comm->pack( &minStepPrecisionFac_, 1, buf, bsize, pos );
1557  comm->pack( &newtonStepReduction_, 1, buf, bsize, pos );
1558  comm->pack( &tolAimFac_, 1, buf, bsize, pos );
1559  comm->pack( &estOverTol_, 1, buf, bsize, pos );
1560  // Subtract one, because we won't write out the pause breakpoint at the
1561  // final time
1562  int size = breakPoints_.size() -1 ;
1563  std::set<N_UTL_BreakPoint>::iterator bpStart = breakPoints_.begin();
1564  std::set<N_UTL_BreakPoint>::iterator bpEnd = breakPoints_.end();
1565  comm->pack( &size, 1, buf, bsize, pos );
1566 
1567  double val;
1568  int bptype;
1569  for( std::set<N_UTL_BreakPoint>::iterator iterSD = bpStart;
1570  iterSD != bpEnd; ++iterSD)
1571  {
1572  val=iterSD->value();
1573  bptype=iterSD->bptype();
1574  if (!(bptype == Xyce::Util::PAUSE_BREAKPOINT && val == finalTime))
1575  {
1576  comm->pack( &(val), 1, buf, bsize, pos );
1577  comm->pack( &(bptype), 1, buf, bsize, pos );
1578  }
1579  }
1580  int im = anaManager_.getIntegrationMethod();
1581  comm->pack( &im, 1, buf, bsize, pos );
1582  int sN = anaManager_.getStepNumber();
1583  comm->pack( &sN, 1, buf, bsize, pos );
1584  int tSN = anaManager_.getTranStepNumber();
1585  comm->pack( &tSN, 1, buf, bsize, pos );
1586  int bPRS = anaManager_.breakPointRestartStep;
1587  comm->pack( &bPRS, 1, buf, bsize, pos );
1588  int beginFlag = (anaManager_.getBeginningIntegrationFlag())?1:0;
1589  comm->pack( &beginFlag, 1, buf, bsize, pos );
1590  }
1591  else
1592  {
1593  // count here will be the size for the base N_TIA_StepErrorControl
1594  // class *only*.
1595  int count = N_TIA_StepErrorControl::restartDataSize( false );
1596  int startIndex = pos;
1597 
1598  // Clobber any data in buf lest we leave garbage
1599  for( int i = startIndex; i < (startIndex+count); ++i) buf[i] = ' ';
1600 
1601  std::ostringstream ost;
1602  ost.width(24);ost.precision(16);ost.setf(std::ios::scientific);
1603  ost << startingTimeStep << " ";
1604  ost << currentTimeStep << " ";
1605  ost << lastAttemptedTimeStep << " ";
1606  ost << lastTimeStep << " ";
1607  ost << minTimeStep << " ";
1608  ost << maxTimeStep << " ";
1609  ost << maxTimeStepUser << " ";
1610  ost << lastTime << " ";
1611  ost << currentTime << " ";
1612  ost << nextTime << " ";
1613  ost << initialTime << " ";
1614  ost << currentTimeStepRatio << " ";
1615  ost << currentTimeStepSum << " ";
1616  ost << lastTimeStepRatio << " ";
1617  ost << lastTimeStepSum << " ";
1618  ost << newtonConvergenceStatus << " ";
1619  ost << numberSuccessiveFailures << " ";
1620  int flag = (stepAttemptStatus)?1:0;
1621  ost << flag << " ";
1622  ost << minStepPrecisionFac_ << " ";
1623  ost << newtonStepReduction_ << " ";
1624  ost << tolAimFac_ << " ";
1625  ost << estOverTol_ << " ";
1626  // Subtract one because we won't write out the pause breakpoint at the
1627  // final time
1628  int size = breakPoints_.size() - 1;
1629  ost << size << " ";
1630 
1631  std::set<N_UTL_BreakPoint>::iterator bpStart = breakPoints_.begin();
1632  std::set<N_UTL_BreakPoint>::iterator bpEnd = breakPoints_.end();
1633  for( std::set<N_UTL_BreakPoint>::iterator iterSD = bpStart;
1634  iterSD != bpEnd; ++iterSD )
1635  {
1636  if (!(iterSD->bptype() == Xyce::Util::PAUSE_BREAKPOINT &&
1637  iterSD->value() == finalTime))
1638  {
1639  ost << iterSD->value() << " ";
1640  ost << iterSD->bptype() << " ";
1641  }
1642  }
1643  int im = anaManager_.getIntegrationMethod();
1644  ost << im << " ";
1645  int sN = anaManager_.getStepNumber();
1646  ost << sN << " ";
1647  int tSN = anaManager_.getTranStepNumber();
1648  ost << tSN << " ";
1649  int bPRS = anaManager_.breakPointRestartStep;
1650  ost << bPRS << " ";
1651  int beginFlag = (anaManager_.getBeginningIntegrationFlag())?1:0;
1652  ost << beginFlag << " ";
1653 
1654  std::string data( ost.str() );
1655  for( unsigned int i = 0; i < data.length(); ++i ) buf[startIndex+i] = data[i];
1656  // The line above copies the characters of the data string into buf,
1657  // but doesn't null-terminate buf.
1658  // it is essential to terminate the buffer with a null, or attempts
1659  // to construct a string object from it will get memory access problems.
1660  buf[startIndex+data.length()] = '\0';
1661  pos += data.length();
1662 
1663 #ifdef Xyce_DEBUG_RESTART
1664  std::string outputString(buf);
1665 
1666  Xyce::dout() << "StepErrorControl UNPACKED output buffer:" << std::endl;
1667  Xyce::dout() << outputString << std::endl;
1668 #endif
1669  }
1670 
1671 #ifdef Xyce_DEBUG_RESTART
1672  Xyce::dout() << "TIA Restart Data DUMP (DAE)! " << netListFile << "\n";
1673  Xyce::dout() << Xyce::section_divider << std::endl<<std::endl;
1674  Xyce::dout() << "alphas_ = " <<alphas_<<std::endl;
1675  Xyce::dout() << "alpha0_ = " <<alpha0_<<std::endl;
1676  Xyce::dout() << "cj_ = " <<cj_<<std::endl;
1677  Xyce::dout() << "ck_ = " <<ck_<<std::endl;
1678  Xyce::dout() << "usedStep_ = " <<usedStep_<<std::endl;
1679  Xyce::dout() << "Ek_ = " <<Ek_<<std::endl;
1680  Xyce::dout() << "Ekm1_ = " <<Ekm1_<<std::endl;
1681  Xyce::dout() << "Ekm2_ = " <<Ekm2_<<std::endl;
1682  Xyce::dout() << "Ekp1_ = " <<Ekp1_<<std::endl;
1683  Xyce::dout() << "Est_ = " <<Est_<<std::endl;
1684  Xyce::dout() << "Tk_ = " <<Tk_<<std::endl;
1685  Xyce::dout() << "Tkm1_ = " <<Tkm1_<<std::endl;
1686  Xyce::dout() << "Tkm2_ = " <<Tkm2_<<std::endl;
1687  Xyce::dout() << "Tkp1_ = " <<Tkp1_<<std::endl;
1688  Xyce::dout() << "h0_safety_ = " <<h0_safety_<<std::endl;
1689  Xyce::dout() << "h0_max_factor_ = " <<h0_max_factor_<<std::endl;
1690  Xyce::dout() << "h_phase0_incr_ = " <<h_phase0_incr_<<std::endl;
1691  Xyce::dout() << "h_max_inv_ = " <<h_max_inv_<<std::endl;
1692  Xyce::dout() << "Tkm1_Tk_safety_ = " <<Tkm1_Tk_safety_<<std::endl;
1693  Xyce::dout() << "Tkp1_Tk_safety_ = " <<Tkp1_Tk_safety_<<std::endl;
1694  Xyce::dout() << "r_factor_ = " <<r_factor_<<std::endl;
1695  Xyce::dout() << "r_safety_ = " <<r_safety_<<std::endl;
1696  Xyce::dout() << "r_fudge_ = " <<r_fudge_<<std::endl;
1697  Xyce::dout() << "r_min_ = " <<r_min_<<std::endl;
1698  Xyce::dout() << "r_max_ = " <<r_max_<<std::endl;
1699  Xyce::dout() << "r_hincr_test_ = " <<r_hincr_test_<<std::endl;
1700  Xyce::dout() << "r_hincr_ = " <<r_hincr_<<std::endl;
1701 
1702  for (int i=0;i<6;++i)
1703  {
1704  Xyce::dout() << " alpha_["<<i<<"] = " << alpha_[i]<<std::endl;
1705  Xyce::dout() << " sigma_["<<i<<"] = " << sigma_[i]<<std::endl;
1706  Xyce::dout() << " gamma_["<<i<<"] = " << gamma_[i]<<std::endl;
1707  Xyce::dout() << " beta_["<<i<<"] = " << beta_[i]<<std::endl;
1708  Xyce::dout() << " psi_["<<i<<"] = " << psi_[i]<<std::endl;
1709  }
1710 
1711  Xyce::dout() << Xyce::section_divider << std::endl << std::endl << std::endl;
1712 #endif
1713 
1714  if( pack )
1715  {
1716  // doubles:
1717  comm->pack( &alphas_ , 1, buf, bsize, pos );
1718  comm->pack( &alpha0_ , 1, buf, bsize, pos );
1719  comm->pack( &cj_ , 1, buf, bsize, pos );
1720  comm->pack( &ck_ , 1, buf, bsize, pos );
1721  comm->pack( &usedStep_ , 1, buf, bsize, pos );
1722  comm->pack( &Ek_ , 1, buf, bsize, pos );
1723  comm->pack( &Ekm1_ , 1, buf, bsize, pos );
1724  comm->pack( &Ekm2_ , 1, buf, bsize, pos );
1725  comm->pack( &Ekp1_ , 1, buf, bsize, pos );
1726  comm->pack( &Est_ , 1, buf, bsize, pos );
1727  comm->pack( &Tk_ , 1, buf, bsize, pos );
1728  comm->pack( &Tkm1_ , 1, buf, bsize, pos );
1729  comm->pack( &Tkm2_ , 1, buf, bsize, pos );
1730  comm->pack( &Tkp1_ , 1, buf, bsize, pos );
1731  comm->pack( &h0_safety_ , 1, buf, bsize, pos );
1732  comm->pack( &h0_max_factor_ , 1, buf, bsize, pos );
1733  comm->pack( &h_phase0_incr_ , 1, buf, bsize, pos );
1734  comm->pack( &h_max_inv_ , 1, buf, bsize, pos );
1735  comm->pack( &Tkm1_Tk_safety_ , 1, buf, bsize, pos );
1736  comm->pack( &Tkp1_Tk_safety_ , 1, buf, bsize, pos );
1737  comm->pack( &r_factor_ , 1, buf, bsize, pos );
1738  comm->pack( &r_safety_ , 1, buf, bsize, pos );
1739  comm->pack( &r_fudge_ , 1, buf, bsize, pos );
1740  comm->pack( &r_min_ , 1, buf, bsize, pos );
1741  comm->pack( &r_max_ , 1, buf, bsize, pos );
1742  comm->pack( &r_hincr_test_ , 1, buf, bsize, pos );
1743  comm->pack( &r_hincr_ , 1, buf, bsize, pos );
1744 
1745  // vectors of doubles:
1746  for (int i=0;i<6;++i)
1747  {
1748  comm->pack( &alpha_[i], 1, buf, bsize, pos );
1749  comm->pack( &sigma_[i], 1, buf, bsize, pos );
1750  comm->pack( &gamma_[i], 1, buf, bsize, pos );
1751  comm->pack( &beta_[i], 1, buf, bsize, pos );
1752  comm->pack( &psi_[i], 1, buf, bsize, pos );
1753  }
1754 
1755  // ints:
1756  comm->pack ( &currentOrder_, 1, buf, bsize, pos);
1757  comm->pack ( &oldOrder_, 1, buf, bsize, pos);
1758  comm->pack ( &maxOrder_, 1, buf, bsize, pos);
1759  comm->pack ( &minOrder_, 1, buf, bsize, pos);
1760  comm->pack ( &usedOrder_, 1, buf, bsize, pos);
1761  comm->pack ( &numberOfSteps_, 1, buf, bsize, pos);
1762  comm->pack ( &nef_, 1, buf, bsize, pos);
1763  comm->pack ( &nscsco_, 1, buf, bsize, pos);
1764  comm->pack ( &newOrder_, 1, buf, bsize, pos);
1765  comm->pack ( &max_LET_fail_, 1, buf, bsize, pos);
1766 
1767  // bools:
1768  int iP = (initialPhase_)?1:0;
1769  comm->pack ( &iP, 1, buf, bsize, pos);
1770  }
1771  else
1772  {
1773  std::ostringstream ost;
1774  ost.width(24);ost.precision(16);ost.setf(std::ios::scientific);
1775 
1776  // doubles:
1777  ost << alphas_ << " ";
1778  ost << alpha0_ << " ";
1779  ost << cj_ << " ";
1780  ost << ck_ << " ";
1781  ost << usedStep_ << " ";
1782  ost << Ek_ << " ";
1783  ost << Ekm1_ << " ";
1784  ost << Ekm2_ << " ";
1785  ost << Ekp1_ << " ";
1786  ost << Est_ << " ";
1787  ost << Tk_ << " ";
1788  ost << Tkm1_ << " ";
1789  ost << Tkm2_ << " ";
1790  ost << Tkp1_ << " ";
1791  ost << h0_safety_ << " ";
1792  ost << h0_max_factor_ << " ";
1793  ost << h_phase0_incr_ << " ";
1794  ost << h_max_inv_ << " ";
1795  ost << Tkm1_Tk_safety_ << " ";
1796  ost << Tkp1_Tk_safety_ << " ";
1797  ost << r_factor_ << " ";
1798  ost << r_safety_ << " ";
1799  ost << r_fudge_ << " ";
1800  ost << r_min_ << " ";
1801  ost << r_max_ << " ";
1802  ost << r_hincr_test_ << " ";
1803  ost << r_hincr_ << " ";
1804 
1805  // vectors of doubles:
1806  for (int i=0;i<6;++i)
1807  {
1808  ost << alpha_[i]<< " " ;
1809  ost << sigma_[i]<< " " ;
1810  ost << gamma_[i]<< " " ;
1811  ost << beta_[i]<< " " ;
1812  ost << psi_[i]<< " " ;
1813  }
1814 
1815  // ints:
1816  ost << currentOrder_ << " ";
1817  ost << oldOrder_ << " ";
1818  ost << maxOrder_ << " ";
1819  ost << minOrder_ << " ";
1820  ost << usedOrder_ << " ";
1821  ost << numberOfSteps_ << " ";
1822  ost << nef_ << " ";
1823  ost << nscsco_ << " ";
1824  ost << newOrder_ << " ";
1825  ost << max_LET_fail_ << " ";
1826 
1827  // bools:
1828  int iP = (initialPhase_)?1:0;
1829  ost << iP << " ";
1830 
1831  std::string data( ost.str() );
1832  for( unsigned int i = 0; i < data.length(); ++i ) buf[pos+i] = data[i];
1833  // null terminate buf, essential if buf is used as a string anywhere,
1834  // including in the string constructor below:
1835  buf[pos+data.length()] = '\0';
1836 
1837 #ifdef Xyce_DEBUG_RESTART
1838  std::string outputString(buf);
1839 
1840  Xyce::dout() << "StepErrorControlDAE UNPACKED output buffer:" << std::endl;
1841  Xyce::dout() << outputString << std::endl;
1842 #endif
1843  pos = newPos;
1844  }
1845 
1846  return true;
1847 }
1848 
1849 //-----------------------------------------------------------------------------
1850 // Function : N_TIA_StepErrorControl::restoreRestartData
1851 // Purpose :
1852 // Special Notes : ERK: 6/20/2010:
1853 // There are no longer 2 distinct classes. The DAE version is
1854 // now part of the original, as one single class. The two
1855 // blocks of code in this function correspond to the original
1856 // class (first block), and the DAE class (second block).
1857 //
1858 // Scope : public
1859 // Creator : Eric R. Keiter, SNL
1860 // Creation Date : 7/28/06
1861 //-----------------------------------------------------------------------------
1863  (char * buf, int bsize, int & pos, N_PDS_Comm * comm, bool pack)
1864 {
1865 
1866  // original class variables:
1867  if( pack )
1868  {
1869  comm->unpack(buf, bsize, pos, &startingTimeStep, 1);
1870  comm->unpack(buf, bsize, pos, &currentTimeStep, 1);
1871  comm->unpack(buf, bsize, pos, &lastAttemptedTimeStep, 1);
1872  comm->unpack(buf, bsize, pos, &lastTimeStep, 1);
1873  comm->unpack(buf, bsize, pos, &minTimeStep, 1);
1874  comm->unpack(buf, bsize, pos, &maxTimeStep, 1);
1875  comm->unpack(buf, bsize, pos, &maxTimeStepUser, 1);
1876  comm->unpack(buf, bsize, pos, &lastTime, 1);
1877  comm->unpack(buf, bsize, pos, &currentTime, 1);
1878  comm->unpack(buf, bsize, pos, &nextTime, 1);
1879  comm->unpack(buf, bsize, pos, &initialTime, 1);
1880  comm->unpack(buf, bsize, pos, &currentTimeStepRatio, 1);
1881  comm->unpack(buf, bsize, pos, &currentTimeStepSum, 1);
1882  comm->unpack(buf, bsize, pos, &lastTimeStepRatio, 1);
1883  comm->unpack(buf, bsize, pos, &lastTimeStepSum, 1);
1884  comm->unpack(buf, bsize, pos, &newtonConvergenceStatus, 1);
1885  comm->unpack(buf, bsize, pos, &numberSuccessiveFailures, 1);
1886  int flag;
1887  comm->unpack(buf, bsize, pos, &flag, 1);
1888  stepAttemptStatus = flag;
1889  comm->unpack(buf, bsize, pos, &minStepPrecisionFac_, 1);
1890  comm->unpack(buf, bsize, pos, &newtonStepReduction_, 1);
1891  comm->unpack(buf, bsize, pos, &tolAimFac_, 1);
1892  comm->unpack(buf, bsize, pos, &estOverTol_, 1);
1893 
1894  double bpTol = 2.0 * minTimeStep;
1895  anaManager_.setBreakpointTol(bpTol);
1896  tiaParams_.initialTime=initialTime;
1897  tiaParams_.pauseTime=initialTime;
1898  std::set<N_UTL_BreakPoint> tmpSet = breakPoints_;
1899  breakPoints_.clear();
1900  std::set<N_UTL_BreakPoint>::iterator iterSD;
1901  std::set<N_UTL_BreakPoint>::iterator firstSD = tmpSet.begin();
1902  std::set<N_UTL_BreakPoint>::iterator lastSD = tmpSet.end();
1903  for (iterSD = firstSD; iterSD != lastSD; ++iterSD)
1904  {
1905  if (iterSD->value() > currentTime)
1906  {
1907  breakPoints_.insert(*iterSD);
1908  if (iterSD->bptype() == Xyce::Util::PAUSE_BREAKPOINT)
1909  updatePauseTime(*iterSD);
1910  }
1911  }
1912 
1913  int size;
1914  double val;
1915  int bptype;
1916  N_UTL_BreakPoint TmpBP;
1917  comm->unpack(buf, bsize, pos, &size, 1);
1918 
1919  for (int i = 0; i < size; ++i)
1920  {
1921  comm->unpack(buf, bsize, pos, &val, 1);
1922  comm->unpack(buf, bsize, pos, &bptype, 1);
1923  if (val > currentTime)
1924  {
1925  TmpBP.set(val,bptype);
1926  breakPoints_.insert(TmpBP);
1927  if (TmpBP.bptype() == Xyce::Util::PAUSE_BREAKPOINT)
1928  {
1929  updatePauseTime(TmpBP);
1930  }
1931  }
1932  }
1933 
1934  int im;
1935  comm->unpack(buf, bsize, pos, &im, 1);
1936  anaManager_.setIntegrationMethod(im);
1937  comm->unpack(buf, bsize, pos, &im, 1);
1938  anaManager_.setStepNumber(im);
1939  comm->unpack(buf, bsize, pos, &im, 1);
1940  anaManager_.setTranStepNumber(im);
1941  comm->unpack(buf, bsize, pos, &im, 1);
1942  anaManager_.breakPointRestartStep = im;
1943  comm->unpack(buf, bsize, pos, &im, 1);
1944  anaManager_.setBeginningIntegrationFlag(im==1);
1945  }
1946  else
1947  {
1948  std::string str1(buf);
1949  int length = str1.size() - pos;
1950  std::string str2(str1,pos,length);
1951 
1952  std::istringstream ist( str2 );
1953 
1954  // count here will be the size for the base N_TIA_StepErrorControl
1955  // class *only*.
1956 
1957  // THIS IS INCORRECT! restartDataSize returns the MAXIMUM the thing
1958  // is allowed to be, which allows for 24 characters for each integer
1959  // value in the output. This is almost always an overestimate, and
1960  // using it as a way of pointing to the next character after our
1961  // data is a sure-fire way to break downstream processing!
1962  // Instead, we'll use the tellg function from the stringstream to
1963  // return the offset after we read everything out.
1964  // int count = N_TIA_StepErrorControl::restartDataSize( false );
1965  // pos += count;
1966 
1967  ist >> startingTimeStep;
1968  ist >> currentTimeStep;
1969  ist >> lastAttemptedTimeStep;
1970  ist >> lastTimeStep;
1971  ist >> minTimeStep;
1972  ist >> maxTimeStep;
1973  ist >> maxTimeStepUser;
1974  ist >> lastTime;
1975  ist >> currentTime;
1976  ist >> nextTime;
1977  ist >> initialTime;
1978  ist >> currentTimeStepRatio;
1979  ist >> currentTimeStepSum;
1980  ist >> lastTimeStepRatio;
1981  ist >> lastTimeStepSum;
1982  ist >> newtonConvergenceStatus;
1983  ist >> numberSuccessiveFailures;
1984  int flag;
1985  ist >> flag;
1986  stepAttemptStatus = flag;
1987  ist >> minStepPrecisionFac_;
1988  ist >> newtonStepReduction_;
1989  ist >> tolAimFac_;
1990  ist >> estOverTol_;
1991 
1992  double bpTol = 2.0 * minTimeStep;
1993  anaManager_.setBreakpointTol(bpTol);
1994  tiaParams_.initialTime=initialTime;
1995  tiaParams_.pauseTime=initialTime;
1996 
1997  std::set<N_UTL_BreakPoint> tmpSet = breakPoints_;
1998  breakPoints_.clear();
1999  std::set<N_UTL_BreakPoint>::iterator iterSD;
2000  std::set<N_UTL_BreakPoint>::iterator firstSD = tmpSet.begin();
2001  std::set<N_UTL_BreakPoint>::iterator lastSD = tmpSet.end();
2002  for (iterSD = firstSD; iterSD != lastSD; ++iterSD)
2003  {
2004  if (iterSD->value() > currentTime)
2005  {
2006  breakPoints_.insert(*iterSD);
2007  if (iterSD->bptype() == Xyce::Util::PAUSE_BREAKPOINT)
2008  updatePauseTime(*iterSD);
2009  }
2010  }
2011 
2012  int size;
2013  double val;
2014  int bptype;
2015  N_UTL_BreakPoint TmpBP;
2016  ist >> size;
2017 
2018  for( int i = 0; i < size; ++i )
2019  {
2020  ist >> val;
2021  ist >> bptype;
2022  if (val > currentTime)
2023  {
2024  TmpBP.set(val,bptype);
2025  breakPoints_.insert( TmpBP );
2026  if (TmpBP.bptype() == Xyce::Util::PAUSE_BREAKPOINT)
2027  {
2028  updatePauseTime(TmpBP);
2029  }
2030  }
2031  }
2032 
2033  int tmpInt;
2034  ist >> tmpInt;
2035  anaManager_.setIntegrationMethod(tmpInt);
2036  ist >> tmpInt;
2037  anaManager_.setStepNumber(tmpInt);
2038  ist >> tmpInt;
2039  anaManager_.setTranStepNumber(tmpInt);
2040  ist >> tmpInt;
2041  anaManager_.breakPointRestartStep = tmpInt;
2042  ist >> tmpInt;
2043  anaManager_.setBeginningIntegrationFlag(tmpInt==1);
2044 
2045  pos += ist.tellg();
2046  }
2047 
2048 #ifdef Xyce_DEBUG_RESTART
2049  std::string netListFile = commandLine_.getArgumentValue("netlist");
2050  Xyce::dout() << "TIA Restart Data RESTORE! " << netListFile << "\n";
2051  Xyce::dout() << Xyce::section_divider << std::endl;
2052  Xyce::dout() << "startingTimeStep: " << startingTimeStep << std::endl;
2053  Xyce::dout() << "currentTimeStep: " << currentTimeStep << std::endl;
2054  Xyce::dout() << "lastAttemptedTimeStep: " << lastAttemptedTimeStep << std::endl;
2055  Xyce::dout() << "lastTimeStep: " << lastTimeStep << std::endl;
2056  Xyce::dout() << "minTimeStep: " << minTimeStep << std::endl;
2057  Xyce::dout() << "maxTimeStep: " << maxTimeStep << std::endl;
2058  Xyce::dout() << "maxTimeStepUser: " << maxTimeStepUser << std::endl;
2059  Xyce::dout() << "lastTime: " << lastTime << std::endl;
2060  Xyce::dout() << "currentTime: " << currentTime << std::endl;
2061  Xyce::dout() << "nextTime: " << nextTime << std::endl;
2062  Xyce::dout() << "initialTime: " << initialTime << std::endl;
2063  Xyce::dout() << "estOverTol_: " << estOverTol_ << std::endl;
2064  Xyce::dout() << "breakpts: ";
2065  for (std::set<N_UTL_BreakPoint>::iterator iterSD = breakPoints_.begin();
2066  iterSD != breakPoints_.end(); ++iterSD)
2067  {
2068  Xyce::dout() << iterSD->value() << " " << iterSD->bptype() << std::endl;
2069  }
2070  Xyce::dout() << std::endl;
2071  Xyce::dout() << "integMethod: " << anaManager_.getIntegrationMethod() << std::endl;
2072  Xyce::dout() << "stepNumber: " << anaManager_.getStepNumber() << std::endl;
2073  Xyce::dout() << "tranStepNumber: " << anaManager_.getTranStepNumber() << std::endl;
2074  Xyce::dout() << "breakPointRestartStep: " << anaManager_.breakPointRestartStep <<
2075  std::endl;
2076  Xyce::dout() << Xyce::section_divider << std::endl << std::endl;
2077 #endif
2078 
2079  // DAE class variables:
2080  if( pack )
2081  {
2082  // doubles:
2083  comm->unpack(buf, bsize, pos, &alphas_ , 1);
2084  comm->unpack(buf, bsize, pos, &alpha0_ , 1);
2085  comm->unpack(buf, bsize, pos, &cj_ , 1);
2086  comm->unpack(buf, bsize, pos, &ck_ , 1);
2087  comm->unpack(buf, bsize, pos, &usedStep_ , 1);
2088  comm->unpack(buf, bsize, pos, &Ek_ , 1);
2089  comm->unpack(buf, bsize, pos, &Ekm1_ , 1);
2090  comm->unpack(buf, bsize, pos, &Ekm2_ , 1);
2091  comm->unpack(buf, bsize, pos, &Ekp1_ , 1);
2092  comm->unpack(buf, bsize, pos, &Est_ , 1);
2093  comm->unpack(buf, bsize, pos, &Tk_ , 1);
2094  comm->unpack(buf, bsize, pos, &Tkm1_ , 1);
2095  comm->unpack(buf, bsize, pos, &Tkm2_ , 1);
2096  comm->unpack(buf, bsize, pos, &Tkp1_ , 1);
2097  comm->unpack(buf, bsize, pos, &h0_safety_ , 1);
2098  comm->unpack(buf, bsize, pos, &h0_max_factor_ , 1);
2099  comm->unpack(buf, bsize, pos, &h_phase0_incr_ , 1);
2100  comm->unpack(buf, bsize, pos, &h_max_inv_ , 1);
2101  comm->unpack(buf, bsize, pos, &Tkm1_Tk_safety_ , 1);
2102  comm->unpack(buf, bsize, pos, &Tkp1_Tk_safety_ , 1);
2103  comm->unpack(buf, bsize, pos, &r_factor_ , 1);
2104  comm->unpack(buf, bsize, pos, &r_safety_ , 1);
2105  comm->unpack(buf, bsize, pos, &r_fudge_ , 1);
2106  comm->unpack(buf, bsize, pos, &r_min_ , 1);
2107  comm->unpack(buf, bsize, pos, &r_max_ , 1);
2108  comm->unpack(buf, bsize, pos, &r_hincr_test_ , 1);
2109  comm->unpack(buf, bsize, pos, &r_hincr_ , 1);
2110 
2111  // vectors of doubles:
2112  for (int i=0;i<6;++i)
2113  {
2114  comm->unpack(buf, bsize, pos, &alpha_[i], 1);
2115  comm->unpack(buf, bsize, pos, &sigma_[i], 1);
2116  comm->unpack(buf, bsize, pos, &gamma_[i], 1);
2117  comm->unpack(buf, bsize, pos, &beta_[i], 1);
2118  comm->unpack(buf, bsize, pos, &psi_[i], 1);
2119  }
2120 
2121  // ints:
2122  comm->unpack(buf, bsize, pos, &currentOrder_, 1);
2123  comm->unpack(buf, bsize, pos, &oldOrder_, 1);
2124  comm->unpack(buf, bsize, pos, &maxOrder_, 1);
2125  comm->unpack(buf, bsize, pos, &minOrder_, 1);
2126  comm->unpack(buf, bsize, pos, &usedOrder_, 1);
2127  comm->unpack(buf, bsize, pos, &numberOfSteps_, 1);
2128  comm->unpack(buf, bsize, pos, &nef_, 1);
2129  comm->unpack(buf, bsize, pos, &nscsco_, 1);
2130  comm->unpack(buf, bsize, pos, &newOrder_, 1);
2131  comm->unpack(buf, bsize, pos, &max_LET_fail_, 1);
2132 
2133  // bools:
2134  int iP;
2135  comm->unpack (buf, bsize, pos, &iP, 1);
2136  if (iP == 0) initialPhase_ = false;
2137  else initialPhase_ = true;
2138  }
2139  else
2140  {
2141  // want the string stream to only represent the new-DAE part of
2142  // the buf array.
2143  std::string str1(buf);
2144  int length = str1.size() - pos;
2145  std::string str2(str1,pos,length);
2146 
2147  std::istringstream ist( str2 );
2148 
2149  int count = N_TIA_StepErrorControl::restartDataSize(false);
2150  pos = count; // can update here, as pos isn't used after this.
2151 
2152  // doubles:
2153  ist >> alphas_;
2154  ist >> alpha0_;
2155  ist >> cj_;
2156  ist >> ck_;
2157  ist >> usedStep_;
2158  ist >> Ek_;
2159  ist >> Ekm1_;
2160  ist >> Ekm2_;
2161  ist >> Ekp1_;
2162  ist >> Est_;
2163  ist >> Tk_;
2164  ist >> Tkm1_;
2165  ist >> Tkm2_;
2166  ist >> Tkp1_;
2167  ist >> h0_safety_;
2168  ist >> h0_max_factor_;
2169  ist >> h_phase0_incr_;
2170  ist >> h_max_inv_;
2171  ist >> Tkm1_Tk_safety_;
2172  ist >> Tkp1_Tk_safety_;
2173  ist >> r_factor_;
2174  ist >> r_safety_;
2175  ist >> r_fudge_;
2176  ist >> r_min_;
2177  ist >> r_max_;
2178  ist >> r_hincr_test_;
2179  ist >> r_hincr_;
2180 
2181  // vectors of doubles:
2182  for (int i=0;i<6;++i)
2183  {
2184  ist >> alpha_[i];
2185  ist >> sigma_[i];
2186  ist >> gamma_[i];
2187  ist >> beta_[i];
2188  ist >> psi_[i];
2189  }
2190 
2191  // ints:
2192  ist >> currentOrder_;
2193  ist >> oldOrder_;
2194  ist >> maxOrder_;
2195  ist >> minOrder_;
2196  ist >> usedOrder_;
2197  ist >> numberOfSteps_;
2198  ist >> nef_;
2199  ist >> nscsco_;
2200  ist >> newOrder_;
2201  ist >> max_LET_fail_;
2202 
2203  // bools:
2204  int iP;
2205  ist >> iP;
2206  if (iP == 0) initialPhase_ = false;
2207  else initialPhase_ = true;
2208  }
2209 
2210 #ifdef Xyce_DEBUG_RESTART
2211  Xyce::dout() << "TIA Restart Data RESTORE (DAE)! " << netListFile << "\n";
2212  Xyce::dout() << Xyce::section_divider << std::endl<<std::endl;
2213  Xyce::dout() << "alphas_ = " <<alphas_<<std::endl;
2214  Xyce::dout() << "alpha0_ = " <<alpha0_<<std::endl;
2215  Xyce::dout() << "cj_ = " <<cj_<<std::endl;
2216  Xyce::dout() << "ck_ = " <<ck_<<std::endl;
2217  Xyce::dout() << "usedStep_ = " <<usedStep_<<std::endl;
2218  Xyce::dout() << "Ek_ = " <<Ek_<<std::endl;
2219  Xyce::dout() << "Ekm1_ = " <<Ekm1_<<std::endl;
2220  Xyce::dout() << "Ekm2_ = " <<Ekm2_<<std::endl;
2221  Xyce::dout() << "Ekp1_ = " <<Ekp1_<<std::endl;
2222  Xyce::dout() << "Est_ = " <<Est_<<std::endl;
2223  Xyce::dout() << "Tk_ = " <<Tk_<<std::endl;
2224  Xyce::dout() << "Tkm1_ = " <<Tkm1_<<std::endl;
2225  Xyce::dout() << "Tkm2_ = " <<Tkm2_<<std::endl;
2226  Xyce::dout() << "Tkp1_ = " <<Tkp1_<<std::endl;
2227  Xyce::dout() << "h0_safety_ = " <<h0_safety_<<std::endl;
2228  Xyce::dout() << "h0_max_factor_ = " <<h0_max_factor_<<std::endl;
2229  Xyce::dout() << "h_phase0_incr_ = " <<h_phase0_incr_<<std::endl;
2230  Xyce::dout() << "h_max_inv_ = " <<h_max_inv_<<std::endl;
2231  Xyce::dout() << "Tkm1_Tk_safety_ = " <<Tkm1_Tk_safety_<<std::endl;
2232  Xyce::dout() << "Tkp1_Tk_safety_ = " <<Tkp1_Tk_safety_<<std::endl;
2233  Xyce::dout() << "r_factor_ = " <<r_factor_<<std::endl;
2234  Xyce::dout() << "r_safety_ = " <<r_safety_<<std::endl;
2235  Xyce::dout() << "r_fudge_ = " <<r_fudge_<<std::endl;
2236  Xyce::dout() << "r_min_ = " <<r_min_<<std::endl;
2237  Xyce::dout() << "r_max_ = " <<r_max_<<std::endl;
2238  Xyce::dout() << "r_hincr_test_ = " <<r_hincr_test_<<std::endl;
2239  Xyce::dout() << "r_hincr_ = " <<r_hincr_<<std::endl;
2240 
2241  for (int i=0;i<6;++i)
2242  {
2243  Xyce::dout() << " alpha_["<<i<<"] = " << alpha_[i]<<std::endl;
2244  Xyce::dout() << " sigma_["<<i<<"] = " << sigma_[i]<<std::endl;
2245  Xyce::dout() << " gamma_["<<i<<"] = " << gamma_[i]<<std::endl;
2246  Xyce::dout() << " beta_["<<i<<"] = " << beta_[i]<<std::endl;
2247  Xyce::dout() << " psi_["<<i<<"] = " << psi_[i]<<std::endl;
2248  }
2249 
2250  Xyce::dout() << Xyce::section_divider << std::endl << std::endl << std::endl;
2251 #endif
2252 
2253  return true;
2254 }
2255 
2256 //-----------------------------------------------------------------------------
2257 // Function : N_TIA_StepErrorControl::updateTwoLevelTimeInfo
2258 // Purpose :
2259 // Special Notes :
2260 // Scope : public
2261 // Creator : Eric Keiter, SNL, Parallel ComputationalSciences.
2262 // Creation Date : 3/14/06
2263 //-----------------------------------------------------------------------------
2265 {
2266  updateStopTime();
2267 
2268  // Need to get this right.
2269  if (previousCallStepSuccessful == true)
2270  {
2275  }
2276 
2277  // If the step needs to be adjusted:
2279  double newTimeStep = tiInfo.nextTimeStep;
2280  nextTime = tiInfo.nextTime;
2281  currentTimeStepRatio = newTimeStep/lastTimeStep;
2282  currentTimeStepSum = newTimeStep + lastTimeStep;
2283  currentTimeStep = newTimeStep;
2284  currentOrder_ = tiInfo.currentOrder;
2285 }
2286 
2287 //-----------------------------------------------------------------------------
2288 // Function : N_TIA_StepErrorControl::outputTimeInfo
2289 // Purpose :
2290 // Special Notes :
2291 // Scope : public
2292 // Creator : Todd Coffey, 1414
2293 // Creation Date : 03/04/08
2294 //-----------------------------------------------------------------------------
2295 
2297 {
2298  {
2299  Xyce::ios_flags_saver flagsave(os);
2300 
2301  os << " " << (Xyce::DEBUG_TIME ? commandLine_.getArgumentValue("netlist") : " ") << " "
2302  << "Current,Next,Step: "
2303  << std::setw(Xyce::DEBUG_TIME ? 14 : 16) << std::setprecision(Xyce::DEBUG_TIME ? 7 : 9)
2304  << currentTime << ", " << nextTime << ", " << currentTimeStep;
2305  }
2306 
2307  os << " ("<<numberOfSteps_<<") Used, Next Order: " << usedOrder_ << ", " << currentOrder_;
2308 }
2309 
2310 //-----------------------------------------------------------------------------
2311 // Function : operator<<
2312 // Purpose : "<<" operator for step error control class.
2313 // Special Notes :
2314 // Scope : public
2315 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
2316 // Creation Date : 10/17/05
2317 //-----------------------------------------------------------------------------
2318 std::ostream & operator<<(std::ostream & os, const N_TIA_StepErrorControl & sec)
2319 {
2320  os << "\n\n-----------------------------------------" << std::endl
2321  << "\tStepErrorControl:\n"
2322  << "\t\tstartingTimeStep = " << sec.startingTimeStep << std::endl
2323  << "\t\tcurrentTimeStep = " << sec.currentTimeStep << std::endl
2324  << "\t\tlastAttemptedTimeStep = " << sec.lastAttemptedTimeStep << std::endl
2325  << "\t\tlastTimeStep = " << sec.lastTimeStep << std::endl
2326  << "\t\tminTimeStep = " << sec.minTimeStep << std::endl
2327  << "\t\tmaxTimeStep = " << sec.maxTimeStep << std::endl
2328  << "\t\tmaxTimeStepUser = " << sec.maxTimeStepUser << std::endl
2329  << "\t\tlastTime = " << sec.lastTime << std::endl
2330  << "\t\tcurrentTime = " << sec.currentTime << std::endl
2331  << "\t\tnextTime = " << sec.nextTime << std::endl
2332  << "\t\tstopTime = " << sec.stopTime << std::endl
2333  << "\t\tinitialTime = " << sec.initialTime << std::endl
2334  << "\t\tfinalTime = " << sec.finalTime << std::endl
2335  << std::endl
2336  << "\t\tBreak Points:" << std::endl;
2337 
2338  sec.printBreakPoints (os);
2339 
2340 
2341  os << Xyce::section_divider << std::endl;
2342  os << std::endl;
2343 
2344  return os;
2345 }
2346