39 #include <Xyce_config.h>
48 #include <N_ERH_Progress.h>
49 #include <N_IO_CmdParse.h>
50 #include <N_IO_OutputMgr.h>
51 #include <N_IO_RestartMgr.h>
52 #include <N_LAS_System.h>
53 #include <N_LOA_Loader.h>
54 #include <N_MPDE_Manager.h>
59 #include <N_UTL_ExpressionData.h>
60 #include <N_UTL_NoCase.h>
61 #include <N_UTL_Timer.h>
77 Util::ListenerAutoSubscribe<
StepEvent>(&analysis_manager),
78 comm_(analysis_manager.getPDSComm().comm()),
80 firstTranOutput_(true),
86 historyTrackingOn_(true),
87 maxTimeStepExpressionGiven_(false),
88 maxTimeStepExpressionAsString_(
""),
90 oldPercentComplete(0.0),
137 for (Util::ParameterList::const_iterator it = paramsBlock.getParams().begin(), end = paramsBlock.getParams().end(); it != end; ++it)
139 if ((*it).uTag() ==
"TSTART")
144 else if ((*it).uTag() ==
"TSTOP")
148 else if ((*it).uTag() ==
"TSTEP")
152 else if ((*it).uTag() ==
"NOOP" ||
153 (*it).uTag() ==
"UIC")
157 else if ((*it).uTag() ==
"DTMAX")
161 #ifdef Xyce_DEBUG_ANALYSIS
168 else if ((*it).uTag() ==
"MAXTIMEEXPRESSION")
186 <<
" is earlier or same as start time of " <<
tiaParams_.
tStart << std::endl
187 <<
" Check netlist for invalid .TRAN specification";
198 #ifdef Xyce_DEBUG_ANALYSIS
202 << section_divider << std::endl
203 <<
" Transient simulation parameters" << std::endl
211 dout() <<
" NOOP/UIC is NOT set" << std::endl;
215 dout() <<
" NOOP/UIC is set" << std::endl;
218 dout() << section_divider << std::endl;
268 bool bsuccess =
true;
274 bsuccess = bsuccess &
init();
281 bsuccess = bsuccess &
finish();
297 bool bsuccess =
true;
335 #ifdef Xyce_PARALLEL_MPI
418 #ifdef Xyce_PARALLEL_MPI
477 #ifdef Xyce_DEBUG_ANALYSIS
479 dout() <<
" transient loop called with resume true " << std::endl;
489 double suggestedMaxTime=0.0;
523 bool bsuccess =
true;
530 #ifdef Xyce_VERBOSE_TIME
549 #ifdef Xyce_DEBUG_ANALYSIS
553 dout() <<
"Transient::loopProcess()" << std::endl;
568 double suggestedMaxTime=0.0;
587 #ifdef Xyce_VERBOSE_TIME
637 UserWarning(*
this) <<
"Nonlinear solver stalled. Calling this a pass";
648 UserWarning(*
this) <<
"Update too big. Calling this a pass";
685 #ifdef Xyce_DEBUG_ANALYSIS
689 dout() <<
" Here we are, just before checking whether to pause. " << std::endl;
697 dout() <<
" Pause time and current time equal " << std::endl;
701 dout() <<
" difference between current and pause times is "
706 dout() <<
" Pause time and initial time equal " << std::endl;
715 #ifdef Xyce_DEBUG_ANALYSIS
718 dout() <<
"Transient::loopProcess(): pausing simulation " << std::endl;
731 lout() <<
"Exit time exceeded. Exiting transient loop\n" << std::endl;
739 lout() <<
"Exit step. Exiting transient loop\n" << std::endl;
778 #ifdef Xyce_VERBOSE_TIME
798 if (maxTimeStepFromHabanero > 0)
804 #ifdef Xyce_DEBUG_ANALYSIS
808 dout() <<
"Transient::loopProcess()" << std::endl;
824 double suggestedMaxTime=0.0;
843 #ifdef Xyce_VERBOSE_TIME
872 bool recoverableFailureFlag =
true;
881 recoverableFailureFlag =
false;
900 Report::UserWarning0() <<
"Nonlinear solver stalled, calling this a pass";
908 Report::UserWarning0() <<
"Update too big, calling this a pass";
932 #ifdef Xyce_DEBUG_ANALYSIS
936 dout() <<
" Here we are, just before checking whether to pause. " << std::endl;
944 dout() <<
" Pause time and current time equal " << std::endl;
952 dout() <<
" Pause time and initial time equal " << std::endl;
961 #ifdef Xyce_DEBUG_ANALYSIS
964 dout() <<
"Transient::loopProcess(): pausing simulation " << std::endl;
969 recoverableFailureFlag =
false;
977 lout() <<
"Exit time exceeded. Exiting transient loop\n" << std::endl;
978 recoverableFailureFlag =
false;
984 lout() <<
"Exit step. Exiting transient loop\n" << std::endl;
985 recoverableFailureFlag =
false;
988 return recoverableFailureFlag;
1001 bool bsuccess =
true;
1055 <<
" Calling dumpRestartData" << std::endl;
1060 dout() <<
" Done Calling dumpRestartData" << std::endl;
1106 #ifdef Xyce_DEBUG_ANALYSIS
1109 dout() <<
" Transient::processSuccessfulStep()" << std::endl
1110 <<
"Newton step succeeded:" << std::endl
1111 <<
"nextSolutionPtr: " << std::endl;
1114 dout() << std::endl;
1139 double suggestedMaxTime=0.0;
1149 #ifdef Xyce_VERBOSE_TIME
1152 dout() <<
"Transient Analysis: accepting time step" << std::endl;
1154 #endif // Xyce_VERBOSE_TIME
1158 #ifdef Xyce_VERBOSE_TIME
1161 dout().precision(15);
1166 #endif // Xyce_VERBOSE_TIME
1190 timeDiff1 = fabs(timeDiff1);
1191 timeDiff2 = fabs(timeDiff2);
1193 #ifdef Xyce_DEBUG_ANALYSIS
1196 dout() <<
" Checking whether to set breakpointrestartstep" << std::endl;
1197 dout() <<
" current - stop = " << timeDiff1 << std::endl;
1198 dout() <<
" current - final = " << timeDiff2 << std::endl;
1199 dout() <<
" bpTol = " << bpTol << std::endl;
1200 if (timeDiff1 <= bpTol && timeDiff2 > bpTol)
1201 dout() <<
" setting breakPointRestartStep to " <<
tranStepNumber;
1204 if (timeDiff1 <= bpTol && timeDiff2 > bpTol)
1246 #ifdef Xyce_DEBUG_ANALYSIS
1247 #ifdef Xyce_DEBUG_TIME
1281 bool bsuccess =
true;
1310 #ifdef Xyce_VERBOSE_TIME
1313 dout() <<
"Transient Analysis: rejecting time step" << std::endl;
1314 #endif // Xyce_VERBOSE_TIME
1318 #ifdef Xyce_VERBOSE_TIME
1321 dout().precision(15);
1326 #endif // Xyce_VERBOSE_TIME
1328 #ifdef Xyce_DEBUG_ANALYSIS
1331 dout() <<
" Transient::processFailedStep" << std::endl
1332 <<
"Newton step failed:" << std::endl
1333 <<
"nextSolutionPtr: " << std::endl;
1335 dout() << std::endl;
1343 #ifdef Xyce_DEBUG_ANALYSIS
1356 lout() <<
"Attempting to retake and accept step where estimated error over tolerance was: " <<
minEstErrorOverTol
1365 lout() <<
"Time step too small near step number: " <<
stepNumber <<
" Exiting transient loop.\n" << std::endl;
1374 lout() <<
"Newton solver failed in constant time step mode. Exiting transient loop.\n" << std::endl;
1383 lout() <<
"Exit Step. Exiting transient loop\n" << std::endl;
1386 #ifdef Xyce_VERBOSE_TIME
1408 bool bsuccess =
true;
1416 lout() <<
"DC Operating Point Failed. Exiting transient loop" << std::endl;
1431 bool bsuccess =
true;
1438 N_LAS_Vector * aVecPtr =
new N_LAS_Vector( *(dsPtr_->
currSolutionPtr) );
1450 #ifdef Xyce_DEBUG_ANALYSIS
1451 dout() <<
"Calling finishOutput" << std::endl;
1481 #ifdef Xyce_DEBUG_ANALYSIS
1482 #ifdef Xyce_DEBUG_TIME
1485 dout() <<
" Transient::handlePredictor" << std::endl;
1544 bool bsuccess =
true;
1559 lout() <<
" ***** DCOP time: " << time <<
" seconds. Breakdown follows:" << std::endl;
1587 #ifndef Xyce_PARALLEL_MPI
1590 int nodeNameSize = nodeNames.size();
1591 nameVec_.resize(nodeNameSize+1,
"gnd");
1592 Xyce::NodeNamePairMap::const_iterator mapI, mapEnd;
1593 mapEnd = nodeNames.end();
1594 mapI = nodeNames.begin();
1595 for ( ; mapI != mapEnd ; ++mapI)
1597 nameVec_[(*mapI).second.first] = (*mapI).first;
1604 lout() <<
" *** Transient failure history: " << std::endl;
1608 lout() <<
"Time Time Step Non-Linear Solver node node" << std::endl;
1609 lout() <<
"(sec) Step Status Status Iters ||F|| index name" << std::endl;
1613 lout() <<
"Time Time Step EstErr Non-Linear Solver node node" << std::endl;
1614 lout() <<
"(sec) Step Status OverTol Status Iters ||F|| index name" << std::endl;
1620 lout() << std::scientific << std::setprecision(fieldWidth-7) << std::setfill(
' ') << std::right << std::setw( fieldWidth )
1639 lout() << std::setw(7) << std::right;
1642 lout() <<
"P:s nrm";
1650 lout() <<
"P:near ";
1654 lout() <<
"P:s up ";
1656 else if( nlStatus == nlReturnCodes.
nanFail )
1662 lout() <<
"F:max s";
1666 lout() <<
"F:max s";
1670 lout() <<
"F:big u";
1672 else if( nlStatus == nlReturnCodes.
stalled )
1674 lout() <<
"F:stall";
1678 lout() <<
"F:n zro";
1682 lout() <<
"F:in Fl";
1686 lout() <<
"code=" <<
1690 lout() << std::right << std::setw( 4 )
1695 lout() << std::right << std::fixed << std::setw( 7 ) << outIndex;
1697 std::string outIndexName(
"");
1701 if (nsize > outIndex && outIndex >=0)
1708 outIndexName =
"N/A";
1710 lout() << std::left <<
" " << outIndexName;
1711 lout() << std::endl;
1730 #ifdef Xyce_DEBUG_ANALYSIS
1807 lout() <<
"Time step too small near step number: " <<
stepNumber <<
" Exiting transient loop.\n" << std::endl;
1832 os <<
"Start of DCOP STEP # ";
1840 os <<
"Start of Time Step (INITIAL STEP) # ";
1844 os <<
"Start of Time Step (DISCONTINUITY STEP) # ";
1851 os <<
"Start of Time Step (AFTER FAILED STEP) # ";
1855 os <<
"Start of Time Step (AFTER SUCCESS STEP) # ";
1880 double percentComplete;
1882 double aveCPUTimePerStep;
1884 double aveSimTimePerStep;
1886 double estCompletionTime = 0.0;
1894 Report::signalProgress(
"Xyce in DC Operating Point Calculation");
1896 os <<
"***** Beginning DC Operating Point Calculation...\n" << std::endl;
1905 Report::signalProgress(
"Xyce in Transient Calculation");
1907 os <<
"***** Beginning Transient Calculation...\n" << std::endl;
1921 percentComplete = 100.0 * diff1/diff2;
1932 if (aveSimTimePerStep > Util::MachineDependentParams::MachineEpsilon())
1933 estCompletionTime = aveCPUTimePerStep *
1939 os <<
"***** Percent complete: " << percentComplete <<
" %" << std::endl;
1942 if (estCompletionTime > Util::MachineDependentParams::MachineEpsilon())
1944 unsigned int days, hours, minutes, seconds;
1945 days =
static_cast<int> (estCompletionTime / 86400);
1946 hours =
static_cast<int> ((estCompletionTime - days * 86400) / 3600);
1947 minutes =
static_cast<int> ((estCompletionTime - days * 86400 - hours * 3600) / 60);
1948 seconds =
static_cast<int> (estCompletionTime - days * 86400 - hours * 3600 - minutes * 60);
1951 for (
char *c = timeStr; c != timeStr +
sizeof(timeStr); ++c)
1954 #ifdef Xyce_PARALLEL_MPI
1956 time_t t = time( NULL );
1957 struct tm * now = localtime( &t );
1960 if ( ( t != (time_t)-1 ) && ( strftime( timeStr, 255,
"%c", now ) != 0 ) )
1962 os <<
"***** Current system time: " << timeStr << std::endl;
1967 os <<
"***** Current system time could not be determined." << std::endl;
1972 sprintf(timeStr,
"%3d days, %2d hrs., %2d min., %2d sec.", days, hours, minutes, seconds);
1974 sprintf(timeStr,
"%2d hrs., %2d min., %2d sec.", hours, minutes, seconds);
1975 else if (minutes > 0)
1976 sprintf(timeStr,
"%2d min., %2d sec.", minutes, seconds);
1978 sprintf(timeStr,
"%2d sec.", seconds);
1982 std::ostringstream ost;
1983 ost <<
"Xyce transient ";
1984 if (percentComplete < 10)
1988 ost << percentComplete
1989 <<
"%% complete ... Estimated time to completion: "
1990 << timeStr << std::endl;
1991 Report::signalProgress(ost.str());
1995 os <<
"***** Estimated time to completion: " << timeStr << std::endl << std::endl;
2017 bool printIC =
true;
2054 #ifdef Xyce_DEBUG_ANALYSIS
2055 dout() <<
"Calling conventional TRANOP outputs!" << std::endl;
2096 bool doNotInterpolate=
2099 #ifdef Xyce_DEBUG_ANALYSIS
2102 if (doNotInterpolate)
2104 dout() <<
"doNotInterpolate is TRUE!" << std::endl;
2108 dout() <<
"doNotInterpolate is FALSE!" << std::endl;
2117 #ifdef Xyce_DEBUG_ANALYSIS
2120 dout() <<
"Calling MPDE outputs!" << std::endl;
2144 fastTimes, phiGID );
2210 #ifdef Xyce_DEBUG_ANALYSIS
2213 dout().width(21); dout().precision(13); dout().setf(std::ios::scientific);
2215 dout() <<
"Transient::testOutputTime. tStart = " <<
tiaParams_.
tStart << std::endl;
2220 dout() << std::endl;
2222 dout() << std::endl;
2281 std::pair<double, double> currInterval, nextInterval;
2283 for (
int i = 0; i < size; ++i)
2290 int step =
static_cast<int> ((currTime-currInterval.first) /
2291 currInterval.second);
2293 if (nextInterval.first && (nextInterval.first!=currInterval.first)
2324 while (t < currTime)
2330 if( (t - currTime) <= 100 * Util::MachineDependentParams::MachinePrecision() )
2353 while (t <= currTime)