47 #include <Xyce_config.h>
51 #include <N_UTL_Misc.h>
65 #include <N_ERH_ErrorMgr.h>
67 #include <N_LAS_Vector.h>
68 #include <N_LAS_Matrix.h>
69 #include <N_LAS_BlockVector.h>
70 #include <N_LAS_System.h>
72 #include <N_PDS_Comm.h>
73 #include <N_PDS_Manager.h>
94 sec.maxOrder_=(Xycemin(5,tiaParams.maxOrder));
95 sec.minOrder_=(Xycemax(1,tiaParams.minOrder));
96 if (sec.minOrder_ > sec.maxOrder_)
98 sec.minOrder_ = sec.maxOrder_;
116 for (
int i=sec.nscsco_;i<=sec.currentOrder_;++i)
118 (ds.xHistory[i])->scale(sec.beta_[i]);
119 (ds.qHistory[i])->scale(sec.beta_[i]);
120 (ds.sHistory[i])->scale(sec.beta_[i]);
121 (ds.stoHistory[i])->scale(sec.beta_[i]);
122 (ds.stoLeadCurrQCompHistory[i])->scale(sec.beta_[i]);
126 *ds.xn0Ptr = *(ds.xHistory[0]);
127 *ds.qn0Ptr = *(ds.qHistory[0]);
128 *ds.sn0Ptr = *(ds.sHistory[0]);
129 *ds.ston0Ptr = *(ds.stoHistory[0]);
130 *ds.stoQCn0Ptr = *(ds.stoLeadCurrQCompHistory[0]);
132 ds.qpn0Ptr->putScalar(0.0);
133 ds.spn0Ptr->putScalar(0.0);
134 ds.stopn0Ptr->putScalar(0.0);
135 ds.stoQCpn0Ptr->putScalar(0.0);
136 for (
int i=1;i<=sec.currentOrder_;++i)
138 ds.xn0Ptr->linearCombo(1.0,*(ds.xHistory[i]),1.0,*ds.xn0Ptr);
139 ds.qn0Ptr->linearCombo(1.0,*(ds.qHistory[i]),1.0,*ds.qn0Ptr);
140 ds.sn0Ptr->linearCombo(1.0,*(ds.sHistory[i]),1.0,*ds.sn0Ptr);
141 ds.ston0Ptr->linearCombo(1.0,*(ds.stoHistory[i]),1.0,*ds.ston0Ptr);
142 ds.stoQCn0Ptr->linearCombo(1.0,*(ds.stoLeadCurrQCompHistory[i]),1.0,*ds.stoQCn0Ptr);
143 ds.qpn0Ptr->linearCombo(sec.gamma_[i],*(ds.qHistory[i]),1.0,*ds.qpn0Ptr);
144 ds.spn0Ptr->linearCombo(sec.gamma_[i],*(ds.sHistory[i]),1.0,*ds.spn0Ptr);
145 ds.stopn0Ptr->linearCombo(sec.gamma_[i],*(ds.stoHistory[i]),1.0,*ds.stopn0Ptr);
146 ds.stoQCpn0Ptr->linearCombo(sec.gamma_[i],*(ds.stoLeadCurrQCompHistory[i]),1.0,*ds.stoQCpn0Ptr);
150 #ifdef Xyce_DEBUG_TIME
151 Xyce::dout().width(21); cout.precision(13); cout.setf(std::ios::scientific);
153 if (tiaParams.debugLevel > 1)
155 Xyce::dout() << std::endl;
156 Xyce::dout() << Xyce::section_divider << std::endl;
157 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::obtainPredictor" << std::endl;
158 Xyce::dout() <<
"\n currentOrder = " << sec.currentOrder_ << endl;
159 Xyce::dout() <<
"\n sec.nscsco_: " << sec.nscsco_ << endl;
160 for (
int i=0; i<=sec.currentOrder_ ; ++i)
161 Xyce::dout() <<
"\n sec.beta_[" << i <<
"] = " << sec.beta_[i] <<
"\n" << endl;
162 for (
int i=0; i<=sec.currentOrder_ ; ++i)
164 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
165 (ds.xHistory[i])->printPetraObject(Xyce::dout());
166 Xyce::dout() << endl;
168 for (
int i=0; i<=sec.currentOrder_ ; ++i)
170 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
171 (ds.qHistory[i])->printPetraObject(Xyce::dout());
172 Xyce::dout() << endl;
174 for (
int i=0; i<=sec.currentOrder_ ; ++i)
176 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
177 (ds.sHistory[i])->printPetraObject(Xyce::dout());
178 Xyce::dout() << endl;
180 Xyce::dout() <<
"\n xn0: \n" << endl;
181 ds.xn0Ptr->printPetraObject(Xyce::dout());
182 Xyce::dout() << endl;
183 Xyce::dout() <<
"\n qn0: \n" << endl;
184 ds.qn0Ptr->printPetraObject(Xyce::dout());
185 Xyce::dout() << endl;
186 Xyce::dout() <<
"\n qpn0: \n" << endl;
187 ds.qpn0Ptr->printPetraObject(Xyce::dout());
188 Xyce::dout() << endl;
189 Xyce::dout() <<
"\n sn0: \n" << endl;
190 ds.sn0Ptr->printPetraObject(Xyce::dout());
191 Xyce::dout() << endl;
192 Xyce::dout() <<
"\n spn0: \n" << endl;
193 ds.spn0Ptr->printPetraObject(Xyce::dout());
194 Xyce::dout() << endl;
195 Xyce::dout() <<
"\n stoQCn0Ptr: \n" << endl;
196 ds.stoQCn0Ptr->printPetraObject(Xyce::dout());
197 Xyce::dout() << endl;
198 Xyce::dout() <<
"\n stoQCpn0Ptr: \n" << endl;
199 ds.stoQCpn0Ptr->printPetraObject(Xyce::dout());
200 Xyce::dout() << endl;
201 Xyce::dout() << Xyce::section_divider << std::endl;
203 #endif // Xyce_DEBUG_TIME
205 *(ds.nextSolutionPtr) = *(ds.xn0Ptr);
227 ds.RHSVectorPtr->linearCombo(1.0,*ds.daeQVectorPtr,-1.0,*ds.qn0Ptr);
228 ds.RHSVectorPtr->linearCombo(1.0,*ds.qpn0Ptr,-sec.alphas_/sec.currentTimeStep,*ds.RHSVectorPtr);
230 #ifdef Xyce_DEBUG_TIME
231 if (tiaParams.debugLevel > 1)
233 Xyce::dout() << std::endl;
234 Xyce::dout() << Xyce::section_divider << std::endl;
235 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::obtainResidual" << std::endl;
236 Xyce::dout() <<
"\n t = " << sec.nextTime <<
"\n" << endl;
237 Xyce::dout() <<
"\n solution: \n" << endl;
238 ds.nextSolutionPtr->printPetraObject(Xyce::dout());
239 Xyce::dout() <<
"\n daeQVector: \n" << endl;
240 ds.daeQVectorPtr->printPetraObject(Xyce::dout());
241 Xyce::dout() <<
"\n qn0: \n" << endl;
242 ds.qn0Ptr->printPetraObject(Xyce::dout());
243 Xyce::dout() <<
"\n qpn0: \n" << endl;
244 ds.qpn0Ptr->printPetraObject(Xyce::dout());
245 Xyce::dout() <<
"\n sec.alphas_/hn: " << sec.alphas_/sec.currentTimeStep <<
"\n" << endl;
246 Xyce::dout() <<
"\n daeFVector: \n" << endl;
247 ds.daeFVectorPtr->printPetraObject(Xyce::dout());
249 Xyce::dout() <<
"\n dQdt-vector: \n" << endl;
250 ds.RHSVectorPtr->printPetraObject(Xyce::dout());
251 Xyce::dout() << endl;
255 ds.RHSVectorPtr->linearCombo(1.0,*ds.RHSVectorPtr,+1.0,*ds.daeFVectorPtr);
258 ds.RHSVectorPtr->scale(-1.0);
263 (ds.dQdxdVpVectorPtr)->scale( -sec.alphas_/sec.currentTimeStep );
265 (ds.RHSVectorPtr)->daxpy(
266 *(ds.RHSVectorPtr), +1.0, *(ds.dQdxdVpVectorPtr));
268 (ds.RHSVectorPtr)->daxpy(
269 *(ds.RHSVectorPtr), +1.0, *(ds.dFdxdVpVectorPtr));
272 #ifdef Xyce_DEBUG_TIME
273 if (tiaParams.debugLevel > 1)
275 Xyce::dout() <<
"\n Residual-vector: \n" << endl;
276 Xyce::dout() <<
"-(qpn0-(sec.alpha_s/h)*(Q-qn0)+F-B) \n" << endl;
277 ds.RHSVectorPtr->printPetraObject(Xyce::dout());
278 Xyce::dout() << Xyce::section_divider << std::endl;
279 Xyce::dout() << endl;
297 #ifdef Xyce_DEBUG_TIME
298 if (tiaParams.debugLevel > 1)
300 Xyce::dout() << std::endl;
301 Xyce::dout() << Xyce::section_divider << std::endl;
302 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::obtainJacobian" << std::endl;
313 N_LAS_Matrix & dQdx = *(ds.dQdxMatrixPtr);
314 N_LAS_Matrix & dFdx = *(ds.dFdxMatrixPtr);
315 N_LAS_Matrix & Jac = *(ds.JMatrixPtr);
317 double qscalar(-sec.alphas_/sec.currentTimeStep);
319 Jac.linearCombo( qscalar, dQdx, 1.0, dFdx );
321 #ifdef Xyce_DEBUG_TIME
322 if (tiaParams.debugLevel > 1)
324 Xyce::dout() <<
"\n dFdx:" <<endl;
325 dFdx.printPetraObject(Xyce::dout());
326 Xyce::dout() <<
"\n Total Jacobian:" <<endl;
327 Jac.printPetraObject(Xyce::dout());
333 Xyce::dout() << Xyce::section_divider << std::endl;
334 Xyce::dout() << endl;
353 N_LAS_Vector * tmpSolVectorPtr, std::vector<N_LAS_Vector*> & historyVec)
365 double tn = sec.currentTime;
366 double hh = sec.currentTimeStep;
367 double hused = sec.usedStep_;
368 int kused = sec.usedOrder_;
373 double uround = N_UTL_MachineDependentParams::MachinePrecision();
375 tfuzz = 100 * uround * (tn + hh);
376 tp = tn - hused - tfuzz;
378 if ( (timepoint - tp)*hh < 0.0 )
381 *tmpSolVectorPtr = *(historyVec[0]);
383 if ( (kused == 0) || (timepoint == tn) )
386 delt = timepoint - tn;
387 gam = delt/sec.psi_[0];
388 for (
int j=1 ; j <= kord ; ++j)
391 gam = (delt + sec.psi_[j-1])/sec.psi_[j];
392 tmpSolVectorPtr->linearCombo(1.0,*tmpSolVectorPtr,c,*(historyVec[j]));
415 N_LAS_Vector * tmpSolVectorPtr)
426 N_LAS_BlockVector * blockTempSolVectorPtr =
427 dynamic_cast<N_LAS_BlockVector*
>(tmpSolVectorPtr);
428 if (blockTempSolVectorPtr == NULL)
430 std::string msg =
"N_TIA_BackwardDifferentiation15::interpolateMPDESolution: ";
431 msg +=
"N_LAS_Vector tmpSolVectorPtr is not of type N_LAS_BlockVector";
432 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
438 int numblocks = timepoint.size();
439 int blockCount = blockTempSolVectorPtr->blockCount();
440 if (numblocks > blockCount)
442 std::string msg =
"N_TIA_BackwardDifferentiation15::interpolateMPDESolution: ";
443 msg +=
"Number of time points requested is greater than number of fast time points in MPDE block vector";
444 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
451 double tn = sec.currentTime;
452 double hh = sec.currentTimeStep;
453 double hused = sec.usedStep_;
454 int kused = sec.usedOrder_;
457 tfuzz = 100 * uround * (tn + hh);
458 tp = tn - hused - tfuzz;
459 for (
int i=0; i<numblocks ; ++i)
461 if ( (timepoint[i] - tp)*hh < 0.0 )
465 *tmpSolVectorPtr = *(ds.xHistory[0]);
467 N_LAS_Vector * solVectorPtr;
468 N_LAS_Vector * xHistoryVectorPtr;
470 for (
int i=0; i < numblocks ; ++i)
472 if ((kused == 0) || (timepoint[i] == tn)) { kord = 1; }
473 else { kord = kused; }
474 solVectorPtr = &(blockTempSolVectorPtr->block(i));
476 delt = timepoint[i] - tn;
477 gam = delt/sec.psi_[0];
478 for (
int j=1 ; j <= kord ; ++j)
481 gam = (delt + sec.psi_[j-1])/sec.psi_[j];
482 N_LAS_BlockVector * blockXHistoryVectorPtr =
483 dynamic_cast<N_LAS_BlockVector*>(ds.xHistory[j]);
484 if (blockXHistoryVectorPtr == NULL)
486 Xyce::Report::DevelFatal0().in(
"N_TIA_BackwardDifferentiation15::interpolateMPDESolution") <<
"N_LAS_Vector ds.xHistory[j] is not of type N_LAS_BlockVector\n j = " << j;
489 xHistoryVectorPtr = &(blockXHistoryVectorPtr->block(i));
490 solVectorPtr->linearCombo(1.0,*solVectorPtr,c,*xHistoryVectorPtr);
505 RefCountPtr< N_ANP_OutputMgrAdapter > outputMgrAdapterRCPtr,
507 N_LAS_Vector * solnVecPtr,
508 const std::vector<double> & fastTimes )
510 #ifdef Xyce_DEBUG_TIME
511 if (tiaParams.debugLevel > 0)
513 Xyce::dout() << std::endl;
514 Xyce::dout() << Xyce::section_divider << std::endl;
515 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::printMPDEOutputSolution" << std::endl;
517 #endif // Xyce_DEBUG_TIME
518 double timestep = sec.lastAttemptedTimeStep;
519 double lasttime = sec.currentTime - timestep;
520 double tn = sec.currentTime;
522 double beg_of_output_time_interval = lasttime;
523 double end_of_output_time_interval = tn;
524 double start_time = max(lasttime,beg_of_output_time_interval);
525 double stop_time = min(tn,end_of_output_time_interval);
526 #ifdef Xyce_DEBUG_TIME
527 if (tiaParams.debugLevel > 0)
529 Xyce::dout() <<
"timestep = " << timestep << endl;
530 Xyce::dout() <<
"lasttime = " << lasttime << endl;
531 Xyce::dout() <<
"tn = " << tn << endl;
532 Xyce::dout() <<
"beg_of_output_time_interval = " << beg_of_output_time_interval << endl;
533 Xyce::dout() <<
"end_of_output_time_interval = " << end_of_output_time_interval << endl;
534 Xyce::dout() <<
"start_time = " << start_time << endl;
535 Xyce::dout() <<
"stop_time = " << stop_time << endl;
537 #endif // Xyce_DEBUG_TIME
540 N_LAS_BlockVector * blockTmpSolVectorPtr =
541 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpSolVectorPtr);
543 if (blockTmpSolVectorPtr == NULL)
545 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
546 msg +=
"N_LAS_Vector ds.tmpSolVectorPtr is not of type N_LAS_BlockVector";
547 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
550 int blockCount = blockTmpSolVectorPtr->blockCount();
553 double T2 = fastTimes.back();
555 double charcross = fmod(start_time,T2);
559 for (
int i=0 ; i<=blockCount ; ++i)
561 if (fastTimes[i] >= charcross)
569 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
570 msg +=
"Cannot find where characteristic curve crosses fast time slice at start_time";
571 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
574 std::vector<double> h2(blockCount,0);
575 for (
int j=0 ; j < blockCount ; ++j)
577 h2[j] = fastTimes[j+1] - fastTimes[j];
579 std::vector<double> ti;
581 double first_interp = start_time - charcross + fastTimes[s_ind_0];
582 #ifdef Xyce_DEBUG_TIME
583 if (tiaParams.debugLevel > 0)
585 Xyce::dout() <<
"first_interp = " << first_interp << endl;
587 #endif // Xyce_DEBUG_TIME
588 if (s_ind_0 == blockCount) { s_ind_0 = 0; };
590 double eps = fabs(start_time)*1.0e-6;
591 if ( fabs(first_interp-timept_) <= eps )
593 first_interp += h2[s_ind_0];
595 if (s_ind_0 == blockCount) { s_ind_0 = 0; };
596 #ifdef Xyce_DEBUG_TIME
597 if (tiaParams.debugLevel > 0)
599 Xyce::dout() <<
"Moving first_interp forward to avoid duplicate outputs: " << first_interp << endl;
601 #endif // Xyce_DEBUG_TIME
604 double t = first_interp;
605 while (t <= stop_time)
610 if (sn >= blockCount) { sn = 0; }
612 #ifdef Xyce_DEBUG_TIME
613 if (tiaParams.debugLevel > 0)
615 Xyce::dout() <<
"T2 = " << T2 << endl;
616 Xyce::dout() <<
"charcross = " << charcross << endl;
617 Xyce::dout() <<
"s_ind_0 = " << s_ind_0 << endl;
618 Xyce::dout() <<
"Expecting to interpolate the following points:" << endl;
619 unsigned int numinterp = ti.size();
620 for (
unsigned int i=0 ; i < numinterp ; ++i)
622 Xyce::dout() << ti[i] << endl;
624 Xyce::dout() <<
"Total of " << numinterp <<
" points" << endl;
626 #endif // Xyce_DEBUG_TIME
627 timept_ = start_time;
628 unsigned int tinum = ti.size();
629 int total_interp = 0;
630 std::vector<double> timepoint_vec(blockCount,stop_time);
631 int num_interp_this_cycle = 0;
633 for (
unsigned int i=0; i < tinum ; ++i)
635 timepoint_vec[s_ind] = ti[i];
636 num_interp_this_cycle++;
638 if (s_ind >= blockCount) { s_ind = 0; };
640 if ((s_ind == s_ind_0) || (i == tinum-1))
642 interpolateMPDESolution(timepoint_vec, ds.tmpSolVectorPtr);
645 for (
int j=0 ; j < num_interp_this_cycle ; ++j)
647 timept_ = timepoint_vec[s];
648 outputMgrAdapterRCPtr->tranOutput(
649 timept_, blockTmpSolVectorPtr->block(s),
650 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
651 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
652 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_);
655 if (s >= blockCount) { s = 0; }
656 #ifdef Xyce_DEBUG_TIME
657 Xyce::dout() <<
"Interpolated to t = " << timept_ << endl;
658 #endif // Xyce_DEBUG_TIME
660 num_interp_this_cycle = 0;
663 #ifdef Xyce_DEBUG_TIME
664 Xyce::dout() <<
"Total of " << total_interp <<
" points" << endl;
665 #endif // Xyce_DEBUG_TIME
668 eps = fabs(stop_time)*1.0e-8;
670 if (fabs(timept_ - stop_time) >= eps)
672 #ifdef Xyce_DEBUG_TIME
673 if (tiaParams.debugLevel > 0)
675 Xyce::dout() <<
"Previous timept = " << timept_ << endl;
676 Xyce::dout() <<
"Expecting to interpolate the following point: " << stop_time << endl;
678 #endif // Xyce_DEBUG_TIME
679 N_LAS_Vector* tmpSolnVecPtr = solnVecPtr;
680 N_LAS_Vector* tmpVecPtr = ds.tmpXn0APtr;
683 interpolateSolution(stop_time,ds.tmpXn0BPtr, ds.xHistory);
684 tmpSolnVecPtr = ds.tmpXn0BPtr;
686 N_LAS_BlockVector * blockTmpSolnVecPtr =
687 dynamic_cast<N_LAS_BlockVector*
>(tmpSolnVecPtr);
688 N_LAS_BlockVector * blockTmpVecPtr =
689 dynamic_cast<N_LAS_BlockVector*
>(tmpVecPtr);
690 if (blockTmpSolnVecPtr == NULL)
692 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
693 msg +=
"N_LAS_Vector tmpSolnVecPtr is not of type N_LAS_BlockVector";
694 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
697 if (blockTmpVecPtr == NULL)
699 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
700 msg +=
"N_LAS_Vector tmpVecPtr is not of type N_LAS_BlockVector";
701 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
706 charcross = fmod(stop_time,T2);
709 if( charcross < fastTimes[0] )
712 s_ind_1 = blockCount-1;
716 for (
int i=blockCount-1 ; i>=0 ; --i)
718 if (fastTimes[i] <= charcross)
727 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
728 msg +=
"Cannot find where characteristic curve crosses fast time slice at stop_time";
729 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
734 double coeff_sm = fastTimes[sp]-charcross;
735 double coeff_sp = charcross-fastTimes[sm];
736 if (sp == blockCount) { sp = 0; }
737 double dt = h2[s_ind_1];
739 #ifdef Xyce_DEBUG_TIME
740 Xyce::dout() <<
"charcross = " << charcross << endl;
741 Xyce::dout() <<
"s_ind_1 = " << s_ind_1 << endl;
742 Xyce::dout() <<
"sp = " << sp << endl;
743 Xyce::dout() <<
"sm = " << sm << endl;
744 Xyce::dout() <<
"dt = " << dt << endl;
745 Xyce::dout() <<
"timept = " << timept_ << endl;
746 Xyce::dout() <<
"coeff_sm = " << coeff_sm << endl;
747 Xyce::dout() <<
"coeff_sp = " << coeff_sp << endl;
748 #endif // Xyce_DEBUG_TIME
749 blockTmpVecPtr->block(0).linearCombo(
750 coeff_sm/dt, blockTmpSolnVecPtr->block(sm),
751 coeff_sp/dt, blockTmpSolnVecPtr->block(sp)
753 outputMgrAdapterRCPtr->tranOutput(
754 timept_, blockTmpVecPtr->block(0),
755 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
756 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
757 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_);
759 #ifdef Xyce_DEBUG_TIME
760 Xyce::dout() <<
"Interpolated to t = " << timept_ << endl;
761 #endif // Xyce_DEBUG_TIME
763 #ifdef Xyce_DEBUG_TIME
766 if (tiaParams.debugLevel > 0)
768 Xyce::dout() <<
"No further interpolation required." << endl;
771 #endif // Xyce_DEBUG_TIME
773 #ifdef Xyce_DEBUG_TIME
774 Xyce::dout() << Xyce::section_divider << std::endl;
775 #endif // Xyce_DEBUG_TIME
789 RefCountPtr< N_ANP_OutputMgrAdapter > outputMgrAdapterRCPtr,
791 N_LAS_Vector * solnVecPtr,
792 const std::vector<double> & fastTimes,
795 #ifdef Xyce_DEBUG_TIME
796 if (tiaParams.debugLevel > 0)
798 Xyce::dout() << std::endl;
799 Xyce::dout() << Xyce::section_divider << std::endl;
801 " N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution" << std::endl;
803 #endif // Xyce_DEBUG_TIME
804 double timestep = sec.lastAttemptedTimeStep;
805 double lasttime = sec.currentTime - timestep;
806 double tn = sec.currentTime;
808 double beg_of_output_time_interval = lasttime;
809 double end_of_output_time_interval = tn;
810 double start_time = max(lasttime,beg_of_output_time_interval);
811 double stop_time = min(tn,end_of_output_time_interval);
812 #ifdef Xyce_DEBUG_TIME
813 if (tiaParams.debugLevel > 0)
815 Xyce::dout() <<
"start_time = " << start_time << endl;
816 Xyce::dout() <<
"stop_time = " << stop_time << endl;
818 #endif // Xyce_DEBUG_TIME
842 N_LAS_BlockVector * blockTmpSolVectorPtr =
843 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpSolVectorPtr);
844 N_LAS_BlockVector * blockTmpXn0APtr =
845 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpXn0APtr);
846 N_LAS_BlockVector * blockTmpXn0BPtr =
847 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpXn0BPtr);
848 if (blockTmpSolVectorPtr == NULL)
850 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
851 msg +=
"N_LAS_Vector ds.tmpSolVectorPtr is not of type N_LAS_BlockVector";
852 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
855 if (blockTmpXn0APtr == NULL)
857 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
858 msg +=
"N_LAS_Vector ds.tmpXn0APtr is not of type N_LAS_BlockVector";
859 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
862 if (blockTmpXn0BPtr == NULL)
864 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
865 msg +=
"N_LAS_Vector ds.tmpXn0BPtr is not of type N_LAS_BlockVector";
866 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
869 int phiLID = blockTmpSolVectorPtr->pmap()->globalToLocalIndex(phiGID);
870 double hh = timestep/(sec.usedOrder_);
873 #ifdef Xyce_DEBUG_TIME
874 if (tiaParams.debugLevel > 0)
876 Xyce::dout() <<
" sec.usedOrder_ = " << sec.usedOrder_ << endl;
877 Xyce::dout() <<
" sec.currentTime_ = " << sec.currentTime << endl;
878 Xyce::dout() <<
" lasttime = " << lasttime << endl;
880 #endif // Xyce_DEBUG_TIME
882 for (
int i=0 ; i < sec.usedOrder_ ; ++i)
887 timeA = lasttime + hh*i;
888 junk = interpolateSolution(timeA,ds.tmpXn0APtr, ds.xHistory);
891 std::string msg =
"interpolateSolution returned false!";
892 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0,msg);
898 *ds.tmpXn0APtr = *ds.tmpXn0BPtr;
901 timeB = lasttime + hh*(i+1);
902 interpolateSolution(timeB,ds.tmpXn0BPtr, ds.xHistory);
903 #ifdef Xyce_DEBUG_TIME
904 if (tiaParams.debugLevel > 0)
906 Xyce::dout() <<
"Interpolating in [ " << timeA <<
", " << timeB <<
" ]" << endl;
907 Xyce::dout() <<
"timeA = " << timeA << endl;
908 Xyce::dout() <<
"timeB = " << timeB << endl;
910 #endif // Xyce_DEBUG_TIME
913 std::vector<double> t1vals;
914 double T2 = fastTimes.back();
915 int blockCount = blockTmpSolVectorPtr->blockCount();
916 double h2 = T2/blockCount;
917 double tval = timeA+h2;
918 while (tval <= timeB)
920 t1vals.push_back(tval);
924 double eps = fabs(timeB)*1.0e-8;
925 if ( (t1vals.size() == 0) || (fabs(t1vals.back() - timeB) >= eps) )
927 t1vals.push_back(timeB);
929 std::vector<double> t2vals, phiAB(2);
930 std::vector<double> tmpPhiAB(2, 0.0);
933 tmpPhiAB[0] = (*ds.tmpXn0APtr)[phiLID];
934 tmpPhiAB[1] = (*ds.tmpXn0BPtr)[phiLID];
936 blockTmpSolVectorPtr->pmap()->pdsComm()->sumAll( &tmpPhiAB[0], &phiAB[0], 2 );
938 double phiA = phiAB[0], phiB = phiAB[1];
939 for (
unsigned int j=0 ; j<t1vals.size() ; ++j)
941 double phi = (1/(timeB-timeA))*(phiA*(timeB-t1vals[j])+phiB*(t1vals[j]-timeA));
942 t2vals.push_back(fmod(phi,T2));
944 #ifdef Xyce_DEBUG_TIME
945 if (tiaParams.debugLevel > 0)
947 Xyce::dout() <<
"t1vals = " << endl;
948 for (
unsigned int j=0 ; j < t1vals.size() ; ++j)
950 Xyce::dout() << t1vals[j] << endl;
952 Xyce::dout() <<
"phi(" << timeA <<
") = " << phiA << endl;
953 Xyce::dout() <<
"phi(" << timeB <<
") = " << phiB << endl;
954 Xyce::dout() <<
"t2vals = " << endl;
955 for (
unsigned int j=0 ; j< t2vals.size() ; ++j)
957 Xyce::dout() << t2vals[j] << endl;
960 #endif // Xyce_DEBUG_TIME
965 double t = t1vals[0];
966 double s = t2vals[0];
970 for (
int j=0 ; j < blockCount ; ++j)
972 if ((fastTimes[j] <= s) && (s < fastTimes[j+1]))
978 if (b2 == blockCount)
982 double s1 = fastTimes[b1];
983 double s2 = fastTimes[b1+1];
984 if ((s < s1) || (s > s2))
986 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
987 msg +=
" Interpolator cannot find a fast time block containing the first point ";
988 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
990 #ifdef Xyce_DEBUG_TIME
991 Xyce::dout() <<
"Found s = " << s <<
" in block " << b1;
992 Xyce::dout() <<
" with boundary = [" << s1 <<
"," << s2 <<
"]" << endl;
993 #endif // Xyce_DEBUG_TIME
994 for (
unsigned int j=0 ; j < t1vals.size() ; ++j)
1000 if ( (s < s1) || (s > s2) )
1002 #ifdef Xyce_DEBUG_TIME
1003 Xyce::dout() <<
"Incrementing fast time block for next interpolation." << endl;
1004 #endif // Xyce_DEBUG_TIME
1006 if (b1 == blockCount)
1011 if (b2 == blockCount)
1016 s2 = fastTimes[b1+1];
1019 if ((s < s1) || (s > s2))
1021 #ifdef Xyce_DEBUG_TIME
1022 Xyce::dout() <<
"Searching for fast time block for next interpolation." << endl;
1023 #endif // Xyce_DEBUG_TIME
1025 for (
int j2=0 ; j2 < blockCount ; ++j2)
1027 if ((fastTimes[j2] <= s) && (s < fastTimes[j2+1]))
1033 if (b2 == blockCount)
1038 s2 = fastTimes[b1+1];
1041 if ((s < s1) || (s > s2))
1043 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
1044 msg +=
" Interpolator moved fast time block but new point is not in this block ";
1045 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1056 #ifdef Xyce_DEBUG_TIME
1057 if (tiaParams.debugLevel > 0)
1059 Xyce::dout() <<
"Interpolating in the block:" << endl;
1060 Xyce::dout() <<
"(t1,t2) = (" << t1 <<
"," << t2 <<
")" << endl;
1061 Xyce::dout() <<
"(s1,s2) = (" << s1 <<
"," << s2 <<
")" << endl;
1063 #endif // Xyce_DEBUG_TIME
1064 double denom = (t2-t1)*(s2-s1);
1065 double coeff0 = (t2-t)*(s2-s)/denom;
1066 double coeff1 = (t2-t)*(s-s1)/denom;
1067 double coeff2 = (t-t1)*(s2-s)/denom;
1068 double coeff3 = (t-t1)*(s-s1)/denom;
1069 (blockTmpSolVectorPtr->block(b1)).linearCombo(
1070 coeff0, blockTmpXn0APtr->block(b1),
1071 coeff1, blockTmpXn0APtr->block(b2),
1072 coeff2, blockTmpXn0BPtr->block(b1) );
1073 (blockTmpSolVectorPtr->block(b1)).update(
1074 coeff3, blockTmpXn0BPtr->block(b2), 1.0 );
1079 outputMgrAdapterRCPtr->tranOutput(
1080 t, blockTmpSolVectorPtr->block(b1),
1081 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
1082 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1083 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_);
1085 #ifdef Xyce_DEBUG_TIME
1086 Xyce::dout() <<
"Interpolated to (t,phi(t)) = (" << t <<
"," << s <<
")" << endl;
1087 #endif // Xyce_DEBUG_TIME
1092 #ifdef Xyce_DEBUG_TIME
1093 Xyce::dout() << Xyce::section_divider << std::endl;
1094 #endif // Xyce_DEBUG_TIME
1108 RefCountPtr< N_ANP_OutputMgrAdapter > outputMgrAdapterRCPtr,
1110 N_LAS_Vector * solnVecPtr,
1111 const bool doNotInterpolate,
1112 const std::vector<double> &outputInterpolationTimes,
1113 bool skipPrintLineOutput)
1115 #ifdef Xyce_DEBUG_TIME
1116 if (tiaParams.debugLevel > 0)
1118 Xyce::dout() << std::endl;
1119 Xyce::dout() << Xyce::section_divider << std::endl;
1121 " N_TIA_BackwardDifferentiation15::printOutputSolution" << std::endl;
1122 Xyce::dout() <<
"usedOrder_ = " << sec.usedOrder_ << endl;
1124 #endif // Xyce_DEBUG_TIME
1125 double timestep = sec.lastAttemptedTimeStep;
1126 double lasttime = sec.currentTime - timestep;
1127 bool dointerp =
true;
1128 double hh = timestep/(sec.usedOrder_);
1129 if (hh <= 10*sec.minTimeStep)
1134 if (!(tiaParams.interpOutputFlag))
1139 if (doNotInterpolate)
1144 if (dointerp && !outputInterpolationTimes.empty())
1146 for (
unsigned int i=0;i<outputInterpolationTimes.size();++i)
1148 interpolateSolution(outputInterpolationTimes[i], ds.tmpSolVectorPtr, ds.xHistory);
1149 interpolateSolution(outputInterpolationTimes[i], ds.tmpStaVectorPtr, ds.sHistory);
1150 interpolateSolution(outputInterpolationTimes[i], ds.tmpStoVectorPtr, ds.stoHistory);
1151 outputMgrAdapterRCPtr->tranOutput(outputInterpolationTimes[i], *ds.tmpSolVectorPtr,
1152 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
1153 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1154 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_,
1155 skipPrintLineOutput);
1158 else if ( (sec.usedOrder_ > 2) && dointerp )
1160 for (
int i=1 ; i<sec.usedOrder_; ++i)
1162 double timept = lasttime + hh*i;
1163 interpolateSolution(timept,ds.tmpSolVectorPtr, ds.xHistory);
1164 interpolateSolution(timept,ds.tmpStaVectorPtr, ds.sHistory);
1165 interpolateSolution(timept,ds.tmpStoVectorPtr, ds.stoHistory);
1166 outputMgrAdapterRCPtr->tranOutput(timept, *ds.tmpSolVectorPtr,
1167 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
1168 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1169 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_,
1170 skipPrintLineOutput);
1172 #ifdef Xyce_DEBUG_TIME
1173 Xyce::dout() <<
"Interpolated to t = " << timept << endl;
1174 #endif // Xyce_DEBUG_TIME
1181 if (outputInterpolationTimes.empty() || doNotInterpolate)
1182 outputMgrAdapterRCPtr->tranOutput(time, *ds.currSolutionPtr,
1183 *ds.currStatePtr, *ds.currStorePtr,
1184 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1185 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_,
1186 skipPrintLineOutput);
1188 #ifdef Xyce_DEBUG_TIME
1189 Xyce::dout() << Xyce::section_divider << std::endl;
1190 #endif // Xyce_DEBUG_TIME
1204 RefCountPtr< N_ANP_OutputMgrAdapter > outputMgrAdapterRCPtr,
1205 N_LAS_Vector * solnVecPtr,
1206 const double saveTime,
1207 const bool doNotInterpolate)
1209 #ifdef Xyce_DEBUG_TIME
1210 if (tiaParams.debugLevel > 0)
1212 Xyce::dout() << std::endl;
1213 Xyce::dout() << Xyce::section_divider << std::endl;
1215 " N_TIA_BackwardDifferentiation15::saveOutputSolution" << std::endl;
1217 #endif // Xyce_DEBUG_TIME
1219 double timestep = sec.lastAttemptedTimeStep;
1220 double lasttime = sec.currentTime - timestep;
1221 bool dointerp =
true;
1222 double hh = timestep/(sec.usedOrder_);
1223 if (hh <= 10*sec.minTimeStep)
1228 if (!(tiaParams.interpOutputFlag))
1233 if (doNotInterpolate)
1240 interpolateSolution(saveTime,ds.tmpSolVectorPtr, ds.xHistory);
1241 outputMgrAdapterRCPtr->outputDCOP( *(ds.tmpSolVectorPtr) );
1245 outputMgrAdapterRCPtr->outputDCOP( *(solnVecPtr) );
1248 #ifdef Xyce_DEBUG_TIME
1249 Xyce::dout() << Xyce::section_divider << std::endl;
1250 #endif // Xyce_DEBUG_TIME
1330 #ifdef Xyce_DEBUG_TIME
1331 if (tiaParams.debugLevel > 1)
1333 Xyce::dout() << std::endl;
1334 Xyce::dout() << Xyce::section_divider << std::endl;
1336 " N_TIA_BackwardDifferentiation15::updateHistory" << std::endl;
1337 Xyce::dout() <<
"\n Before updates \n" << endl;
1338 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1340 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
1341 (ds.xHistory[i])->printPetraObject(Xyce::dout());
1342 Xyce::dout() << endl;
1344 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1346 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
1347 (ds.qHistory[i])->printPetraObject(Xyce::dout());
1348 Xyce::dout() << endl;
1350 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1352 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
1353 (ds.sHistory[i])->printPetraObject(Xyce::dout());
1354 Xyce::dout() << endl;
1356 Xyce::dout() << Xyce::section_divider << std::endl;
1358 #endif // Xyce_DEBUG_TIME
1361 if (sec.usedOrder_ < sec.maxOrder_)
1363 *(ds.xHistory[sec.usedOrder_+1]) = *ds.newtonCorrectionPtr;
1364 *(ds.qHistory[sec.usedOrder_+1]) = *ds.qNewtonCorrectionPtr;
1367 (ds.xHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.xHistory[sec.usedOrder_]),1.0,*ds.newtonCorrectionPtr);
1368 (ds.qHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.qHistory[sec.usedOrder_]),1.0,*ds.qNewtonCorrectionPtr);
1369 for (
int j=sec.usedOrder_-1;j>=0;j--)
1371 (ds.xHistory[j])->linearCombo(1.0,*(ds.xHistory[j]),1.0,*(ds.xHistory[j+1]));
1372 (ds.qHistory[j])->linearCombo(1.0,*(ds.qHistory[j]),1.0,*(ds.qHistory[j+1]));
1376 if (sec.usedOrder_ < sec.maxOrder_)
1378 *(ds.sHistory[sec.usedOrder_+1]) = *ds.sNewtonCorrectionPtr;
1381 (ds.sHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.sHistory[sec.usedOrder_]),1.0,*ds.sNewtonCorrectionPtr);
1382 for (
int j=sec.usedOrder_-1;j>=0;j--)
1384 (ds.sHistory[j])->linearCombo(1.0,*(ds.sHistory[j]),1.0,*(ds.sHistory[j+1]));
1388 if (sec.usedOrder_ < sec.maxOrder_)
1390 *(ds.stoHistory[sec.usedOrder_+1]) = *ds.stoNewtonCorrectionPtr;
1391 *(ds.stoLeadCurrQCompHistory[sec.usedOrder_+1]) = *ds.stoLeadCurrQCompNewtonCorrectionPtr;
1394 (ds.stoHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.stoHistory[sec.usedOrder_]),1.0,*ds.stoNewtonCorrectionPtr);
1395 (ds.stoLeadCurrQCompHistory[sec.usedOrder_])->
1396 linearCombo(1.0,*(ds.stoLeadCurrQCompHistory[sec.usedOrder_]),1.0,*ds.stoLeadCurrQCompNewtonCorrectionPtr);
1397 for (
int j=sec.usedOrder_-1;j>=0;j--)
1399 (ds.stoHistory[j])->linearCombo(1.0,*(ds.stoHistory[j]),1.0,*(ds.stoHistory[j+1]));
1400 (ds.stoLeadCurrQCompHistory[j])->
1401 linearCombo(1.0,*(ds.stoLeadCurrQCompHistory[j]),1.0,*(ds.stoLeadCurrQCompHistory[j+1]));
1404 #ifdef Xyce_DEBUG_TIME
1405 if (tiaParams.debugLevel > 1)
1407 Xyce::dout() <<
"\n After updates \n" << endl;
1408 Xyce::dout() <<
"\n newtonCorrectionPtr: " << endl;
1409 ds.newtonCorrectionPtr->printPetraObject(Xyce::dout());
1410 Xyce::dout() <<
"\n qnewtonCorrectionPtr: " << endl;
1411 ds.qNewtonCorrectionPtr->printPetraObject(Xyce::dout());
1412 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1414 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
1415 (ds.xHistory[i])->printPetraObject(Xyce::dout());
1416 Xyce::dout() << endl;
1418 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1420 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
1421 (ds.qHistory[i])->printPetraObject(Xyce::dout());
1422 Xyce::dout() << endl;
1424 Xyce::dout() <<
"\n sNewtonCorrectionPtr: " << endl;
1425 ds.sNewtonCorrectionPtr->printPetraObject(Xyce::dout());
1426 Xyce::dout() << endl;
1427 Xyce::dout() <<
"\n nextStatePtr: " << endl;
1428 ds.nextStatePtr->printPetraObject(Xyce::dout());
1429 Xyce::dout() << endl;
1430 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1432 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
1433 (ds.sHistory[i])->printPetraObject(Xyce::dout());
1434 Xyce::dout() << endl;
1436 Xyce::dout() << Xyce::section_divider << std::endl;
1438 #endif // Xyce_DEBUG_TIME
1453 for (
int i=sec.nscsco_;i<=sec.currentOrder_;++i)
1455 (ds.xHistory[i])->scale(1/sec.beta_[i]);
1456 (ds.qHistory[i])->scale(1/sec.beta_[i]);
1457 (ds.sHistory[i])->scale(1/sec.beta_[i]);
1458 (ds.stoHistory[i])->scale(1/sec.beta_[i]);
1460 for (
int i=1;i<=sec.currentOrder_;++i)
1462 sec.psi_[i-1] = sec.psi_[i] - (sec.currentTimeStep);
1464 #ifdef Xyce_DEBUG_TIME
1465 if (tiaParams.debugLevel > 1)
1467 Xyce::dout() << std::endl;
1468 Xyce::dout() << Xyce::section_divider << std::endl;
1470 " N_TIA_BackwardDifferentiation15::restoreHistory" << std::endl;
1471 for (
int i=1;i<=sec.currentOrder_;++i)
1472 Xyce::dout() <<
"\n sec.psi_[i] = " << sec.psi_[i] << endl;
1473 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1475 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
1476 (ds.xHistory[i])->printPetraObject(Xyce::dout());
1477 Xyce::dout() << endl;
1479 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1481 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
1482 (ds.qHistory[i])->printPetraObject(Xyce::dout());
1483 Xyce::dout() << endl;
1485 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1487 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
1488 (ds.sHistory[i])->printPetraObject(Xyce::dout());
1489 Xyce::dout() << endl;
1491 Xyce::dout() << Xyce::section_divider << std::endl;
1493 #endif // Xyce_DEBUG_TIME
1508 #ifdef Xyce_DEBUG_TIME
1509 if (tiaParams.debugLevel > 0)
1511 Xyce::dout() << std::endl;
1512 Xyce::dout() << Xyce::section_divider << std::endl;
1515 " N_TIA_BackwardDifferentiation15::updateCoeffs" << std::endl;
1517 " currentTimeStep = " << sec.currentTimeStep << std::endl;
1519 " numberOfSteps_ = " << sec.numberOfSteps_ << std::endl;
1521 " currentOrder_ = " << sec.currentOrder_ << std::endl;
1523 " nscsco_ = " << sec.nscsco_ << std::endl;
1525 " psi_[0] = " << sec.psi_[0] << std::endl;
1533 if ((sec.currentTimeStep != sec.usedStep_) || (sec.currentOrder_ != sec.usedOrder_))
1535 sec.nscsco_ = min(sec.nscsco_+1,sec.usedOrder_+2);
1536 if (sec.currentOrder_+1 >= sec.nscsco_)
1539 sec.alpha_[0] = 1.0;
1540 double temp1 = sec.currentTimeStep;
1541 sec.sigma_[0] = 1.0;
1542 sec.gamma_[0] = 0.0;
1543 for (
int i=1;i<=sec.currentOrder_;++i)
1545 double temp2 = sec.psi_[i-1];
1546 sec.psi_[i-1] = temp1;
1547 sec.beta_[i] = sec.beta_[i-1]*sec.psi_[i-1]/temp2;
1548 temp1 = temp2 + sec.currentTimeStep;
1549 sec.alpha_[i] = (sec.currentTimeStep)/temp1;
1550 sec.sigma_[i] = (i+1)*sec.sigma_[i-1]*sec.alpha_[i];
1551 sec.gamma_[i] = sec.gamma_[i-1]+sec.alpha_[i-1]/(sec.currentTimeStep);
1553 sec.psi_[sec.currentOrder_] = temp1;
1556 for (
int i=0;i<sec.currentOrder_;++i)
1558 sec.alphas_ = sec.alphas_ - 1.0/(i+1.0);
1559 sec.alpha0_ = sec.alpha0_ - sec.alpha_[i];
1561 sec.cj_ = -sec.alphas_/(sec.currentTimeStep);
1562 sec.ck_ = abs(sec.alpha_[sec.currentOrder_]+sec.alphas_-sec.alpha0_);
1563 sec.ck_ = max(sec.ck_,sec.alpha_[sec.currentOrder_]);
1565 #ifdef Xyce_DEBUG_TIME
1566 if (tiaParams.debugLevel > 0)
1569 " nscsco_ = " << sec.nscsco_ << std::endl;
1571 " beta_[0] = " << sec.beta_[0] << std::endl;
1573 " beta_[1] = " << sec.beta_[1] << std::endl;
1575 " beta_[2] = " << sec.beta_[2] << std::endl;
1577 " beta_[3] = " << sec.beta_[3] << std::endl;
1579 " beta_[4] = " << sec.beta_[4] << std::endl;
1581 " alpha_[0] = " << sec.alpha_[0] << std::endl;
1583 " alpha_[1] = " << sec.alpha_[1] << std::endl;
1585 " alpha_[2] = " << sec.alpha_[2] << std::endl;
1587 " alpha_[3] = " << sec.alpha_[3] << std::endl;
1589 " alpha_[4] = " << sec.alpha_[4] << std::endl;
1591 " alphas_ = " << sec.alphas_ << std::endl;
1593 " alpha0_ = " << sec.alpha0_ << std::endl;
1595 " gamma_[0] = " << sec.gamma_[0] << std::endl;
1597 " gamma_[1] = " << sec.gamma_[1] << std::endl;
1599 " gamma_[2] = " << sec.gamma_[2] << std::endl;
1601 " gamma_[3] = " << sec.gamma_[3] << std::endl;
1603 " gamma_[4] = " << sec.gamma_[4] << std::endl;
1605 " psi_[0] = " << sec.psi_[0] << std::endl;
1607 " psi_[1] = " << sec.psi_[1] << std::endl;
1609 " psi_[2] = " << sec.psi_[2] << std::endl;
1611 " psi_[3] = " << sec.psi_[3] << std::endl;
1613 " psi_[4] = " << sec.psi_[4] << std::endl;
1615 " sigma_[0] = " << sec.sigma_[0] << std::endl;
1617 " sigma_[1] = " << sec.sigma_[1] << std::endl;
1619 " sigma_[2] = " << sec.sigma_[2] << std::endl;
1621 " sigma_[3] = " << sec.sigma_[3] << std::endl;
1623 " sigma_[4] = " << sec.sigma_[4] << std::endl;
1625 " ck_ = " << sec.ck_ << std::endl;
1626 Xyce::dout() << Xyce::section_divider << std::endl;
1628 #endif // Xyce_DEBUG_TIME
1654 double time_to_stop = sec.stopTime - sec.currentTime;
1655 double currentTimeStep;
1656 if (tiaParams.constantStepSize)
1658 currentTimeStep = 0.1 * time_to_stop;
1659 currentTimeStep = Xycemin(sec.startingTimeStep, currentTimeStep);
1660 sec.currentTimeStep = currentTimeStep;
1666 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
1667 double dnorm_q = 0.0;
1668 (ds.qHistory[1])->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1670 double dnorm_q = ds.delta_x_errorNorm_q1();
1674 currentTimeStep = Xycemin(sec.h0_max_factor_*abs(time_to_stop),sqrt(2.0)/(sec.h0_safety_*dnorm_q));
1678 currentTimeStep = sec.h0_max_factor_*abs(time_to_stop);
1681 if (sec.startingTimeStep > 0.0)
1682 currentTimeStep = Xycemin(sec.startingTimeStep, currentTimeStep);
1684 double rh = abs(currentTimeStep)*sec.h_max_inv_;
1685 if (rh>1.0) currentTimeStep = currentTimeStep/rh;
1690 if (sec.currentTime != sec.initialTime)
1692 sec.currentTimeStep = Xycemin(sec.lastTimeStep, currentTimeStep);
1696 sec.currentTimeStep = currentTimeStep;
1700 sec.currentTimeStepRatio = 1.0;
1701 sec.currentTimeStepSum = 2.0*sec.currentTimeStep;
1703 sec.lastTimeStep = sec.currentTimeStep;
1704 sec.lastTimeStepRatio = sec.currentTimeStepRatio;
1705 sec.lastTimeStepSum = sec.currentTimeStepSum;
1707 sec.numberSuccessiveFailures = 0;
1708 sec.stepAttemptStatus =
true;
1712 sec.nextTime = sec.currentTime + sec.currentTimeStep;
1715 *(ds.xHistory[0]) = *(ds.currSolutionPtr);
1716 (ds.xHistory[1])->putScalar(0.0);
1719 *(ds.qHistory[0]) = *(ds.daeQVectorPtr);
1720 *(ds.qHistory[1]) = *(ds.daeFVectorPtr);
1721 (ds.qHistory[1])->scale(-sec.currentTimeStep);
1724 *(ds.sHistory[0]) = *(ds.currStatePtr);
1725 (ds.sHistory[1])->putScalar(0.0);
1728 *(ds.stoHistory[0]) = *(ds.currStorePtr);
1729 (ds.stoHistory[1])->putScalar(0.0);
1732 *(ds.stoLeadCurrQCompHistory[0]) = *(ds.currStoreLeadCurrQCompPtr);
1733 (ds.stoLeadCurrQCompHistory[1])->putScalar(0.0);
1736 sec.numberOfSteps_ = 0;
1737 sec.currentOrder_ = 1;
1739 sec.psi_[0] = sec.currentTimeStep;
1740 sec.cj_ = 1/sec.psi_[0];
1742 #ifdef Xyce_DEBUG_TIME
1743 Xyce::dout() << std::endl;
1744 Xyce::dout() << Xyce::section_divider << std::endl;
1746 " N_TIA_BackwardDifferentiation15::initialize" << std::endl;
1747 if (tiaParams.debugLevel > 1)
1749 Xyce::dout() <<
"\n xHistory: \n" << endl;
1750 (ds.xHistory[0])->printPetraObject(Xyce::dout());
1751 Xyce::dout() << endl;
1752 (ds.xHistory[1])->printPetraObject(Xyce::dout());
1753 Xyce::dout() << endl;
1754 Xyce::dout() <<
"\n qHistory: \n" << endl;
1755 (ds.qHistory[0])->printPetraObject(Xyce::dout());
1756 Xyce::dout() << endl;
1757 (ds.qHistory[1])->printPetraObject(Xyce::dout());
1758 Xyce::dout() << endl;
1759 Xyce::dout() <<
"\n sHistory: \n" << endl;
1760 (ds.sHistory[0])->printPetraObject(Xyce::dout());
1761 Xyce::dout() << endl;
1762 (ds.sHistory[1])->printPetraObject(Xyce::dout());
1763 Xyce::dout() << endl;
1764 Xyce::dout() <<
"\n" <<
"currentTimeStep = " << currentTimeStep <<
"\n" << endl;
1765 Xyce::dout() <<
"\n" <<
"time_to_stop = " << time_to_stop <<
"\n" << endl;
1767 Xyce::dout() << Xyce::section_divider << std::endl;
1768 #endif // Xyce_DEBUG_TIME
1783 double time_to_stop = sec.stopTime - sec.currentTime;
1787 *(ds.xHistory[0]) = *(ds.currSolutionPtr);
1788 (ds.xHistory[1])->putScalar(0.0);
1791 *(ds.qHistory[0]) = *(ds.daeQVectorPtr);
1792 *(ds.qHistory[1]) = *(ds.daeFVectorPtr);
1793 (ds.qHistory[1])->scale(-sec.currentTimeStep);
1796 *(ds.sHistory[0]) = *(ds.nextStatePtr);
1797 (ds.sHistory[1])->putScalar(0.0);
1800 *(ds.stoHistory[0]) = *(ds.nextStatePtr);
1801 (ds.stoHistory[1])->putScalar(0.0);
1804 *(ds.stoLeadCurrQCompHistory[0]) = *(ds.nextStoreLeadCurrQCompPtr);
1805 (ds.stoLeadCurrQCompHistory[1])->putScalar(0.0);
1808 sec.numberOfSteps_ = 0;
1810 sec.psi_[0] = sec.currentTimeStep;
1811 sec.cj_ = 1/sec.psi_[0];
1838 #ifdef Xyce_DEBUG_TIME
1839 if (tiaParams.debugLevel > 0)
1841 Xyce::dout() << std::endl;
1842 Xyce::dout() << Xyce::section_divider << std::endl;
1844 " N_TIA_BackwardDifferentiation15::checkReduceOrder" << std::endl;
1846 #endif // Xyce_DEBUG_TIME
1853 #ifndef Xyce_USE_Q_NORM
1858 double dnorm_x = sec.estOverTol_;
1859 double dnorm = dnorm_x;
1861 double dnorm_x = 0.0, dnorm_q = 0.0;
1862 ds.newtonCorrectionPtr->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1863 ds.qNewtonCorrectionPtr->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1864 double dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
1867 sec.Ek_ = sec.sigma_[sec.currentOrder_]*dnorm;
1868 sec.Tk_ = (sec.currentOrder_+1)*sec.Ek_;
1870 sec.newOrder_ = sec.currentOrder_;
1871 #ifdef Xyce_DEBUG_TIME
1872 if (tiaParams.debugLevel > 0)
1875 " Est_= " << sec.Est_ << std::endl;
1877 " Ek_= " << sec.Ek_ << std::endl;
1879 " dnorm = " << dnorm << std::endl;
1881 " sigma[order] = " << sec.sigma_[sec.currentOrder_] << std::endl;
1883 " Tk_= " << sec.Tk_ << std::endl;
1885 #endif // Xyce_DEBUG_TIME
1888 if (sec.currentOrder_>1)
1891 #ifndef Xyce_USE_Q_NORM
1892 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_]),1.0,*ds.newtonCorrectionPtr);
1893 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
1894 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1897 dnorm_x = sec.ck_ * ds.delta_x_errorNorm_m1();
1901 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_]),1.0,*ds.newtonCorrectionPtr);
1902 ds.delta_q->linearCombo(1.0,*(ds.qHistory[sec.currentOrder_]),1.0,*ds.qNewtonCorrectionPtr);
1903 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1904 ds.delta_q->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1905 dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
1908 sec.Ekm1_ = sec.sigma_[sec.currentOrder_-1]*dnorm;
1909 sec.Tkm1_ = sec.currentOrder_*sec.Ekm1_;
1910 #ifdef Xyce_DEBUG_TIME
1911 if (tiaParams.debugLevel > 0)
1914 " Ekm1_= " << sec.Ekm1_ << std::endl;
1916 " Tkm1_= " << sec.Tkm1_ << std::endl;
1918 #endif // Xyce_DEBUG_TIME
1920 if (sec.currentOrder_>2)
1922 #ifndef Xyce_USE_Q_NORM
1923 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_-1]),1.0,*ds.delta_x);
1924 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
1925 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1928 dnorm_x = sec.ck_ * ds.delta_x_errorNorm_m2();
1932 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_-1]),1.0,*ds.delta_x);
1933 ds.delta_q->linearCombo(1.0,*(ds.qHistory[sec.currentOrder_-1]),1.0,*ds.delta_q);
1934 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1935 ds.delta_q->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1936 dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
1939 sec.Ekm2_ = sec.sigma_[sec.currentOrder_-2]*dnorm;
1940 sec.Tkm2_ = (sec.currentOrder_-1)*sec.Ekm2_;
1941 if (Xycemax(sec.Tkm1_,sec.Tkm2_)<=sec.Tk_)
1944 sec.Est_ = sec.Ekm1_;
1947 else if (sec.Tkm1_ <= sec.Tkm1_Tk_safety_ * sec.Tk_)
1949 #ifdef Xyce_DEBUG_TIME
1950 if (tiaParams.debugLevel > 0)
1953 " Tkm1_Tk_safety= " << sec.Tkm1_Tk_safety_ << std::endl;
1955 " Tkm1_= " << sec.Tkm1_ << std::endl;
1957 " Tk_= " << sec.Tk_ << std::endl;
1959 " Tk_*safety= " << sec.Tk_*sec.Tkm1_Tk_safety_ << std::endl;
1961 #endif // Xyce_DEBUG_TIME
1964 sec.Est_ = sec.Ekm1_;
1967 #ifdef Xyce_DEBUG_TIME
1968 if (tiaParams.debugLevel > 0)
1971 " newOrder = " << sec.newOrder_ << std::endl;
1972 Xyce::dout() << Xyce::section_divider << std::endl;
2004 #ifdef Xyce_DEBUG_TIME
2006 if (tiaParams.debugLevel > 0)
2008 Xyce::dout() << std::endl;
2009 Xyce::dout() << Xyce::section_divider << std::endl;
2012 " N_TIA_BackwardDifferentiation15::rejectStep" << std::endl;
2017 bool adjustStep = (!(tiaParams.constantStepSize) );
2019 sec.lastAttemptedTimeStep = sec.currentTimeStep;
2022 double newTimeStep_ = sec.currentTimeStep;
2024 if ((sec.stepAttemptStatus ==
false) && (adjustStep))
2026 sec.initialPhase_ =
false;
2039 if (sec.nef_ >= sec.max_LET_fail_)
2041 std::string msg =
"N_TIA_BackwardDifferentiation15::rejectStep: ";
2042 msg +=
" Maximum number of local error test failures. ";
2043 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
2047 if ((sec.newtonConvergenceStatus <= 0))
2052 newTimeStep_ = rr * sec.currentTimeStep;
2054 if (sec.nef_ > 2) sec.newOrder_ = 1;
2055 #ifdef Xyce_DEBUG_TIME
2056 Xyce::dout() <<
"rejectStep 1" << std::endl;
2066 #ifndef Xyce_USE_Q_NORM
2067 rr = sec.r_factor_*pow(sec.r_safety_*(sec.Est_+sec.r_fudge_),-1.0/(sec.newOrder_+1.0));
2068 rr = Xycemax(sec.r_min_,Xycemin(sec.r_max_,rr));
2070 rr = sec.r_factor_*pow(sec.r_safety_*sec.Est_+sec.r_fudge_,-1.0/(sec.newOrder_+1.0));
2071 rr = Xycemax(sec.r_min_,Xycemin(sec.r_max_,rr));
2073 newTimeStep_ = rr * sec.currentTimeStep;
2074 #ifdef Xyce_DEBUG_TIME
2075 Xyce::dout() <<
"rejectStep 2" << std::endl;
2078 else if (sec.nef_ == 2)
2081 newTimeStep_ = rr * sec.currentTimeStep;
2082 #ifdef Xyce_DEBUG_TIME
2083 Xyce::dout() <<
"rejectStep 3" << std::endl;
2086 else if (sec.nef_ > 2)
2090 newTimeStep_ = rr * sec.currentTimeStep;
2091 #ifdef Xyce_DEBUG_TIME
2092 Xyce::dout() <<
"rejectStep 4" << std::endl;
2096 if (sec.newOrder_ >= sec.minOrder_)
2098 sec.currentOrder_ = sec.newOrder_;
2099 #ifdef Xyce_DEBUG_TIME
2100 Xyce::dout() <<
"rejectStep 5" << std::endl;
2103 if (sec.numberOfSteps_ == 0)
2105 sec.psi_[0] = newTimeStep_;
2106 (ds.xHistory[1])->scale(rr);
2107 (ds.qHistory[1])->scale(rr);
2108 #ifdef Xyce_DEBUG_TIME
2109 Xyce::dout() <<
"rejectStep 6" << std::endl;
2112 #ifdef Xyce_DEBUG_TIME
2113 if (tiaParams.debugLevel > 0)
2116 " currentTimeStep = " << sec.currentTimeStep << std::endl;
2118 " numberOfSteps_ = " << sec.numberOfSteps_ << std::endl;
2120 " currentOrder_ = " << sec.currentOrder_ << std::endl;
2122 " nscsco_ = " << sec.nscsco_ << std::endl;
2124 " alpha_[0] = " << sec.alpha_[0] << std::endl;
2126 " alpha_[1] = " << sec.alpha_[1] << std::endl;
2128 " alpha_[2] = " << sec.alpha_[2] << std::endl;
2130 " alpha_[3] = " << sec.alpha_[3] << std::endl;
2132 " alpha_[4] = " << sec.alpha_[4] << std::endl;
2134 " psi_[0] = " << sec.psi_[0] << std::endl;
2136 " psi_[1] = " << sec.psi_[1] << std::endl;
2138 " psi_[2] = " << sec.psi_[2] << std::endl;
2140 " psi_[3] = " << sec.psi_[3] << std::endl;
2142 " psi_[4] = " << sec.psi_[4] << std::endl;
2144 " sigma_[0] = " << sec.sigma_[0] << std::endl;
2146 " sigma_[1] = " << sec.sigma_[1] << std::endl;
2148 " sigma_[2] = " << sec.sigma_[2] << std::endl;
2150 " sigma_[3] = " << sec.sigma_[3] << std::endl;
2152 " sigma_[4] = " << sec.sigma_[4] << std::endl;
2154 " rr = " << rr << std::endl;
2156 " r_factor_ = " << sec.r_factor_ << std::endl;
2158 " r_safety_ = " << sec.r_safety_ << std::endl;
2160 " Est_ = " << sec.Est_ << std::endl;
2162 " r_fudge_ = " << sec.r_fudge_ << std::endl;
2164 " newOrder_ = " << sec.newOrder_ << std::endl;
2167 " currentTimeStep = " << sec.currentTimeStep << std::endl;
2169 " newTimeStep_ = " << newTimeStep_ << std::endl;
2171 #endif // Xyce_DEBUG_TIME
2173 else if ((sec.stepAttemptStatus ==
false) & (!adjustStep))
2175 std::string tmp =
" BackwardDifferentiation15:rejectStep: Warning: Local error test failed with constant step-size.\n";
2176 Xyce::dout() << tmp << std::endl;
2182 newTimeStep_ = Xycemax(newTimeStep_, sec.minTimeStep);
2183 newTimeStep_ = Xycemin(newTimeStep_, sec.maxTimeStep);
2185 double nextTimePt = sec.currentTime + newTimeStep_;
2187 if (nextTimePt > sec.stopTime)
2189 nextTimePt = sec.stopTime;
2190 newTimeStep_ = sec.stopTime - sec.currentTime;
2193 sec.nextTime = nextTimePt;
2195 sec.currentTimeStepRatio = newTimeStep_/sec.lastTimeStep;
2196 sec.currentTimeStepSum = newTimeStep_ + sec.lastTimeStep;
2198 #ifdef Xyce_DEBUG_TIME
2199 if (tiaParams.debugLevel >0)
2202 " newTimeStep_ = " << newTimeStep_ << std::endl;
2204 " nextTime = " << sec.nextTime << std::endl;
2206 #endif // Xyce_DEBUG_TIME
2208 sec.currentTimeStep = newTimeStep_;
2212 double nextTimePt = sec.currentTime + sec.currentTimeStep;
2214 if (nextTimePt > sec.stopTime)
2216 nextTimePt = sec.stopTime;
2217 sec.currentTimeStep = sec.stopTime - sec.currentTime;
2220 sec.currentTimeStepRatio = sec.currentTimeStep / sec.lastTimeStep;
2221 sec.currentTimeStepSum = sec.currentTimeStep + sec.lastTimeStep;
2223 sec.nextTime = nextTimePt;
2225 #ifdef Xyce_DEBUG_TIME
2226 if (tiaParams.debugLevel >0)
2228 Xyce::dout() << Xyce::section_divider << std::endl;
2230 #endif // Xyce_DEBUG_TIME
2244 sec.setTimeStep(sec.currentTimeStep);
2258 sec.numberOfSteps_ ++;
2260 sec.lastTime = sec.currentTime;
2261 sec.currentTime = sec.nextTime;
2266 #ifdef Xyce_DEBUG_TIME
2268 if (tiaParams.debugLevel > 0)
2270 Xyce::dout() << std::endl;
2271 Xyce::dout() << Xyce::section_divider << std::endl;
2274 " N_TIA_BackwardDifferentiation15::completeStep" << std::endl;
2279 bool adjustStep = (!(tiaParams.constantStepSize) );
2281 sec.lastAttemptedTimeStep = sec.currentTimeStep;
2283 double newTimeStep_ = sec.currentTimeStep;
2287 sec.lastTimeStep = sec.currentTimeStep;
2288 sec.lastTimeStepRatio = sec.currentTimeStepRatio;
2289 sec.lastTimeStepSum = sec.currentTimeStepSum;
2290 int orderDiff = sec.currentOrder_ - sec.usedOrder_;
2291 sec.usedOrder_ = sec.currentOrder_;
2292 sec.usedStep_ = sec.currentTimeStep;
2293 if ((sec.newOrder_ == sec.currentOrder_-1) || (sec.currentOrder_ == sec.maxOrder_))
2298 sec.initialPhase_ =
false;
2300 if (sec.initialPhase_)
2302 sec.currentOrder_++;
2303 newTimeStep_ = sec.h_phase0_incr_ * sec.currentTimeStep;
2307 int action = TIAAction_UNSET;
2308 if (sec.newOrder_ == sec.currentOrder_-1)
2309 action = TIAAction_LOWER;
2310 else if (sec.newOrder_ == sec.maxOrder_)
2311 action = TIAAction_MAINTAIN;
2312 else if ((sec.currentOrder_+1>=sec.nscsco_) || (orderDiff == 1))
2316 action = TIAAction_MAINTAIN;
2321 #ifndef Xyce_USE_Q_NORM
2322 ds.delta_x->linearCombo(1.0,*ds.newtonCorrectionPtr,-1.0,*(ds.xHistory[sec.currentOrder_+1]));
2323 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
2324 double dnorm_x = 0.0;
2325 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
2328 double dnorm_x = sec.ck_ * ds.delta_x_errorNorm_p1();
2330 double dnorm = dnorm_x;
2332 ds.delta_x->linearCombo(1.0,*ds.newtonCorrectionPtr,-1.0,*(ds.xHistory[sec.currentOrder_+1]));
2333 ds.delta_q->linearCombo(1.0,*ds.qNewtonCorrectionPtr,-1.0,*(ds.qHistory[sec.currentOrder_+1]));
2334 double dnorm_x = 0.0, dnorm_q = 0.0;
2335 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
2336 ds.delta_q->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
2337 double dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
2341 sec.Ekp1_ = sec.Tkp1_/(sec.currentOrder_+2);
2342 if (sec.currentOrder_ == 1)
2344 if (sec.Tkp1_ >= sec.Tkp1_Tk_safety_ * sec.Tk_)
2345 action = TIAAction_MAINTAIN;
2347 action = TIAAction_RAISE;
2351 if (sec.Tkm1_ <= Xycemin(sec.Tk_,sec.Tkp1_))
2352 action = TIAAction_LOWER;
2353 else if (sec.Tkp1_ >= sec.Tk_)
2354 action = TIAAction_MAINTAIN;
2356 action = TIAAction_RAISE;
2359 if (sec.currentOrder_ < sec.minOrder_)
2361 action = TIAAction_RAISE;
2363 else if ((sec.currentOrder_ == sec.minOrder_) && (action == TIAAction_LOWER))
2365 action = TIAAction_MAINTAIN;
2367 if (action == TIAAction_RAISE)
2369 sec.currentOrder_++;
2370 sec.Est_ = sec.Ekp1_;
2372 else if (action == TIAAction_LOWER)
2374 sec.currentOrder_--;
2375 sec.Est_ = sec.Ekm1_;
2377 newTimeStep_ = sec.currentTimeStep;
2383 if (tiaParams.errorAnalysisOption == 1)
2385 rr = 0.4/(sec.r_min_);
2386 newTimeStep_ = rr*sec.currentTimeStep;
2390 #ifndef Xyce_USE_Q_NORM
2391 rr = pow(sec.r_safety_*(sec.Est_+sec.r_fudge_),-1.0/(sec.currentOrder_+1.0));
2393 rr = pow(sec.r_safety_*sec.Est_+sec.r_fudge_,-1.0/(sec.currentOrder_+1.0));
2396 #ifdef Xyce_DEBUG_TIME
2397 if (tiaParams.debugLevel > 0)
2400 " currentOrder_ = " << sec.currentOrder_ << std::endl;
2402 " r_safety = " << sec.r_safety_ << std::endl;
2404 " r_fudge_ = " << sec.r_fudge_ << std::endl;
2406 " r_hincr_ = " << sec.r_hincr_ << std::endl;
2408 " r_hincr_test_ = " << sec.r_hincr_test_ << std::endl;
2410 " Est = " << sec.Est_ << std::endl;
2412 " Ekp1_ = " << sec.Ekp1_ << std::endl;
2414 " Ekm1_ = " << sec.Ekm1_ << std::endl;
2416 " Tkp1_ = " << sec.Tkp1_ << std::endl;
2418 " raw rr = " << rr << std::endl;
2421 if (rr >= sec.r_hincr_test_)
2424 newTimeStep_ = rr*sec.currentTimeStep;
2428 rr = Xycemax(sec.r_min_,Xycemin(sec.r_max_,rr));
2429 newTimeStep_ = rr*sec.currentTimeStep;
2433 #ifdef Xyce_DEBUG_TIME
2434 if (tiaParams.debugLevel > 0)
2437 " initialPhase_ = " << sec.initialPhase_ << std::endl;
2439 " rr = " << rr << std::endl;
2441 " currentTimeStep = " << sec.currentTimeStep << std::endl;
2443 " currentTime = " << sec.currentTime << std::endl;
2445 " nextTime = " << sec.nextTime << std::endl;
2447 " newTimeStep_ = " << newTimeStep_ << std::endl;
2449 " minTimeStep = " << sec.minTimeStep << std::endl;
2451 " maxTimeStep = " << sec.maxTimeStep << std::endl;
2464 if (sec.currentTime < sec.stopTime)
2469 newTimeStep_ = Xycemax(newTimeStep_, sec.minTimeStep);
2470 newTimeStep_ = Xycemin(newTimeStep_, sec.maxTimeStep);
2472 double nextTimePt = sec.currentTime + newTimeStep_;
2474 if (nextTimePt > sec.stopTime)
2476 nextTimePt = sec.stopTime;
2477 newTimeStep_ = sec.stopTime - sec.currentTime;
2480 sec.nextTime = nextTimePt;
2482 sec.currentTimeStepRatio = newTimeStep_/sec.lastTimeStep;
2483 sec.currentTimeStepSum = newTimeStep_ + sec.lastTimeStep;
2485 #ifdef Xyce_DEBUG_TIME
2486 if (tiaParams.debugLevel >0)
2488 Xyce::dout() <<
" nextTime = " << sec.nextTime << std::endl;
2489 Xyce::dout() <<
" newTimeStep_ = " << newTimeStep_ << std::endl;
2493 sec.currentTimeStep = newTimeStep_;
2497 double nextTimePt = sec.currentTime + sec.currentTimeStep;
2499 if (nextTimePt > sec.stopTime)
2501 nextTimePt = sec.stopTime;
2502 sec.currentTimeStep = sec.stopTime - sec.currentTime;
2505 sec.currentTimeStepRatio = sec.currentTimeStep / sec.lastTimeStep;
2506 sec.currentTimeStepSum = sec.currentTimeStep + sec.lastTimeStep;
2508 sec.nextTime = nextTimePt;
2511 #ifdef Xyce_DEBUG_TIME
2512 if (tiaParams.debugLevel >0)
2514 Xyce::dout() << Xyce::section_divider << std::endl;
2536 ds.nextStateDerivPtr->linearCombo(1.0,*ds.nextStatePtr,-1.0,*ds.sn0Ptr);
2537 ds.nextStateDerivPtr->linearCombo(1.0,*ds.spn0Ptr,-sec.alphas_/sec.currentTimeStep,*ds.nextStateDerivPtr);
2553 ds.nextStoreLeadCurrQCompDerivPtr->
2554 linearCombo(1.0,*ds.nextStoreLeadCurrQCompPtr,-1.0,*ds.stoQCn0Ptr);
2555 ds.nextStoreLeadCurrQCompDerivPtr->
2556 linearCombo(1.0,*ds.stoQCpn0Ptr,-sec.alphas_/sec.currentTimeStep,*ds.nextStoreLeadCurrQCompDerivPtr);
2557 ds.nextStorePtr->linearCombo(1.0,*ds.nextStorePtr,1.0,*ds.nextStoreLeadCurrQCompDerivPtr);
2586 tle.
xErrorSum = ds.partialErrorNormSum ();
2587 tle.
qErrorSum = ds.partialQErrorNormSum ();
2588 tle.
xErrorSum_m1 = ds.partialSum_m1 (sec.currentOrder_);
2589 tle.
xErrorSum_m2 = ds.partialSum_m2 (sec.currentOrder_);
2590 tle.
xErrorSum_p1 = ds.partialSum_p1 (sec.currentOrder_, sec.maxOrder_);
2593 #ifdef Xyce_DEBUG_TIME
2594 Xyce::dout() << tle;