39 #include <Xyce_config.h>
49 #include <N_ERH_Progress.h>
50 #include <N_IO_CmdParse.h>
51 #include <N_IO_CircuitBlock.h>
52 #include <N_IO_OptionBlock.h>
53 #include <N_IO_OutputMgr.h>
54 #include <N_IO_PkgOptionsMgr.h>
55 #include <N_IO_RestartMgr.h>
56 #include <N_LAS_System.h>
59 #include <N_MPDE_Manager.h>
62 #include <N_PDS_Comm.h>
63 #include <N_PDS_MPI.h>
64 #include <N_PDS_Serial.h>
70 #include <N_TOP_Topology.h>
71 #include <N_UTL_Diagnostic.h>
72 #include <N_UTL_ExpressionData.h>
73 #include <N_UTL_ExtendedString.h>
74 #include <N_UTL_Factory.h>
75 #include <N_UTL_FeatureTest.h>
76 #include <N_UTL_MachDepParams.h>
77 #include <N_UTL_NoCase.h>
78 #include <N_UTL_Param.h>
79 #include <N_UTL_Timer.h>
84 void writeConductanceFile(
const std::vector<std::string> &device_names, Nonlinear::ConductanceExtractor &conductance_extractor,
const std::string &filename);
96 Linear::System & linear_system,
99 Topo::Topology & topology,
100 IO::InitialConditionsManager & initial_conditions_manager,
101 IO::RestartMgr & restart_manager,
104 N_MPDE_Manager * mpde_manager)
107 comm_(analysis_manager.getPDSManager()->getPDSComm()->comm()),
115 outputManagerAdapter_(analysis_manager.getOutputManagerAdapter()),
116 outputAdapter_(output_adapter),
118 sensFlag_(analysis_manager.getSensFlag()),
119 initialIntegrationMethod_(TimeIntg::OneStep::type),
120 firstTranOutput_(true),
127 maxTimeStepExpressionString_(),
128 maxTimeStepExpression_(0),
130 oldPercentComplete(0.0),
132 nextRestartSaveTime_(0.0),
137 integrationMethod(7),
138 historyTrackingDepth(25),
140 saveTimeStepsFlag(false),
142 condTestDeviceNames(),
143 hbAnalysis_(hb_analysis),
144 mpdeManager_(mpde_manager)
182 const Util::OptionBlock & option_block)
184 for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
186 const Util::Param ¶m = *it;
190 else if (param.uTag() ==
"NOOP" ||
191 param.uTag() ==
"UIC")
195 else if (param.uTag() ==
"MAXTIMEEXPRESSION")
208 IO::ParamError(option_block, param) <<
"Unrecognized analysis option";
215 <<
" Check netlist for invalid .TRAN specification";
226 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
229 << section_divider << std::endl
230 <<
" Transient simulation parameters" << std::endl
238 dout() <<
" NOOP/UIC is NOT set" << std::endl;
242 dout() <<
" NOOP/UIC is set" << std::endl;
245 dout() << section_divider << std::endl;
288 const Util::OptionBlock & option_block)
290 for (Util::ParamList::const_iterator it = option_block.begin(), end = option_block.end(); it != end; ++it)
292 const Util::Param ¶m = (*it);
294 if (param.uTag() ==
"METHOD")
296 if (param.isInteger())
300 ExtendedString stringVal ( param.stringValue() );
303 if (stringVal ==
"TRAP" || stringVal ==
"TRAPEZOIDAL")
305 else if (stringVal ==
"BDF")
307 else if (stringVal ==
"GEAR")
311 IO::ParamError(option_block, param) <<
"Unsupported transient method type";
316 else if (param.uTag()==
"EXITTIME" )
317 exitTime = param.getImmutableValue<
double>();
318 else if (param.uTag()==
"EXITSTEP" )
319 exitStep = param.getImmutableValue<
int>();
320 else if (param.uTag() ==
"HISTORYTRACKINGDEPTH" )
322 else if (param.uTag() ==
"PASSNLSTALL")
324 else if (param.uTag() ==
"CONDTEST")
325 condTestFlag = static_cast<bool> (param.getImmutableValue<
int>());
326 else if (param.uTag() ==
"CONDTESTDEVICENAME")
328 else if (param.uTag() ==
"DAESTATEDERIV" )
330 else if (param.uTag() ==
"DEBUGLEVEL" )
339 IO::ParamError(option_block, param) <<
"Not a recognized time integration option";
357 bool bsuccess =
false;
386 bool bsuccess =
true;
390 Stats::StatTop _sensitivityStat(
"Sensitivity");
422 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
423 dout() <<
" transient init called with resume true " << std::endl;
447 bool bsuccess =
true;
451 Stats::StatTop _sensitivityStat(
"Sensitivity");
584 double suggestedMaxTime = 0.0;
625 bool bsuccess =
true;
627 Stats::Stat _transientStat(Stats::StatTop::getTop());
628 Stats::TimeBlock _transientTimer(_transientStat);
658 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
661 dout() <<
"Transient::loopProcess()" << std::endl;
675 double suggestedMaxTime=0.0;
735 bool bsuccess =
true;
737 Stats::Stat _transientStat(Stats::StatTop::getTop());
738 Stats::TimeBlock _transientTimer(_transientStat);
769 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
772 dout() <<
"Transient::loopProcess()" << std::endl;
786 double suggestedMaxTime=0.0;
837 UserWarning(*
this) <<
"Nonlinear solver stalled. Calling this a pass";
848 UserWarning(*
this) <<
"Update too big. Calling this a pass";
883 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
886 dout() <<
" Here we are, just before checking whether to pause. " << std::endl;
894 dout() <<
" Pause time and current time equal " << std::endl;
898 dout() <<
" difference between current and pause times is "
903 dout() <<
" Pause time and initial time equal " << std::endl;
911 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
913 dout() <<
"Transient::loopProcess(): pausing simulation " << std::endl;
925 lout() <<
"Exit time exceeded. Exiting transient loop\n" << std::endl;
932 lout() <<
"Exit step. Exiting transient loop\n" << std::endl;
974 double maxTimeStepFromHabanero)
1001 if (maxTimeStepFromHabanero > 0)
1007 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
1009 dout() << std::endl;
1010 dout() <<
"Transient::loopProcess()" << std::endl;
1024 double suggestedMaxTime=0.0;
1068 bool recoverableFailureFlag =
true;
1077 recoverableFailureFlag =
false;
1096 Report::UserWarning0() <<
"Nonlinear solver stalled, calling this a pass";
1104 Report::UserWarning0() <<
"Update too big, calling this a pass";
1128 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
1130 dout() << std::endl;
1131 dout() <<
" Here we are, just before checking whether to pause. " << std::endl;
1139 dout() <<
" Pause time and current time equal " << std::endl;
1147 dout() <<
" Pause time and initial time equal " << std::endl;
1155 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
1157 dout() <<
"Transient::loopProcess(): pausing simulation " << std::endl;
1162 recoverableFailureFlag =
false;
1169 lout() <<
"Exit time exceeded. Exiting transient loop\n" << std::endl;
1170 recoverableFailureFlag =
false;
1175 lout() <<
"Exit step. Exiting transient loop\n" << std::endl;
1176 recoverableFailureFlag =
false;
1179 return recoverableFailureFlag;
1192 Stats::StatTop _processSuccessfulDCOPStat(
"Successful DCOP Steps");
1193 Stats::TimeBlock _processSuccessfulDCOPTimer(_processSuccessfulDCOPStat);
1195 bool bsuccess =
true;
1249 <<
" Calling dumpRestart" << std::endl;
1256 analysisManager_.getStepErrorControl().currentTime);
1259 dout() <<
" Done Calling dumpRestart" << std::endl;
1283 Stats::StatTop _processSuccessfulStepStat(
"Successful Step");
1284 Stats::TimeBlock _processSuccessfulStepTimer(_processSuccessfulStepStat);
1309 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
1311 dout() <<
" Transient::processSuccessfulStep()" << std::endl
1312 <<
"Newton step succeeded:" << std::endl
1313 <<
"nextSolutionPtr: " << std::endl;
1316 dout() << std::endl;
1341 double suggestedMaxTime = 0.0;
1351 if (VERBOSE_TIME && isActive(Diag::TIME_PARAMETERS))
1352 dout() <<
"Transient Analysis: accepting time step" << std::endl;
1358 dout().precision(15);
1386 timeDiff1 = fabs(timeDiff1);
1387 timeDiff2 = fabs(timeDiff2);
1389 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
1391 dout() <<
" Checking whether to set breakpointrestartstep" << std::endl;
1392 dout() <<
" current - stop = " << timeDiff1 << std::endl;
1393 dout() <<
" current - final = " << timeDiff2 << std::endl;
1394 dout() <<
" bpTol = " << bpTol << std::endl;
1395 if (timeDiff1 <= bpTol && timeDiff2 > bpTol)
1396 dout() <<
" setting breakPointRestartStep to " <<
tranStepNumber;
1399 if (timeDiff1 <= bpTol && timeDiff2 > bpTol)
1441 if (DEBUG_ANALYSIS & DEBUG_TIME && isActive(Diag::TIME_DUMP_SOLUTION_ARRAYS))
1447 Stats::StatTop _outputStat(
"Output");
1448 Stats::TimeBlock _outputTimer(_outputStat);
1461 analysisManager_.getStepErrorControl().currentTime);
1463 analysisManager_.getStepErrorControl().previousCallStepSuccessful =
true;
1485 Stats::StatTop _processFailedStat(
"Failed Steps");
1486 Stats::TimeBlock _processFailedTimer(_processFailedStat);
1490 Stats::StatTop _nonlinearConvergenceFailureStat(
"Nonlinear Failure");
1491 Stats::TimeBlock _nonlinearConvergenceFailureTimer(_nonlinearConvergenceFailureStat);
1494 bool bsuccess =
true;
1527 dout() <<
"Transient Analysis: rejecting time step" << std::endl;
1534 dout().precision(15);
1535 dout() <<
"ERROROPTION=1: TimeStepLimitedbyBP = "
1537 dout() <<
"ERROROPTION=1: NL Its = "
1539 dout() <<
"ERROROPTION=1: New DeltaT = "
1543 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
1545 dout() <<
" Transient::processFailedStep" << std::endl
1546 <<
"Newton step failed:" << std::endl
1547 <<
"nextSolutionPtr: " << std::endl;
1549 dout() << std::endl;
1558 if (DEBUG_ANALYSIS && isActive(Diag::TIME_PARAMETERS))
1569 lout() <<
"Attempting to retake and accept step where estimated error over tolerance was: "
1579 lout() <<
"Time step too small near step number: " <<
stepNumber
1580 <<
" Exiting transient loop.\n" << std::endl;
1589 lout() <<
"Newton solver failed in constant time step mode. Exiting transient loop.\n" << std::endl;
1597 lout() <<
"Exit Step. Exiting transient loop\n" << std::endl;
1602 if (VERBOSE_TIME && bsuccess)
1608 if (VERBOSE_TIME && !bsuccess)
1628 Stats::StatTop _processFailedDCOPStat(
"Failed DCOP Steps");
1629 Stats::TimeBlock _processFailedDCOPTimer(_processFailedDCOPStat);
1631 bool bsuccess =
true;
1639 lout() <<
"DC Operating Point Failed. Exiting transient loop" << std::endl;
1654 bool bsuccess =
true;
1670 dout() <<
"Calling finishOutput" << std::endl;
1700 if (DEBUG_ANALYSIS & DEBUG_TIME && isActive(Diag::TIME_DUMP_SOLUTION_ARRAYS))
1702 dout() <<
" Transient::doHandlePredictor" << std::endl;
1759 bool bsuccess =
true;
1774 lout() <<
" ***** DCOP time: " << time <<
" seconds. Breakdown follows:" << std::endl;
1781 lout() <<
" ***** Transient Stepping time: " << endTRANtime_ -
startTRANtime_ <<
" seconds. Breakdown follows:" << std::endl;
1804 lout() <<
" *** Transient failure history: " << std::endl;
1808 lout() <<
"Time Time Step Non-Linear Solver node node" << std::endl;
1809 lout() <<
"(sec) Step Status Status Iters ||F|| index name" << std::endl;
1813 lout() <<
"Time Time Step EstErr Non-Linear Solver node node" << std::endl;
1814 lout() <<
"(sec) Step Status OverTol Status Iters ||F|| index name" << std::endl;
1817 for (
int i = 0; i <
timeQueue_.get_size(); i++ )
1820 lout() << std::scientific
1821 << std::setprecision(fieldWidth-7)
1822 << std::setfill(
' ')
1824 << std::setw( fieldWidth )
1844 lout() << std::setw(7) << std::right;
1847 lout() <<
"P:s nrm";
1855 lout() <<
"P:near ";
1859 lout() <<
"P:s up ";
1861 else if( nlStatus == nlReturnCodes.
nanFail )
1867 lout() <<
"F:max s";
1871 lout() <<
"F:max s";
1875 lout() <<
"F:big u";
1877 else if( nlStatus == nlReturnCodes.
stalled )
1879 lout() <<
"F:stall";
1883 lout() <<
"F:n zro";
1887 lout() <<
"F:in Fl";
1891 lout() <<
"code=" <<
1895 lout() << std::right << std::setw( 4 )
1900 lout() << std::right << std::fixed << std::setw( 7 ) << outIndex;
1902 const std::vector<const std::string *> &name_vec =
topology_.getSolutionNodeNames();
1904 lout() <<
" " << std::left << ((outIndex < name_vec.size() && outIndex >= 0) ? *name_vec[outIndex] :
"N/A") << std::endl;
1927 lout() <<
"************\n*** Transient failure information: " << std::endl;
1931 lout() <<
"Time Time Step Non-Linear Solver node node" << std::endl;
1932 lout() <<
"(sec) Step Status Status Iters ||F|| index name" << std::endl;
1936 lout() <<
"Time Time Step EstErr Non-Linear Solver node node" << std::endl;
1937 lout() <<
"(sec) Step Status OverTol Status Iters ||F|| index name" << std::endl;
1943 lout() << std::scientific
1944 << std::setprecision(fieldWidth-7)
1945 << std::setfill(
' ')
1947 << std::setw( fieldWidth )
1967 lout() << std::setw(7) << std::right;
1970 lout() <<
"P:s nrm";
1978 lout() <<
"P:near ";
1982 lout() <<
"P:s up ";
1984 else if( nlStatus == nlReturnCodes.
nanFail )
1990 lout() <<
"F:max s";
1994 lout() <<
"F:max s";
1998 lout() <<
"F:big u";
2000 else if( nlStatus == nlReturnCodes.
stalled )
2002 lout() <<
"F:stall";
2006 lout() <<
"F:n zro";
2010 lout() <<
"F:in Fl";
2014 lout() <<
"code=" <<
2018 lout() << std::right << std::setw( 4 )
2023 lout() << std::right << std::fixed << std::setw( 7 ) << outIndex;
2025 const std::vector<const std::string *> &name_vec =
topology_.getSolutionNodeNames();
2027 lout() <<
" " << std::left << ((outIndex < name_vec.size() && outIndex >= 0) ? *name_vec[outIndex] :
"N/A") << std::endl;
2029 lout() <<
"************" << std::endl;
2047 Stats::StatTop _predictorStat(
"Predictor");
2048 Stats::TimeBlock _predictorTimer(_predictorStat);
2058 Stats::StatTop _updateDeviceSourceStat(
"Update Device Sources");
2059 Stats::TimeBlock _updateDeviceSourceTimer(_updateDeviceSourceStat);
2066 Stats::StatTop _nonlinearSolveStat(
"Nonlinear Solve");
2067 Stats::TimeBlock _nonlinearSolveTimer(_nonlinearSolveStat);
2156 lout() <<
"Time step too small near step number: " <<
stepNumber <<
" Exiting transient loop.\n" << std::endl;
2182 os <<
"Start of DCOP STEP # ";
2190 os <<
"Start of Time Step (INITIAL STEP) # ";
2194 os <<
"Start of Time Step (DISCONTINUITY STEP) # ";
2201 os <<
"Start of Time Step (AFTER FAILED STEP) # ";
2205 os <<
"Start of Time Step (AFTER SUCCESS STEP) # ";
2230 double percentComplete;
2232 double aveCPUTimePerStep;
2234 double aveSimTimePerStep;
2236 double estCompletionTime = 0.0;
2244 Report::signalProgress(
"Xyce in DC Operating Point Calculation");
2246 os <<
"***** Beginning DC Operating Point Calculation...\n" << std::endl;
2255 Report::signalProgress(
"Xyce in Transient Calculation");
2257 os <<
"***** Beginning Transient Calculation...\n" << std::endl;
2271 percentComplete = 100.0 * diff1/diff2;
2282 if (aveSimTimePerStep > Util::MachineDependentParams::MachineEpsilon())
2283 estCompletionTime = aveCPUTimePerStep *
2289 os <<
"***** Percent complete: " << percentComplete <<
" %" << std::endl;
2292 if (estCompletionTime > Util::MachineDependentParams::MachineEpsilon())
2294 unsigned int days, hours, minutes, seconds;
2295 days =
static_cast<int> (estCompletionTime / 86400);
2296 hours =
static_cast<int> ((estCompletionTime - days * 86400) / 3600);
2297 minutes =
static_cast<int> ((estCompletionTime - days * 86400 - hours * 3600) / 60);
2298 seconds =
static_cast<int> (estCompletionTime - days * 86400 - hours * 3600 - minutes * 60);
2301 for (
char *c = timeStr; c != timeStr +
sizeof(timeStr); ++c)
2304 if (Parallel::rank(
comm_) == 0)
2307 time_t t = time( NULL );
2308 struct tm * now = localtime( &t );
2311 if ( ( t != (time_t)-1 ) && ( strftime( timeStr, 255,
"%c", now ) != 0 ) )
2313 os <<
"***** Current system time: " << timeStr << std::endl;
2318 os <<
"***** Current system time could not be determined." << std::endl;
2323 sprintf(timeStr,
"%3d days, %2d hrs., %2d min., %2d sec.", days, hours, minutes, seconds);
2325 sprintf(timeStr,
"%2d hrs., %2d min., %2d sec.", hours, minutes, seconds);
2326 else if (minutes > 0)
2327 sprintf(timeStr,
"%2d min., %2d sec.", minutes, seconds);
2329 sprintf(timeStr,
"%2d sec.", seconds);
2333 std::ostringstream ost;
2334 ost <<
"Xyce transient ";
2335 if (percentComplete < 10)
2339 ost << percentComplete
2340 <<
"%% complete ... Estimated time to completion: "
2341 << timeStr << std::endl;
2342 Report::signalProgress(ost.str());
2346 os <<
"***** Estimated time to completion: " << timeStr << std::endl << std::endl;
2411 dout() <<
"Transient::tranopOutputs:" << std::endl;
2412 dout() <<
"current lead current vector:" << std::endl;
2416 dout() <<
"current lead current deltaV vector:" << std::endl;
2486 std::vector<double> output_interpolation_times =
2499 output_interpolation_times,
2505 std::vector<double> output_interpolation_times =
2518 output_interpolation_times,
2533 std::vector<double> output_interpolation_times =
2544 output_interpolation_times,
2574 IO::InitialConditionsManager & initial_conditions_manager)
2578 if( !initial_conditions_manager.getSaveFlag())
2594 Xyce::dout() <<
"Calling SAVE outputs!" <<std::endl;
2610 double current_time,
2611 double next_output_time,
2616 if (current_time < start_time)
2620 else if ((current_time < next_output_time)&& (fabs(current_time - next_output_time) >= 2 * Util::MachineDependentParams::MachinePrecision()))
2638 double current_time,
2639 double next_output_time,
2640 double final_output_time,
2641 double initial_output_interval,
2642 const IO::IntervalVector & output_intervals)
2646 if (initial_output_interval > 0.0)
2648 if (output_intervals.empty())
2651 while ((next_output_time < current_time)|| (fabs(current_time - next_output_time) < 2 * Util::MachineDependentParams::MachinePrecision()))
2652 next_output_time = next_output_time + initial_output_interval;
2654 else if (current_time < output_intervals[0].first)
2657 while (next_output_time <= current_time)
2658 next_output_time = next_output_time + initial_output_interval;
2659 if (next_output_time > output_intervals[0].first)
2660 next_output_time = output_intervals[0].first;
2665 std::pair<double, double> currInterval, nextInterval;
2666 int size = output_intervals.size();
2667 for (
int i = 0; i < size; ++i)
2668 if (output_intervals[i].first <= current_time)
2670 currInterval = output_intervals[i];
2671 if ((i+1) < static_cast<int>(output_intervals.size()))
2672 nextInterval = output_intervals[i+1];
2674 int step =
static_cast<int> ((current_time-currInterval.first) /
2675 currInterval.second);
2676 next_output_time = currInterval.first + (step+1)*currInterval.second;
2677 if (nextInterval.first && (nextInterval.first!=currInterval.first) && (next_output_time>=nextInterval.first))
2678 next_output_time = nextInterval.first;
2681 if (next_output_time >= final_output_time)
2682 next_output_time =final_output_time;
2685 return next_output_time;
2699 IO::RestartMgr & restart_manager,
2700 double current_time,
2701 double & next_restart_save_time)
2703 double initial_restart_interval = restart_manager.getInitialRestartInterval();
2704 const IO::IntervalVector &restart_intervals = restart_manager.getRestartIntervals();
2708 Xyce::dout() <<
"TESTING FOR RESTART SAVE" << std::endl
2709 << Xyce::subsection_divider << std::endl
2710 <<
"current_time: " << current_time << std::endl
2711 <<
"nextSaveTime: " << next_restart_save_time << std::endl
2712 <<
"initial_restart_interval: " << initial_restart_interval << std::endl;
2713 if (!restart_intervals.empty())
2715 Xyce::dout() <<
"First restart interval: " << restart_intervals[0].first << std::endl;
2719 Xyce::dout() <<
"restart_intervals is empty" << std::endl;
2724 if (initial_restart_interval == 0.0)
2728 else if (current_time < next_restart_save_time)
2732 else if (restart_intervals.empty())
2734 while (next_restart_save_time <= current_time)
2736 next_restart_save_time += initial_restart_interval;
2740 else if (current_time < restart_intervals[0].first)
2742 while (next_restart_save_time <= current_time)
2744 next_restart_save_time += initial_restart_interval;
2746 if (next_restart_save_time > restart_intervals[0].first)
2748 next_restart_save_time = restart_intervals[0].first;
2754 std::pair<double, double> currInterval, nextInterval;
2755 int size = restart_intervals.size();
2756 for (
int i = 0; i < size; ++i)
2758 if (restart_intervals[i].first <= current_time)
2760 currInterval = restart_intervals[i];
2761 if ((i+1) < (
int)restart_intervals.size())
2763 nextInterval = restart_intervals[i+1];
2767 int step = static_cast <
int> ((current_time - currInterval.first) /
2768 currInterval.second);
2769 next_restart_save_time = currInterval.first + (step+1)*currInterval.second;
2771 if (nextInterval.first && (nextInterval.first!=currInterval.first)
2772 && (next_restart_save_time >= nextInterval.first))
2774 next_restart_save_time = nextInterval.first;
2780 Xyce::dout() <<
"new nextSaveTime: " << next_restart_save_time << std::endl
2781 <<
"restart flag: " << flag << std::endl
2782 << Xyce::subsection_divider << std::endl;
2799 double current_time,
2800 double next_output_time,
2801 double final_output_time,
2802 double initial_output_interval,
2803 const IO::IntervalVector & output_intervals)
2805 std::vector<double> output_interpolation_times;
2808 if (initial_output_interval > 0.0)
2810 if (output_intervals.empty() || current_time <= output_intervals[0].first)
2813 double t = next_output_time;
2814 while ((t < current_time) && ( current_time -t ) > 2 * Util::MachineDependentParams::MachinePrecision())
2816 output_interpolation_times.push_back(t);
2817 t += initial_output_interval;
2820 if ((t - current_time) <= 2 * Util::MachineDependentParams::MachinePrecision() )
2822 output_interpolation_times.push_back(current_time);
2825 if ((t - final_output_time) > 2 * Util::MachineDependentParams::MachinePrecision())
2828 output_interpolation_times.push_back(final_output_time);
2835 lastInt=output_intervals.size()-1;
2839 outInt<lastInt&&output_intervals[outInt+1].first<=next_output_time;
2842 double t = next_output_time;
2843 while (t <= current_time)
2845 output_interpolation_times.push_back(t);
2846 t += output_intervals[outInt].second;
2847 if (outInt != lastInt && t >= output_intervals[outInt+1].first)
2850 t = output_intervals[outInt].first;
2856 return output_interpolation_times;
2869 std::map<std::string,double> inputMap;
2872 for (std::vector<std::string>::const_iterator it = device_names.begin(), end = device_names.end(); it != end; ++it)
2873 inputMap[*it] = 0.0;
2883 int isize = inputMap.size();
2884 std::vector<double> outputVector(isize, 0.0);
2885 std::vector< std::vector<double> > jacobian(isize);
2886 for (
int i = 0; i < isize; ++i)
2888 jacobian[i].resize(isize, 0.0);
2891 bool b1 = conductance_extractor.
extract(inputMap, outputVector, jacobian);
2894 int numElectrodes = isize;
2897 fp1 = fopen(filename.c_str(),
"w");
2899 fprintf(fp1,
"%s",
"Conductance array: \n");
2900 fprintf(fp1,
"%s",
" ");
2903 std::map<std::string,double>::const_iterator iterM = inputMap.begin();
2904 std::map<std::string,double>::const_iterator endM = inputMap.end ();
2905 for (iE2 = 0; iE2 < numElectrodes; ++iE2, ++iterM)
2907 std::string srcname = iterM->first;
2908 fprintf(fp1,
"\t%14s", srcname.c_str());
2910 fprintf(fp1,
"%s",
"\n");
2912 iterM = inputMap.begin();
2913 for (iE1 = 0; iE1 < numElectrodes; ++iE1, ++iterM)
2915 std::string srcname = iterM->first;
2916 fprintf(fp1,
"%14s",srcname.c_str());
2917 for (iE2 = 0; iE2 < numElectrodes; ++iE2)
2919 fprintf(fp1,
"\t%14.4e",jacobian[iE1][iE2]);
2921 fprintf(fp1,
"%s",
"\n");
2923 fprintf(fp1,
"%s",
"\n");
2927 fprintf(fp1,
"%s",
"\nConductance calculation failed!\n");
2935 typedef Util::Factory<AnalysisBase, Transient> TransientFactoryBase;
2948 class TransientFactory:
public TransientFactoryBase
2976 Linear::System & linear_system,
2979 Topo::Topology & topology,
2980 IO::InitialConditionsManager & initial_conditions_manager,
2981 IO::RestartMgr & restart_manager)
2982 : TransientFactoryBase(),
2992 virtual ~TransientFactory()
3008 Transient *create()
const
3033 void setTransientAnalysisOptionBlock(
const Util::OptionBlock &option_block)
3053 bool setTimeIntegratorOptionBlock(
const Util::OptionBlock &option_block)
3075 struct TransientAnalysisReg :
public IO::PkgOptionsReg
3077 TransientAnalysisReg(
3078 TransientFactory & factory)
3082 bool operator()(
const Util::OptionBlock &option_block)
3084 factory_.setTransientAnalysisOptionBlock(option_block);
3106 IO::PkgOptionsMgr & options_manager,
3107 IO::CircuitBlock & circuit_block,
3108 const std::string & netlist_filename,
3109 const IO::TokenVector & parsed_line)
3111 Util::OptionBlock option_block(
"TRAN");
3113 int numFields = parsed_line.size();
3116 if ( numFields < 3 || numFields > 6 )
3118 Report::UserError0().at(netlist_filename, parsed_line[0].lineNumber_)
3119 <<
".TRAN line has an unexpected number of fields";
3124 int linePosition = 1;
3125 int endPosition = numFields;
3127 Util::Param parameter(
"",
"");
3130 parameter.setTag(
"TSTEP" );
3131 parameter.setVal( parsed_line[linePosition].string_ );
3132 option_block.addParam( parameter );
3135 parameter.setTag(
"TSTOP" );
3136 parameter.setVal( parsed_line[linePosition].string_ );
3137 option_block.addParam( parameter );
3147 bool tstartFound=
false;
3148 bool dtmaxFound=
false;
3149 while( linePosition < endPosition )
3155 parameter.setTag( parsed_line[linePosition].string_ );
3156 parameter.setVal( parsed_line[linePosition].string_ );
3158 if(parameter.hasExpressionValue())
3161 parameter.setTag(
"MAXTIMEEXPRESSION");
3162 option_block.addParam( parameter );
3167 if ( parameter.uTag() ==
"NOOP" || parameter.uTag() ==
"UIC" )
3169 parameter.setVal(
"1" );
3170 option_block.addParam( parameter );
3176 parameter.setTag(
"TSTART" );
3177 option_block.addParam( parameter );
3180 else if( !dtmaxFound )
3182 parameter.setTag(
"DTMAX" );
3183 option_block.addParam( parameter );
3188 Report::UserError0().at(netlist_filename, parsed_line[linePosition].lineNumber_)
3189 <<
"expected NOOP/UIC field on .TRAN line but found" << parameter.usVal();
3196 circuit_block.addOptions(option_block);
3213 factory_block.
optionsManager_.addCommandParser(
".TRAN", extractTRANData);
3214 factory_block.
optionsManager_.addCommandParser(
".TR", extractTRANData);
3216 factory_block.
optionsManager_.addCommandProcessor(
"TRAN",
new TransientAnalysisReg(*factory));
3218 factory_block.
optionsManager_.addOptionsProcessor(
"TIMEINT", IO::createRegistrationOptions(*factory, &TransientFactory::setTimeIntegratorOptionBlock));
bool setAnalysisOption(const Util::Param ¶m)
bool enableSensitivity(TimeIntg::DataStore &data_store, Parallel::Manager ¶llel_manager, Topo::Topology &topology)
IO::OutputMgr & getOutputManager()
Linear::Vector * lastSolutionPtr
std::vector< Linear::Vector * > fastTimeQVec
Util::FixedQueue< double > timeQueue_
IO::PkgOptionsMgr & optionsManager_
void setDAEStateDerivFlag(bool state)
unsigned int successStepsThisParameter_
TimeIntg::TIAParams tiaParams_
virtual int getMaxNormFindex() const =0
Topo::Topology & topology_
void takeAnIntegrationStep_()
IO::InitialConditionsManager & initialConditionsManager_
void notify(const StepEvent &event)
std::vector< double > timeSteps
unsigned int successfulStepsTaken_
Number of consecutive successful time-integration steps.
bool icSensitivity(std::vector< double > &objectiveVec, std::vector< double > &dOdpVec, std::vector< double > &dOdpAdjVec, std::vector< double > &scaled_dOdpVec, std::vector< double > &scaled_dOdpAdjVec)
bool beginningIntegration
unsigned int tranStepNumber
int newtonConvergenceStatus
virtual bool setInitialGuess(Linear::Vector *solVectorPtr)
double initialTimeStep
User specified initial time step.
TwoLevelMode getTwoLevelMode() const
std::vector< bool > timeStepsBreakpointFlag
void setSavedAlready(bool saved_already)
void setNextOutputTime(double next_output_time)
bool testRestartSaveTime(AnalysisManager &analysis_manager, IO::RestartMgr &restart_manager, double current_time, double &next_restart_save_time)
bool setTimeIntegratorOption(const Util::Param ¶m)
bool testSaveOutputTime(Analysis::AnalysisManager &analysis_manager, IO::InitialConditionsManager &initial_conditions_manager)
bool calcSensitivity(std::vector< double > &objectiveVec, std::vector< double > &dOdpVec, std::vector< double > &dOdpAdjVec, std::vector< double > &scaled_dOdpVec, std::vector< double > &scaled_dOdpAdjVec)
void evaluateStepError(const Loader::Loader &loader, const TIAParams &tia_params)
Pure virtual class to augment a linear system.
int errorAnalysisOptionResetCount
Iteration count down to reset errorAnalysisOption to LOCAL_TRUNCATED_ESTIMATES.
std::vector< std::string > condTestDeviceNames
names for conductance test
int nIterations
Number of newton iterations.
virtual void outputMPDE(double time, const Linear::Vector *solution_vector)
std::vector< double > objectiveVec_
Topo::Topology & topology_
double minEstErrorOverTol
virtual void stepFailure(Analysis::TwoLevelMode analysis)
void dumpRestart(Parallel::Communicator ¶llel_communicator, Topo::Topology &topology, Analysis::AnalysisManager &analysis_manager, const std::string &job_name, bool pack, double current_time) const
Util::OptionBlock timeIntegratorOptionBlock_
IO::RestartMgr & restartManager_
Util::FixedQueue< int > nonlinearSolverStatusQueue_
virtual bool outputPlotFiles() const
bool resetForStepAnalysis()
std::vector< double > dOdpAdjVec_
unsigned int stepNumber
Time-integration step number counter.
void outputSolDataArrays(std::ostream &os)
double getPauseTime() const
virtual double getMaxNormF() const =0
bool getSwitchIntegrator() const
Linear::Vector * currStorePtr
Linear::Vector * lastStatePtr
bool isTimeIntegrationMethodCreated()
void gatherStepStatistics(StatCounts &stats, Nonlinear::NonLinearSolver &nonlinear_solver, int newton_convergence_status)
double timeStepAtMinEstErrorOverTol
int errorAnalysisOption
Error analysis option.
Topo::Topology & topology_
Util::ExpressionData * maxTimeStepExpression_
double finalTime
End time for simulation.
void createTimeIntegratorMethod(const TimeIntg::TIAParams &tia_params, const unsigned int integration_method)
Linear::System & linearSystem_
ConductanceExtractor & getConductanceExtractor()
int exitStep
Exit after taking this many steps.
bool getSavedAlready() const
OutputMgrAdapter & outputManagerAdapter_
bool resetAll(const TIAParams &tia_params)
Util::FixedQueue< int > nonlinearSolverNumIterationsQueue_
std::vector< Linear::Vector * > fastTimeStateVec
bool processSuccessfulDCOP()
Util::ListenerAutoSubscribe< StepEvent > StepEventListener
Util::Timer & getXyceTranTimer()
const Util::BreakPointLess & getBreakPointLess() const
void setAnalysisMode(AnalysisMode mode)
Linear::Vector * currStatePtr
unsigned int failedStepsAttempted_
Total number of failed time-integration steps.
bool getResumingSimulation() const
void obtainCorrectorDeriv()
Parallel::Manager * getPDSManager() const
bool setDCOPOption(const Util::Param ¶m)
TimeIntg::StepErrorControl & getStepErrorControl()
bool constantTimeStepFlag
Constant time step integration flag.
void updateSolDataArrays()
bool getBeginningIntegrationFlag() const
void computeDividedDifferences()
std::vector< Linear::Vector * > fastTimeSolutionVec
NonLinearSolver & getNonlinearSolver()
bool getProgressFlag() const
void completeStep(const TIAParams &tia_params)
std::vector< TwoLevelError > innerErrorInfoVec
int minTimeStepsBP
User specified mininum number of steps between breakpoints.
Linear::Vector * daeQVectorPtr
void setConstantHistory()
std::vector< double > dOdpVec_
double nextRestartSaveTime_
virtual bool initializeProblem(Linear::Vector *nextSolVectorPtr, Linear::Vector *currSolVectorPtr, Linear::Vector *lastSolVectorPtr, Linear::Vector *nextStaVectorPtr, Linear::Vector *currStaVectorPtr, Linear::Vector *lastStaVectorPtr, Linear::Vector *StateDerivVectorPtr, Linear::Vector *nextStoVectorPtr, Linear::Vector *currStoVectorPtr, Linear::Vector *lastStoVectorPtr, Linear::Vector *QVectorPtr, Linear::Vector *FVectorPtr, Linear::Vector *BVectorPtr, Linear::Vector *dFdxdVpVectorPtr, Linear::Vector *dQdxdVpVectorPtr) const =0
Linear::System & linearSystem_
unsigned int breakPointRestartStep
void updateStopTime(Parallel::Machine comm, bool breakpoints_enabled, double initial_time, bool min_time_steps_breakpoint_given, double min_time_steps_breakpoint)
virtual bool outputFunkyMPDE()
void resetAll(AnalysisMode mode)
virtual bool startTimeStep(bool beginIntegrationFlag, double nextTimeStep, double nextTime, int currentOrder)
void setErrorWtVector(const TIAParams &tia_params)
void rejectStep(const TIAParams &tia_params)
const ReturnCodes & getReturnCodes() const
void setTimeStep(double newTimeStep)
bool saveTimeStepsFlag
flag to save timestpes in data store for later use
virtual bool isPDESystem() const
bool registerTransientFactory(FactoryBlock &factory_block)
bool finalizeMixedSignalStep()
Linear::Vector * daeFVectorPtr
bool mixedSignalStep(double maxTimeStepFromHabanero)
int minTimeStepRecoveryCounter
Util::OptionBlock transientAnalysisOptionBlock_
bool bpEnable
Enable breakpoints flag.
Nonlinear::Manager & nonlinearManager_
bool initialOutputTimeGiven
The FactoryBlock contains parameters needed by the analysis creation functions.
Linear::System & linearSystem_
IO::InitialConditionsManager & initialConditionsManager_
Nonlinear::AnalysisMode nonlinearAnalysisMode(Mode mode)
Returns the nonlinear analysis mode given the analysis mode.
virtual void acceptStep()
OutputAdapter * outputAdapter_
void simulationPaused(double initial_time)
bool processSuccessfulStep()
Util::FixedQueue< double > nonlinearSolverMaxNormQueue_
void printProgress(std::ostream &os)
virtual bool updateSources()
Linear::Vector * currLeadCurrentQDerivPtr
Linear::Vector * nextStatePtr
std::vector< Linear::Vector * > fastTimeStoreVec
AnalysisManager & analysisManager_
void preMixedSignalStepDetails(double maxTimeStepFromHabanero)
AnalysisManager & analysisManager_
void outputTimeInfo(std::ostream &os)
virtual bool printLoopInfo(int start, int finish)
Linear::Vector * dFdxdVpVectorPtr
IO::InitialConditionsManager & initialConditionsManager_
Loader::NonlinearEquationLoader & getNonlinearEquationLoader()
Linear::Vector * currLeadDeltaVPtr
TransientFactory & factory_
void setDoubleDCOPEnabled(bool enable)
void outputPredictedSolution(std::ostream &os)
bool retakeAndAcceptTimeStep(double aTimeStep)
double initialOutputTime
Time at which output starts (StepErrorControl)
int numberSuccessiveFailures
Mode getAnalysisMode() const
N_MPDE_Manager * mpdeManager_
bool doProcessFailedStep()
bool setTimeIntegratorOptions(const Util::OptionBlock &option_block)
Nonlinear::Manager & nonlinearManager_
void outputPredictedDerivative(std::ostream &os)
unsigned int initialIntegrationMethod_
IO::RestartMgr & restartManager_
Linear::Vector * nextSolutionPtr
void setConstantSensitivityHistory()
unsigned int integrationMethod
Time-integration method.
double getEstOverTol() const
Linear::Vector * nextStorePtr
void addAnalysisFactory(FactoryBlock &factory_block, Util::Factory< AnalysisBase, void > *factory)
double initialTime
Beginning time for the time integrator (StepErrorControl, integrators access from StepErrorControl) ...
Linear::Vector * dQdxdVpVectorPtr
bool setAnalysisParams(const Util::OptionBlock ¶msBlock)
bool previousCallStepSuccessful
Linear::Vector * currLeadCurrentPtr
Linear::Vector * lastStorePtr
void setInputOPFlag(bool initial_conditions_loaded)
double getInitialOutputInterval() const
int stepNumberAtMinEstErrorOverTol
TimeIntg::WorkingIntegrationMethod & getWorkingIntegrationMethod()
const IO::CmdParse & getCommandLine() const
void obtainPredictorDeriv()
double oldPercentComplete
std::vector< double > scaled_dOdpAdjVec_
std::string maxTimeStepExpressionString_
void outputFailedStepData()
void setSwitchIntegrator(bool switch_itegrator)
void allocateTranSolver(Analysis::AnalysisManager &analysis_manager, Loader::NonlinearEquationLoader &nonlinear_equation_loader, Linear::System &linear_system, TimeIntg::DataStore &data_store, Parallel::Manager ¶llel_manager, IO::OutputMgr &output_manager, Topo::Topology &topology)
bool saveOutputSolution(Parallel::Machine comm, IO::InitialConditionsManager &initial_conditions_manager, const NodeNameMap &node_name_map, const TIAParams &tia_params, Linear::Vector *solnVecPtr, const double saveTime, const bool doNotInterpolate)
bool finalVerboseOutput()
Linear::Vector * currSolutionPtr
bool firstDoubleDCOPStep() const
TimeIntg::DataStore * getDataStore()
double getSolverStartTime() const
unsigned int baseIntegrationMethod_
Current time-integration method flag.
IO::RestartMgr & restartManager_
bool updateMaxTimeStep(Parallel::Machine comm, Loader::Loader &loader, const TIAParams &tia_params, double suggestedMaxTimeStep=0.0)
Parallel::Machine getComm()
double updateOutputTime(double current_time, double next_output_time, double final_output_time, double initial_output_interval, const IO::IntervalVector &output_intervals)
Util::FixedQueue< double > timeStepQueue_
const IO::IntervalVector & getOutputIntervals() const
bool updateBreakPoints(const Loader::Loader &loader, double initial_time)
std::vector< double > scaled_dOdpVec_
Linear::Vector * nextStateDerivPtr
virtual void stepSuccess(Analysis::TwoLevelMode analysis)
Util::FixedQueue< int > stepStatusQueue_
bool condTestFlag
flag for conductance test
virtual bool finishOutput() const
double exitTime
Exit when it exceeds this time.
int getNumberOfSteps() const
Nonlinear::Manager & nonlinearManager_
virtual bool getInitialQnorm(std::vector< TimeIntg::TwoLevelError > &tleVec)
bool printOutputSolution(Analysis::OutputMgrAdapter &outputManagerAdapter, const TIAParams &tia_params, const double time, Linear::Vector *solnVecPtr, const bool doNotInterpolate, const std::vector< double > &outputInterpolationTimes, bool skipPrintLineOutput)
double getNextOutputTime() const
void setTwoLevelMode(TwoLevelMode two_level_mode)
void writeConductanceFile(const std::vector< std::string > &device_names, Nonlinear::ConductanceExtractor &conductance_extractor, const std::string &filename)
Util::FixedQueue< double > nonlinearSolverMaxNormIndexQueue_
AnalysisManager & analysisManager_
void printStepHeader(std::ostream &os)
bool doProcessSuccessfulStep()
virtual int getNumIterations() const =0
bool passNLStall
option to pass some non-linear solver failures
Linear::Vector * flagSolutionPtr
void initialize(const TIAParams &tia_params)
void tranOutput(double time, Linear::Vector &currSolutionPtr, Linear::Vector &stateVecPtr, Linear::Vector &storeVecPtr, Linear::Vector &lead_current_vector, Linear::Vector &junction_voltage_vector, Linear::Vector &lead_current_dqdt_vector, std::vector< double > &objectiveVec_, std::vector< double > &dOdpVec_, std::vector< double > &dOdpAdjVec_, std::vector< double > &scaled_dOdpVec_, std::vector< double > &scaled_dOdpAdjVec_, bool skipPrintLineOutput=false)
Transient(AnalysisManager &analysis_manager, Linear::System &linear_system, Nonlinear::Manager &nonlinear_manager, Loader::Loader &loader, Topo::Topology &topology, IO::InitialConditionsManager &initial_conditions_manager, IO::RestartMgr &restart_manager, OutputAdapter *output_adapter=0, HB *hb_analysis=0, N_MPDE_Manager *mpde_manager=0)
Util::FixedQueue< double > estErrorOverTolQueue_
Linear::Vector * daeBVectorPtr
bool setReturnCodeOption(const Util::Param ¶m)
std::vector< double > computeOutputInterpolationTimes(double current_time, double next_output_time, double final_output_time, double initial_output_interval, const IO::IntervalVector &output_intervals)
bool testOutputTime(double current_time, double next_output_time, double start_time)