Browse Source

Update on comments.

pre-master-46
Holger Vogt 5 months ago
parent
commit
e168df83fb
  1. 205
      src/spicelib/analysis/dctran.c

205
src/spicelib/analysis/dctran.c

@ -5,8 +5,7 @@ Modified: 2000 AlansFixes
Modified: 2023 XSPICE breakpoint fix for shared ngspice by Vyacheslav Shevchuk Modified: 2023 XSPICE breakpoint fix for shared ngspice by Vyacheslav Shevchuk
**********/ **********/
/* subroutine to do DC TRANSIENT analysis
--- ONLY, unlike spice2 routine with the same name! */
/* subroutine to do DC TRANSIENT analysis */
#include "ngspice/ngspice.h" #include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h" #include "ngspice/cktdefs.h"
@ -21,15 +20,12 @@ extern struct dbcomm *dbs;
#include "ngspice/ftedebug.h" #include "ngspice/ftedebug.h"
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - wbk - Add headers */
#include "ngspice/miftypes.h" #include "ngspice/miftypes.h"
#include "ngspice/evt.h" #include "ngspice/evt.h"
#include "ngspice/enh.h" #include "ngspice/enh.h"
#include "ngspice/mif.h" #include "ngspice/mif.h"
#include "ngspice/evtproto.h" #include "ngspice/evtproto.h"
#include "ngspice/ipctiein.h" #include "ngspice/ipctiein.h"
/* gtri - end - wbk - Add headers */
#endif #endif
#ifdef CLUSTER #ifdef CLUSTER
@ -100,13 +96,12 @@ DCtran(CKTcircuit *ckt,
int ltra_num; int ltra_num;
CKTnode *node; CKTnode *node;
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
/* IPC stuff */
Ipc_Boolean_t ipc_firsttime = IPC_TRUE; Ipc_Boolean_t ipc_firsttime = IPC_TRUE;
Ipc_Boolean_t ipc_secondtime = IPC_FALSE; Ipc_Boolean_t ipc_secondtime = IPC_FALSE;
Ipc_Boolean_t ipc_delta_cut = IPC_FALSE; Ipc_Boolean_t ipc_delta_cut = IPC_FALSE;
double ipc_last_time = 0.0; double ipc_last_time = 0.0;
double ipc_last_delta = 0.0; double ipc_last_delta = 0.0;
/* gtri - end - wbk - 12/19/90 - Add IPC stuff */
// Fix for sharedsync olddelta: When DCTran processes // Fix for sharedsync olddelta: When DCTran processes
// either analog or XSPICE breakpoint, then it subtracts delta from // either analog or XSPICE breakpoint, then it subtracts delta from
@ -154,6 +149,8 @@ DCtran(CKTcircuit *ckt,
ckt->CKTtimePoints = TMALLOC(double, ckt->CKTtimeListSize); ckt->CKTtimePoints = TMALLOC(double, ckt->CKTtimeListSize);
/* end LTRA code addition */ /* end LTRA code addition */
/* Reset the breakpoint list.
Add breakpoints at 0 time and TSTOP (final) time */
if(ckt->CKTbreaks) FREE(ckt->CKTbreaks); if(ckt->CKTbreaks) FREE(ckt->CKTbreaks);
ckt->CKTbreaks = TMALLOC(double, 2); ckt->CKTbreaks = TMALLOC(double, 2);
if(ckt->CKTbreaks == NULL) return(E_NOMEM); if(ckt->CKTbreaks == NULL) return(E_NOMEM);
@ -166,16 +163,18 @@ DCtran(CKTcircuit *ckt,
#endif #endif
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - 12/19/90 - Modify setting of CKTminBreak */
/* Set to 10 times delmin for ATESSE 1 compatibity */
if(ckt->CKTminBreak==0) ckt->CKTminBreak = 10.0 * ckt->CKTdelmin;
/* gtri - end - wbk - 12/19/90 - Modify setting of CKTminBreak */
/* Modify setting of CKTminBreak
Set to 10 times delmin (minimum step time). */
if(ckt->CKTminBreak == 0)
ckt->CKTminBreak = 10.0 * ckt->CKTdelmin;
#else #else
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
if(ckt->CKTminBreak == 0)
ckt->CKTminBreak = ckt->CKTmaxStep * 5e-5;
#endif #endif
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and set anal_init and anal_type */
/* Add IPC stuff and set anal_init and anal_type */
/* Tell the beginPlot routine what mode we're in */ /* Tell the beginPlot routine what mode we're in */
g_ipc.anal_type = IPC_ANAL_TRAN; g_ipc.anal_type = IPC_ANAL_TRAN;
@ -183,7 +182,6 @@ DCtran(CKTcircuit *ckt,
g_mif_info.circuit.anal_type = MIF_DC; g_mif_info.circuit.anal_type = MIF_DC;
g_mif_info.circuit.anal_init = MIF_TRUE; g_mif_info.circuit.anal_init = MIF_TRUE;
/* gtri - end - wbk */
#endif #endif
error = CKTnames(ckt,&numNames,&nameList); error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error); if(error) return(error);
@ -196,7 +194,7 @@ DCtran(CKTcircuit *ckt,
tfree(nameList); tfree(nameList);
if(error) return(error); if(error) return(error);
/* initialize CKTsoaCheck `warn' counters */
/* initialize CKTsoaCheck 'warn' counters */
if (ckt->CKTsoaCheck) if (ckt->CKTsoaCheck)
error = CKTsoaInit(); error = CKTsoaInit();
@ -225,13 +223,12 @@ DCtran(CKTcircuit *ckt,
} }
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - set a breakpoint at end of supply ramping time */
/* must do this after CKTtime set to 0 above */
/* set a breakpoint at end of supply ramping time.
Must do this after CKTtime is set to 0 above */
if(ckt->enh->ramp.ramptime > 0.0) if(ckt->enh->ramp.ramptime > 0.0)
CKTsetBreak(ckt, ckt->enh->ramp.ramptime); CKTsetBreak(ckt, ckt->enh->ramp.ramptime);
/* gtri - end - wbk - set a breakpoint at end of supply ramping time */
/* gtri - begin - wbk - Call EVTop if event-driven instances exist */
/* Call EVTop if event-driven instances exist */
if(ckt->evt->counts.num_insts != 0) { if(ckt->evt->counts.num_insts != 0) {
/* use new DCOP algorithm */ /* use new DCOP algorithm */
converged = EVTop(ckt, converged = EVTop(ckt,
@ -242,10 +239,9 @@ DCtran(CKTcircuit *ckt,
EVTdump(ckt, IPC_ANAL_DCOP, 0.0); EVTdump(ckt, IPC_ANAL_DCOP, 0.0);
EVTop_save(ckt, MIF_FALSE, 0.0); EVTop_save(ckt, MIF_FALSE, 0.0);
/* gtri - end - wbk - Call EVTop if event-driven instances exist */
} else } else
#endif #endif
/* Get operating point for analogue circuit */
converged = CKTop(ckt, converged = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT, (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITFLOAT, (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITFLOAT,
@ -280,40 +276,31 @@ DCtran(CKTcircuit *ckt,
return(converged); return(converged);
} }
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
/* Send the operating point results for Mspice compatibility */
/* IPC stuff: Send the operating point results */
if(g_ipc.enabled) { if(g_ipc.enabled) {
ipc_send_dcop_prefix(); ipc_send_dcop_prefix();
CKTdump(ckt, 0.0, job->TRANplot); CKTdump(ckt, 0.0, job->TRANplot);
ipc_send_dcop_suffix(); ipc_send_dcop_suffix();
} }
/* gtri - end - wbk */
/* gtri - add - wbk - 12/19/90 - set anal_init and anal_type */
/* set anal_init and anal_type */
g_mif_info.circuit.anal_init = MIF_TRUE; g_mif_info.circuit.anal_init = MIF_TRUE;
/* Tell the code models what mode we're in */ /* Tell the code models what mode we're in */
g_mif_info.circuit.anal_type = MIF_TRAN; g_mif_info.circuit.anal_type = MIF_TRAN;
/* gtri - end - wbk */
/* gtri - begin - wbk - Add Breakpoint stuff */
/* Breakpoint stuff */
/* Initialize the temporary breakpoint variables to infinity */ /* Initialize the temporary breakpoint variables to infinity */
g_mif_info.breakpoint.current = 1.0e30; g_mif_info.breakpoint.current = 1.0e30;
g_mif_info.breakpoint.last = 1.0e30; g_mif_info.breakpoint.last = 1.0e30;
/* gtri - end - wbk - Add Breakpoint stuff */
#endif #endif
ckt->CKTstat->STATtimePts ++; ckt->CKTstat->STATtimePts ++;
ckt->CKTorder = 1; ckt->CKTorder = 1;
/* Initialze CKTdeltaOld with maximum value */
for(i=0;i<7;i++) { for(i=0;i<7;i++) {
ckt->CKTdeltaOld[i]=ckt->CKTmaxStep; ckt->CKTdeltaOld[i]=ckt->CKTmaxStep;
} }
ckt->CKTdelta = delta; /* delta set in line 135 */
ckt->CKTdelta = delta; /* delta set in line 130 */
#ifdef STEPDEBUG #ifdef STEPDEBUG
(void)printf("delta initialized to %g\n",ckt->CKTdelta); (void)printf("delta initialized to %g\n",ckt->CKTdelta);
#endif #endif
@ -339,9 +326,9 @@ DCtran(CKTcircuit *ckt,
ckt->CKTorder = save2; ckt->CKTorder = save2;
} }
#endif #endif
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITTRAN;
/* modeinittran set here */ /* modeinittran set here */
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITTRAN;
/* Reset the gear variable coefficient matrix. */
ckt->CKTag[0]=ckt->CKTag[1]=0; ckt->CKTag[0]=ckt->CKTag[1]=0;
if (ckt->CKTstate1 && ckt->CKTstate0) { if (ckt->CKTstate1 && ckt->CKTstate0) {
memcpy(ckt->CKTstate1, ckt->CKTstate0, memcpy(ckt->CKTstate1, ckt->CKTstate0,
@ -360,14 +347,16 @@ DCtran(CKTcircuit *ckt,
#ifdef CLUSTER #ifdef CLUSTER
CLUsetup(ckt); CLUsetup(ckt);
#endif #endif
/* End of (restart || ckt->CKTtime == 0) */
} else { } else {
/* saj As traninit resets CKTmode */
/* traninit resets CKTmode */
ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITPRED; ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITPRED;
/* saj */
INIT_STATS(); INIT_STATS();
if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5;
if(ckt->CKTminBreak == 0)
ckt->CKTminBreak = ckt->CKTmaxStep * 5e-5;
firsttime=0; firsttime=0;
/* To get rawfile working saj*/
/* To get rawfile working */
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL, error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
NULL, NULL,
NULL, 0, NULL, 0,
@ -377,8 +366,7 @@ DCtran(CKTcircuit *ckt,
fprintf(stderr, "Couldn't relink rawfile\n"); fprintf(stderr, "Couldn't relink rawfile\n");
return error; return error;
} }
/* end saj*/
goto resume;
goto resume; /* line 517 */
} }
/* 650 */ /* 650 */
@ -403,7 +391,8 @@ DCtran(CKTcircuit *ckt,
error = CKTaccept(ckt); error = CKTaccept(ckt);
/* check if current breakpoint is outdated; if so, clear */ /* check if current breakpoint is outdated; if so, clear */
if (ckt->CKTtime > ckt->CKTbreaks[0]) CKTclrBreak(ckt);
if (ckt->CKTtime > ckt->CKTbreaks[0])
CKTclrBreak(ckt);
if (ckt->CKTsoaCheck) if (ckt->CKTsoaCheck)
error = CKTsoaCheck(ckt); error = CKTsoaCheck(ckt);
@ -432,8 +421,8 @@ DCtran(CKTcircuit *ckt,
return(error); return(error);
} }
#ifdef XSPICE #ifdef XSPICE
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
/* Send IPC stuff */
if ((g_ipc.enabled) || wantevtdata) { if ((g_ipc.enabled) || wantevtdata) {
/* Send event-driven results */ /* Send event-driven results */
@ -477,8 +466,8 @@ DCtran(CKTcircuit *ckt,
g_ipc.last_time = ckt->CKTtime; g_ipc.last_time = ckt->CKTtime;
} }
/* End of Send IPC stuff*/
} else } else
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
#endif #endif
#ifdef CLUSTER #ifdef CLUSTER
CLUoutput(ckt); CLUoutput(ckt);
@ -487,15 +476,14 @@ DCtran(CKTcircuit *ckt,
|| (!(ckt->CKTmode&MODEUIC) && ckt->CKTtime >= ckt->CKTinitTime)) || (!(ckt->CKTmode&MODEUIC) && ckt->CKTtime >= ckt->CKTinitTime))
CKTdump(ckt, ckt->CKTtime, job->TRANplot); CKTdump(ckt, ckt->CKTtime, job->TRANplot);
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - Update event queues/data for accepted timepoint */
/* Note: this must be done AFTER sending results to SI so it can't */
/* go next to CKTaccept() above */
/* Update event queues/data for accepted timepoint */
/* Note: this must be done AFTER sending results to SI so it can't
go next to CKTaccept() above */
if(ckt->evt->counts.num_insts > 0) if(ckt->evt->counts.num_insts > 0)
EVTaccept(ckt, ckt->CKTtime); EVTaccept(ckt, ckt->CKTtime);
/* gtri - end - wbk - Update event queues/data for accepted timepoint */
#endif #endif
ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter; ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter;
/* check for the end of the tran simulation, either by< stop time given,
/* Check for the end of the tran simulation, either by stop time given,
or final time has been reached. */ or final time has been reached. */
if (have_autostop) if (have_autostop)
/* time consuming autostop check only, when variable 'autostop' has been set /* time consuming autostop check only, when variable 'autostop' has been set
@ -518,7 +506,7 @@ DCtran(CKTcircuit *ckt,
if (flag_autostop) if (flag_autostop)
fprintf(stdout, "\nNote: Autostop after %e s, all measurement conditions are fulfilled.\n", ckt->CKTtime); fprintf(stdout, "\nNote: Autostop after %e s, all measurement conditions are fulfilled.\n", ckt->CKTtime);
/* Final return from tran*/
/* Final return from tran upon success */
return(OK); return(OK);
} }
if(SPfrontEnd->IFpauseTest()) { if(SPfrontEnd->IFpauseTest()) {
@ -556,14 +544,12 @@ resume:
#endif #endif
/* are we at a breakpoint, or indistinguishably close? */
/* if ((ckt->CKTtime == ckt->CKTbreaks[0]) || (ckt->CKTbreaks[0] - */
/* Are we at a breakpoint, or indistinguishably close? */
if ( AlmostEqualUlps( ckt->CKTtime, ckt->CKTbreaks[0], 100 ) || if ( AlmostEqualUlps( ckt->CKTtime, ckt->CKTbreaks[0], 100 ) ||
ckt->CKTbreaks[0] - ckt->CKTtime <= ckt->CKTdelmin) { ckt->CKTbreaks[0] - ckt->CKTtime <= ckt->CKTdelmin) {
/* first timepoint after a breakpoint - cut integration order */
/* and limit timestep to .1 times minimum of time to next breakpoint,
* and previous timestep
*/
/* First timepoint after a breakpoint: cut integration order
and limit timestep to .1 times minimum of time to next breakpoint,
and previous timestep. */
ckt->CKTorder = 1; ckt->CKTorder = 1;
#ifdef STEPDEBUG #ifdef STEPDEBUG
if( (ckt->CKTdelta > .1*ckt->CKTsaveDelta) || if( (ckt->CKTdelta > .1*ckt->CKTsaveDelta) ||
@ -612,11 +598,10 @@ resume:
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - Add Breakpoint stuff */
/* More Breakpoint stuff */
if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) { if(ckt->CKTtime + ckt->CKTdelta >= g_mif_info.breakpoint.current) {
/* If next time > temporary breakpoint, force it to the breakpoint */
/* And mark that timestep was set by temporary breakpoint */
/* If next time > temporary breakpoint, force it to the breakpoint,
and mark that timestep was set by temporary breakpoint */
ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTsaveDelta = ckt->CKTdelta;
ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime; ckt->CKTdelta = g_mif_info.breakpoint.current - ckt->CKTtime;
g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta; g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta;
@ -625,12 +610,8 @@ resume:
g_mif_info.breakpoint.last = 1.0e30; g_mif_info.breakpoint.last = 1.0e30;
} }
/* gtri - end - wbk - Add Breakpoint stuff */
/* gtri - begin - wbk - Modify Breakpoint stuff */
/* Throw out any permanent breakpoint with time <= current time or in the /* Throw out any permanent breakpoint with time <= current time or in the
* very near future, unless it the final stop break.
*/
very near future, unless it is the final stop break. */
#ifdef STEPDEBUG #ifdef STEPDEBUG
printf(" brk_pt: %g ckt_time: %g ckt_min_break: %g\n", printf(" brk_pt: %g ckt_time: %g ckt_min_break: %g\n",
ckt->CKTbreaks[0], ckt->CKTtime, ckt->CKTminBreak); ckt->CKTbreaks[0], ckt->CKTtime, ckt->CKTminBreak);
@ -654,8 +635,6 @@ resume:
ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime; ckt->CKTdelta = ckt->CKTbreaks[0] - ckt->CKTtime;
} }
/* gtri - end - wbk - Modify Breakpoint stuff */
#ifdef SHARED_MODULE #ifdef SHARED_MODULE
/* Either directly go to next time step, or modify ckt->CKTdelta depending on /* Either directly go to next time step, or modify ckt->CKTdelta depending on
synchronization requirements. sharedsync() returns 0. */ synchronization requirements. sharedsync() returns 0. */
@ -663,17 +642,16 @@ resume:
ckt->CKTdelmin, 0, &ckt->CKTstat->STATrejected, 0); ckt->CKTdelmin, 0, &ckt->CKTstat->STATrejected, 0);
#endif #endif
/* gtri - begin - wbk - Do event solution */
/* Do event solution */
if(ckt->evt->counts.num_insts > 0) { if(ckt->evt->counts.num_insts > 0) {
/* if time = 0 and op_alternate was specified as false during */
/* dcop analysis, call any changed instances to let them */
/* post their outputs with their associated delays */
/* If time = 0 and op_alternate was specified as false during
dcop analysis, call any changed instances to let them
post their outputs with their associated delays */
if((ckt->CKTtime == 0.0) && (! ckt->evt->options.op_alternate)) if((ckt->CKTtime == 0.0) && (! ckt->evt->options.op_alternate))
EVTiter(ckt); EVTiter(ckt);
/* while there are events on the queue with event time <= next */
/* While there are events on the queue with event time <= next */
/* projected analog time, process them */ /* projected analog time, process them */
while((g_mif_info.circuit.evt_step = EVTnext_time(ckt)) while((g_mif_info.circuit.evt_step = EVTnext_time(ckt))
<= (ckt->CKTtime + ckt->CKTdelta)) { <= (ckt->CKTtime + ckt->CKTdelta)) {
@ -685,14 +663,14 @@ resume:
EVTdequeue(ckt, g_mif_info.circuit.evt_step); EVTdequeue(ckt, g_mif_info.circuit.evt_step);
EVTiter(ckt); EVTiter(ckt);
/* If any instances have forced an earlier */
/* next analog time, cut the delta */
/* If any instances have forced an earlier
next analog time, cut the delta */
if(ckt->CKTbreaks[0] < g_mif_info.breakpoint.current) if(ckt->CKTbreaks[0] < g_mif_info.breakpoint.current)
if(ckt->CKTbreaks[0] > ckt->CKTtime + ckt->CKTminBreak) if(ckt->CKTbreaks[0] > ckt->CKTtime + ckt->CKTminBreak)
g_mif_info.breakpoint.current = ckt->CKTbreaks[0]; g_mif_info.breakpoint.current = ckt->CKTbreaks[0];
if(g_mif_info.breakpoint.current < ckt->CKTtime + ckt->CKTdelta) { if(g_mif_info.breakpoint.current < ckt->CKTtime + ckt->CKTdelta) {
/* Breakpoint must be > last accepted timepoint */
/* and >= current event time */
/* Breakpoint must be > last accepted timepoint
and >= current event time */
if(g_mif_info.breakpoint.current > ckt->CKTtime + ckt->CKTminBreak && if(g_mif_info.breakpoint.current > ckt->CKTtime + ckt->CKTminBreak &&
g_mif_info.breakpoint.current >= g_mif_info.circuit.evt_step) { g_mif_info.breakpoint.current >= g_mif_info.circuit.evt_step) {
ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTsaveDelta = ckt->CKTdelta;
@ -704,7 +682,6 @@ resume:
} /* end while next event time <= next analog time */ } /* end while next event time <= next analog time */
} /* end if there are event instances */ } /* end if there are event instances */
/* gtri - end - wbk - Do event solution */
#else /* no XSPICE */ #else /* no XSPICE */
#ifdef CLUSTER #ifdef CLUSTER
@ -739,14 +716,10 @@ resume:
redostep = 1; redostep = 1;
#endif #endif
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - wbk - 4/17/91 - Fix Berkeley bug */
/* This is needed here to allow CAPask to output currents */
/* during Transient analysis. A grep for CKTcurrentAnalysis */
/* indicates that it should not hurt anything else ... */
/* This is needed here to allow CAPask to output currents
during Transient analysis. */
ckt->CKTcurrentAnalysis = DOING_TRAN; ckt->CKTcurrentAnalysis = DOING_TRAN;
/* gtri - end - wbk - 4/17/91 - Fix Berkeley bug */
xspice_breakpoints_processed = 0; xspice_breakpoints_processed = 0;
#endif #endif
olddelta=ckt->CKTdelta; olddelta=ckt->CKTdelta;
@ -763,33 +736,25 @@ resume:
save_mode = ckt->CKTmode; save_mode = ckt->CKTmode;
save_order = ckt->CKTorder; save_order = ckt->CKTorder;
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - Add Breakpoint stuff */
/* Initialize temporary breakpoint to infinity */ /* Initialize temporary breakpoint to infinity */
g_mif_info.breakpoint.current = 1.0e30; g_mif_info.breakpoint.current = 1.0e30;
/* gtri - end - wbk - Add Breakpoint stuff */
/* gtri - begin - wbk - add convergence problem reporting flags */
/* Add convergence problem reporting flags */
/* delta is forced to equal delmin on last attempt near line 650 */ /* delta is forced to equal delmin on last attempt near line 650 */
if(ckt->CKTdelta <= ckt->CKTdelmin) if(ckt->CKTdelta <= ckt->CKTdelmin)
ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE; ckt->enh->conv_debug.last_NIiter_call = MIF_TRUE;
else else
ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE; ckt->enh->conv_debug.last_NIiter_call = MIF_FALSE;
/* gtri - begin - wbk - add convergence problem reporting flags */
/* gtri - begin - wbk - Call all hybrids */
/* gtri - begin - wbk - Set evt_step */
/* Call all hybrids */
/* Set evt_step */
if(ckt->evt->counts.num_insts > 0) { if(ckt->evt->counts.num_insts > 0) {
g_mif_info.circuit.evt_step = ckt->CKTtime; g_mif_info.circuit.evt_step = ckt->CKTtime;
} }
/* gtri - end - wbk - Set evt_step */
#endif #endif
/* Central solver step */
converged = NIiter(ckt,ckt->CKTtranMaxIter); converged = NIiter(ckt,ckt->CKTtranMaxIter);
ckt->CKTstat->STATtimePts ++; ckt->CKTstat->STATtimePts ++;
@ -805,6 +770,7 @@ resume:
return(converged); return(converged);
} }
/* If no convergence in Central solver step */
if(converged != 0) { if(converged != 0) {
#ifndef CLUSTER #ifndef CLUSTER
#ifndef SHARED_MODULE #ifndef SHARED_MODULE
@ -825,10 +791,12 @@ resume:
ckt->CKTorder = 1; ckt->CKTorder = 1;
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - Add Breakpoint stuff */
/* Add Breakpoint stuff */
} else if(g_mif_info.breakpoint.current < ckt->CKTtime) { } else if(g_mif_info.breakpoint.current < ckt->CKTtime) {
/* Force backup if temporary breakpoint is < current time */
/* Force backup if temporary breakpoint is < current time:
- save old delta
- retract time by old delta
- new delta by difference between by retracted time and breakpoint */
past_breakpoint: past_breakpoint:
ckt->CKTsaveDelta = ckt->CKTdelta; ckt->CKTsaveDelta = ckt->CKTdelta;
@ -841,11 +809,13 @@ resume:
ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN;
} }
ckt->CKTorder = 1; ckt->CKTorder = 1;
/* gtri - end - wbk - Add Breakpoint stuff */
#endif #endif
} else { } else {
/* If converged:
- go to next time step if this was the first time.
- If not the first time step, don not accept, but check the truncation errors,
and reduce delta accordingly, thenm redo the step, to bound the error. */
if (firsttime) { if (firsttime) {
#ifdef WANT_SENSE2 #ifdef WANT_SENSE2
if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){ if(ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & TRANSEN)){
@ -863,15 +833,16 @@ resume:
#endif #endif
firsttime = 0; firsttime = 0;
#if !defined CLUSTER && !defined SHARED_MODULE #if !defined CLUSTER && !defined SHARED_MODULE
goto nextTime; /* no check on
* first time point
*/
/* no check on first time point */
goto nextTime; /* line 373 */
#else #else
redostep = 0; redostep = 0;
goto chkStep; goto chkStep;
#endif #endif
} }
newdelta = ckt->CKTdelta; newdelta = ckt->CKTdelta;
/* Scan through all devices, estimate the truncation error,
and reduce the time step, if necessary.*/
error = CKTtrunc(ckt,&newdelta); error = CKTtrunc(ckt,&newdelta);
if(error) { if(error) {
UPDATE_STATS(DOING_TRAN); UPDATE_STATS(DOING_TRAN);
@ -893,13 +864,12 @@ resume:
EVTcall_hybrids(ckt); EVTcall_hybrids(ckt);
if (g_mif_info.breakpoint.current < ckt->CKTtime) { if (g_mif_info.breakpoint.current < ckt->CKTtime) {
/* A hybrid requested a breakpoint in the past. */ /* A hybrid requested a breakpoint in the past. */
goto past_breakpoint; goto past_breakpoint;
} }
} }
#endif #endif
if ((ckt->CKTorder == 1) && (ckt->CKTmaxOrder > 1)) { /* don't rise the order for backward Euler */
/* don't raise the order for backward Euler */
if ((ckt->CKTorder == 1) && (ckt->CKTmaxOrder > 1)) {
newdelta = ckt->CKTdelta; newdelta = ckt->CKTdelta;
ckt->CKTorder = 2; ckt->CKTorder = 2;
error = CKTtrunc(ckt, &newdelta); error = CKTtrunc(ckt, &newdelta);
@ -950,13 +920,16 @@ resume:
#endif #endif
#if !defined CLUSTER && !defined SHARED_MODULE #if !defined CLUSTER && !defined SHARED_MODULE
/* go to 650 - trapezoidal */
goto nextTime;
/* trapezoidal */
goto nextTime; /* line 373 */
#else #else
redostep = 0; redostep = 0;
goto chkStep; goto chkStep;
#endif #endif
} else { } else {
/* not (newdelta > .9 * ckt->CKTdelta): reject the step
- redo the time
- apply the new (reduced) delta */
#ifndef CLUSTER #ifndef CLUSTER
#ifndef SHARED_MODULE #ifndef SHARED_MODULE
ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta; ckt->CKTtime = ckt->CKTtime -ckt->CKTdelta;
@ -968,11 +941,13 @@ resume:
ckt->CKTdelta = newdelta; ckt->CKTdelta = newdelta;
#ifdef STEPDEBUG #ifdef STEPDEBUG
(void)printf( (void)printf(
"delta set to truncation error result:point rejected\n");
"delta set to truncation error result: point rejected\n");
#endif #endif
} }
} }
/* Set the new delta to delmin (minimum delta allowed). However:
If the new delta has been less than the minimum delta
for the second time, bail out with 'Timestep too small'. */
if (ckt->CKTdelta <= ckt->CKTdelmin) { if (ckt->CKTdelta <= ckt->CKTdelmin) {
if (olddelta > ckt->CKTdelmin) { if (olddelta > ckt->CKTdelmin) {
ckt->CKTdelta = ckt->CKTdelmin; ckt->CKTdelta = ckt->CKTdelmin;
@ -990,8 +965,7 @@ resume:
} }
} }
#ifdef XSPICE #ifdef XSPICE
/* gtri - begin - wbk - Do event backup */
/* Do event backup */
if(ckt->evt->counts.num_insts > 0) { if(ckt->evt->counts.num_insts > 0) {
#ifdef SHARED_MODULE #ifdef SHARED_MODULE
double discard_start_time = ckt->CKTtime + ckt->CKTdelta; double discard_start_time = ckt->CKTtime + ckt->CKTdelta;
@ -1011,7 +985,6 @@ resume:
#endif #endif
} }
/* gtri - end - wbk - Do event backup */
#endif #endif
#ifdef CLUSTER #ifdef CLUSTER
chkStep: chkStep:

Loading…
Cancel
Save