47 #include <Xyce_config.h>
51 #include <N_UTL_Misc.h>
63 #include <N_ERH_ErrorMgr.h>
64 #include <N_LAS_BlockVector.h>
65 #include <N_LAS_Matrix.h>
66 #include <N_LAS_System.h>
67 #include <N_LAS_Vector.h>
68 #include <N_PDS_Comm.h>
69 #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_;
115 for (
int i=sec.nscsco_;i<=sec.currentOrder_;++i)
117 (ds.xHistory[i])->scale(sec.beta_[i]);
118 (ds.qHistory[i])->scale(sec.beta_[i]);
119 (ds.sHistory[i])->scale(sec.beta_[i]);
120 (ds.stoHistory[i])->scale(sec.beta_[i]);
121 (ds.stoLeadCurrQHistory[i])->scale(sec.beta_[i]);
125 *ds.xn0Ptr = *(ds.xHistory[0]);
126 *ds.qn0Ptr = *(ds.qHistory[0]);
127 *ds.sn0Ptr = *(ds.sHistory[0]);
128 *ds.ston0Ptr = *(ds.stoHistory[0]);
129 *ds.stoQn0Ptr = *(ds.stoLeadCurrQHistory[0]);
131 ds.qpn0Ptr->putScalar(0.0);
132 ds.spn0Ptr->putScalar(0.0);
133 ds.stopn0Ptr->putScalar(0.0);
134 ds.stoQpn0Ptr->putScalar(0.0);
135 for (
int i=1;i<=sec.currentOrder_;++i)
137 ds.xn0Ptr->linearCombo(1.0,*(ds.xHistory[i]),1.0,*ds.xn0Ptr);
138 ds.qn0Ptr->linearCombo(1.0,*(ds.qHistory[i]),1.0,*ds.qn0Ptr);
139 ds.sn0Ptr->linearCombo(1.0,*(ds.sHistory[i]),1.0,*ds.sn0Ptr);
140 ds.ston0Ptr->linearCombo(1.0,*(ds.stoHistory[i]),1.0,*ds.ston0Ptr);
141 ds.stoQn0Ptr->linearCombo(1.0,*(ds.stoLeadCurrQHistory[i]),1.0,*ds.stoQn0Ptr);
142 ds.qpn0Ptr->linearCombo(sec.gamma_[i],*(ds.qHistory[i]),1.0,*ds.qpn0Ptr);
143 ds.spn0Ptr->linearCombo(sec.gamma_[i],*(ds.sHistory[i]),1.0,*ds.spn0Ptr);
144 ds.stopn0Ptr->linearCombo(sec.gamma_[i],*(ds.stoHistory[i]),1.0,*ds.stopn0Ptr);
145 ds.stoQpn0Ptr->linearCombo(sec.gamma_[i],*(ds.stoLeadCurrQHistory[i]),1.0,*ds.stoQpn0Ptr);
148 #ifdef Xyce_DEBUG_TIME
149 Xyce::dout().width(21); cout.precision(13); cout.setf(std::ios::scientific);
150 if (tiaParams.debugLevel > 1)
152 Xyce::dout() << std::endl;
153 Xyce::dout() << Xyce::section_divider << std::endl;
154 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::obtainPredictor" << std::endl;
155 Xyce::dout() <<
"\n currentOrder = " << sec.currentOrder_ << endl;
156 Xyce::dout() <<
"\n sec.nscsco_: " << sec.nscsco_ << endl;
157 for (
int i=0; i<=sec.currentOrder_ ; ++i)
158 Xyce::dout() <<
"\n sec.beta_[" << i <<
"] = " << sec.beta_[i] <<
"\n" << endl;
159 for (
int i=0; i<=sec.currentOrder_ ; ++i)
161 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
162 (ds.xHistory[i])->printPetraObject(Xyce::dout());
163 Xyce::dout() << endl;
165 for (
int i=0; i<=sec.currentOrder_ ; ++i)
167 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
168 (ds.qHistory[i])->printPetraObject(Xyce::dout());
169 Xyce::dout() << endl;
171 for (
int i=0; i<=sec.currentOrder_ ; ++i)
173 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
174 (ds.sHistory[i])->printPetraObject(Xyce::dout());
175 Xyce::dout() << endl;
177 Xyce::dout() <<
"\n xn0: \n" << endl;
178 ds.xn0Ptr->printPetraObject(Xyce::dout());
179 Xyce::dout() << endl;
180 Xyce::dout() <<
"\n qn0: \n" << endl;
181 ds.qn0Ptr->printPetraObject(Xyce::dout());
182 Xyce::dout() << endl;
183 Xyce::dout() <<
"\n qpn0: \n" << endl;
184 ds.qpn0Ptr->printPetraObject(Xyce::dout());
185 Xyce::dout() << endl;
186 Xyce::dout() <<
"\n sn0: \n" << endl;
187 ds.sn0Ptr->printPetraObject(Xyce::dout());
188 Xyce::dout() << endl;
189 Xyce::dout() <<
"\n spn0: \n" << endl;
190 ds.spn0Ptr->printPetraObject(Xyce::dout());
191 Xyce::dout() << endl;
192 Xyce::dout() <<
"\n stoQn0Ptr: \n" << endl;
193 ds.stoQn0Ptr->printPetraObject(Xyce::dout());
194 Xyce::dout() << endl;
195 Xyce::dout() <<
"\n stoQpn0Ptr: \n" << endl;
196 ds.stoQpn0Ptr->printPetraObject(Xyce::dout());
197 Xyce::dout() << endl;
198 Xyce::dout() << Xyce::section_divider << std::endl;
200 #endif // Xyce_DEBUG_TIME
202 *(ds.nextSolutionPtr) = *(ds.xn0Ptr);
223 ds.RHSVectorPtr->linearCombo(1.0,*ds.daeQVectorPtr,-1.0,*ds.qn0Ptr);
224 ds.RHSVectorPtr->linearCombo(1.0,*ds.qpn0Ptr,-sec.alphas_/sec.currentTimeStep,*ds.RHSVectorPtr);
226 #ifdef Xyce_DEBUG_TIME
227 if (tiaParams.debugLevel > 1)
229 Xyce::dout() << std::endl;
230 Xyce::dout() << Xyce::section_divider << std::endl;
231 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::obtainResidual" << std::endl;
232 Xyce::dout() <<
"\n t = " << sec.nextTime <<
"\n" << endl;
233 Xyce::dout() <<
"\n solution: \n" << endl;
234 ds.nextSolutionPtr->printPetraObject(Xyce::dout());
235 Xyce::dout() <<
"\n daeQVector: \n" << endl;
236 ds.daeQVectorPtr->printPetraObject(Xyce::dout());
237 Xyce::dout() <<
"\n qn0: \n" << endl;
238 ds.qn0Ptr->printPetraObject(Xyce::dout());
239 Xyce::dout() <<
"\n qpn0: \n" << endl;
240 ds.qpn0Ptr->printPetraObject(Xyce::dout());
241 Xyce::dout() <<
"\n sec.alphas_/hn: " << sec.alphas_/sec.currentTimeStep <<
"\n" << endl;
242 Xyce::dout() <<
"\n daeFVector: \n" << endl;
243 ds.daeFVectorPtr->printPetraObject(Xyce::dout());
245 Xyce::dout() <<
"\n dQdt-vector: \n" << endl;
246 ds.RHSVectorPtr->printPetraObject(Xyce::dout());
247 Xyce::dout() << endl;
251 ds.RHSVectorPtr->linearCombo(1.0,*ds.RHSVectorPtr,+1.0,*ds.daeFVectorPtr);
252 #ifdef SEPARATE_F_AND_B
253 ds.RHSVectorPtr->linearCombo(1.0,*ds.RHSVectorPtr,-1.0,*ds.daeBVectorPtr);
257 ds.RHSVectorPtr->scale(-1.0);
262 (ds.dQdxdVpVectorPtr)->scale( -sec.alphas_/sec.currentTimeStep );
264 (ds.RHSVectorPtr)->daxpy(
265 *(ds.RHSVectorPtr), +1.0, *(ds.dQdxdVpVectorPtr));
267 (ds.RHSVectorPtr)->daxpy(
268 *(ds.RHSVectorPtr), +1.0, *(ds.dFdxdVpVectorPtr));
271 #ifdef Xyce_DEBUG_TIME
272 if (tiaParams.debugLevel > 1)
274 Xyce::dout() <<
"\n Residual-vector: \n" << endl;
275 Xyce::dout() <<
"-(qpn0-(sec.alpha_s/h)*(Q-qn0)+F-B) \n" << endl;
276 ds.RHSVectorPtr->printPetraObject(Xyce::dout());
277 Xyce::dout() << Xyce::section_divider << std::endl;
278 Xyce::dout() << endl;
294 int numParams = ds.sensRHSPtrVector.size();
295 for (
int ip=0; ip<numParams;++ip)
297 N_LAS_Vector & RHSVec = *(ds.sensRHSPtrVector[ip]);
298 N_LAS_Vector & dfdpVec = *(ds.nextDfdpPtrVector[ip]);
299 N_LAS_Vector & dqdpVec = *(ds.nextDqdpPtrVector[ip]);
300 N_LAS_Vector & dbdpVec = *(ds.nextDbdpPtrVector[ip]);
302 N_LAS_Vector & dqdpn0Vec = *(ds.dqdpn0PtrVector[ip]);
304 RHSVec.linearCombo(1.0,dqdpVec,-1.0,dqdpn0Vec);
305 RHSVec.linearCombo(1.0,*ds.qpn0Ptr,-sec.alphas_/sec.currentTimeStep,RHSVec);
307 RHSVec.linearCombo(1.0,RHSVec,+1.0,dfdpVec);
308 #ifdef SEPARATE_F_AND_B
309 RHSVec.linearCombo(1.0,RHSVec,-1.0,dbdpVec);
329 #ifdef Xyce_DEBUG_TIME
330 if (tiaParams.debugLevel > 1)
332 Xyce::dout() << std::endl;
333 Xyce::dout() << Xyce::section_divider << std::endl;
334 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::obtainJacobian" << std::endl;
345 N_LAS_Matrix & dQdx = *(ds.dQdxMatrixPtr);
346 N_LAS_Matrix & dFdx = *(ds.dFdxMatrixPtr);
347 N_LAS_Matrix & Jac = *(ds.JMatrixPtr);
349 double qscalar(-sec.alphas_/sec.currentTimeStep);
351 Jac.linearCombo( qscalar, dQdx, 1.0, dFdx );
353 #ifdef Xyce_DEBUG_TIME
354 if (tiaParams.debugLevel > 1)
356 Xyce::dout() <<
"\n dFdx:" <<endl;
357 dFdx.printPetraObject(Xyce::dout());
358 Xyce::dout() <<
"\n Total Jacobian:" <<endl;
359 Jac.printPetraObject(Xyce::dout());
365 Xyce::dout() << Xyce::section_divider << std::endl;
366 Xyce::dout() << endl;
385 N_LAS_Vector * tmpSolVectorPtr, std::vector<N_LAS_Vector*> & historyVec)
397 double tn = sec.currentTime;
398 double hh = sec.currentTimeStep;
399 double hused = sec.usedStep_;
400 int kused = sec.usedOrder_;
405 double uround = N_UTL_MachineDependentParams::MachinePrecision();
407 tfuzz = 100 * uround * (tn + hh);
408 tp = tn - hused - tfuzz;
410 if ( (timepoint - tp)*hh < 0.0 )
413 *tmpSolVectorPtr = *(historyVec[0]);
415 if ( (kused == 0) || (timepoint == tn) )
418 delt = timepoint - tn;
419 gam = delt/sec.psi_[0];
420 for (
int j=1 ; j <= kord ; ++j)
423 gam = (delt + sec.psi_[j-1])/sec.psi_[j];
424 tmpSolVectorPtr->linearCombo(1.0,*tmpSolVectorPtr,c,*(historyVec[j]));
447 N_LAS_Vector * tmpSolVectorPtr)
449 N_LAS_BlockVector * blockTempSolVectorPtr =
450 dynamic_cast<N_LAS_BlockVector*
>(tmpSolVectorPtr);
451 if (blockTempSolVectorPtr == NULL)
453 std::string msg =
"N_TIA_BackwardDifferentiation15::interpolateMPDESolution: ";
454 msg +=
"N_LAS_Vector tmpSolVectorPtr is not of type N_LAS_BlockVector";
455 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
461 int numblocks = timepoint.size();
462 int blockCount = blockTempSolVectorPtr->blockCount();
463 if (numblocks > blockCount)
465 std::string msg =
"N_TIA_BackwardDifferentiation15::interpolateMPDESolution: ";
466 msg +=
"Number of time points requested is greater than number of fast time points in MPDE block vector";
467 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
474 double tn = sec.currentTime;
475 double hh = sec.currentTimeStep;
476 double hused = sec.usedStep_;
477 int kused = sec.usedOrder_;
480 tfuzz = 100 * uround * (tn + hh);
481 tp = tn - hused - tfuzz;
482 for (
int i=0; i<numblocks ; ++i)
484 if ( (timepoint[i] - tp)*hh < 0.0 )
488 *tmpSolVectorPtr = *(ds.xHistory[0]);
490 N_LAS_Vector * solVectorPtr;
491 N_LAS_Vector * xHistoryVectorPtr;
493 for (
int i=0; i < numblocks ; ++i)
495 if ((kused == 0) || (timepoint[i] == tn)) { kord = 1; }
496 else { kord = kused; }
497 solVectorPtr = &(blockTempSolVectorPtr->block(i));
499 delt = timepoint[i] - tn;
500 gam = delt/sec.psi_[0];
501 for (
int j=1 ; j <= kord ; ++j)
504 gam = (delt + sec.psi_[j-1])/sec.psi_[j];
505 N_LAS_BlockVector * blockXHistoryVectorPtr =
506 dynamic_cast<N_LAS_BlockVector*>(ds.xHistory[j]);
507 if (blockXHistoryVectorPtr == NULL)
509 Xyce::Report::DevelFatal0().in(
"N_TIA_BackwardDifferentiation15::interpolateMPDESolution") <<
"N_LAS_Vector ds.xHistory[j] is not of type N_LAS_BlockVector\n j = " << j;
512 xHistoryVectorPtr = &(blockXHistoryVectorPtr->block(i));
513 solVectorPtr->linearCombo(1.0,*solVectorPtr,c,*xHistoryVectorPtr);
530 N_LAS_Vector * solnVecPtr,
531 const std::vector<double> & fastTimes )
533 #ifdef Xyce_DEBUG_TIME
534 if (tiaParams.debugLevel > 0)
536 Xyce::dout() << std::endl;
537 Xyce::dout() << Xyce::section_divider << std::endl;
538 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::printMPDEOutputSolution" << std::endl;
540 #endif // Xyce_DEBUG_TIME
541 double timestep = sec.lastAttemptedTimeStep;
542 double lasttime = sec.currentTime - timestep;
543 double tn = sec.currentTime;
545 double beg_of_output_time_interval = lasttime;
546 double end_of_output_time_interval = tn;
547 double start_time = max(lasttime,beg_of_output_time_interval);
548 double stop_time = min(tn,end_of_output_time_interval);
549 #ifdef Xyce_DEBUG_TIME
550 if (tiaParams.debugLevel > 0)
552 Xyce::dout() <<
"timestep = " << timestep << endl;
553 Xyce::dout() <<
"lasttime = " << lasttime << endl;
554 Xyce::dout() <<
"tn = " << tn << endl;
555 Xyce::dout() <<
"beg_of_output_time_interval = " << beg_of_output_time_interval << endl;
556 Xyce::dout() <<
"end_of_output_time_interval = " << end_of_output_time_interval << endl;
557 Xyce::dout() <<
"start_time = " << start_time << endl;
558 Xyce::dout() <<
"stop_time = " << stop_time << endl;
560 #endif // Xyce_DEBUG_TIME
563 N_LAS_BlockVector * blockTmpSolVectorPtr =
564 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpSolVectorPtr);
566 if (blockTmpSolVectorPtr == NULL)
568 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
569 msg +=
"N_LAS_Vector ds.tmpSolVectorPtr is not of type N_LAS_BlockVector";
570 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
573 int blockCount = blockTmpSolVectorPtr->blockCount();
576 double T2 = fastTimes.back();
578 double charcross = fmod(start_time,T2);
582 for (
int i=0 ; i<=blockCount ; ++i)
584 if (fastTimes[i] >= charcross)
592 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
593 msg +=
"Cannot find where characteristic curve crosses fast time slice at start_time";
594 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
597 std::vector<double> h2(blockCount,0);
598 for (
int j=0 ; j < blockCount ; ++j)
600 h2[j] = fastTimes[j+1] - fastTimes[j];
602 std::vector<double> ti;
604 double first_interp = start_time - charcross + fastTimes[s_ind_0];
605 #ifdef Xyce_DEBUG_TIME
606 if (tiaParams.debugLevel > 0)
608 Xyce::dout() <<
"first_interp = " << first_interp << endl;
610 #endif // Xyce_DEBUG_TIME
611 if (s_ind_0 == blockCount) { s_ind_0 = 0; };
613 double eps = fabs(start_time)*1.0e-6;
614 if ( fabs(first_interp-timept_) <= eps )
616 first_interp += h2[s_ind_0];
618 if (s_ind_0 == blockCount) { s_ind_0 = 0; };
619 #ifdef Xyce_DEBUG_TIME
620 if (tiaParams.debugLevel > 0)
622 Xyce::dout() <<
"Moving first_interp forward to avoid duplicate outputs: " << first_interp << endl;
624 #endif // Xyce_DEBUG_TIME
627 double t = first_interp;
628 while (t <= stop_time)
633 if (sn >= blockCount) { sn = 0; }
635 #ifdef Xyce_DEBUG_TIME
636 if (tiaParams.debugLevel > 0)
638 Xyce::dout() <<
"T2 = " << T2 << endl;
639 Xyce::dout() <<
"charcross = " << charcross << endl;
640 Xyce::dout() <<
"s_ind_0 = " << s_ind_0 << endl;
641 Xyce::dout() <<
"Expecting to interpolate the following points:" << endl;
642 unsigned int numinterp = ti.size();
643 for (
unsigned int i=0 ; i < numinterp ; ++i)
645 Xyce::dout() << ti[i] << endl;
647 Xyce::dout() <<
"Total of " << numinterp <<
" points" << endl;
649 #endif // Xyce_DEBUG_TIME
650 timept_ = start_time;
651 unsigned int tinum = ti.size();
652 int total_interp = 0;
653 std::vector<double> timepoint_vec(blockCount,stop_time);
654 int num_interp_this_cycle = 0;
656 for (
unsigned int i=0; i < tinum ; ++i)
658 timepoint_vec[s_ind] = ti[i];
659 num_interp_this_cycle++;
661 if (s_ind >= blockCount) { s_ind = 0; };
663 if ((s_ind == s_ind_0) || (i == tinum-1))
665 interpolateMPDESolution(timepoint_vec, ds.tmpSolVectorPtr);
668 for (
int j=0 ; j < num_interp_this_cycle ; ++j)
670 timept_ = timepoint_vec[s];
672 timept_, blockTmpSolVectorPtr->block(s),
673 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
674 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
675 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_);
678 if (s >= blockCount) { s = 0; }
679 #ifdef Xyce_DEBUG_TIME
680 Xyce::dout() <<
"Interpolated to t = " << timept_ << endl;
681 #endif // Xyce_DEBUG_TIME
683 num_interp_this_cycle = 0;
686 #ifdef Xyce_DEBUG_TIME
687 Xyce::dout() <<
"Total of " << total_interp <<
" points" << endl;
688 #endif // Xyce_DEBUG_TIME
691 eps = fabs(stop_time)*1.0e-8;
693 if (fabs(timept_ - stop_time) >= eps)
695 #ifdef Xyce_DEBUG_TIME
696 if (tiaParams.debugLevel > 0)
698 Xyce::dout() <<
"Previous timept = " << timept_ << endl;
699 Xyce::dout() <<
"Expecting to interpolate the following point: " << stop_time << endl;
701 #endif // Xyce_DEBUG_TIME
702 N_LAS_Vector* tmpSolnVecPtr = solnVecPtr;
703 N_LAS_Vector* tmpVecPtr = ds.tmpXn0APtr;
706 interpolateSolution(stop_time,ds.tmpXn0BPtr, ds.xHistory);
707 tmpSolnVecPtr = ds.tmpXn0BPtr;
709 N_LAS_BlockVector * blockTmpSolnVecPtr =
710 dynamic_cast<N_LAS_BlockVector*
>(tmpSolnVecPtr);
711 N_LAS_BlockVector * blockTmpVecPtr =
712 dynamic_cast<N_LAS_BlockVector*
>(tmpVecPtr);
713 if (blockTmpSolnVecPtr == NULL)
715 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
716 msg +=
"N_LAS_Vector tmpSolnVecPtr is not of type N_LAS_BlockVector";
717 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
720 if (blockTmpVecPtr == NULL)
722 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
723 msg +=
"N_LAS_Vector tmpVecPtr is not of type N_LAS_BlockVector";
724 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
729 charcross = fmod(stop_time,T2);
732 if( charcross < fastTimes[0] )
735 s_ind_1 = blockCount-1;
739 for (
int i=blockCount-1 ; i>=0 ; --i)
741 if (fastTimes[i] <= charcross)
750 std::string msg =
"N_TIA_BackwardDifferentiation15::printMPDEOutputSolution: ";
751 msg +=
"Cannot find where characteristic curve crosses fast time slice at stop_time";
752 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
757 double coeff_sm = fastTimes[sp]-charcross;
758 double coeff_sp = charcross-fastTimes[sm];
759 if (sp == blockCount) { sp = 0; }
760 double dt = h2[s_ind_1];
762 #ifdef Xyce_DEBUG_TIME
763 Xyce::dout() <<
"charcross = " << charcross << endl;
764 Xyce::dout() <<
"s_ind_1 = " << s_ind_1 << endl;
765 Xyce::dout() <<
"sp = " << sp << endl;
766 Xyce::dout() <<
"sm = " << sm << endl;
767 Xyce::dout() <<
"dt = " << dt << endl;
768 Xyce::dout() <<
"timept = " << timept_ << endl;
769 Xyce::dout() <<
"coeff_sm = " << coeff_sm << endl;
770 Xyce::dout() <<
"coeff_sp = " << coeff_sp << endl;
771 #endif // Xyce_DEBUG_TIME
772 blockTmpVecPtr->block(0).linearCombo(
773 coeff_sm/dt, blockTmpSolnVecPtr->block(sm),
774 coeff_sp/dt, blockTmpSolnVecPtr->block(sp)
777 timept_, blockTmpVecPtr->block(0),
778 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
779 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
780 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_);
782 #ifdef Xyce_DEBUG_TIME
783 Xyce::dout() <<
"Interpolated to t = " << timept_ << endl;
784 #endif // Xyce_DEBUG_TIME
786 #ifdef Xyce_DEBUG_TIME
789 if (tiaParams.debugLevel > 0)
791 Xyce::dout() <<
"No further interpolation required." << endl;
794 #endif // Xyce_DEBUG_TIME
796 #ifdef Xyce_DEBUG_TIME
797 Xyce::dout() << Xyce::section_divider << std::endl;
798 #endif // Xyce_DEBUG_TIME
814 N_LAS_Vector * solnVecPtr,
815 const std::vector<double> & fastTimes,
818 #ifdef Xyce_DEBUG_TIME
819 if (tiaParams.debugLevel > 0)
821 Xyce::dout() << std::endl;
822 Xyce::dout() << Xyce::section_divider << std::endl;
823 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution" << std::endl;
825 #endif // Xyce_DEBUG_TIME
826 double timestep = sec.lastAttemptedTimeStep;
827 double lasttime = sec.currentTime - timestep;
828 double tn = sec.currentTime;
830 double beg_of_output_time_interval = lasttime;
831 double end_of_output_time_interval = tn;
832 double start_time = max(lasttime,beg_of_output_time_interval);
833 double stop_time = min(tn,end_of_output_time_interval);
834 #ifdef Xyce_DEBUG_TIME
835 if (tiaParams.debugLevel > 0)
837 Xyce::dout() <<
"start_time = " << start_time << endl;
838 Xyce::dout() <<
"stop_time = " << stop_time << endl;
840 #endif // Xyce_DEBUG_TIME
864 N_LAS_BlockVector * blockTmpSolVectorPtr =
865 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpSolVectorPtr);
866 N_LAS_BlockVector * blockTmpXn0APtr =
867 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpXn0APtr);
868 N_LAS_BlockVector * blockTmpXn0BPtr =
869 dynamic_cast<N_LAS_BlockVector*
>(ds.tmpXn0BPtr);
870 if (blockTmpSolVectorPtr == NULL)
872 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
873 msg +=
"N_LAS_Vector ds.tmpSolVectorPtr is not of type N_LAS_BlockVector";
874 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
877 if (blockTmpXn0APtr == NULL)
879 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
880 msg +=
"N_LAS_Vector ds.tmpXn0APtr is not of type N_LAS_BlockVector";
881 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
884 if (blockTmpXn0BPtr == NULL)
886 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
887 msg +=
"N_LAS_Vector ds.tmpXn0BPtr is not of type N_LAS_BlockVector";
888 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
891 int phiLID = blockTmpSolVectorPtr->pmap()->globalToLocalIndex(phiGID);
892 double hh = timestep/(sec.usedOrder_);
895 #ifdef Xyce_DEBUG_TIME
896 if (tiaParams.debugLevel > 0)
898 Xyce::dout() <<
" sec.usedOrder_ = " << sec.usedOrder_ << endl;
899 Xyce::dout() <<
" sec.currentTime_ = " << sec.currentTime << endl;
900 Xyce::dout() <<
" lasttime = " << lasttime << endl;
902 #endif // Xyce_DEBUG_TIME
904 for (
int i=0 ; i < sec.usedOrder_ ; ++i)
909 timeA = lasttime + hh*i;
910 junk = interpolateSolution(timeA,ds.tmpXn0APtr, ds.xHistory);
913 std::string msg =
"interpolateSolution returned false!";
914 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0,msg);
920 *ds.tmpXn0APtr = *ds.tmpXn0BPtr;
923 timeB = lasttime + hh*(i+1);
924 interpolateSolution(timeB,ds.tmpXn0BPtr, ds.xHistory);
925 #ifdef Xyce_DEBUG_TIME
926 if (tiaParams.debugLevel > 0)
928 Xyce::dout() <<
"Interpolating in [ " << timeA <<
", " << timeB <<
" ]" << endl;
929 Xyce::dout() <<
"timeA = " << timeA << endl;
930 Xyce::dout() <<
"timeB = " << timeB << endl;
932 #endif // Xyce_DEBUG_TIME
935 std::vector<double> t1vals;
936 double T2 = fastTimes.back();
937 int blockCount = blockTmpSolVectorPtr->blockCount();
938 double h2 = T2/blockCount;
939 double tval = timeA+h2;
940 while (tval <= timeB)
942 t1vals.push_back(tval);
946 double eps = fabs(timeB)*1.0e-8;
947 if ( (t1vals.size() == 0) || (fabs(t1vals.back() - timeB) >= eps) )
949 t1vals.push_back(timeB);
951 std::vector<double> t2vals, phiAB(2);
952 std::vector<double> tmpPhiAB(2, 0.0);
955 tmpPhiAB[0] = (*ds.tmpXn0APtr)[phiLID];
956 tmpPhiAB[1] = (*ds.tmpXn0BPtr)[phiLID];
958 blockTmpSolVectorPtr->pmap()->pdsComm()->sumAll( &tmpPhiAB[0], &phiAB[0], 2 );
960 double phiA = phiAB[0], phiB = phiAB[1];
961 for (
unsigned int j=0 ; j<t1vals.size() ; ++j)
963 double phi = (1/(timeB-timeA))*(phiA*(timeB-t1vals[j])+phiB*(t1vals[j]-timeA));
964 t2vals.push_back(fmod(phi,T2));
966 #ifdef Xyce_DEBUG_TIME
967 if (tiaParams.debugLevel > 0)
969 Xyce::dout() <<
"t1vals = " << endl;
970 for (
unsigned int j=0 ; j < t1vals.size() ; ++j)
972 Xyce::dout() << t1vals[j] << endl;
974 Xyce::dout() <<
"phi(" << timeA <<
") = " << phiA << endl;
975 Xyce::dout() <<
"phi(" << timeB <<
") = " << phiB << endl;
976 Xyce::dout() <<
"t2vals = " << endl;
977 for (
unsigned int j=0 ; j< t2vals.size() ; ++j)
979 Xyce::dout() << t2vals[j] << endl;
982 #endif // Xyce_DEBUG_TIME
987 double t = t1vals[0];
988 double s = t2vals[0];
992 for (
int j=0 ; j < blockCount ; ++j)
994 if ((fastTimes[j] <= s) && (s < fastTimes[j+1]))
1000 if (b2 == blockCount)
1004 double s1 = fastTimes[b1];
1005 double s2 = fastTimes[b1+1];
1006 if ((s < s1) || (s > s2))
1008 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
1009 msg +=
" Interpolator cannot find a fast time block containing the first point ";
1010 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1012 #ifdef Xyce_DEBUG_TIME
1013 Xyce::dout() <<
"Found s = " << s <<
" in block " << b1;
1014 Xyce::dout() <<
" with boundary = [" << s1 <<
"," << s2 <<
"]" << endl;
1015 #endif // Xyce_DEBUG_TIME
1016 for (
unsigned int j=0 ; j < t1vals.size() ; ++j)
1022 if ( (s < s1) || (s > s2) )
1024 #ifdef Xyce_DEBUG_TIME
1025 Xyce::dout() <<
"Incrementing fast time block for next interpolation." << endl;
1026 #endif // Xyce_DEBUG_TIME
1028 if (b1 == blockCount)
1033 if (b2 == blockCount)
1038 s2 = fastTimes[b1+1];
1041 if ((s < s1) || (s > s2))
1043 #ifdef Xyce_DEBUG_TIME
1044 Xyce::dout() <<
"Searching for fast time block for next interpolation." << endl;
1045 #endif // Xyce_DEBUG_TIME
1047 for (
int j2=0 ; j2 < blockCount ; ++j2)
1049 if ((fastTimes[j2] <= s) && (s < fastTimes[j2+1]))
1055 if (b2 == blockCount)
1060 s2 = fastTimes[b1+1];
1063 if ((s < s1) || (s > s2))
1065 std::string msg =
"N_TIA_BackwardDifferentiation15::printWaMPDEOutputSolution: ";
1066 msg +=
" Interpolator moved fast time block but new point is not in this block ";
1067 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, msg);
1078 #ifdef Xyce_DEBUG_TIME
1079 if (tiaParams.debugLevel > 0)
1081 Xyce::dout() <<
"Interpolating in the block:" << endl;
1082 Xyce::dout() <<
"(t1,t2) = (" << t1 <<
"," << t2 <<
")" << endl;
1083 Xyce::dout() <<
"(s1,s2) = (" << s1 <<
"," << s2 <<
")" << endl;
1085 #endif // Xyce_DEBUG_TIME
1086 double denom = (t2-t1)*(s2-s1);
1087 double coeff0 = (t2-t)*(s2-s)/denom;
1088 double coeff1 = (t2-t)*(s-s1)/denom;
1089 double coeff2 = (t-t1)*(s2-s)/denom;
1090 double coeff3 = (t-t1)*(s-s1)/denom;
1091 (blockTmpSolVectorPtr->block(b1)).linearCombo(
1092 coeff0, blockTmpXn0APtr->block(b1),
1093 coeff1, blockTmpXn0APtr->block(b2),
1094 coeff2, blockTmpXn0BPtr->block(b1) );
1095 (blockTmpSolVectorPtr->block(b1)).update(
1096 coeff3, blockTmpXn0BPtr->block(b2), 1.0 );
1102 t, blockTmpSolVectorPtr->block(b1),
1103 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
1104 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1105 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_);
1107 #ifdef Xyce_DEBUG_TIME
1108 Xyce::dout() <<
"Interpolated to (t,phi(t)) = (" << t <<
"," << s <<
")" << endl;
1109 #endif // Xyce_DEBUG_TIME
1114 #ifdef Xyce_DEBUG_TIME
1115 Xyce::dout() << Xyce::section_divider << std::endl;
1116 #endif // Xyce_DEBUG_TIME
1132 N_LAS_Vector * solnVecPtr,
1133 const bool doNotInterpolate,
1134 const std::vector<double> &outputInterpolationTimes,
1135 bool skipPrintLineOutput)
1137 #ifdef Xyce_DEBUG_TIME
1138 if (tiaParams.debugLevel > 0)
1140 Xyce::dout() << std::endl;
1141 Xyce::dout() << Xyce::section_divider << std::endl;
1142 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::printOutputSolution" << std::endl;
1143 Xyce::dout() <<
"usedOrder_ = " << sec.usedOrder_ << endl;
1145 #endif // Xyce_DEBUG_TIME
1146 double timestep = sec.lastAttemptedTimeStep;
1147 double lasttime = sec.currentTime - timestep;
1148 bool dointerp =
true;
1149 double hh = timestep/(sec.usedOrder_);
1150 if (hh <= 10*sec.minTimeStep)
1155 if (!(tiaParams.interpOutputFlag))
1160 if (doNotInterpolate)
1165 if (dointerp && !outputInterpolationTimes.empty())
1167 for (
unsigned int i=0;i<outputInterpolationTimes.size();++i)
1169 interpolateSolution(outputInterpolationTimes[i], ds.tmpSolVectorPtr, ds.xHistory);
1170 interpolateSolution(outputInterpolationTimes[i], ds.tmpStaVectorPtr, ds.sHistory);
1171 interpolateSolution(outputInterpolationTimes[i], ds.tmpStoVectorPtr, ds.stoHistory);
1172 outputManagerAdapter.
tranOutput(outputInterpolationTimes[i], *ds.tmpSolVectorPtr,
1173 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
1174 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1175 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_,
1176 skipPrintLineOutput);
1179 else if ( (sec.usedOrder_ > 2) && dointerp )
1181 for (
int i=1 ; i<sec.usedOrder_; ++i)
1183 double timept = lasttime + hh*i;
1184 interpolateSolution(timept,ds.tmpSolVectorPtr, ds.xHistory);
1185 interpolateSolution(timept,ds.tmpStaVectorPtr, ds.sHistory);
1186 interpolateSolution(timept,ds.tmpStoVectorPtr, ds.stoHistory);
1187 outputManagerAdapter.
tranOutput(timept, *ds.tmpSolVectorPtr,
1188 *ds.tmpStaVectorPtr, *ds.tmpStoVectorPtr,
1189 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1190 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_,
1191 skipPrintLineOutput);
1193 #ifdef Xyce_DEBUG_TIME
1194 Xyce::dout() <<
"Interpolated to t = " << timept << endl;
1195 #endif // Xyce_DEBUG_TIME
1202 if (outputInterpolationTimes.empty() || doNotInterpolate)
1203 outputManagerAdapter.
tranOutput(time, *ds.currSolutionPtr,
1204 *ds.currStatePtr, *ds.currStorePtr,
1205 ds.objectiveVec_, ds.dOdpVec_, ds.dOdpAdjVec_,
1206 ds.scaled_dOdpVec_, ds.scaled_dOdpAdjVec_,
1207 skipPrintLineOutput);
1209 #ifdef Xyce_DEBUG_TIME
1210 Xyce::dout() << Xyce::section_divider << std::endl;
1211 #endif // Xyce_DEBUG_TIME
1226 N_LAS_Vector * solnVecPtr,
1227 const double saveTime,
1228 const bool doNotInterpolate)
1230 #ifdef Xyce_DEBUG_TIME
1231 if (tiaParams.debugLevel > 0)
1233 Xyce::dout() << std::endl;
1234 Xyce::dout() << Xyce::section_divider << std::endl;
1235 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::saveOutputSolution" << std::endl;
1237 #endif // Xyce_DEBUG_TIME
1239 double timestep = sec.lastAttemptedTimeStep;
1240 double lasttime = sec.currentTime - timestep;
1241 bool dointerp =
true;
1242 double hh = timestep/(sec.usedOrder_);
1243 if (hh <= 10*sec.minTimeStep)
1248 if (!(tiaParams.interpOutputFlag))
1253 if (doNotInterpolate)
1260 interpolateSolution(saveTime,ds.tmpSolVectorPtr, ds.xHistory);
1261 outputManagerAdapter.
outputDCOP( *(ds.tmpSolVectorPtr) );
1265 outputManagerAdapter.
outputDCOP( *(solnVecPtr) );
1268 #ifdef Xyce_DEBUG_TIME
1269 Xyce::dout() << Xyce::section_divider << std::endl;
1270 #endif // Xyce_DEBUG_TIME
1350 #ifdef Xyce_DEBUG_TIME
1351 if (tiaParams.debugLevel > 1)
1353 Xyce::dout() << std::endl;
1354 Xyce::dout() << Xyce::section_divider << std::endl;
1356 " N_TIA_BackwardDifferentiation15::updateHistory" << std::endl;
1357 Xyce::dout() <<
"\n Before updates \n" << endl;
1358 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1360 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
1361 (ds.xHistory[i])->printPetraObject(Xyce::dout());
1362 Xyce::dout() << endl;
1364 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1366 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
1367 (ds.qHistory[i])->printPetraObject(Xyce::dout());
1368 Xyce::dout() << endl;
1370 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1372 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
1373 (ds.sHistory[i])->printPetraObject(Xyce::dout());
1374 Xyce::dout() << endl;
1376 Xyce::dout() << Xyce::section_divider << std::endl;
1378 #endif // Xyce_DEBUG_TIME
1381 if (sec.usedOrder_ < sec.maxOrder_)
1383 *(ds.xHistory[sec.usedOrder_+1]) = *ds.newtonCorrectionPtr;
1384 *(ds.qHistory[sec.usedOrder_+1]) = *ds.qNewtonCorrectionPtr;
1387 (ds.xHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.xHistory[sec.usedOrder_]),1.0,*ds.newtonCorrectionPtr);
1388 (ds.qHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.qHistory[sec.usedOrder_]),1.0,*ds.qNewtonCorrectionPtr);
1389 for (
int j=sec.usedOrder_-1;j>=0;j--)
1391 (ds.xHistory[j])->linearCombo(1.0,*(ds.xHistory[j]),1.0,*(ds.xHistory[j+1]));
1392 (ds.qHistory[j])->linearCombo(1.0,*(ds.qHistory[j]),1.0,*(ds.qHistory[j+1]));
1396 if (sec.usedOrder_ < sec.maxOrder_)
1398 *(ds.sHistory[sec.usedOrder_+1]) = *ds.sNewtonCorrectionPtr;
1401 (ds.sHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.sHistory[sec.usedOrder_]),1.0,*ds.sNewtonCorrectionPtr);
1402 for (
int j=sec.usedOrder_-1;j>=0;j--)
1404 (ds.sHistory[j])->linearCombo(1.0,*(ds.sHistory[j]),1.0,*(ds.sHistory[j+1]));
1408 if (sec.usedOrder_ < sec.maxOrder_)
1410 *(ds.stoHistory[sec.usedOrder_+1]) = *ds.stoNewtonCorrectionPtr;
1411 *(ds.stoLeadCurrQHistory[sec.usedOrder_+1]) = *ds.stoLeadCurrQNewtonCorrectionPtr;
1414 (ds.stoHistory[sec.usedOrder_])->linearCombo(1.0,*(ds.stoHistory[sec.usedOrder_]),1.0,*ds.stoNewtonCorrectionPtr);
1415 (ds.stoLeadCurrQHistory[sec.usedOrder_])->
1416 linearCombo(1.0,*(ds.stoLeadCurrQHistory[sec.usedOrder_]),1.0,*ds.stoLeadCurrQNewtonCorrectionPtr);
1417 for (
int j=sec.usedOrder_-1;j>=0;j--)
1419 (ds.stoHistory[j])->linearCombo(1.0,*(ds.stoHistory[j]),1.0,*(ds.stoHistory[j+1]));
1420 (ds.stoLeadCurrQHistory[j])->
1421 linearCombo(1.0,*(ds.stoLeadCurrQHistory[j]),1.0,*(ds.stoLeadCurrQHistory[j+1]));
1424 #ifdef Xyce_DEBUG_TIME
1425 if (tiaParams.debugLevel > 1)
1427 Xyce::dout() <<
"\n After updates \n" << endl;
1428 Xyce::dout() <<
"\n newtonCorrectionPtr: " << endl;
1429 ds.newtonCorrectionPtr->printPetraObject(Xyce::dout());
1430 Xyce::dout() <<
"\n qnewtonCorrectionPtr: " << endl;
1431 ds.qNewtonCorrectionPtr->printPetraObject(Xyce::dout());
1432 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1434 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
1435 (ds.xHistory[i])->printPetraObject(Xyce::dout());
1436 Xyce::dout() << endl;
1438 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1440 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
1441 (ds.qHistory[i])->printPetraObject(Xyce::dout());
1442 Xyce::dout() << endl;
1444 Xyce::dout() <<
"\n sNewtonCorrectionPtr: " << endl;
1445 ds.sNewtonCorrectionPtr->printPetraObject(Xyce::dout());
1446 Xyce::dout() << endl;
1447 Xyce::dout() <<
"\n nextStatePtr: " << endl;
1448 ds.nextStatePtr->printPetraObject(Xyce::dout());
1449 Xyce::dout() << endl;
1450 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1452 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
1453 (ds.sHistory[i])->printPetraObject(Xyce::dout());
1454 Xyce::dout() << endl;
1456 Xyce::dout() << Xyce::section_divider << std::endl;
1458 #endif // Xyce_DEBUG_TIME
1472 for (
int i=sec.nscsco_;i<=sec.currentOrder_;++i)
1474 (ds.xHistory[i])->scale(1/sec.beta_[i]);
1475 (ds.qHistory[i])->scale(1/sec.beta_[i]);
1476 (ds.sHistory[i])->scale(1/sec.beta_[i]);
1477 (ds.stoHistory[i])->scale(1/sec.beta_[i]);
1479 for (
int i=1;i<=sec.currentOrder_;++i)
1481 sec.psi_[i-1] = sec.psi_[i] - (sec.currentTimeStep);
1483 #ifdef Xyce_DEBUG_TIME
1484 if (tiaParams.debugLevel > 1)
1486 Xyce::dout() << std::endl;
1487 Xyce::dout() << Xyce::section_divider << std::endl;
1489 " N_TIA_BackwardDifferentiation15::restoreHistory" << std::endl;
1490 for (
int i=1;i<=sec.currentOrder_;++i)
1491 Xyce::dout() <<
"\n sec.psi_[i] = " << sec.psi_[i] << endl;
1492 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1494 Xyce::dout() <<
"\n xHistory["<< i <<
"]: \n" << endl;
1495 (ds.xHistory[i])->printPetraObject(Xyce::dout());
1496 Xyce::dout() << endl;
1498 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1500 Xyce::dout() <<
"\n qHistory["<< i <<
"]: \n" << endl;
1501 (ds.qHistory[i])->printPetraObject(Xyce::dout());
1502 Xyce::dout() << endl;
1504 for (
int i=0; i<=sec.maxOrder_ ; ++i)
1506 Xyce::dout() <<
"\n sHistory["<< i <<
"]: \n" << endl;
1507 (ds.sHistory[i])->printPetraObject(Xyce::dout());
1508 Xyce::dout() << endl;
1510 Xyce::dout() << Xyce::section_divider << std::endl;
1512 #endif // Xyce_DEBUG_TIME
1527 #ifdef Xyce_DEBUG_TIME
1528 if (tiaParams.debugLevel > 0)
1530 Xyce::dout() << std::endl;
1531 Xyce::dout() << Xyce::section_divider << std::endl;
1534 " N_TIA_BackwardDifferentiation15::updateCoeffs" << std::endl;
1536 " currentTimeStep = " << sec.currentTimeStep << std::endl;
1538 " numberOfSteps_ = " << sec.numberOfSteps_ << std::endl;
1540 " currentOrder_ = " << sec.currentOrder_ << std::endl;
1542 " nscsco_ = " << sec.nscsco_ << std::endl;
1544 " psi_[0] = " << sec.psi_[0] << std::endl;
1552 if ((sec.currentTimeStep != sec.usedStep_) || (sec.currentOrder_ != sec.usedOrder_))
1554 sec.nscsco_ = min(sec.nscsco_+1,sec.usedOrder_+2);
1555 if (sec.currentOrder_+1 >= sec.nscsco_)
1558 sec.alpha_[0] = 1.0;
1559 double temp1 = sec.currentTimeStep;
1560 sec.sigma_[0] = 1.0;
1561 sec.gamma_[0] = 0.0;
1562 for (
int i=1;i<=sec.currentOrder_;++i)
1564 double temp2 = sec.psi_[i-1];
1565 sec.psi_[i-1] = temp1;
1566 sec.beta_[i] = sec.beta_[i-1]*sec.psi_[i-1]/temp2;
1567 temp1 = temp2 + sec.currentTimeStep;
1568 sec.alpha_[i] = (sec.currentTimeStep)/temp1;
1569 sec.sigma_[i] = (i+1)*sec.sigma_[i-1]*sec.alpha_[i];
1570 sec.gamma_[i] = sec.gamma_[i-1]+sec.alpha_[i-1]/(sec.currentTimeStep);
1572 sec.psi_[sec.currentOrder_] = temp1;
1575 for (
int i=0;i<sec.currentOrder_;++i)
1577 sec.alphas_ = sec.alphas_ - 1.0/(i+1.0);
1578 sec.alpha0_ = sec.alpha0_ - sec.alpha_[i];
1580 sec.cj_ = -sec.alphas_/(sec.currentTimeStep);
1581 sec.ck_ = abs(sec.alpha_[sec.currentOrder_]+sec.alphas_-sec.alpha0_);
1582 sec.ck_ = max(sec.ck_,sec.alpha_[sec.currentOrder_]);
1584 #ifdef Xyce_DEBUG_TIME
1585 if (tiaParams.debugLevel > 0)
1587 Xyce::dout() <<
" nscsco_ = " << sec.nscsco_ << std::endl;
1588 Xyce::dout() <<
" beta_[0] = " << sec.beta_[0] << std::endl;
1589 Xyce::dout() <<
" beta_[1] = " << sec.beta_[1] << std::endl;
1590 Xyce::dout() <<
" beta_[2] = " << sec.beta_[2] << std::endl;
1591 Xyce::dout() <<
" beta_[3] = " << sec.beta_[3] << std::endl;
1592 Xyce::dout() <<
" beta_[4] = " << sec.beta_[4] << std::endl;
1593 Xyce::dout() <<
" alpha_[0] = " << sec.alpha_[0] << std::endl;
1594 Xyce::dout() <<
" alpha_[1] = " << sec.alpha_[1] << std::endl;
1595 Xyce::dout() <<
" alpha_[2] = " << sec.alpha_[2] << std::endl;
1596 Xyce::dout() <<
" alpha_[3] = " << sec.alpha_[3] << std::endl;
1597 Xyce::dout() <<
" alpha_[4] = " << sec.alpha_[4] << std::endl;
1598 Xyce::dout() <<
" alphas_ = " << sec.alphas_ << std::endl;
1599 Xyce::dout() <<
" alpha0_ = " << sec.alpha0_ << std::endl;
1600 Xyce::dout() <<
" gamma_[0] = " << sec.gamma_[0] << std::endl;
1601 Xyce::dout() <<
" gamma_[1] = " << sec.gamma_[1] << std::endl;
1602 Xyce::dout() <<
" gamma_[2] = " << sec.gamma_[2] << std::endl;
1603 Xyce::dout() <<
" gamma_[3] = " << sec.gamma_[3] << std::endl;
1604 Xyce::dout() <<
" gamma_[4] = " << sec.gamma_[4] << std::endl;
1605 Xyce::dout() <<
" psi_[0] = " << sec.psi_[0] << std::endl;
1606 Xyce::dout() <<
" psi_[1] = " << sec.psi_[1] << std::endl;
1607 Xyce::dout() <<
" psi_[2] = " << sec.psi_[2] << std::endl;
1608 Xyce::dout() <<
" psi_[3] = " << sec.psi_[3] << std::endl;
1609 Xyce::dout() <<
" psi_[4] = " << sec.psi_[4] << std::endl;
1610 Xyce::dout() <<
" sigma_[0] = " << sec.sigma_[0] << std::endl;
1611 Xyce::dout() <<
" sigma_[1] = " << sec.sigma_[1] << std::endl;
1612 Xyce::dout() <<
" sigma_[2] = " << sec.sigma_[2] << std::endl;
1613 Xyce::dout() <<
" sigma_[3] = " << sec.sigma_[3] << std::endl;
1614 Xyce::dout() <<
" sigma_[4] = " << sec.sigma_[4] << std::endl;
1615 Xyce::dout() <<
" ck_ = " << sec.ck_ << std::endl;
1616 Xyce::dout() << Xyce::section_divider << std::endl;
1618 #endif // Xyce_DEBUG_TIME
1644 double time_to_stop = sec.stopTime - sec.currentTime;
1645 double currentTimeStep;
1646 if (tiaParams.constantStepSize)
1648 currentTimeStep = 0.1 * time_to_stop;
1649 currentTimeStep =
Xycemin(sec.startingTimeStep, currentTimeStep);
1650 sec.currentTimeStep = currentTimeStep;
1656 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
1657 double dnorm_q = 0.0;
1658 (ds.qHistory[1])->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1660 double dnorm_q = ds.delta_x_errorNorm_q1();
1664 currentTimeStep =
Xycemin(sec.h0_max_factor_*abs(time_to_stop),sqrt(2.0)/(sec.h0_safety_*dnorm_q));
1668 currentTimeStep = sec.h0_max_factor_*abs(time_to_stop);
1671 if (sec.startingTimeStep > 0.0)
1672 currentTimeStep =
Xycemin(sec.startingTimeStep, currentTimeStep);
1674 double rh = abs(currentTimeStep)*sec.h_max_inv_;
1675 if (rh>1.0) currentTimeStep = currentTimeStep/rh;
1680 if (sec.currentTime != sec.initialTime)
1682 sec.currentTimeStep =
Xycemin(sec.lastTimeStep, currentTimeStep);
1686 sec.currentTimeStep = currentTimeStep;
1690 sec.currentTimeStepRatio = 1.0;
1691 sec.currentTimeStepSum = 2.0*sec.currentTimeStep;
1693 sec.lastTimeStep = sec.currentTimeStep;
1694 sec.lastTimeStepRatio = sec.currentTimeStepRatio;
1695 sec.lastTimeStepSum = sec.currentTimeStepSum;
1697 sec.numberSuccessiveFailures = 0;
1698 sec.stepAttemptStatus =
true;
1702 sec.nextTime = sec.currentTime + sec.currentTimeStep;
1705 *(ds.xHistory[0]) = *(ds.currSolutionPtr);
1706 (ds.xHistory[1])->putScalar(0.0);
1709 *(ds.qHistory[0]) = *(ds.daeQVectorPtr);
1710 *(ds.qHistory[1]) = *(ds.daeFVectorPtr);
1711 (ds.qHistory[1])->scale(-sec.currentTimeStep);
1714 *(ds.sHistory[0]) = *(ds.currStatePtr);
1715 (ds.sHistory[1])->putScalar(0.0);
1718 *(ds.stoHistory[0]) = *(ds.currStorePtr);
1719 (ds.stoHistory[1])->putScalar(0.0);
1722 *(ds.stoLeadCurrQHistory[0]) = *(ds.currStoreLeadCurrQPtr);
1723 (ds.stoLeadCurrQHistory[1])->putScalar(0.0);
1726 sec.numberOfSteps_ = 0;
1727 sec.currentOrder_ = 1;
1729 sec.psi_[0] = sec.currentTimeStep;
1730 sec.cj_ = 1/sec.psi_[0];
1732 #ifdef Xyce_DEBUG_TIME
1733 Xyce::dout() << std::endl;
1734 Xyce::dout() << Xyce::section_divider << std::endl;
1735 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::initialize" << std::endl;
1736 if (tiaParams.debugLevel > 1)
1738 Xyce::dout() <<
"\n xHistory: \n" << endl;
1739 (ds.xHistory[0])->printPetraObject(Xyce::dout());
1740 Xyce::dout() << endl;
1741 (ds.xHistory[1])->printPetraObject(Xyce::dout());
1742 Xyce::dout() << endl;
1743 Xyce::dout() <<
"\n qHistory: \n" << endl;
1744 (ds.qHistory[0])->printPetraObject(Xyce::dout());
1745 Xyce::dout() << endl;
1746 (ds.qHistory[1])->printPetraObject(Xyce::dout());
1747 Xyce::dout() << endl;
1748 Xyce::dout() <<
"\n sHistory: \n" << endl;
1749 (ds.sHistory[0])->printPetraObject(Xyce::dout());
1750 Xyce::dout() << endl;
1751 (ds.sHistory[1])->printPetraObject(Xyce::dout());
1752 Xyce::dout() << endl;
1753 Xyce::dout() <<
"\n" <<
"currentTimeStep = " << currentTimeStep <<
"\n" << endl;
1754 Xyce::dout() <<
"\n" <<
"time_to_stop = " << time_to_stop <<
"\n" << endl;
1756 Xyce::dout() << Xyce::section_divider << std::endl;
1757 #endif // Xyce_DEBUG_TIME
1772 double time_to_stop = sec.stopTime - sec.currentTime;
1776 *(ds.xHistory[0]) = *(ds.currSolutionPtr);
1777 (ds.xHistory[1])->putScalar(0.0);
1780 *(ds.qHistory[0]) = *(ds.daeQVectorPtr);
1781 *(ds.qHistory[1]) = *(ds.daeFVectorPtr);
1782 (ds.qHistory[1])->scale(-sec.currentTimeStep);
1785 *(ds.sHistory[0]) = *(ds.nextStatePtr);
1786 (ds.sHistory[1])->putScalar(0.0);
1789 *(ds.stoHistory[0]) = *(ds.nextStatePtr);
1790 (ds.stoHistory[1])->putScalar(0.0);
1793 *(ds.stoLeadCurrQHistory[0]) = *(ds.nextStoreLeadCurrQPtr);
1794 (ds.stoLeadCurrQHistory[1])->putScalar(0.0);
1797 sec.numberOfSteps_ = 0;
1799 sec.psi_[0] = sec.currentTimeStep;
1800 sec.cj_ = 1/sec.psi_[0];
1827 #ifdef Xyce_DEBUG_TIME
1828 if (tiaParams.debugLevel > 0)
1830 Xyce::dout() << std::endl;
1831 Xyce::dout() << Xyce::section_divider << std::endl;
1832 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::checkReduceOrder" << std::endl;
1834 #endif // Xyce_DEBUG_TIME
1841 #ifndef Xyce_USE_Q_NORM
1846 double dnorm_x = sec.estOverTol_;
1847 double dnorm = dnorm_x;
1849 double dnorm_x = 0.0, dnorm_q = 0.0;
1850 ds.newtonCorrectionPtr->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1851 ds.qNewtonCorrectionPtr->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1852 double dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
1855 sec.Ek_ = sec.sigma_[sec.currentOrder_]*dnorm;
1856 sec.Tk_ = (sec.currentOrder_+1)*sec.Ek_;
1858 sec.newOrder_ = sec.currentOrder_;
1859 #ifdef Xyce_DEBUG_TIME
1860 if (tiaParams.debugLevel > 0)
1862 Xyce::dout() <<
" Est_= " << sec.Est_ << std::endl;
1863 Xyce::dout() <<
" Ek_= " << sec.Ek_ << std::endl;
1864 Xyce::dout() <<
" dnorm = " << dnorm << std::endl;
1865 Xyce::dout() <<
" sigma[order] = " << sec.sigma_[sec.currentOrder_] << std::endl;
1866 Xyce::dout() <<
" Tk_= " << sec.Tk_ << std::endl;
1868 #endif // Xyce_DEBUG_TIME
1871 if (sec.currentOrder_>1)
1874 #ifndef Xyce_USE_Q_NORM
1875 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_]),1.0,*ds.newtonCorrectionPtr);
1876 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
1877 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1880 dnorm_x = sec.ck_ * ds.delta_x_errorNorm_m1();
1884 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_]),1.0,*ds.newtonCorrectionPtr);
1885 ds.delta_q->linearCombo(1.0,*(ds.qHistory[sec.currentOrder_]),1.0,*ds.qNewtonCorrectionPtr);
1886 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1887 ds.delta_q->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1888 dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
1891 sec.Ekm1_ = sec.sigma_[sec.currentOrder_-1]*dnorm;
1892 sec.Tkm1_ = sec.currentOrder_*sec.Ekm1_;
1893 #ifdef Xyce_DEBUG_TIME
1894 if (tiaParams.debugLevel > 0)
1896 Xyce::dout() <<
" Ekm1_= " << sec.Ekm1_ << std::endl;
1897 Xyce::dout() <<
" Tkm1_= " << sec.Tkm1_ << std::endl;
1899 #endif // Xyce_DEBUG_TIME
1901 if (sec.currentOrder_>2)
1903 #ifndef Xyce_USE_Q_NORM
1904 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_-1]),1.0,*ds.delta_x);
1905 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
1906 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1909 dnorm_x = sec.ck_ * ds.delta_x_errorNorm_m2();
1913 ds.delta_x->linearCombo(1.0,*(ds.xHistory[sec.currentOrder_-1]),1.0,*ds.delta_x);
1914 ds.delta_q->linearCombo(1.0,*(ds.qHistory[sec.currentOrder_-1]),1.0,*ds.delta_q);
1915 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
1916 ds.delta_q->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
1917 dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
1920 sec.Ekm2_ = sec.sigma_[sec.currentOrder_-2]*dnorm;
1921 sec.Tkm2_ = (sec.currentOrder_-1)*sec.Ekm2_;
1922 if (
Xycemax(sec.Tkm1_,sec.Tkm2_)<=sec.Tk_)
1925 sec.Est_ = sec.Ekm1_;
1928 else if (sec.Tkm1_ <= sec.Tkm1_Tk_safety_ * sec.Tk_)
1930 #ifdef Xyce_DEBUG_TIME
1931 if (tiaParams.debugLevel > 0)
1933 Xyce::dout() <<
" Tkm1_Tk_safety= " << sec.Tkm1_Tk_safety_ << std::endl;
1934 Xyce::dout() <<
" Tkm1_= " << sec.Tkm1_ << std::endl;
1935 Xyce::dout() <<
" Tk_= " << sec.Tk_ << std::endl;
1936 Xyce::dout() <<
" Tk_*safety= " << sec.Tk_*sec.Tkm1_Tk_safety_ << std::endl;
1938 #endif // Xyce_DEBUG_TIME
1941 sec.Est_ = sec.Ekm1_;
1944 #ifdef Xyce_DEBUG_TIME
1945 if (tiaParams.debugLevel > 0)
1947 Xyce::dout() <<
" newOrder = " << sec.newOrder_ << std::endl;
1948 Xyce::dout() << Xyce::section_divider << std::endl;
1980 #ifdef Xyce_DEBUG_TIME
1982 if (tiaParams.debugLevel > 0)
1984 Xyce::dout() << std::endl;
1985 Xyce::dout() << Xyce::section_divider << std::endl;
1986 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::rejectStep" << std::endl;
1991 bool adjustStep = (!(tiaParams.constantStepSize) );
1993 sec.lastAttemptedTimeStep = sec.currentTimeStep;
1996 double newTimeStep_ = sec.currentTimeStep;
1998 if ((sec.stepAttemptStatus ==
false) && (adjustStep))
2000 sec.initialPhase_ =
false;
2004 if ((sec.newtonConvergenceStatus <= 0))
2009 newTimeStep_ = rr * sec.currentTimeStep;
2011 if (sec.nef_ > 2) sec.newOrder_ = 1;
2012 #ifdef Xyce_DEBUG_TIME
2013 Xyce::dout() <<
"rejectStep 1" << std::endl;
2023 #ifndef Xyce_USE_Q_NORM
2024 rr = sec.r_factor_*pow(sec.r_safety_*(sec.Est_+sec.r_fudge_),-1.0/(sec.newOrder_+1.0));
2027 rr = sec.r_factor_*pow(sec.r_safety_*sec.Est_+sec.r_fudge_,-1.0/(sec.newOrder_+1.0));
2030 newTimeStep_ = rr * sec.currentTimeStep;
2031 #ifdef Xyce_DEBUG_TIME
2032 Xyce::dout() <<
"rejectStep 2" << std::endl;
2035 else if (sec.nef_ == 2)
2038 newTimeStep_ = rr * sec.currentTimeStep;
2039 #ifdef Xyce_DEBUG_TIME
2040 Xyce::dout() <<
"rejectStep 3" << std::endl;
2043 else if (sec.nef_ > 2)
2047 newTimeStep_ = rr * sec.currentTimeStep;
2048 #ifdef Xyce_DEBUG_TIME
2049 Xyce::dout() <<
"rejectStep 4" << std::endl;
2053 if (sec.newOrder_ >= sec.minOrder_)
2055 sec.currentOrder_ = sec.newOrder_;
2056 #ifdef Xyce_DEBUG_TIME
2057 Xyce::dout() <<
"rejectStep 5" << std::endl;
2060 if (sec.numberOfSteps_ == 0)
2062 sec.psi_[0] = newTimeStep_;
2063 (ds.xHistory[1])->scale(rr);
2064 (ds.qHistory[1])->scale(rr);
2065 #ifdef Xyce_DEBUG_TIME
2066 Xyce::dout() <<
"rejectStep 6" << std::endl;
2069 #ifdef Xyce_DEBUG_TIME
2070 if (tiaParams.debugLevel > 0)
2072 Xyce::dout() <<
" currentTimeStep = " << sec.currentTimeStep << std::endl;
2073 Xyce::dout() <<
" numberOfSteps_ = " << sec.numberOfSteps_ << std::endl;
2074 Xyce::dout() <<
" currentOrder_ = " << sec.currentOrder_ << std::endl;
2075 Xyce::dout() <<
" nscsco_ = " << sec.nscsco_ << std::endl;
2076 Xyce::dout() <<
" alpha_[0] = " << sec.alpha_[0] << std::endl;
2077 Xyce::dout() <<
" alpha_[1] = " << sec.alpha_[1] << std::endl;
2078 Xyce::dout() <<
" alpha_[2] = " << sec.alpha_[2] << std::endl;
2079 Xyce::dout() <<
" alpha_[3] = " << sec.alpha_[3] << std::endl;
2080 Xyce::dout() <<
" alpha_[4] = " << sec.alpha_[4] << std::endl;
2081 Xyce::dout() <<
" psi_[0] = " << sec.psi_[0] << std::endl;
2082 Xyce::dout() <<
" psi_[1] = " << sec.psi_[1] << std::endl;
2083 Xyce::dout() <<
" psi_[2] = " << sec.psi_[2] << std::endl;
2084 Xyce::dout() <<
" psi_[3] = " << sec.psi_[3] << std::endl;
2085 Xyce::dout() <<
" psi_[4] = " << sec.psi_[4] << std::endl;
2086 Xyce::dout() <<
" sigma_[0] = " << sec.sigma_[0] << std::endl;
2087 Xyce::dout() <<
" sigma_[1] = " << sec.sigma_[1] << std::endl;
2088 Xyce::dout() <<
" sigma_[2] = " << sec.sigma_[2] << std::endl;
2089 Xyce::dout() <<
" sigma_[3] = " << sec.sigma_[3] << std::endl;
2090 Xyce::dout() <<
" sigma_[4] = " << sec.sigma_[4] << std::endl;
2091 Xyce::dout() <<
" rr = " << rr << std::endl;
2092 Xyce::dout() <<
" r_factor_ = " << sec.r_factor_ << std::endl;
2093 Xyce::dout() <<
" r_safety_ = " << sec.r_safety_ << std::endl;
2094 Xyce::dout() <<
" Est_ = " << sec.Est_ << std::endl;
2095 Xyce::dout() <<
" r_fudge_ = " << sec.r_fudge_ << std::endl;
2096 Xyce::dout() <<
" newOrder_ = " << sec.newOrder_ << std::endl;
2097 Xyce::dout() <<
" currentTimeStep = " << sec.currentTimeStep << std::endl;
2098 Xyce::dout() <<
" newTimeStep_ = " << newTimeStep_ << std::endl;
2100 #endif // Xyce_DEBUG_TIME
2102 else if ((sec.stepAttemptStatus ==
false) & (!adjustStep))
2104 std::string tmp =
" BackwardDifferentiation15:rejectStep: Warning: Local error test failed with constant step-size.\n";
2105 Xyce::dout() << tmp << std::endl;
2111 newTimeStep_ =
Xycemax(newTimeStep_, sec.minTimeStep);
2112 newTimeStep_ =
Xycemin(newTimeStep_, sec.maxTimeStep);
2114 double nextTimePt = sec.currentTime + newTimeStep_;
2116 if (nextTimePt > sec.stopTime)
2118 nextTimePt = sec.stopTime;
2119 newTimeStep_ = sec.stopTime - sec.currentTime;
2122 sec.nextTime = nextTimePt;
2124 sec.currentTimeStepRatio = newTimeStep_/sec.lastTimeStep;
2125 sec.currentTimeStepSum = newTimeStep_ + sec.lastTimeStep;
2127 #ifdef Xyce_DEBUG_TIME
2128 if (tiaParams.debugLevel >0)
2130 Xyce::dout() <<
" newTimeStep_ = " << newTimeStep_ << std::endl;
2131 Xyce::dout() <<
" nextTime = " << sec.nextTime << std::endl;
2133 #endif // Xyce_DEBUG_TIME
2135 sec.currentTimeStep = newTimeStep_;
2139 double nextTimePt = sec.currentTime + sec.currentTimeStep;
2141 if (nextTimePt > sec.stopTime)
2143 nextTimePt = sec.stopTime;
2144 sec.currentTimeStep = sec.stopTime - sec.currentTime;
2147 sec.currentTimeStepRatio = sec.currentTimeStep / sec.lastTimeStep;
2148 sec.currentTimeStepSum = sec.currentTimeStep + sec.lastTimeStep;
2150 sec.nextTime = nextTimePt;
2152 #ifdef Xyce_DEBUG_TIME
2153 if (tiaParams.debugLevel >0)
2155 Xyce::dout() << Xyce::section_divider << std::endl;
2157 #endif // Xyce_DEBUG_TIME
2171 sec.setTimeStep(sec.currentTimeStep);
2184 sec.numberOfSteps_ ++;
2186 sec.lastTime = sec.currentTime;
2187 sec.currentTime = sec.nextTime;
2191 #ifdef Xyce_DEBUG_TIME
2192 if (tiaParams.debugLevel > 0)
2194 Xyce::dout() << std::endl;
2195 Xyce::dout() << Xyce::section_divider << std::endl;
2196 Xyce::dout() <<
" N_TIA_BackwardDifferentiation15::completeStep" << std::endl;
2201 bool adjustStep = (!(tiaParams.constantStepSize) );
2203 sec.lastAttemptedTimeStep = sec.currentTimeStep;
2205 double newTimeStep_ = sec.currentTimeStep;
2209 sec.lastTimeStep = sec.currentTimeStep;
2210 sec.lastTimeStepRatio = sec.currentTimeStepRatio;
2211 sec.lastTimeStepSum = sec.currentTimeStepSum;
2212 int orderDiff = sec.currentOrder_ - sec.usedOrder_;
2213 sec.usedOrder_ = sec.currentOrder_;
2214 sec.usedStep_ = sec.currentTimeStep;
2215 if ((sec.newOrder_ == sec.currentOrder_-1) || (sec.currentOrder_ == sec.maxOrder_))
2220 sec.initialPhase_ =
false;
2222 if (sec.initialPhase_)
2224 sec.currentOrder_++;
2225 newTimeStep_ = sec.h_phase0_incr_ * sec.currentTimeStep;
2229 int action = TIAAction_UNSET;
2230 if (sec.newOrder_ == sec.currentOrder_-1)
2231 action = TIAAction_LOWER;
2232 else if (sec.newOrder_ == sec.maxOrder_)
2233 action = TIAAction_MAINTAIN;
2234 else if ((sec.currentOrder_+1>=sec.nscsco_) || (orderDiff == 1))
2238 action = TIAAction_MAINTAIN;
2242 #ifndef Xyce_USE_Q_NORM
2243 ds.delta_x->linearCombo(1.0,*ds.newtonCorrectionPtr,-1.0,*(ds.xHistory[sec.currentOrder_+1]));
2244 #ifdef Xyce_INCOMPLETE_2LEVEL_NORMS
2245 double dnorm_x = 0.0;
2246 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
2249 double dnorm_x = sec.ck_ * ds.delta_x_errorNorm_p1();
2251 double dnorm = dnorm_x;
2253 ds.delta_x->linearCombo(1.0,*ds.newtonCorrectionPtr,-1.0,*(ds.xHistory[sec.currentOrder_+1]));
2254 ds.delta_q->linearCombo(1.0,*ds.qNewtonCorrectionPtr,-1.0,*(ds.qHistory[sec.currentOrder_+1]));
2255 double dnorm_x = 0.0, dnorm_q = 0.0;
2256 ds.delta_x->wRMSNorm(*ds.errWtVecPtr, &dnorm_x);
2257 ds.delta_q->wRMSNorm(*ds.qErrWtVecPtr, &dnorm_q);
2258 double dnorm = sqrt(0.5*dnorm_x*dnorm_x+0.5*dnorm_q*dnorm_q);
2262 sec.Ekp1_ = sec.Tkp1_/(sec.currentOrder_+2);
2263 if (sec.currentOrder_ == 1)
2265 if (sec.Tkp1_ >= sec.Tkp1_Tk_safety_ * sec.Tk_)
2266 action = TIAAction_MAINTAIN;
2268 action = TIAAction_RAISE;
2272 if (sec.Tkm1_ <=
Xycemin(sec.Tk_,sec.Tkp1_))
2273 action = TIAAction_LOWER;
2274 else if (sec.Tkp1_ >= sec.Tk_)
2275 action = TIAAction_MAINTAIN;
2277 action = TIAAction_RAISE;
2280 if (sec.currentOrder_ < sec.minOrder_)
2282 action = TIAAction_RAISE;
2284 else if ((sec.currentOrder_ == sec.minOrder_) && (action == TIAAction_LOWER))
2286 action = TIAAction_MAINTAIN;
2288 if (action == TIAAction_RAISE)
2290 sec.currentOrder_++;
2291 sec.Est_ = sec.Ekp1_;
2293 else if (action == TIAAction_LOWER)
2295 sec.currentOrder_--;
2296 sec.Est_ = sec.Ekm1_;
2298 newTimeStep_ = sec.currentTimeStep;
2304 if (tiaParams.errorAnalysisOption == 1)
2306 rr = 0.4/(sec.r_min_);
2307 newTimeStep_ = rr*sec.currentTimeStep;
2311 #ifndef Xyce_USE_Q_NORM
2312 rr = pow(sec.r_safety_*(sec.Est_+sec.r_fudge_),-1.0/(sec.currentOrder_+1.0));
2314 rr = pow(sec.r_safety_*sec.Est_+sec.r_fudge_,-1.0/(sec.currentOrder_+1.0));
2317 #ifdef Xyce_DEBUG_TIME
2318 if (tiaParams.debugLevel > 0)
2320 Xyce::dout() <<
" currentOrder_ = " << sec.currentOrder_ << std::endl;
2321 Xyce::dout() <<
" r_safety = " << sec.r_safety_ << std::endl;
2322 Xyce::dout() <<
" r_fudge_ = " << sec.r_fudge_ << std::endl;
2323 Xyce::dout() <<
" r_hincr_ = " << sec.r_hincr_ << std::endl;
2324 Xyce::dout() <<
" r_hincr_test_ = " << sec.r_hincr_test_ << std::endl;
2325 Xyce::dout() <<
" Est = " << sec.Est_ << std::endl;
2326 Xyce::dout() <<
" Ekp1_ = " << sec.Ekp1_ << std::endl;
2327 Xyce::dout() <<
" Ekm1_ = " << sec.Ekm1_ << std::endl;
2328 Xyce::dout() <<
" Tkp1_ = " << sec.Tkp1_ << std::endl;
2329 Xyce::dout() <<
" raw rr = " << rr << std::endl;
2332 if (rr >= sec.r_hincr_test_)
2335 newTimeStep_ = rr*sec.currentTimeStep;
2340 newTimeStep_ = rr*sec.currentTimeStep;
2344 #ifdef Xyce_DEBUG_TIME
2345 if (tiaParams.debugLevel > 0)
2347 Xyce::dout() <<
" initialPhase_ = " << sec.initialPhase_ << std::endl;
2348 Xyce::dout() <<
" rr = " << rr << std::endl;
2349 Xyce::dout() <<
" currentTimeStep = " << sec.currentTimeStep << std::endl;
2350 Xyce::dout() <<
" currentTime = " << sec.currentTime << std::endl;
2351 Xyce::dout() <<
" nextTime = " << sec.nextTime << std::endl;
2352 Xyce::dout() <<
" newTimeStep_ = " << newTimeStep_ << std::endl;
2353 Xyce::dout() <<
" minTimeStep = " << sec.minTimeStep << std::endl;
2354 Xyce::dout() <<
" maxTimeStep = " << sec.maxTimeStep << std::endl;
2367 if (sec.currentTime < sec.stopTime)
2372 newTimeStep_ =
Xycemax(newTimeStep_, sec.minTimeStep);
2373 newTimeStep_ =
Xycemin(newTimeStep_, sec.maxTimeStep);
2375 double nextTimePt = sec.currentTime + newTimeStep_;
2377 if (nextTimePt > sec.stopTime)
2379 nextTimePt = sec.stopTime;
2380 newTimeStep_ = sec.stopTime - sec.currentTime;
2383 sec.nextTime = nextTimePt;
2385 sec.currentTimeStepRatio = newTimeStep_/sec.lastTimeStep;
2386 sec.currentTimeStepSum = newTimeStep_ + sec.lastTimeStep;
2388 #ifdef Xyce_DEBUG_TIME
2389 if (tiaParams.debugLevel >0)
2391 Xyce::dout() <<
" nextTime = " << sec.nextTime << std::endl;
2392 Xyce::dout() <<
" newTimeStep_ = " << newTimeStep_ << std::endl;
2396 sec.currentTimeStep = newTimeStep_;
2400 double nextTimePt = sec.currentTime + sec.currentTimeStep;
2402 if (nextTimePt > sec.stopTime)
2404 nextTimePt = sec.stopTime;
2405 sec.currentTimeStep = sec.stopTime - sec.currentTime;
2408 sec.currentTimeStepRatio = sec.currentTimeStep / sec.lastTimeStep;
2409 sec.currentTimeStepSum = sec.currentTimeStep + sec.lastTimeStep;
2411 sec.nextTime = nextTimePt;
2414 #ifdef Xyce_DEBUG_TIME
2415 if (tiaParams.debugLevel >0)
2417 Xyce::dout() << Xyce::section_divider << std::endl;
2439 ds.nextStateDerivPtr->linearCombo(1.0,*ds.nextStatePtr,-1.0,*ds.sn0Ptr);
2440 ds.nextStateDerivPtr->linearCombo(1.0,*ds.spn0Ptr,-sec.alphas_/sec.currentTimeStep,*ds.nextStateDerivPtr);
2455 ds.nextStoreLeadCurrQDerivPtr->
2456 linearCombo(1.0,*ds.nextStoreLeadCurrQPtr,-1.0,*ds.stoQn0Ptr);
2457 ds.nextStoreLeadCurrQDerivPtr->
2458 linearCombo(1.0,*ds.stoQpn0Ptr,-sec.alphas_/sec.currentTimeStep,*ds.nextStoreLeadCurrQDerivPtr);
2459 ds.nextStorePtr->linearCombo(1.0,*ds.nextStorePtr,1.0,*ds.nextStoreLeadCurrQDerivPtr);
2485 tle.
xErrorSum = ds.partialErrorNormSum ();
2486 tle.
qErrorSum = ds.partialQErrorNormSum ();
2487 tle.
xErrorSum_m1 = ds.partialSum_m1 (sec.currentOrder_);
2488 tle.
xErrorSum_m2 = ds.partialSum_m2 (sec.currentOrder_);
2489 tle.
xErrorSum_p1 = ds.partialSum_p1 (sec.currentOrder_, sec.maxOrder_);
2492 #ifdef Xyce_DEBUG_TIME
2493 Xyce::dout() << tle;