39 #include <Xyce_config.h>
51 #include <N_LOA_Loader.h>
52 #include <N_LAS_System.h>
53 #include <N_MPDE_Manager.h>
54 #include <N_IO_OutputMgr.h>
55 #include <N_IO_RestartMgr.h>
57 #include <N_UTL_Timer.h>
58 #include <N_UTL_NoCase.h>
59 #include <N_ERH_Progress.h>
61 #include <N_IO_CmdParse.h>
65 #include<N_UTL_ExpressionData.h>
82 firstTranOutput_(true),
88 historyTrackingOn_(true),
89 maxTimeStepExpressionGiven_(false),
90 maxTimeStepExpressionAsString_(
""),
92 oldPercentComplete(0.0),
114 std::list<N_UTL_Param>::const_iterator it_tp;
115 std::list<N_UTL_Param>::const_iterator first = paramsBlock.getParams().begin();
116 std::list<N_UTL_Param>::const_iterator last = paramsBlock.getParams().end();
117 for (it_tp = first; it_tp != last; ++it_tp)
119 if (it_tp->uTag() ==
"TSTART")
124 else if (it_tp->uTag() ==
"TSTOP")
128 else if (it_tp->uTag() ==
"TSTEP")
132 else if (it_tp->uTag() ==
"NOOP" ||
133 it_tp->uTag() ==
"UIC")
137 else if (it_tp->uTag() ==
"DTMAX")
141 #ifdef Xyce_DEBUG_ANALYSIS
148 else if (it_tp->uTag() ==
"MAXTIMEEXPRESSION")
165 std::ostringstream ost;
166 ost <<
" In N_TIA_StepErrorControl::setTranAnalysisParams: " << std::endl;
168 <<
" is earlier or same as start time of "
170 ost <<
" Check netlist for invalid .TRAN specification " << std::endl;
171 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL_0, ost.str());
182 #ifdef Xyce_DEBUG_ANALYSIS
186 << section_divider << std::endl
187 <<
" Transient simulation parameters" << std::endl
191 <<
" tStart (time of first output) = " <<
tiaParams.
tStart << std::endl;
195 dout() <<
" NOOP/UIC is NOT set" << std::endl;
199 dout() <<
" NOOP/UIC is set" << std::endl;
202 dout() << section_divider << std::endl;
252 bool bsuccess =
true;
258 bsuccess = bsuccess &
init();
265 bsuccess = bsuccess &
finish();
281 bool bsuccess =
true;
315 #ifdef Xyce_PARALLEL_MPI
397 #ifdef Xyce_PARALLEL_MPI
441 if (
wimRCPtr_->getIntegMethodPtr() == NULL)
447 #ifdef Xyce_DEBUG_ANALYSIS
449 dout() <<
" transient loop called with resume true " << std::endl;
459 double suggestedMaxTime=0.0;
465 secRCPtr_->updateMaxTimeStep( suggestedMaxTime );
491 bool bsuccess =
true;
496 #ifdef Xyce_VERBOSE_TIME
515 #ifdef Xyce_DEBUG_ANALYSIS
519 dout() <<
"Transient::loopProcess()" << std::endl;
521 dout() <<
"secRCPtr_->stepAttemptStatus = " <<
secRCPtr_->stepAttemptStatus << std::endl;
534 double suggestedMaxTime=0.0;
540 secRCPtr_->updateMaxTimeStep( suggestedMaxTime );
553 #ifdef Xyce_VERBOSE_TIME
600 if(
secRCPtr_->newtonConvergenceStatus == -3)
602 std::string msg =
"Transient::loopProcess() Nonlinear solver stalled. Calling this a pass";
603 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_WARNING_0, msg);
609 if(
secRCPtr_->newtonConvergenceStatus == -2)
611 std::string msg =
"Transient::loopProcess() Update too big. Calling this a pass";
612 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_WARNING_0, msg);
648 #ifdef Xyce_DEBUG_ANALYSIS
652 dout() <<
" Here we are, just before checking whether to pause. " << std::endl;
653 dout() <<
" minTimeStep = " <<
secRCPtr_->minTimeStep << std::endl;
655 dout() <<
" pause time = " <<
anaManagerRCPtr_->getPauseTime() << std::endl;
656 dout() <<
" initial time = " <<
secRCPtr_->initialTime << std::endl;
657 dout() <<
" current time = " <<
secRCPtr_->currentTime << std::endl;
660 dout() <<
" Pause time and current time equal " << std::endl;
664 dout() <<
" difference between current and pause times is "
669 dout() <<
" Pause time and initial time equal " << std::endl;
678 #ifdef Xyce_DEBUG_ANALYSIS
681 dout() <<
"Transient::loopProcess(): pausing simulation " << std::endl;
694 lout() <<
"Exit time exceeded. Exiting transient loop\n" << std::endl;
702 lout() <<
"Exit step. Exiting transient loop\n" << std::endl;
739 #ifdef Xyce_VERBOSE_TIME
759 if (maxTimeStepFromHabanero > 0)
761 double currentTimeStep = Xycemin(maxTimeStepFromHabanero,
secRCPtr_->currentTimeStep);
765 #ifdef Xyce_DEBUG_ANALYSIS
769 dout() <<
"Transient::loopProcess()" << std::endl;
771 dout() <<
"secRCPtr_->stepAttemptStatus = " <<
secRCPtr_->stepAttemptStatus << std::endl;
785 double suggestedMaxTime=0.0;
791 secRCPtr_->updateMaxTimeStep( suggestedMaxTime );
804 #ifdef Xyce_VERBOSE_TIME
833 bool recoverableFailureFlag =
true;
842 recoverableFailureFlag =
false;
859 if(
secRCPtr_->newtonConvergenceStatus == -3)
861 std::string msg =
"Transient::loopProcess() Nonlinear solver stalled. Calling this a pass";
862 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_WARNING_0, msg);
868 if(
secRCPtr_->newtonConvergenceStatus == -2)
870 std::string msg =
"Transient::loopProcess() Update too big. Calling this a pass";
871 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_WARNING_0, msg);
896 #ifdef Xyce_DEBUG_ANALYSIS
900 dout() <<
" Here we are, just before checking whether to pause. " << std::endl;
901 dout() <<
" minTimeStep = " <<
secRCPtr_->minTimeStep << std::endl;
903 dout() <<
" pause time = " <<
anaManagerRCPtr_->getPauseTime() << std::endl;
904 dout() <<
" initial time = " <<
secRCPtr_->initialTime << std::endl;
905 dout() <<
" current time = " <<
secRCPtr_->currentTime << std::endl;
908 dout() <<
" Pause time and current time equal " << std::endl;
912 dout() <<
" difference between current and pause times is " <<
anaManagerRCPtr_->getPauseTime() -
secRCPtr_->currentTime << std::endl;
916 dout() <<
" Pause time and initial time equal " << std::endl;
925 #ifdef Xyce_DEBUG_ANALYSIS
928 dout() <<
"Transient::loopProcess(): pausing simulation " << std::endl;
933 recoverableFailureFlag =
false;
941 lout() <<
"Exit time exceeded. Exiting transient loop\n" << std::endl;
942 recoverableFailureFlag =
false;
948 lout() <<
"Exit step. Exiting transient loop\n" << std::endl;
949 recoverableFailureFlag =
false;
952 return recoverableFailureFlag;
965 bool bsuccess =
true;
1012 dout() <<
"\n " <<
commandLine_.getArgumentValue(
"netlist")
1013 <<
" Calling dumpRestartData" << std::endl;
1018 dout() <<
" Done Calling dumpRestartData" << std::endl;
1026 secRCPtr_->previousCallStepSuccessful =
true;
1041 bool bsuccess =
true;
1057 #ifdef Xyce_DEBUG_ANALYSIS
1060 dout() <<
" Transient::processSuccessfulStep()" << std::endl
1061 <<
"Newton step succeeded:" << std::endl
1062 <<
"nextSolutionPtr: " << std::endl;
1064 anaManagerRCPtr_->getTIADataStore()->nextSolutionPtr->printPetraObject(dout());
1065 dout() << std::endl;
1089 double currentTime =
secRCPtr_->currentTime;
1090 double suggestedMaxTime=0.0;
1096 secRCPtr_->updateMaxTimeStep( suggestedMaxTime );
1100 #ifdef Xyce_VERBOSE_TIME
1103 dout() <<
"Transient Analysis: accepting time step" << std::endl;
1105 #endif // Xyce_VERBOSE_TIME
1109 #ifdef Xyce_VERBOSE_TIME
1112 dout().precision(15);
1114 dout() <<
"ERROROPTION=1: NL Its = " <<
secRCPtr_->nIterations <<
"\n" << std::endl;
1115 dout() <<
"ERROROPTION=1: New DeltaT = " <<
secRCPtr_->currentTimeStep <<
"\n" << std::endl;
1117 #endif // Xyce_VERBOSE_TIME
1124 secRCPtr_->numberSuccessiveFailures -= 1;
1125 if (
secRCPtr_->numberSuccessiveFailures < 0)
1126 secRCPtr_->numberSuccessiveFailures = 0;
1141 timeDiff1 = fabs(timeDiff1);
1142 timeDiff2 = fabs(timeDiff2);
1144 #ifdef Xyce_DEBUG_ANALYSIS
1147 dout() <<
" Checking whether to set breakpointrestartstep" << std::endl;
1148 dout() <<
" current - stop = " << timeDiff1 << std::endl;
1149 dout() <<
" current - final = " << timeDiff2 << std::endl;
1150 dout() <<
" bpTol = " << bpTol << std::endl;
1151 if (timeDiff1 <= bpTol && timeDiff2 > bpTol)
1152 dout() <<
" setting breakPointRestartStep to " <<
tranStepNumber;
1155 if (timeDiff1 <= bpTol && timeDiff2 > bpTol)
1184 N_LAS_Vector * aVecPtr =
new N_LAS_Vector( *(
anaManagerRCPtr_->getTIADataStore()->currSolutionPtr) );
1185 anaManagerRCPtr_->getTIADataStore()->fastTimeSolutionVec.push_back( aVecPtr );
1186 aVecPtr =
new N_LAS_Vector( *(
anaManagerRCPtr_->getTIADataStore()->currStatePtr) );
1187 anaManagerRCPtr_->getTIADataStore()->fastTimeStateVec.push_back( aVecPtr );
1188 aVecPtr =
new N_LAS_Vector( *(
anaManagerRCPtr_->getTIADataStore()->daeQVectorPtr) );
1190 aVecPtr =
new N_LAS_Vector( *(
anaManagerRCPtr_->getTIADataStore()->currStorePtr) );
1191 anaManagerRCPtr_->getTIADataStore()->fastTimeStoreVec.push_back( aVecPtr );
1197 #ifdef Xyce_DEBUG_ANALYSIS
1198 #ifdef Xyce_DEBUG_TIME
1210 secRCPtr_->previousCallStepSuccessful =
true;
1232 bool bsuccess =
true;
1248 double estOverTol =
secRCPtr_->getEstOverTol();
1259 #ifdef Xyce_VERBOSE_TIME
1262 dout() <<
"Transient Analysis: rejecting time step" << std::endl;
1263 #endif // Xyce_VERBOSE_TIME
1267 #ifdef Xyce_VERBOSE_TIME
1270 dout().precision(15);
1272 dout() <<
"ERROROPTION=1: NL Its = " <<
secRCPtr_->nIterations <<
"\n" << std::endl;
1273 dout() <<
"ERROROPTION=1: New DeltaT = " <<
secRCPtr_->currentTimeStep <<
"\n" << std::endl;
1275 #endif // Xyce_VERBOSE_TIME
1277 #ifdef Xyce_DEBUG_ANALYSIS
1280 dout() <<
" Transient::processFailedStep" << std::endl
1281 <<
"Newton step failed:" << std::endl
1282 <<
"nextSolutionPtr: " << std::endl;
1283 anaManagerRCPtr_->getTIADataStore()->nextSolutionPtr->printPetraObject(dout());
1284 dout() << std::endl;
1288 secRCPtr_->numberSuccessiveFailures += 1;
1292 #ifdef Xyce_DEBUG_ANALYSIS
1295 dout() <<
"currTimeStep: " <<
secRCPtr_->currentTimeStep << std::endl;
1296 dout() <<
"minTimeStep: " <<
secRCPtr_->minTimeStep << std::endl;
1305 lout() <<
"Attempting to retake and accept step where estimated error over tolerance was: " <<
minEstErrorOverTol
1314 lout() <<
"Time step too small near step number: " <<
stepNumber <<
" Exiting transient loop.\n" << std::endl;
1323 lout() <<
"Newton solver failed in constant time step mode. Exiting transient loop.\n" << std::endl;
1332 lout() <<
"Exit Step. Exiting transient loop\n" << std::endl;
1335 #ifdef Xyce_VERBOSE_TIME
1357 bool bsuccess =
true;
1363 (
secRCPtr_->numberSuccessiveFailures)++;
1365 lout() <<
"DC Operating Point Failed. Exiting transient loop" << std::endl;
1380 bool bsuccess =
true;
1385 dsPtr_->timeSteps.push_back(
secRCPtr_->currentTime);
1387 N_LAS_Vector * aVecPtr =
new N_LAS_Vector( *(dsPtr_->currSolutionPtr) );
1388 dsPtr_->fastTimeSolutionVec.push_back( aVecPtr );
1389 aVecPtr =
new N_LAS_Vector( *(dsPtr_->currStatePtr) );
1390 dsPtr_->fastTimeStateVec.push_back( aVecPtr );
1391 aVecPtr =
new N_LAS_Vector( *(dsPtr_->daeQVectorPtr) );
1392 dsPtr_->fastTimeQVec.push_back( aVecPtr );
1393 aVecPtr =
new N_LAS_Vector( *(dsPtr_->currStorePtr) );
1394 dsPtr_->fastTimeStoreVec.push_back( aVecPtr );
1399 #ifdef Xyce_DEBUG_ANALYSIS
1400 dout() <<
"Calling finishOutput" << std::endl;
1430 #ifdef Xyce_DEBUG_ANALYSIS
1431 #ifdef Xyce_DEBUG_TIME
1434 dout() <<
" Transient::handlePredictor" << std::endl;
1435 anaManagerRCPtr_->getTIADataStore()->outputPredictedSolution(Xyce::dout());
1436 anaManagerRCPtr_->getTIADataStore()->outputPredictedDerivative(Xyce::dout());
1529 bool bsuccess =
true;
1531 lout() <<
"***** Problem read in and set up time: " <<
anaManagerRCPtr_->solverStartTime_ <<
" seconds" << std::endl;
1544 lout() <<
" ***** DCOP time: " << time <<
" seconds. Breakdown follows:" << std::endl;
1552 lout() <<
" ***** Transient Stepping time: " <<
endTRANtime-
anaManagerRCPtr_->startTRANtime <<
" seconds. Breakdown follows:" << std::endl;
1572 #ifndef Xyce_PARALLEL_MPI
1575 int nodeNameSize = nodeNames.size();
1576 nameVec_.resize(nodeNameSize+1,
"gnd");
1577 Xyce::NodeNamePairMap::iterator mapI, mapEnd;
1578 mapEnd = nodeNames.end();
1579 mapI = nodeNames.begin();
1580 for ( ; mapI != mapEnd ; ++mapI)
1582 nameVec_[(*mapI).second.first] = (*mapI).first;
1589 lout() <<
" *** Transient failure history: " << std::endl;
1593 lout() <<
"Time Time Step Non-Linear Solver node node" << std::endl;
1594 lout() <<
"(sec) Step Status Status Iters ||F|| index name" << std::endl;
1598 lout() <<
"Time Time Step EstErr Non-Linear Solver node node" << std::endl;
1599 lout() <<
"(sec) Step Status OverTol Status Iters ||F|| index name" << std::endl;
1605 lout() << std::scientific << std::setprecision(fieldWidth-7) << std::setfill(
' ') << std::right << std::setw( fieldWidth )
1624 lout() << std::setw(7) << std::right;
1627 lout() <<
"P:s nrm";
1635 lout() <<
"P:near ";
1639 lout() <<
"P:s up ";
1641 else if( nlStatus == nlReturnCodes.
nanFail )
1647 lout() <<
"F:max s";
1651 lout() <<
"F:max s";
1655 lout() <<
"F:big u";
1657 else if( nlStatus == nlReturnCodes.
stalled )
1659 lout() <<
"F:stall";
1663 lout() <<
"F:n zro";
1667 lout() <<
"F:in Fl";
1671 lout() <<
"code=" <<
1675 lout() << std::right << std::setw( 4 )
1680 lout() << std::right << std::fixed << std::setw( 7 ) << outIndex;
1682 std::string outIndexName(
"");
1686 if (nsize > outIndex && outIndex >=0)
1693 outIndexName =
"N/A";
1695 lout() << std::left <<
" " << outIndexName;
1696 lout() << std::endl;
1715 #ifdef Xyce_DEBUG_ANALYSIS
1716 dout() <<
"Transient::takeAnIntegrationStep_: newtonConvergenceStatus = " <<
secRCPtr_->newtonConvergenceStatus << std::endl;
1795 lout() <<
"Time step too small near step number: " <<
stepNumber <<
" Exiting transient loop.\n" << std::endl;
1816 os <<
"***** " << (DEBUG_ANALYSIS ?
commandLine_.getArgumentValue(
"netlist") :
"") <<
" ";
1820 os <<
"Start of DCOP STEP # ";
1828 os <<
"Start of Time Step (INITIAL STEP) # ";
1832 os <<
"Start of Time Step (DISCONTINUITY STEP) # ";
1839 os <<
"Start of Time Step (AFTER FAILED STEP) # ";
1843 os <<
"Start of Time Step (AFTER SUCCESS STEP) # ";
1868 double percentComplete;
1870 double aveCPUTimePerStep;
1872 double aveSimTimePerStep;
1874 double estCompletionTime = 0.0;
1882 Report::signalProgress(
"Xyce in DC Operating Point Calculation");
1884 os <<
"***** Beginning DC Operating Point Calculation...\n" << std::endl;
1893 Report::signalProgress(
"Xyce in Transient Calculation");
1895 os <<
"***** Beginning Transient Calculation...\n" << std::endl;
1909 percentComplete = 100.0 * diff1/diff2;
1920 if (aveSimTimePerStep > N_UTL_MachineDependentParams::MachineEpsilon())
1921 estCompletionTime = aveCPUTimePerStep *
1927 os <<
"***** Percent complete: " << percentComplete <<
" %" << std::endl;
1930 if (estCompletionTime > N_UTL_MachineDependentParams::MachineEpsilon())
1932 unsigned int days, hours, minutes, seconds;
1933 days =
static_cast<int> (estCompletionTime / 86400);
1934 hours =
static_cast<int> ((estCompletionTime - days * 86400) / 3600);
1935 minutes =
static_cast<int> ((estCompletionTime - days * 86400 - hours * 3600) / 60);
1936 seconds =
static_cast<int> (estCompletionTime - days * 86400 - hours * 3600 - minutes * 60);
1939 for (
char *c = timeStr; c != timeStr +
sizeof(timeStr); ++c)
1942 #ifdef Xyce_PARALLEL_MPI
1944 time_t t = time( NULL );
1945 struct tm * now = localtime( &t );
1948 if ( ( t != (time_t)-1 ) && ( strftime( timeStr, 255,
"%c", now ) != 0 ) )
1950 os <<
"***** Current system time: " << timeStr << std::endl;
1955 os <<
"***** Current system time could not be determined." << std::endl;
1960 sprintf(timeStr,
"%3d days, %2d hrs., %2d min., %2d sec.", days, hours, minutes, seconds);
1962 sprintf(timeStr,
"%2d hrs., %2d min., %2d sec.", hours, minutes, seconds);
1963 else if (minutes > 0)
1964 sprintf(timeStr,
"%2d min., %2d sec.", minutes, seconds);
1966 sprintf(timeStr,
"%2d sec.", seconds);
1970 std::ostringstream ost;
1971 ost <<
"Xyce transient ";
1972 if (percentComplete < 10)
1976 ost << percentComplete
1977 <<
"%% complete ... Estimated time to completion: "
1978 << timeStr << std::endl;
1979 Report::signalProgress(ost.str());
1983 os <<
"***** Estimated time to completion: " << timeStr << std::endl << std::endl;
2005 bool printIC =
true;
2046 #ifdef Xyce_DEBUG_ANALYSIS
2047 dout() <<
"Calling conventional TRANOP outputs!" << std::endl;
2089 bool doNotInterpolate=
2092 #ifdef Xyce_DEBUG_ANALYSIS
2095 if (doNotInterpolate)
2097 dout() <<
"doNotInterpolate is TRUE!" << std::endl;
2101 dout() <<
"doNotInterpolate is FALSE!" << std::endl;
2110 #ifdef Xyce_DEBUG_ANALYSIS
2113 dout() <<
"Calling MPDE outputs!" << std::endl;
2124 std::vector<double> fastTimes =
anaManagerRCPtr_->mpdeMgrPtr_->getFastTimePoints();
2132 std::vector<double> fastTimes =
anaManagerRCPtr_->mpdeMgrPtr_->getFastTimePoints();
2137 fastTimes, phiGID );
2203 #ifdef Xyce_DEBUG_ANALYSIS
2206 dout().width(21); dout().precision(13); dout().setf(std::ios::scientific);
2207 dout() <<
"Transient::testOutputTime. secPtr_->currentTime = " <<
secRCPtr_->currentTime << std::endl;
2208 dout() <<
"Transient::testOutputTime. tStart = " <<
tiaParams.
tStart << std::endl;
2209 dout() <<
"Transient::testOutputTime. nextOutputTime_ = " <<
anaManagerRCPtr_->nextOutputTime_ << std::endl;
2212 dout() <<
"outputIntervals_["<<i<<
"].first = " <<
anaManagerRCPtr_->outputIntervals_[i].first;
2213 dout() << std::endl;
2215 dout() << std::endl;
2263 else if (currTime < anaManagerRCPtr_->outputIntervals_[0].first)
2274 std::pair<double, double> currInterval, nextInterval;
2276 for (
int i = 0; i < size; ++i)
2283 int step =
static_cast<int> ((currTime-currInterval.first) /
2284 currInterval.second);
2285 anaManagerRCPtr_->nextOutputTime_ = currInterval.first + (step+1)*currInterval.second;
2286 if (nextInterval.first && (nextInterval.first!=currInterval.first)
2317 while (t < currTime)
2323 if( (t - currTime) <= 100 * N_UTL_MachineDependentParams::MachinePrecision() )
2328 if( (t -
tiaParams.
finalTime) > 100 * N_UTL_MachineDependentParams::MachinePrecision() )
2346 while (t <= currTime)
2350 if (outInt != lastInt && t >=
anaManagerRCPtr_->outputIntervals_[outInt+1].first)