Xyce  6.1
N_TIA_Gear12.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2015 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-----------------------------------------------------------------------------
26 // Filename : $RCSfile: N_TIA_Gear12.C,v $
27 //
28 // Purpose : This file contains the functions which define the
29 // backward differentiation, order 1-2, class.
30 //
31 // Special Notes :
32 //
33 // Creator : Ting Mei
34 //
35 // Creation Date : 2/16/04
36 //
37 // Revision Information:
38 // ---------------------
39 //
40 // Revision Number: $Revision: 1.58.2.1 $
41 //
42 // Revision Date : $Date: 2015/04/02 18:20:18 $
43 //
44 // Current Owner : $Author: tvrusso $
45 //-----------------------------------------------------------------------------
46 
47 #include <Xyce_config.h>
48 
49 // ---------- Standard Includes ----------
50 #include <iostream>
51 
52 // ---------- Xyce Includes ----------
53 #include <N_ANP_OutputMgrAdapter.h>
54 #include <N_ERH_ErrorMgr.h>
55 #include <N_LAS_BlockVector.h>
56 #include <N_LAS_Matrix.h>
57 #include <N_LAS_System.h>
58 #include <N_LAS_Vector.h>
59 #include <N_PDS_Comm.h>
60 #include <N_PDS_Manager.h>
61 #include <N_TIA_DataStore.h>
62 #include <N_TIA_Gear12.h>
63 #include <N_TIA_StepErrorControl.h>
64 #include <N_TIA_TIAParams.h>
66 #include <N_UTL_Diagnostic.h>
67 #include <N_UTL_FeatureTest.h>
68 #include <N_UTL_MachDepParams.h>
69 
70 using std::abs;
71 
72 namespace Xyce {
73 namespace TimeIntg {
74 
75 const char *
76 Gear12::name = "Gear 12";
77 
78 //-----------------------------------------------------------------------------
79 // Function : Gear12::factory
80 // Purpose :
81 // Special Notes :
82 // Scope : public
83 // Creator : Ting Mei, SNL
84 // Creation Date : 10/31/07
85 //-----------------------------------------------------------------------------
86 TimeIntegrationMethod *
88  const TIAParams & tia_params,
89  StepErrorControl & step_error_control,
90  DataStore & data_store)
91 {
92  return new Gear12(tia_params, step_error_control, data_store);
93 }
94 
95 //-----------------------------------------------------------------------------
96 // Function : Gear::Gear
97 // Purpose : constructor
98 // Special Notes :
99 // Scope : public
100 // Creator : Ting Mei, SNL
101 // Creation Date : 10/10/12
102 //-----------------------------------------------------------------------------
104  const TIAParams & tia_params,
105  StepErrorControl & secTmp,
106  DataStore & dsTmp)
108  leadingCoeff(1.0),
109  sec(secTmp),
110  ds(dsTmp)
111 {
112  leadingCoeff = 1;
113  sec.maxOrder_=(std::min(2,tia_params.maxOrder));
114  sec.minOrder_=(std::max(1,tia_params.minOrder));
115 
116  if (sec.minOrder_ > sec.maxOrder_)
117  {
119  }
120  // sec.maxOrder_ = 2;
121  timept_ = -1.0;
122 }
123 
124 //-----------------------------------------------------------------------------
125 // Function : Gear12::obtainPredictor
126 // Purpose : Calculate predictor
127 // Special Notes : stored in ds.xn0Ptr,qn0Ptr,qpn0Ptr
128 // Scope : public
129 // Creator : Ting Mei, SNL
130 // Creation Date : 10/10/12
131 //-----------------------------------------------------------------------------
133 {
134  // evaluate predictor
135  *ds.sn0Ptr = *(ds.sHistory[0]);
136  ds.xn0Ptr->putScalar(0.0);
137  ds.qn0Ptr->putScalar(0.0);
140 
141  ds.spn0Ptr->putScalar(0.0);
142  for (int i=0;i<=sec.currentOrder_;++i)
143  {
144  ds.xn0Ptr->linearCombo(sec.beta_[i],*(ds.xHistory[i]),1.0,*ds.xn0Ptr);
145  ds.qn0Ptr->linearCombo(sec.beta_[i],*(ds.qHistory[i]),1.0,*ds.qn0Ptr);
146  }
147 
148  if (DEBUG_TIME && isActive(Diag::TIME_PREDICTOR))
149  {
150  Xyce::dout().width(21); Xyce::dout().precision(13); Xyce::dout().setf(std::ios::scientific);
151  Xyce::dout() << std::endl
152  << Xyce::section_divider << std::endl
153  << " Gear12::obtainPredictor" << std::endl
154  << "\n currentOrder = " << sec.currentOrder_ << std::endl
155  << "\n sec.nscsco_: " << sec.nscsco_ << std::endl;
156  for (int i=0; i<=sec.currentOrder_ ; ++i)
157  Xyce::dout() << "\n sec.beta_[" << i << "] = " << sec.beta_[i] << "\n" << std::endl;
158  for (int i=0; i<=sec.currentOrder_ ; ++i)
159  {
160  Xyce::dout() << "\n xHistory["<< i << "]: \n" << std::endl;
161  (ds.xHistory[i])->printPetraObject(Xyce::dout());
162  Xyce::dout() << std::endl;
163  }
164  for (int i=0; i<=sec.currentOrder_ ; ++i)
165  {
166  Xyce::dout() << "\n qHistory["<< i << "]: \n" << std::endl;
167  (ds.qHistory[i])->printPetraObject(Xyce::dout());
168  Xyce::dout() << std::endl;
169  }
170  for (int i=0; i<=sec.currentOrder_ ; ++i)
171  {
172  Xyce::dout() << "\n sHistory["<< i << "]: \n" << std::endl;
173  (ds.sHistory[i])->printPetraObject(Xyce::dout());
174  Xyce::dout() << std::endl;
175  }
176  Xyce::dout() << "\n xn0: \n" << std::endl;
177  ds.xn0Ptr->printPetraObject(Xyce::dout());
178  Xyce::dout() << std::endl;
179  Xyce::dout() << "\n qn0: \n" << std::endl;
180  ds.qn0Ptr->printPetraObject(Xyce::dout());
181  Xyce::dout() << std::endl;
182  Xyce::dout() << "\n qpn0: \n" << std::endl;
183  ds.qpn0Ptr->printPetraObject(Xyce::dout());
184  Xyce::dout() << std::endl;
185  Xyce::dout() << "\n sn0: \n" << std::endl;
186  ds.sn0Ptr->printPetraObject(Xyce::dout());
187  Xyce::dout() << std::endl;
188  Xyce::dout() << "\n spn0: \n" << std::endl;
189  ds.spn0Ptr->printPetraObject(Xyce::dout());
190  Xyce::dout() << std::endl;
191  Xyce::dout() << Xyce::section_divider << std::endl;
192  }
193 
194  // copy the prediction into the next solution:
195  *(ds.nextSolutionPtr) = *(ds.xn0Ptr);
196 
198 
199  return;
200 }
201 
202 //-----------------------------------------------------------------------------
203 // Function : Gear12::obtainSensitivityPredictors
204 // Purpose : Calculate predictor
205 // Special Notes :
206 // Scope : public
207 // Creator : Eric Keiter, SNL
208 // Creation Date :
209 //-----------------------------------------------------------------------------
211 {}
212 
213  // Computes the step addjustment.
214  // 2/16/04 tscoffe: I'm not exactly sure what this routine is for...
215 double
217  double stepadjust)
218 {
219  return pow(stepadjust, 1.0 / 3.0);
220 }
221 
222 //-----------------------------------------------------------------------------
223 // Function : Gear12::obtainResidual
224 // Purpose : Calculate Residual
225 // Special Notes :
226 // Scope : public
227 // Creator : Ting Mei, SNL
228 // Creation Date : 11/16/07
229 //-----------------------------------------------------------------------------
231 {
232  // output: ds.RHSVectorPtr
233  // Note: ds.nextSolutionPtr is used to get Q,F,B in Analysis::AnalysisManager::loadRHS.
234  ds.RHSVectorPtr->linearCombo(sec.alpha_[0],*ds.daeQVectorPtr, sec.alpha_[1],*(ds.qHistory[0]) );
235 
236  if (DEBUG_TIME && isActive(Diag::TIME_RESIDUAL))
237  {
238  Xyce::dout() << std::endl
239  << Xyce::section_divider << std::endl
240  << " Gear12::obtainResidual" << std::endl
241  << "\n t = " << sec.nextTime << "\n" << std::endl
242  << "\n solution: \n" << std::endl;
243  ds.nextSolutionPtr->printPetraObject(Xyce::dout());
244  Xyce::dout() << "\n daeQVector: \n" << std::endl;
245  ds.daeQVectorPtr->printPetraObject(Xyce::dout());
246  Xyce::dout() << "\n qn0: \n" << std::endl;
247  ds.qn0Ptr->printPetraObject(Xyce::dout());
248  Xyce::dout() << "\n qpn0: \n" << std::endl;
249  ds.qpn0Ptr->printPetraObject(Xyce::dout());
250  Xyce::dout() << "\n sec.alphas_/hn: " << sec.alphas_/sec.currentTimeStep << "\n" << std::endl
251  << "\n daeFVector: \n" << std::endl;
252  ds.daeFVectorPtr->printPetraObject(Xyce::dout());
253 
254  Xyce::dout() << "\n dQdt-vector: \n" << std::endl;
255  ds.RHSVectorPtr->printPetraObject(Xyce::dout());
256  Xyce::dout() << std::endl;
257  }
258 
259  if (sec.currentOrder_ == 2)
260  {
261  ds.RHSVectorPtr->linearCombo(1.0, *ds.RHSVectorPtr, sec.alpha_[2],*(ds.qHistory[1]));
262  }
263 
265  ds.RHSVectorPtr->linearCombo(1.0,*ds.RHSVectorPtr,-1.0,*ds.daeBVectorPtr);
266 
267  // since the nonlinear solver is expecting a -f, scale by -1.0:
268  ds.RHSVectorPtr->scale(-1.0);
269 
270  // if voltage limiting is on, add it in:
271  if (ds.limiterFlag)
272  {
274  // double qscalar(sec.alpha_[0]/sec.currentTimeStep);
275 
276  (ds.RHSVectorPtr)->daxpy(
277  *(ds.RHSVectorPtr), +1.0, *(ds.dQdxdVpVectorPtr));
278 
279  (ds.RHSVectorPtr)->daxpy(
280  *(ds.RHSVectorPtr), +1.0, *(ds.dFdxdVpVectorPtr));
281  }
282 
283  if (DEBUG_TIME && isActive(Diag::TIME_RESIDUAL))
284  {
285  Xyce::dout() << "\n Residual-vector: \n" << std::endl
286  << "-(qpn0-(sec.alpha_s/h)*(Q-qn0)+F-B) \n" << std::endl;
287  ds.RHSVectorPtr->printPetraObject(Xyce::dout());
288  Xyce::dout() << Xyce::section_divider << std::endl
289  << std::endl;
290  }
291 }
292 
293 //-----------------------------------------------------------------------------
294 // Function : Gear12::obtainSensitivityResiduals
295 // Purpose : Calculate sensitivity residual
296 // Special Notes :
297 // Scope : public
298 // Creator : Eric Keiter
299 // Creation Date :
300 //-----------------------------------------------------------------------------
302 {
303  int numParams = ds.sensRHSPtrVector.size();
304  for (int ip=0; ip<numParams;++ip)
305  {
306  Linear::Vector & RHSVec = *(ds.sensRHSPtrVector[ip]);
307  Linear::Vector & dfdpVec = *(ds.nextDfdpPtrVector[ip]);
308  Linear::Vector & dqdpVec = *(ds.nextDqdpPtrVector[ip]);
309  Linear::Vector & dbdpVec = *(ds.nextDbdpPtrVector[ip]);
310 
311  Linear::Vector & currDXdpVec = *(ds.currDXdpPtrVector[ip]);
312  Linear::Vector & lastDXdpVec = *(ds.lastDXdpPtrVector[ip]);
313 
314  std::vector<Linear::Vector*> & dqdpHistoryVec = ds.dqdpHistory[ip];
315 
316  Linear::Vector & currDQdxDXdpVec = *(ds.currDQdxDXdpPtrVector[ip]);
317  Linear::Vector & lastDQdxDXdpVec = *(ds.lastDQdxDXdpPtrVector[ip]);
318 
319  RHSVec.linearCombo(sec.alpha_[0],dqdpVec, sec.alpha_[1],*(dqdpHistoryVec[0]) );
320 
321  if (sec.currentOrder_ == 2)
322  {
323  RHSVec.linearCombo(1.0, RHSVec, sec.alpha_[2],*(dqdpHistoryVec[1]));
324  }
325 
326  RHSVec.linearCombo(1.0/sec.currentTimeStep,RHSVec,+1.0,dfdpVec);
327  RHSVec.linearCombo(1.0,RHSVec,-1.0,dbdpVec);
328 
329  // since the nonlinear solver is expecting a -f, scale by -1.0:
330  RHSVec.scale(-1.0);
331 
332  // deal with the matvec corrections
333  // This assumes that the matvecs have been properly stored.
334  double qscalar1(sec.alpha_[1]/sec.currentTimeStep);
335  RHSVec.linearCombo(1.0,RHSVec, -qscalar1, currDQdxDXdpVec);
336 
337  if (sec.currentOrder_ == 2)
338  {
339  double qscalar2(sec.alpha_[2]/sec.currentTimeStep);
340  RHSVec.linearCombo(1.0,RHSVec, -qscalar2, lastDQdxDXdpVec);
341  }
342 
343 #ifdef DEBUG_SENS
344  Xyce::dout() << "obtainSensitivityResiduals: RHS Vector, ip = " << ip << ":\n";
345  RHSVec.printPetraObject(Xyce::dout());
346 #endif
347  }
348 }
349 
350 //-----------------------------------------------------------------------------
351 // Function : Gear12::obtainJacobian
352 // Purpose : Calculate Jacobian
353 // Special Notes :
354 // Scope : public
355 // Creator : Ting Mei, SNL
356 // Creation Date : 11/16/07
357 //-----------------------------------------------------------------------------
359 {
360 
361  if (DEBUG_TIME && isActive(Diag::TIME_JACOBIAN))
362  {
363  Xyce::dout() << std::endl
364  << Xyce::section_divider << std::endl
365  << " Gear12::obtainJacobian" << std::endl;
366  }
367 
368  // output: ds.JMatrixPtr
369 
370  // This function returns the following matrix:
371  // $-(sec.alphas_/hn)dQdx(x)+dFdx$
372 
373  // Note: ds.nextSolutionPtr is used to get dQdx,dFdx in Analysis::AnalysisManager::loadJacobian.
374 
375  Linear::Matrix & dQdx = *(ds.dQdxMatrixPtr);
376  Linear::Matrix & dFdx = *(ds.dFdxMatrixPtr);
377  Linear::Matrix & Jac = *(ds.JMatrixPtr);
378 
379  double qscalar(sec.alpha_[0]/sec.currentTimeStep);
380  double fscalar(1.0);
381 
382  Jac.linearCombo( qscalar, dQdx, fscalar, dFdx );
383 
384  if (DEBUG_TIME && isActive(Diag::TIME_JACOBIAN))
385  {
386  Xyce::dout() << "\n dFdx:" <<std::endl;
387  dFdx.printPetraObject(Xyce::dout());
388  Xyce::dout() << "\n Total Jacobian:" <<std::endl;
389  Jac.printPetraObject(Xyce::dout());
390  // for (int i=0;i<3;++i)
391  // {
392  // printf("[ %25.20g\t%25.20g\t%25.20g ]\n",Jac[i][0],Jac[i][1],Jac[i][2]);
393  // }
394 
395  Xyce::dout() << Xyce::section_divider << std::endl << std::endl;
396  }
397 }
398 
399 //-----------------------------------------------------------------------------
400 // Function : Gear12::interpolateSolution
401 // Purpose : Interpolate solution approximation at prescribed time point.
402 // Scope : public
403 // Creator : Ting Mei, SNL
404 // Creation Date : 11/16/07
405 //-----------------------------------------------------------------------------
406 bool Gear12::interpolateSolution(double timepoint,
407  Linear::Vector * tmpSolVectorPtr, std::vector<Linear::Vector*> & historyVec)
408 
409 {
410  // this is a very course approximation to determine if we are too
411  // close to the actual time step to do an interpolation.
412  // it could use more work.
413  double dtr = timepoint - sec.currentTime; // the delta time requested.
414  if( -dtr < 100 * Util::MachineDependentParams::MachinePrecision() )
415  {
416  *tmpSolVectorPtr = *(historyVec[0]);
417  return false;
418  }
419 
420  tmpSolVectorPtr->linearCombo(1.0, *(historyVec[0]), -1.0, *(historyVec[1]));
421 
422  if( sec.usedOrder_ <= 2)
423  {
424  // do first order interpolation
425  // X_interp = X + delta_t_requested * delta_X/delta_t[last step]
426  dtr = dtr / sec.lastTimeStep;
427  tmpSolVectorPtr->linearCombo(1.0, *(historyVec[0]), dtr, *tmpSolVectorPtr);
428  }
429 
430  return true;
431 }
432 
433 //-----------------------------------------------------------------------------
434 // Function : Gear12::interpolateMPDESolution
435 // Purpose : Interpolate solution approximation at prescribed time points.
436 // Special Notes : This routine computes the solution at the output
437 // : timepoints by intepolation of the history using the order
438 // : used for the most recent completed step, orderUsed.
439 // : The output is put into provided Linear::Vector pointer.
440 // : The interpolation is as follows:
441 // : tmpSolVectorPtr->block(i) is interpolated at timepoint(i)
442 // : Therefore, if you want them all interpolated at the same time,
443 // : then use timepoint(i) = timepoint(0) forall i
444 // : or use interpolateSolution.
445 // Scope : public
446 // Creator : Ting Mei, Eric Keiter, SNL
447 // Creation Date : 11/28/06
448 //-----------------------------------------------------------------------------
449 bool Gear12::interpolateMPDESolution(std::vector<double>& timepoint,
450  Linear::Vector * tmpSolVectorPtr)
451 {
452  Linear::BlockVector * blockTempSolVectorPtr =
453  dynamic_cast<Linear::BlockVector*>(tmpSolVectorPtr);
454  if (blockTempSolVectorPtr == NULL)
455  {
456  std::string msg = "Gear12::interpolateMPDESolution: ";
457  msg += "Linear::Vector tmpSolVectorPtr is not of type Linear::BlockVector";
458  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
459  return(false);
460  }
461 
462  double tfuzz; // fuzz factor to check for valid output time
463  double tp; // approximately t_{n-1}
464  int numblocks = timepoint.size();
465  int blockCount = blockTempSolVectorPtr->blockCount();
466  if (numblocks > blockCount)
467  {
468  std::string msg = "Gear12::interpolateMPDESolution: ";
469  msg += "Number of time points requested is greater than number of fast time points in MPDE block vector";
470  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
471  return(false);
472  }
473  double delt;
474  double c = 1.0;
475  double gam;
476  int kord; // order of interpolation
477  double tn = sec.currentTime;
478  double hh = sec.currentTimeStep;
479  double hused = sec.usedStep_;
480  int kused = sec.usedOrder_;
481  double uround = 0.0; // unit round-off (set to zero for now)
482 
483  tfuzz = 100 * uround * (tn + hh);
484  tp = tn - hused - tfuzz;
485  for (int i=0; i<numblocks ; ++i)
486  {
487  if ( (timepoint[i] - tp)*hh < 0.0 )
488  return false;
489  }
490 
491  *tmpSolVectorPtr = *(ds.xHistory[0]);
492 
493  Linear::Vector * solVectorPtr;
494  Linear::Vector * xHistoryVectorPtr;
495  // Loop over blocks first so that maximal order can be maintained
496  for (int i=0; i < numblocks ; ++i)
497  {
498  if ((kused == 0) || (timepoint[i] == tn)) { kord = 1; }
499  else { kord = kused; }
500  solVectorPtr = &(blockTempSolVectorPtr->block(i));
501  c = 1.0;
502  delt = timepoint[i] - tn;
503  gam = delt/sec.psi_[0];
504  for (int j=1 ; j <= kord ; ++j)
505  {
506  c = c*gam;
507  gam = (delt + sec.psi_[j-1])/sec.psi_[j];
508  Linear::BlockVector * blockXHistoryVectorPtr =
509  dynamic_cast<Linear::BlockVector*>(ds.xHistory[j]);
510  if (blockXHistoryVectorPtr == NULL)
511  {
512  Xyce::Report::DevelFatal0().in("Gear12::interpolateMPDESolution") << "Linear::Vector ds.xHistory[j] is not of type Linear::BlockVector\n j = " << j;
513  return(false);
514  }
515  xHistoryVectorPtr = &(blockXHistoryVectorPtr->block(i));
516  solVectorPtr->linearCombo(1.0,*solVectorPtr,c,*xHistoryVectorPtr);
517  }
518  }
519  return true;
520 }
521 
522 //-----------------------------------------------------------------------------
523 // Function : Gear12::printMPDEOutputSolution()
524 // Purpose : Print transient output from MPDE simulation
525 // Special Notes : This routine uses interpolateMPDESolution.
526 // Scope : public
527 // Creator : Ting Mei, SNL, 1414
528 // Creation Date : 11/28/06
529 //-----------------------------------------------------------------------------
531  Analysis::OutputMgrAdapter & outputManagerAdapter,
532  const double time,
533  Linear::Vector * solnVecPtr,
534  const std::vector<double> & fastTimes )
535 {
536  return true;
537 }
538 
539 
540 //-----------------------------------------------------------------------------
541 // Function : Gear12::printWaMPDEOutputSolution()
542 // Purpose : Print transient output from WaMPDE simulation
543 // Special Notes : This routine uses interpolateSolution.
544 // Scope : public
545 // Creator : Ting Mei, SNL, 1414
546 // Creation Date : 12/15/06
547 //-----------------------------------------------------------------------------
549  Analysis::OutputMgrAdapter & outputManagerAdapter,
550  const double time,
551  Linear::Vector * solnVecPtr,
552  const std::vector<double> & fastTimes,
553  const int phiGID )
554 {
555  return true;
556 }
557 
558 //-----------------------------------------------------------------------------
559 // Function : Gear12::printOutputSolution()
560 // Purpose : Print output that is dumbed down in order.
561 // Special Notes : This routine picks smaller time steps to approximate first
562 // : order integration from the perspective of the output.
563 // Scope : public
564 // Creator : Ting Mei, SNL, 1414
565 // Creation Date : 11/16/07
566 //-----------------------------------------------------------------------------
567 
569  Analysis::OutputMgrAdapter & outputManagerAdapter,
570  const TIAParams & tia_params,
571  const double time,
572  Linear::Vector * solnVecPtr,
573  const bool doNotInterpolate,
574  const std::vector<double> & outputInterpolationTimes,
575  bool skipPrintLineOutput)
576 {
577  if (DEBUG_TIME && isActive(Diag::TIME_OUTPUT))
578  {
579  Xyce::dout() << std::endl
580  << Xyce::section_divider << std::endl
581  << " Gear12::printOutputSolution" << std::endl
582  << "usedOrder_ = " << sec.usedOrder_ << std::endl;
583  }
584 
585  double timestep = sec.lastAttemptedTimeStep;
586  double lasttime = sec.currentTime - timestep;
587  bool dointerp = true;
588  double hh = timestep/(sec.usedOrder_);
589 
590  if (hh <= 10*sec.minTimeStep)
591  {
592  dointerp = false;
593  }
594 
595  if (!tia_params.interpOutputFlag)
596  {
597  dointerp = false;
598  }
599 
600  if (doNotInterpolate)
601  {
602  dointerp = false;
603  }
604 
605  if (dointerp && !outputInterpolationTimes.empty())
606  {
607  for (unsigned int i=0;i<outputInterpolationTimes.size();++i)
608  {
609  interpolateSolution(outputInterpolationTimes[i], ds.tmpSolVectorPtr, ds.xHistory); // interpolate solution vector
610  interpolateSolution(outputInterpolationTimes[i], ds.tmpStaVectorPtr, ds.sHistory); // interpolate state vector
611  interpolateSolution(outputInterpolationTimes[i], ds.tmpStoVectorPtr, ds.stoHistory); // interpolate store vector
612  interpolateSolution(outputInterpolationTimes[i], ds.tmpLeadCurrentVectorPtr, ds.leadCurrentHistory); // interpolate store vector
613  interpolateSolution(outputInterpolationTimes[i], ds.tmpLeadDeltaVPtr, ds.leadDeltaVHistory); // interpolate store vector
614  outputManagerAdapter.tranOutput(outputInterpolationTimes[i], *ds.tmpSolVectorPtr,
618  skipPrintLineOutput);
619 
620  }
621  }
622 
623  // Either way, do an output on the actual computed time step, but only
624  // if we weren't given a list of specific times *or* we were told not to
625  // interpoloate.
626  if (outputInterpolationTimes.empty() || doNotInterpolate)
627  {
628  outputManagerAdapter.tranOutput(time, *ds.currSolutionPtr,
632  skipPrintLineOutput);
633  }
634 
635  if (DEBUG_TIME && isActive(Diag::TIME_OUTPUT))
636  Xyce::dout() << Xyce::section_divider << std::endl;
637 
638  return true;
639 }
640 
641 //-----------------------------------------------------------------------------
642 // Function : Gear12::saveOutputSolution
643 // Purpose : This is similar to printOutputSolution, but is in support of
644 // the .SAVE capability, rather than .PRINT.
645 // Special Notes :
646 // Scope : public
647 // Creator : Eric Keiter, SNL
648 // Creation Date : 10/21/07
649 //-----------------------------------------------------------------------------
650 bool
652  Analysis::OutputMgrAdapter & outputManagerAdapter,
653  const TIAParams & tia_params,
654  Linear::Vector * solnVecPtr,
655  const double saveTime,
656  const bool doNotInterpolate)
657 {
658  if (DEBUG_TIME && isActive(Diag::TIME_OUTPUT))
659  {
660  Xyce::dout() << std::endl
661  << Xyce::section_divider << std::endl
662  << " Gear12::saveOutputSolution" << std::endl;
663  }
664 
665  double timestep = sec.lastAttemptedTimeStep;
666  double lasttime = sec.currentTime - timestep;
667  bool dointerp = true;
668  double hh = timestep/(sec.usedOrder_);
669 
670  outputManagerAdapter.outputDCOP( *(ds.currSolutionPtr) );
671 
672  if (DEBUG_TIME && isActive(Diag::TIME_OUTPUT))
673  Xyce::dout() << Xyce::section_divider << std::endl;
674 
675  return true;
676 }
677 
678 //-----------------------------------------------------------------------------
679 // Function : Gear12::updateHistory
680 // Purpose : Update history array after a successful step
681 // Special Notes :
682 // Scope : public
683 // Creator : Ting Mei, SNL
684 // Creation Date : 11/16/07
685 //-----------------------------------------------------------------------------
687 {
688  if (DEBUG_TIME && isActive(Diag::TIME_OUTPUT))
689  {
690  Xyce::dout() << std::endl
691  << Xyce::section_divider << std::endl
692  << " Gear12::updateHistory" << std::endl
693  << "\n Before updates \n" << std::endl;
694  for (int i=0; i<=sec.maxOrder_ ; ++i)
695  {
696  Xyce::dout() << "\n xHistory["<< i << "]: \n" << std::endl;
697  (ds.xHistory[i])->printPetraObject(Xyce::dout());
698  Xyce::dout() << std::endl;
699  }
700  for (int i=0; i<=sec.maxOrder_ ; ++i)
701  {
702  Xyce::dout() << "\n qHistory["<< i << "]: \n" << std::endl;
703  (ds.qHistory[i])->printPetraObject(Xyce::dout());
704  Xyce::dout() << std::endl;
705  }
706  for (int i=0; i<=sec.maxOrder_ ; ++i)
707  {
708  Xyce::dout() << "\n sHistory["<< i << "]: \n" << std::endl;
709  (ds.sHistory[i])->printPetraObject(Xyce::dout());
710  Xyce::dout() << std::endl;
711  }
712  Xyce::dout() << Xyce::section_divider << std::endl;
713  }
714 
715  if (sec.currentOrder_ == 2)
716  {
717  *(ds.xHistory[2]) = *(ds.xHistory[1]);
718  }
719  *(ds.qHistory[1]) = *(ds.qHistory[0]);
720  *(ds.xHistory[1]) = *(ds.xHistory[0]);
721 
723  *(ds.sHistory[1]) = *(ds.sHistory[0]);
724  *(ds.stoHistory[1]) = *(ds.stoHistory[0]);
725 
729 
730  *(ds.xHistory[0]) = *ds.nextSolutionPtr;
731  *(ds.qHistory[0]) = *ds.daeQVectorPtr;
732  *(ds.sHistory[0]) = *ds.nextStatePtr;
734  *(ds.stoHistory[0]) = *ds.nextStorePtr;
735 
739 
740  if (DEBUG_TIME && isActive(Diag::TIME_HISTORY))
741  {
742  Xyce::dout() << "\n After updates \n" << std::endl;
743  Xyce::dout() << "\n newtonCorrectionPtr: " << std::endl;
744  ds.newtonCorrectionPtr->printPetraObject(Xyce::dout());
745  Xyce::dout() << "\n qnewtonCorrectionPtr: " << std::endl;
746  ds.qNewtonCorrectionPtr->printPetraObject(Xyce::dout());
747  for (int i=0; i<=sec.maxOrder_ ; ++i)
748  {
749  Xyce::dout() << "\n xHistory["<< i << "]: \n" << std::endl;
750  (ds.xHistory[i])->printPetraObject(Xyce::dout());
751  Xyce::dout() << std::endl;
752  }
753  for (int i=0; i<=sec.maxOrder_ ; ++i)
754  {
755  Xyce::dout() << "\n qHistory["<< i << "]: \n" << std::endl;
756  (ds.qHistory[i])->printPetraObject(Xyce::dout());
757  Xyce::dout() << std::endl;
758  }
759  Xyce::dout() << "\n sNewtonCorrectionPtr: " << std::endl;
760  ds.sNewtonCorrectionPtr->printPetraObject(Xyce::dout());
761  Xyce::dout() << std::endl;
762  Xyce::dout() << "\n nextStatePtr: " << std::endl;
763  ds.nextStatePtr->printPetraObject(Xyce::dout());
764  Xyce::dout() << std::endl;
765  for (int i=0; i<=sec.maxOrder_ ; ++i)
766  {
767  Xyce::dout() << "\n sHistory["<< i << "]: \n" << std::endl;
768  (ds.sHistory[i])->printPetraObject(Xyce::dout());
769  Xyce::dout() << std::endl;
770  }
771  Xyce::dout() << Xyce::section_divider << std::endl;
772  }
773 
775 }
776 
777 //-----------------------------------------------------------------------------
778 // Function : Gear12::updateSensitivityHistory
779 // Purpose : Update sensitivity history array after a successful step
780 // Special Notes :
781 // Scope : public
782 // Creator : Eric Keiter, SNL
783 // Creation Date :
784 //-----------------------------------------------------------------------------
786 {
787  int numParams = ds.sensRHSPtrVector.size();
788  for (int ip=0; ip<numParams;++ip)
789  {
790  std::vector<Linear::Vector*> & dqdpHistory = ds.dqdpHistory[ip];
791  std::vector<Linear::Vector*> & dXdpHistory = ds.dXdpHistory[ip];
792  std::vector<Linear::Vector*> & dQdxdXdpHistory = ds.dQdxdXdpHistory[ip];
793 
794  Linear::Vector & nextDQdxDXdpVec = *(ds.nextDQdxDXdpPtrVector[ip]);
795  Linear::Vector & nextDXdpVec = *(ds.nextDXdpPtrVector[ip]);
796  Linear::Vector & nextDqdpVec = *(ds.nextDqdpPtrVector[ip]);
797 
798  if (sec.currentOrder_ == 2)
799  {
800  *(dQdxdXdpHistory[2]) = *(dQdxdXdpHistory[1]);
801  *(dXdpHistory[2]) = *(dXdpHistory[1]);
802  *(dqdpHistory[1]) = *(dqdpHistory[0]);
803  }
804 
805  *(dQdxdXdpHistory[1]) = *(dQdxdXdpHistory[0]);
806  *(dXdpHistory[1]) = *(dXdpHistory[0]);
807 
808  *(dQdxdXdpHistory[0]) = nextDQdxDXdpVec;
809  *(dXdpHistory[0]) = nextDXdpVec;
810  *(dqdpHistory[0]) = nextDqdpVec;
811  }
812 }
813 
814 //-----------------------------------------------------------------------------
815 // Function : Gear12::restoreHistory
816 // Purpose : Restore history array after a failed step
817 // Special Notes :
818 // Scope : public
819 // Creator : Ting Mei, SNL
820 // Creation Date : 10/21/07
821 //-----------------------------------------------------------------------------
823 {
824  for (int i=1;i<=sec.currentOrder_;++i)
825  {
826  sec.psi_[i-1] = sec.psi_[i];
827  }
828  if (DEBUG_TIME && isActive(Diag::TIME_HISTORY))
829  {
830  Xyce::dout() << std::endl
831  << Xyce::section_divider << std::endl
832  << " Gear12::restoreHistory" << std::endl;
833  for (int i=1;i<=sec.currentOrder_;++i)
834  Xyce::dout() << "\n sec.psi_[i] = " << sec.psi_[i] << std::endl;
835  for (int i=0; i<=sec.maxOrder_ ; ++i)
836  {
837  Xyce::dout() << "\n xHistory["<< i << "]: \n" << std::endl;
838  (ds.xHistory[i])->printPetraObject(Xyce::dout());
839  Xyce::dout() << std::endl;
840  }
841  for (int i=0; i<=sec.maxOrder_ ; ++i)
842  {
843  Xyce::dout() << "\n qHistory["<< i << "]: \n" << std::endl;
844  (ds.qHistory[i])->printPetraObject(Xyce::dout());
845  Xyce::dout() << std::endl;
846  }
847  for (int i=0; i<=sec.maxOrder_ ; ++i)
848  {
849  Xyce::dout() << "\n sHistory["<< i << "]: \n" << std::endl;
850  (ds.sHistory[i])->printPetraObject(Xyce::dout());
851  Xyce::dout() << std::endl;
852  }
853  Xyce::dout() << Xyce::section_divider << std::endl;
854  }
855 }
856 
857 //-----------------------------------------------------------------------------
858 // Function : Gear12::updateCoeffs
859 // Purpose : Update method coefficients
860 // Special Notes :
861 // Scope : public
862 // Creator : Ting Mei, SNL
863 // Creation Date : 10/21/07
864 //-----------------------------------------------------------------------------
866 {
867  // synchronize with Step Error Control
868  // sec.psi_[0] = sec.currentTimeStep;
869  if (DEBUG_TIME && isActive(Diag::TIME_COEFFICIENTS))
870  {
871  Xyce::dout() << std::endl
872  << Xyce::section_divider << std::endl
873  << " Gear12::updateCoeffs" << std::endl
874  << " currentTimeStep = " << sec.currentTimeStep << std::endl
875  << " numberOfSteps_ = " << sec.numberOfSteps_ << std::endl
876  << " currentOrder_ = " << sec.currentOrder_ << std::endl
877  << " nscsco_ = " << sec.nscsco_ << std::endl
878  << " psi_[0] = " << sec.psi_[0] << std::endl;
879  }
880 
881  double temp1 = sec.currentTimeStep;
882 
883  if (sec.currentOrder_ == 2)
884  {
885  sec.psi_[2] = sec.psi_[1];
886  }
887  sec.psi_[1] = sec.psi_[0];
888  sec.psi_[0] = temp1;
889 
890  // sec.beta_[0] = 1.0;
891  // sec.alpha_[0] = 1.0;
892  sec.ck_ = 1.0;
893  sec.alphas_ = -1.0;
894 
895  if (sec.currentOrder_ == 2)
896  {
897  // the coeffs of predictor
898  sec.beta_[2] = temp1/sec.psi_[2] * (temp1 + sec.psi_[1])/(sec.psi_[1] + sec.psi_[2]);
899  sec.beta_[1] = -temp1/sec.psi_[1] - sec.beta_[2] * (sec.psi_[1] + sec.psi_[2])/sec.psi_[1];
900  sec.beta_[0] = 1.0 - sec.beta_[2] - sec.beta_[1];
901 
902  sec.alpha_[2] = -temp1/sec.psi_[1] * temp1/(2 * temp1 + sec.psi_[1]);
903  sec.alpha_[1] = 1 - sec.alpha_[2];
904  sec.alpha_[0] = -sec.alpha_[1] - sec.alpha_[2] * (1 + sec.psi_[1]/temp1);
905 
906  sec.alpha_[2] = sec.alpha_[2]/sec.alpha_[0];
907  sec.alpha_[1] = sec.alpha_[1]/sec.alpha_[0];
908  sec.alpha_[0] = -1/sec.alpha_[0];
909 
910  sec.ck_ = sec.currentTimeStep/(temp1 + sec.psi_[1] + sec.psi_[2]);
911  }
912  else
913  {
914  sec.beta_[0] = 1.0 + temp1/sec.psi_[1];
915  sec.beta_[1] = -temp1/sec.psi_[1];
916  sec.alpha_[0] = 1.0;
917  sec.alpha_[1] = -1.0;
918 
919  sec.ck_ = sec.currentTimeStep/(temp1 + sec.psi_[1]);
920  }
921 
922  if (DEBUG_TIME && isActive(Diag::TIME_COEFFICIENTS))
923  {
924  Xyce::dout() << " nscsco_ = " << sec.nscsco_ << std::endl
925  << " beta_[0] = " << sec.beta_[0] << std::endl
926  << " beta_[1] = " << sec.beta_[1] << std::endl
927  << " beta_[2] = " << sec.beta_[2] << std::endl
928  << " beta_[3] = " << sec.beta_[3] << std::endl
929  << " beta_[4] = " << sec.beta_[4] << std::endl
930  << " alpha_[0] = " << sec.alpha_[0] << std::endl
931  << " alpha_[1] = " << sec.alpha_[1] << std::endl
932  << " alpha_[2] = " << sec.alpha_[2] << std::endl
933  << " alpha_[3] = " << sec.alpha_[3] << std::endl
934  << " alpha_[4] = " << sec.alpha_[4] << std::endl
935  << " alphas_ = " << sec.alphas_ << std::endl
936  << " alpha0_ = " << sec.alpha0_ << std::endl
937  << " gamma_[0] = " << sec.gamma_[0] << std::endl
938  << " gamma_[1] = " << sec.gamma_[1] << std::endl
939  << " gamma_[2] = " << sec.gamma_[2] << std::endl
940  << " gamma_[3] = " << sec.gamma_[3] << std::endl
941  << " gamma_[4] = " << sec.gamma_[4] << std::endl
942  << " psi_[0] = " << sec.psi_[0] << std::endl
943  << " psi_[1] = " << sec.psi_[1] << std::endl
944  << " psi_[2] = " << sec.psi_[2] << std::endl
945  << " psi_[3] = " << sec.psi_[3] << std::endl
946  << " psi_[4] = " << sec.psi_[4] << std::endl
947  << " sigma_[0] = " << sec.sigma_[0] << std::endl
948  << " sigma_[1] = " << sec.sigma_[1] << std::endl
949  << " sigma_[2] = " << sec.sigma_[2] << std::endl
950  << " sigma_[3] = " << sec.sigma_[3] << std::endl
951  << " sigma_[4] = " << sec.sigma_[4] << std::endl
952  << " ck_ = " << sec.ck_ << std::endl
953  << Xyce::section_divider << std::endl;
954  }
955 }
956 
957 //-----------------------------------------------------------------------------
958 // Function : Gear12::initialize
959 // Purpose : Initialize method with initial solution & step-size
960 // Special Notes :
961 // Scope : public
962 // Creator : Ting Mei, SNL
963 // Creation Date : 10/21/07
964 //-----------------------------------------------------------------------------
965 void Gear12::initialize(const TIAParams &tia_params)
966 {
967  // we assume the solution vector is available here
968  // Note that I'm using currSolutionPtr instead of
969  // nextSolutionPtr because this is the first step.
970 
971  // Update next stop time from StepErrorControl:
972  // ERK. Commenting this out, as it is already called from Analysis::AnalysisManager,
973  // right before this initialize call. It should not be called 2x, as
974  // it is history dependent (unfortunately), so calling it 2x in a row changes
975  // the stop time to a different number.
976  // sec.updateStopTime();
977 
978  // Choose initial step-size
979  double time_to_stop = sec.stopTime - sec.currentTime;
980  double currentTimeStep;
981 
982  sec.TimeStepLimitedbyBP = false;
983 
984  if (tia_params.constantTimeStepFlag)
985  {
986  currentTimeStep = 0.1 * time_to_stop;
987  currentTimeStep = std::min(sec.startingTimeStep, currentTimeStep);
988  sec.currentTimeStep = currentTimeStep;
989  }
990  else
991  {
992  // compute an initial step-size based on rate of change in the
993  // solution initially
994 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
995  double dnorm_q = 0.0;
996  (ds.qHistory[1])->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
997 #else
998  double dnorm_q = ds.delta_x_errorNorm_q1();
999 #endif
1000  if (dnorm_q > 0.0) // time-dependent DAE
1001  {
1002  if (sec.currentTime == sec.initialTime)
1003  currentTimeStep = std::min(sec.h0_max_factor_*abs(time_to_stop),sqrt(2.0)/(sec.h0_safety_*dnorm_q));
1004  else
1005  currentTimeStep = 0.1* std::min(sec.savedTimeStep, abs(time_to_stop));
1006  }
1007  else // non-time-dependent DAE
1008  {
1009  if (sec.currentTime == sec.initialTime)
1010  currentTimeStep = sec.h0_max_factor_*abs(time_to_stop);
1011  else
1012  currentTimeStep = 0.1* std::min(sec.savedTimeStep, abs(time_to_stop));
1013  }
1014 
1015  // choose min of user specified value and our value:
1016  if (sec.startingTimeStep > 0.0 && (sec.currentTime == sec.initialTime))
1017  currentTimeStep = std::min(sec.startingTimeStep, currentTimeStep);
1018 
1019  // check for maximum step-size:
1020  double rh = abs(currentTimeStep)*sec.h_max_inv_;
1021  if (rh>1.0)
1022  currentTimeStep = currentTimeStep/rh;
1023 
1024  sec.currentTimeStep = currentTimeStep;
1025  }
1026 
1027  sec.currentTimeStepRatio = 1.0;
1029 
1033 
1035  sec.stepAttemptStatus = true;
1036 
1037  if (VERBOSE_TIME && tia_params.errorAnalysisOption == TimeIntg::NO_LOCAL_TRUNCATED_ESTIMATES)
1038  {
1039  Xyce::dout() << "ERROROPTION=1: DeltaT Grow = 2" << "\n" << std::endl
1040  << "ERROROPTION=1: DeltaT Cut = 0.125" << "\n" << std::endl
1041  << "ERROROPTION=1: NL MIN = " << tia_params.NLmin << "\n" << std::endl
1042  << "ERROROPTION=1: NL MAX = " << tia_params.NLmax << "\n" << std::endl
1043  << "ERROROPTION=1: DELMAX = " << sec.maxTimeStep << "\n" << std::endl;
1044  }
1045 
1046  // sec.tolAimFac_ = 0.5;
1047 
1049 
1050  // if (sec.currentTime == sec.initialTime)
1051  {
1052  // x history
1053  *(ds.xHistory[0]) = *(ds.currSolutionPtr);
1054  *(ds.xHistory[1]) = *(ds.currSolutionPtr);
1055 
1056  // q history
1057  *(ds.qHistory[0]) = *(ds.daeQVectorPtr);
1058  // *(ds.qHistory[1]) = *(ds.daeFVectorPtr);
1059  // (ds.qHistory[1])->scale(-sec.currentTimeStep);
1060  // (ds.qHistory[1])->putScalar(0.0);
1061  *(ds.qHistory[1]) = *(ds.daeQVectorPtr);
1062 
1063  // state history
1064  *(ds.sHistory[0]) = *(ds.currStatePtr);
1065  (ds.sHistory[1])->putScalar(0.0);
1066 
1067  // lead current Q compontent history
1070 
1071  // store history
1072  *(ds.stoHistory[0]) = *(ds.currStorePtr);
1073  (ds.stoHistory[1])->putScalar(0.0);
1074 
1075  // lead current history
1077  (ds.leadCurrentHistory[1])->putScalar(0.0);
1081  (ds.leadDeltaVHistory[1])->putScalar(0.0);
1082 
1083 
1084  }
1085  // Coefficient initialization
1086  sec.numberOfSteps_ = 0; // number of total time integration steps taken
1087  sec.currentOrder_ = 1;
1088  // sec.usedOrder_ = 1;
1089  // if (sec.currentTime == sec.initialTime)
1090  // {
1091  sec.usedOrder_ = 1;
1092  sec.psi_[0] = sec.currentTimeStep;
1093  sec.cj_ = 1/sec.psi_[0];
1094  // }
1095  sec.nscsco_ = 0;
1096  if (DEBUG_TIME && isActive(Diag::TIME_HISTORY))
1097  {
1098  Xyce::dout() << std::endl
1099  << Xyce::section_divider << std::endl
1100  << " Gear12::initialize" << std::endl
1101  << "\n xHistory: \n" << std::endl;
1102  (ds.xHistory[0])->printPetraObject(Xyce::dout());
1103  Xyce::dout() << std::endl;
1104  (ds.xHistory[1])->printPetraObject(Xyce::dout());
1105  Xyce::dout() << std::endl
1106  << "\n qHistory: \n" << std::endl;
1107  (ds.qHistory[0])->printPetraObject(Xyce::dout());
1108  Xyce::dout() << std::endl;
1109  (ds.qHistory[1])->printPetraObject(Xyce::dout());
1110  Xyce::dout() << std::endl
1111  << "\n sHistory: \n" << std::endl;
1112  (ds.sHistory[0])->printPetraObject(Xyce::dout());
1113  Xyce::dout() << std::endl;
1114  (ds.sHistory[1])->printPetraObject(Xyce::dout());
1115  Xyce::dout() << std::endl
1116  << "\n" << "currentTimeStep = " << currentTimeStep << "\n" << std::endl
1117  << "\n" << "time_to_stop = " << time_to_stop << "\n" << std::endl
1118  << Xyce::section_divider << std::endl;
1119  }
1120 
1122 }
1123 
1124 //-----------------------------------------------------------------------------
1125 // Function : Gear12::initializeSensitivities
1126 // Purpose :
1127 // Special Notes :
1128 // Scope : public
1129 // Creator : Eric Keiter, SNL
1130 // Creation Date :
1131 //-----------------------------------------------------------------------------
1133 {
1134  int numParams = ds.sensRHSPtrVector.size();
1135  for (int ip=0; ip<numParams;++ip)
1136  {
1137  std::vector<Linear::Vector*> & dqdpHistory = ds.dqdpHistory[ip];
1138  std::vector<Linear::Vector*> & dXdpHistory = ds.dXdpHistory[ip];
1139  std::vector<Linear::Vector*> & dQdxdXdpHistory = ds.dQdxdXdpHistory[ip];
1140 
1141  Linear::Vector * currDQdxDxdpPtr = ds.currDQdxDXdpPtrVector[ip];
1142  Linear::Vector * currDxdpPtr = ds.currDXdpPtrVector[ip];
1143  Linear::Vector * currDqdpPtr = ds.currDqdpPtrVector[ip];
1144 
1145  // dQdx*dXdp matvec history
1146  *(dQdxdXdpHistory[0]) = *(currDQdxDxdpPtr);
1147  *(dQdxdXdpHistory[1]) = *(currDQdxDxdpPtr);
1148 
1149  // dXdp history
1150  *(dXdpHistory[0]) = *(currDxdpPtr);
1151  *(dXdpHistory[1]) = *(currDxdpPtr);
1152 
1153  // dqdp history
1154  *(dqdpHistory[0]) = *(currDqdpPtr);
1155  *(dqdpHistory[1]) = *(currDqdpPtr);
1156  }
1157 }
1158 
1159 //-----------------------------------------------------------------------------
1160 // Function : Gear12::setTwoLevelTimeInfo
1161 // Purpose :
1162 // Special Notes :
1163 // Scope : public
1164 // Creator : Eric Keiter, SNL
1165 // Creation Date : 03/01/07
1166 //-----------------------------------------------------------------------------
1168 (const TimeIntInfo & tiInfo)
1169 {
1170  // set initial step-size
1171  double time_to_stop = sec.stopTime - sec.currentTime;
1172 
1173 
1174  // x history
1175  *(ds.xHistory[0]) = *(ds.currSolutionPtr);
1176  *(ds.xHistory[1]) = *(ds.currSolutionPtr);
1177 
1178  // q history
1179  *(ds.qHistory[0]) = *(ds.daeQVectorPtr);
1180  *(ds.qHistory[1]) = *(ds.daeQVectorPtr);
1181 
1182  // state history
1183  *(ds.sHistory[0]) = *(ds.currStatePtr);
1184  (ds.sHistory[1])->putScalar(0.0);
1185 
1186  // Coefficient initialization
1187  sec.numberOfSteps_ = 0; // number of total time integration steps taken
1188  sec.usedOrder_ = 1;
1189  sec.psi_[0] = sec.currentTimeStep;
1190  sec.cj_ = 1/sec.psi_[0];
1191  sec.nscsco_ = 0;
1192 }
1193 
1194 //-----------------------------------------------------------------------------
1195 // Function : Gear12::checkReduceOrder()
1196 // Purpose : check whether to reduce order independent of local error test
1197 // Special Notes :
1198 // Scope : public
1199 // Creator : Ting Mei, SNL
1200 // Creation Date : 10/21/07
1201 //-----------------------------------------------------------------------------
1203 {
1204 
1205 }
1206 
1207 //-----------------------------------------------------------------------------
1208 // Function : Gear12::rejectStep()
1209 // Purpose : code to restore history, choose new order/step-size
1210 // Special Notes :
1211 // Scope : public
1212 // Creator : Ting Mei, SNL
1213 // Creation Date : 10/21/07
1214 //-----------------------------------------------------------------------------
1215 void
1217  const TIAParams & tia_params)
1218 {
1219  // This routine puts its output in newTimeStep_ and sec.newOrder_
1220 
1221  // This routine changes the following variables:
1222  // lastAttemptedTimeStep, sec.initialPhase_, sec.nef_, sec.psi_, newTimeStep_,
1223  // sec.newOrder_, sec.currentOrder_, currentTimeStep_, ds.xHistory,
1224  // ds.qHistory, nextTimePt, nextTime, currentTimeStepRatio,
1225  // currentTimeStepSum, nextTimePt
1226 
1227  // This routine reades but does not change the following variables:
1228  // stepAttemptStatus, sec.r_factor_, sec.r_safety_, sec.Est_, sec.r_fudge_, sec.r_min_, sec.r_max_,
1229  // minTimeStep, maxTimeStep, currentTime, stopTime, lastTimeStep
1230 
1231  sec.TimeStepLimitedbyBP = false;
1232 
1233  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1234  {
1235  Xyce::dout() << std::endl
1236  << Xyce::section_divider << std::endl
1237  << " Gear12::rejectStep" << std::endl;
1238  }
1239 
1240  // Only update the time step if we are NOT running constant stepsize.
1241  bool adjustStep = !tia_params.constantTimeStepFlag;
1242 
1244 
1245 
1246  double newTimeStep_ = sec.currentTimeStep;
1247  double rr = 1.0; // step size ratio = new step / old step
1248  if ((sec.stepAttemptStatus == false) && (adjustStep))
1249  {
1251  {
1252  newTimeStep_ = sec.currentTimeStep/8;
1253  }
1254  else
1255  {
1256  sec.initialPhase_ = false;
1257  sec.nef_++;
1258  restoreHistory();
1259  // restore sec.psi_
1260  // for (int i=1;i<=sec.currentOrder_;++i)
1261  // sec.psi_[i-1] = sec.psi_[i] - sec.currentTimeStep;
1262 
1263  if (sec.nef_ >= sec.max_LET_fail_)
1264  {
1265  std::string msg = "Gear12::rejectStep: ";
1266  msg += " Maximum number of local error test failures. ";
1267  N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1268  }
1269 
1270  if ((sec.newtonConvergenceStatus <= 0))
1271  {
1272  /// 11/11/05 erkeite: If the Newton solver fails, don't
1273  // rely on the error estimate - it may be full of Nan's.
1274  // rr = sec.r_min_;
1275 
1276  newTimeStep_ = sec.currentTimeStep/8;
1277  // sec.currentOrder_ = 1;
1279  // if (sec.nef_ > 2) sec.newOrder_ = 1;//consistent with block below.
1280  }
1281  else
1282  {
1283  // 03/11/04 tscoffe: Here is the block for choosing order &
1284  // step-size when the local error test FAILS (but Newton
1285  // succeeded).
1286  if (sec.nef_ == 1) // first local error test failure
1287  {
1288  // sec.estOverTol_
1289  sec.Est_ = sec.estOverTol_;
1290 
1291  rr = sec.tolAimFac_/(sec.estOverTol_ + 0.0001);
1292  rr = pow(rr, 1.0/(sec.currentOrder_+1.0));
1293  rr = std::max(sec.r_min_,std::min(sec.r_max_,rr));
1294 
1295  newTimeStep_ = rr * sec.currentTimeStep;
1296 
1297  // sec.currentOrder_ = 1;
1298  // sec.currentOrder_ = sec.minOrder_;
1299  }
1300  else // if (sec.nef_ == 2) // second Dae failure
1301  {
1302  rr = sec.r_min_;
1303  newTimeStep_ = rr * sec.currentTimeStep;
1304 
1305  // sec.currentOrder_ = 1;
1307  }
1308  }
1309  if (DEBUG_TIME && isActive(Diag::TIME_STEP) && isActive(Diag::TIME_COEFFICIENTS))
1310  {
1311  Xyce::dout() << " currentTimeStep = " << sec.currentTimeStep << std::endl
1312  << " numberOfSteps_ = " << sec.numberOfSteps_ << std::endl
1313  << " currentOrder_ = " << sec.currentOrder_ << std::endl
1314  << " nscsco_ = " << sec.nscsco_ << std::endl
1315  << " alpha_[0] = " << sec.alpha_[0] << std::endl
1316  << " alpha_[1] = " << sec.alpha_[1] << std::endl
1317  << " alpha_[2] = " << sec.alpha_[2] << std::endl
1318  << " alpha_[3] = " << sec.alpha_[3] << std::endl
1319  << " alpha_[4] = " << sec.alpha_[4] << std::endl
1320  << " psi_[0] = " << sec.psi_[0] << std::endl
1321  << " psi_[1] = " << sec.psi_[1] << std::endl
1322  << " psi_[2] = " << sec.psi_[2] << std::endl
1323  << " psi_[3] = " << sec.psi_[3] << std::endl
1324  << " psi_[4] = " << sec.psi_[4] << std::endl
1325  << " sigma_[0] = " << sec.sigma_[0] << std::endl
1326  << " sigma_[1] = " << sec.sigma_[1] << std::endl
1327  << " sigma_[2] = " << sec.sigma_[2] << std::endl
1328  << " sigma_[3] = " << sec.sigma_[3] << std::endl
1329  << " sigma_[4] = " << sec.sigma_[4] << std::endl
1330  << " rr = " << rr << std::endl
1331  << " r_factor_ = " << sec.r_factor_ << std::endl
1332  << " r_safety_ = " << sec.r_safety_ << std::endl
1333  << " Est_ = " << sec.Est_ << std::endl
1334  << " r_fudge_ = " << sec.r_fudge_ << std::endl
1335  << " newOrder_ = " << sec.newOrder_ << std::endl
1336  << " currentTimeStep = " << sec.currentTimeStep << std::endl
1337  << " newTimeStep_ = " << newTimeStep_ << std::endl;
1338  }
1339  }
1340  }
1341  else if ((sec.stepAttemptStatus == false) & (!adjustStep))
1342  {
1343  std::string tmp = " Gear12:rejectStep: Warning: Local error test failed with constant step-size.\n";
1344  Xyce::dout() << tmp << std::endl;
1345  }
1346 
1347  // If the step needs to be adjusted:
1348  if (adjustStep)
1349  {
1350  newTimeStep_ = std::max(newTimeStep_, sec.minTimeStep);
1351  newTimeStep_ = std::min(newTimeStep_, sec.maxTimeStep);
1352 
1353  double nextTimePt = sec.currentTime + newTimeStep_;
1354 
1355  if (nextTimePt > sec.stopTime)
1356  {
1357  nextTimePt = sec.stopTime;
1358  newTimeStep_ = sec.stopTime - sec.currentTime;
1359  sec.TimeStepLimitedbyBP = true;
1360  }
1361 
1362  sec.nextTime = nextTimePt;
1363 
1364  sec.currentTimeStepRatio = newTimeStep_/sec.lastTimeStep;
1365  sec.currentTimeStepSum = newTimeStep_ + sec.lastTimeStep;
1366 
1367  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1368  {
1369  Xyce::dout() << " newTimeStep_ = " << newTimeStep_ << std::endl
1370  << " nextTime = " << sec.nextTime << std::endl;
1371  }
1372 
1373  sec.currentTimeStep = newTimeStep_;
1374  }
1375  else // if time step is constant for this step:
1376  {
1377  double nextTimePt = sec.currentTime + sec.currentTimeStep;
1378 
1379  if (nextTimePt > sec.stopTime)
1380  {
1381  nextTimePt = sec.stopTime;
1383  }
1384 
1387 
1388  sec.nextTime = nextTimePt;
1389  }
1390  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1391  {
1392  Xyce::dout() << Xyce::section_divider << std::endl;
1393  }
1394 }
1395 
1396 //-----------------------------------------------------------------------------
1397 // Function : Gear12::rejectStepForHabanero
1398 // Purpose : step rejection, but from an outside program (Habanero API)
1399 // Special Notes :
1400 // Scope : public
1401 // Creator : Eric Keiter, SNL
1402 // Creation Date : 08/11/09
1403 //-----------------------------------------------------------------------------
1405 {
1406  restoreHistory();
1408 }
1409 
1410 //-----------------------------------------------------------------------------
1411 // Function : Gear12::completeStep()
1412 // Purpose : code to update history, choose new order/step-size
1413 // Special Notes :
1414 // Scope : public
1415 // Creator : Ting Mei, SNL
1416 // Creation Date : 10/21/07
1417 //-----------------------------------------------------------------------------
1418 void Gear12::completeStep(const TIAParams &tia_params)
1419 {
1420  sec.TimeStepLimitedbyBP = false;
1421 
1422  sec.numberOfSteps_ ++;
1423  sec.nef_ = 0;
1426 
1427  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1428  {
1429  Xyce::dout() << std::endl
1430  << Xyce::section_divider << std::endl
1431  << " Gear12::completeStep" << std::endl;
1432  }
1433 
1434  // Only update the time step if we are NOT running constant stepsize.
1435  bool adjustStep = !tia_params.constantTimeStepFlag;
1436 
1438 
1439  double newTimeStep_ = sec.currentTimeStep;
1440  double rr = 1.0; // step size ratio = new step / old step
1441  // 03/11/04 tscoffe: Here is the block for choosing order & step-size when
1442  // the local error test PASSES (and Newton succeeded).
1444  sec.lastTimeStepRatio = sec.currentTimeStepRatio; // copied from calcTStep1
1445  sec.lastTimeStepSum = sec.currentTimeStepSum; // copied from calcTStep1
1446  int orderDiff = sec.currentOrder_ - sec.usedOrder_;
1449 
1450  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1451  {
1452  Xyce::dout() << " initialPhase_ = " << sec.initialPhase_ << std::endl
1453  << " rr = " << rr << std::endl
1454  << " currentTimeStep = " << sec.currentTimeStep << std::endl
1455  << " currentTime = " << sec.currentTime << std::endl
1456  << " nextTime = " << sec.nextTime << std::endl
1457  << " newTimeStep_ = " << newTimeStep_ << std::endl
1458  << " minTimeStep = " << sec.minTimeStep << std::endl
1459  << " maxTimeStep = " << sec.maxTimeStep << std::endl;
1460  }
1461 
1462  // 03/22/04 tscoffe: Note that updating the history has nothing to do with
1463  // the step-size and everything to do with the newton correction vectors.
1464 
1465 
1466  /* if (sec.numberOfSteps_ >= 2)
1467  {
1468  sec.currentOrder_ = 2;
1469  // (ds.relErrTolPtr)->putScalar(1e-2);
1470  }
1471  */
1473  {
1474 
1475  if (sec.numberOfSteps_ >= 2 && sec.maxOrder_ == 2)
1476  {
1477  sec.currentOrder_ = 2;
1478  }
1479 
1480  rr = 1;
1481 
1482  if (sec.nIterations <= tia_params.NLmin)
1483  rr = 2;
1484 
1485  if (sec.nIterations > tia_params.NLmax)
1486  rr = 1.0/8;
1487 
1488  newTimeStep_ = rr*sec.currentTimeStep;
1489  }
1490  else
1491  {
1492  rr = sec.tolAimFac_/(sec.estOverTol_ + 0.0001);
1493  rr = pow(rr, 1.0/(sec.currentOrder_+1.0));
1494 
1495  if (sec.numberOfSteps_ >= 2 && sec.maxOrder_ == 2)
1496  {
1497  if (sec.currentOrder_ == 1)
1498  {
1499  sec.currentOrder_ = 2;
1500  rr = sec.tolAimFac_/(sec.estOverTol_ + 0.0001);
1501  rr = pow(rr, 1.0/(sec.currentOrder_+1.0));
1502 
1503  if (rr <= 1.05)
1504  {
1505  // sec.currentOrder_ = 1;
1507  }
1508  }
1509  }
1510  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1511  {
1512  Xyce::dout() << " currentOrder_ = " << sec.currentOrder_ << std::endl;
1513  Xyce::dout() << " r_safety = " << sec.r_safety_ << std::endl;
1514  Xyce::dout() << " r_fudge_ = " << sec.r_fudge_ << std::endl;
1515  Xyce::dout() << " r_hincr_ = " << sec.r_hincr_ << std::endl;
1516  Xyce::dout() << " r_hincr_test_ = " << sec.r_hincr_test_ << std::endl;
1517  Xyce::dout() << " Est = " << sec.Est_ << std::endl;
1518  Xyce::dout() << " raw rr = " << rr << std::endl;
1519  }
1520 
1521  if (rr >= sec.r_hincr_test_)
1522  {
1523  rr = sec.r_hincr_;
1524  newTimeStep_ = rr*sec.currentTimeStep;
1525  }
1526  else if (rr <= 1)
1527  {
1528  rr = std::max(sec.r_min_,std::min(sec.r_max_,rr));
1529  newTimeStep_ = rr*sec.currentTimeStep;
1530  }
1531  }
1532 
1533  updateHistory();
1534 
1535  newTimeStep_ = std::max(newTimeStep_, sec.minTimeStep);
1536  newTimeStep_ = std::min(newTimeStep_, sec.maxTimeStep);
1537 
1538  // 12/01/05 tscoffe: This is necessary to avoid currentTimeStep == 0 right
1539  // before a breakpoint. So I'm checking to see if currentTime is identically
1540  // equal to stopTime, in which case we are right before a breakpoint and we
1541  // should not adjust currentStepSize because that would result in
1542  // currentStepSize == 0.
1543  // if (sec.currentTime < sec.stopTime)
1544  if ((sec.stopTime - sec.currentTime) >= sec.minTimeStep)
1545  {
1546  // If the step needs to be adjusted:
1547  if (adjustStep)
1548  {
1549  // newTimeStep_ = Xycemax(newTimeStep_, sec.minTimeStep);
1550  // newTimeStep_ = Xycemin(newTimeStep_, sec.maxTimeStep);
1551 
1552  double nextTimePt = sec.currentTime + newTimeStep_;
1553 
1554  if (nextTimePt > sec.stopTime)
1555  {
1556 
1557  sec.savedTimeStep = newTimeStep_;
1558 
1559  nextTimePt = sec.stopTime;
1560  newTimeStep_ = sec.stopTime - sec.currentTime;
1561  sec.TimeStepLimitedbyBP = true;
1562  }
1563 
1564  sec.nextTime = nextTimePt;
1565 
1566  sec.currentTimeStepRatio = newTimeStep_/sec.lastTimeStep;
1567  sec.currentTimeStepSum = newTimeStep_ + sec.lastTimeStep;
1568 
1569  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1570  {
1571  Xyce::dout() << " nextTime = " << sec.nextTime << std::endl;
1572  Xyce::dout() << " newTimeStep_ = " << newTimeStep_ << std::endl;
1573  }
1574 
1575 
1576  sec.currentTimeStep = newTimeStep_;
1577  }
1578  else // if time step is constant for this step:
1579  {
1580  double nextTimePt = sec.currentTime + sec.currentTimeStep;
1581 
1582  if (nextTimePt > sec.stopTime)
1583  {
1585 
1586  nextTimePt = sec.stopTime;
1588  }
1589 
1592 
1593  sec.nextTime = nextTimePt;
1594  }
1595  }
1596 
1597  if (DEBUG_TIME && isActive(Diag::TIME_STEP))
1598  {
1599  Xyce::dout() << Xyce::section_divider << std::endl;
1600  }
1601 
1602 // sec.currentTimeStep = newTimeStep_;
1603 }
1604 
1605 //-----------------------------------------------------------------------------
1606 // Function : Gear12::updateStateDeriv
1607 // Purpose :
1608 // Special Notes :
1609 // Scope : public
1610 // Creator : Ting Mei, SNL
1611 // Creation Date : 11/17/05
1612 //-----------------------------------------------------------------------------
1614 {
1616  linearCombo(sec.alpha_[0],*ds.nextStatePtr, sec.alpha_[1],*ds.sn0Ptr);
1617 
1618  if (sec.currentOrder_ == 2)
1619  {
1621  linearCombo(1.0,*ds.nextStateDerivPtr, sec.alpha_[2], *(ds.sHistory[1]));
1622  }
1623 
1625 
1626  if (DEBUG_TIME && isActive(Diag::TIME_DUMP_SOLUTION_ARRAYS))
1627  {
1628  Xyce::dout() << "\n next state Ptr: \n" << std::endl;
1629  ds.nextStatePtr->printPetraObject(Xyce::dout());
1630  Xyce::dout() << std::endl;
1631 
1632  Xyce::dout() << "\n sn0: \n" << std::endl;
1633  ds.sn0Ptr->printPetraObject(Xyce::dout());
1634  Xyce::dout() << std::endl;
1635 
1636  Xyce::dout() << "\n next State Deriv: \n" << std::endl;
1637  ds.nextStateDerivPtr->printPetraObject(Xyce::dout());
1638  Xyce::dout() << std::endl;
1639  }
1640 }
1641 
1642 //-----------------------------------------------------------------------------
1643 // Function : OneStep::updateLeadCurrent
1644 // Purpose : calculates lead currents in store vector with
1645 // the storeLeadCurrQVec.
1646 // Special Notes :
1647 // Scope : public
1648 // Creator : Richard Schiek, Electrical Systems Modeling, SNL
1649 // Creation Date : 03/22/2013
1650 //-----------------------------------------------------------------------------
1652 {
1654  linearCombo(sec.alpha_[0],*ds.nextStoreLeadCurrQPtr, sec.alpha_[1],*ds.stoQn0Ptr);
1655 
1656  if (sec.currentOrder_ == 2)
1657  {
1659  linearCombo(1.0,*ds.nextStoreLeadCurrQDerivPtr, sec.alpha_[2], *(ds.stoLeadCurrQHistory[1]));
1660  }
1661 
1663 
1664  ds.nextStorePtr->linearCombo(1.0,*ds.nextStorePtr,1.0,*ds.nextStoreLeadCurrQDerivPtr);
1665 
1666  if (DEBUG_TIME && isActive(Diag::TIME_DUMP_SOLUTION_ARRAYS))
1667  {
1668  Xyce::dout() << "\n next store Ptr: \n" << std::endl;
1669  ds.nextStorePtr->printPetraObject(Xyce::dout());
1670  Xyce::dout() << std::endl;
1671  }
1672 }
1673 
1674 //-----------------------------------------------------------------------------
1675 // Function : OneStep::updateLeadCurrentVec
1676 // Purpose : calculates lead currents in lead current vector with
1677 // the leadCurrQVec.
1678 // Special Notes :
1679 // Scope : public
1680 // Creator : Richard Schiek, Electrical Systems Modeling, SNL
1681 // Creation Date : 03/22/2013
1682 //-----------------------------------------------------------------------------
1684 {
1687 
1688  if (sec.currentOrder_ == 2)
1689  {
1691  linearCombo(1.0,*ds.nextLeadCurrentQDerivPtr, sec.alpha_[2], *(ds.leadCurrentQHistory[1]));
1692  }
1693 
1695 
1697 
1698  if (DEBUG_TIME && isActive(Diag::TIME_DUMP_SOLUTION_ARRAYS))
1699  {
1700  Xyce::dout() << "\n next leadcurrent q Ptr: \n" << std::endl;
1701  ds.nextLeadCurrentPtr->printPetraObject(Xyce::dout());
1702  Xyce::dout() << std::endl;
1703  }
1704 }
1705 
1706 
1707 //-----------------------------------------------------------------------------
1708 // Function : Gear12::getInitialQnorm
1709 // Purpose : Needed by 2-level solves.
1710 // Special Notes :
1711 // Scope : public
1712 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1713 // Creation Date : 03/18/07
1714 //-----------------------------------------------------------------------------
1716 {
1717  tle.q1HistorySum = ds.partialSum_q1();
1718 }
1719 
1720 //-----------------------------------------------------------------------------
1721 // Function : Gear12::setupTwoLevelError
1722 // Purpose : Needed by 2-level solves.
1723 // Special Notes :
1724 // Scope : public
1725 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
1726 // Creation Date : 03/15/07
1727 //-----------------------------------------------------------------------------
1729 {
1730  tle.xErrorSum = ds.partialErrorNormSum ();
1735  tle.innerSize = ds.globalLength ();
1736 
1737  if (DEBUG_TIME && isActive(Diag::TIME_ERROR))
1738  Xyce::dout() << tle;
1739 }
1740 
1742 {
1743  if (sec.currentTimeStep < 1e-30)
1744  {
1745  Xyce::Report::UserWarning() << "Excessively small current time step, incorrectly returning with large value";
1746 
1747  return leadingCoeff * 1.e+30;
1748  }
1749 
1750  return leadingCoeff / sec.currentTimeStep;
1751 }
1752 
1753 } // namespace TimeIntg
1754 } // namespace Xyce
bool interpolateMPDESolution(std::vector< double > &timepoint, Linear::Vector *tmpSolVectorPtr)
Definition: N_TIA_Gear12.C:449
void rejectStep(const TIAParams &tia_params)
Linear::Vector * sNewtonCorrectionPtr
Linear::Vector * nextLeadCurrentQPtr
Linear::Vector * leadCurrentQn0Ptr
Gear12(const TIAParams &tia_params, StepErrorControl &step_error_control, DataStore &data_store)
Definition: N_TIA_Gear12.C:103
Linear::Vector * tmpLeadDeltaVPtr
std::vector< Linear::Vector * > nextDqdpPtrVector
static const char * name
Definition: N_TIA_Gear12.h:75
std::vector< std::vector< Linear::Vector * > > dQdxdXdpHistory
Linear::Vector * qErrWtVecPtr
Pure virtual class to augment a linear system.
int nIterations
Number of newton iterations.
std::vector< double > dOdpVec_
std::vector< double > scaled_dOdpVec_
void getInitialQnorm(TwoLevelError &tle) const
std::vector< Linear::Vector * > nextDXdpPtrVector
Linear::Vector * tmpStaVectorPtr
Linear::Vector * currStorePtr
std::vector< double > scaled_dOdpAdjVec_
std::vector< Linear::Vector * > leadDeltaVHistory
Linear::Vector * tmpSolVectorPtr
std::vector< Linear::Vector * > nextDbdpPtrVector
double partialSum_m2(int currentOrder)
bool interpolateSolution(double timepoint, Linear::Vector *tmpSolVectorPtr, std::vector< Linear::Vector * > &historyVec)
Definition: N_TIA_Gear12.C:406
int errorAnalysisOption
Error analysis option.
Linear::Vector * tmpStoVectorPtr
std::vector< Linear::Vector * > nextDfdpPtrVector
void completeStep(const TIAParams &tia_params)
bool printOutputSolution(Analysis::OutputMgrAdapter &outputManagerAdapter, const TIAParams &tia_params, const double time, Linear::Vector *solnVecPtr, const bool doNotInterpolate, const std::vector< double > &outputInterpolationTimes, bool skipPrintLineOutput)
Definition: N_TIA_Gear12.C:568
std::vector< Linear::Vector * > qHistory
Linear::Vector * nextLeadDeltaVPtr
Linear::Vector * currStatePtr
std::vector< double > objectiveVec_
std::vector< Linear::Vector * > currDXdpPtrVector
std::vector< Linear::Vector * > leadCurrentHistory
bool constantTimeStepFlag
Constant time step integration flag.
static TimeIntegrationMethod * factory(const TIAParams &tia_params, StepErrorControl &step_error_control, DataStore &data_store)
Definition: N_TIA_Gear12.C:87
void initialize(const TIAParams &tia_params)
Definition: N_TIA_Gear12.C:965
Linear::Vector * daeQVectorPtr
Linear::Vector * tmpLeadCurrentVectorPtr
double partialSum_p1(int currentOrder, int maxOrder)
Linear::Vector * daeFVectorPtr
Linear::Vector * qNewtonCorrectionPtr
Linear::Vector * currLeadCurrentQPtr
double leadingCoeff
Time-integration method leading coefficient value.
Definition: N_TIA_Gear12.h:256
Linear::Vector * nextStoreLeadCurrQDerivPtr
Linear::Matrix * dFdxMatrixPtr
Linear::Matrix * JMatrixPtr
Linear::Vector * nextStatePtr
std::vector< Linear::Vector * > leadCurrentQHistory
void tranOutput(double time, Linear::Vector &currSolutionPtr, Linear::Vector &stateVecPtr, Linear::Vector &storeVecPtr, Linear::Vector &lead_current_vector, Linear::Vector &junction_voltage_vector, std::vector< double > &objectiveVec_, std::vector< double > &dOdpVec_, std::vector< double > &dOdpAdjVec_, std::vector< double > &scaled_dOdpVec_, std::vector< double > &scaled_dOdpAdjVec_, bool skipPrintLineOutput=false)
DataStore & ds
Reference to the TIA data-store object.
Definition: N_TIA_Gear12.h:254
Linear::Vector * dFdxdVpVectorPtr
double computeExpoStepAdjust(double stepadjust)
Definition: N_TIA_Gear12.C:216
std::vector< std::vector< Linear::Vector * > > dqdpHistory
Linear::Vector * currLeadDeltaVPtr
bool printWaMPDEOutputSolution(Analysis::OutputMgrAdapter &outputManagerAdapter, const double time, Linear::Vector *solnVecPtr, const std::vector< double > &fastTimes, const int phiGID)
Definition: N_TIA_Gear12.C:548
Linear::Vector * currStoreLeadCurrQPtr
Linear::Vector * nextSolutionPtr
void getTwoLevelError(TwoLevelError &tle) const
Linear::Vector * RHSVectorPtr
bool printMPDEOutputSolution(Analysis::OutputMgrAdapter &outputManagerAdapter, const double time, Linear::Vector *solnVecPtr, const std::vector< double > &fastTimes)
Definition: N_TIA_Gear12.C:530
Linear::Vector * nextStorePtr
Linear::Vector * stoQn0Ptr
bool saveOutputSolution(Analysis::OutputMgrAdapter &outputManagerAdapter, const TIAParams &tia_params, Linear::Vector *solnVecPtr, const double saveTime, const bool doNotInterpolate)
Definition: N_TIA_Gear12.C:651
Linear::Vector * dQdxdVpVectorPtr
Linear::Vector * currLeadCurrentPtr
std::vector< double > dOdpAdjVec_
double partialTimeDeriv() const
std::vector< Linear::Vector * > lastDQdxDXdpPtrVector
Linear::Vector * nextLeadCurrentQDerivPtr
Linear::Vector * newtonCorrectionPtr
Linear::Vector * currSolutionPtr
StepErrorControl & sec
Reference to step-error control object.
Definition: N_TIA_Gear12.h:255
std::vector< Linear::Vector * > stoHistory
void obtainSensitivityPredictors()
Definition: N_TIA_Gear12.C:210
Linear::Vector * nextStoreLeadCurrQPtr
Linear::Vector * nextStateDerivPtr
std::vector< Linear::Vector * > xHistory
void outputDCOP(const Linear::Vector &solution)
std::vector< Linear::Vector * > sensRHSPtrVector
Linear::Matrix * dQdxMatrixPtr
std::vector< Linear::Vector * > currDQdxDXdpPtrVector
double partialSum_m1(int currentOrder)
std::vector< std::vector< Linear::Vector * > > dXdpHistory
Linear::Vector * daeBVectorPtr
std::vector< Linear::Vector * > nextDQdxDXdpPtrVector
std::vector< Linear::Vector * > currDqdpPtrVector
std::vector< Linear::Vector * > stoLeadCurrQHistory
void setTwoLevelTimeInfo(const TimeIntInfo &tiInfo)
double timept_
Keep track of last interpolation point in printMPDEOutputSolution.
Definition: N_TIA_Gear12.h:253
Linear::Vector * nextLeadCurrentPtr
std::vector< Linear::Vector * > lastDXdpPtrVector
std::vector< Linear::Vector * > sHistory