Fix bugs found while investigating Bug #585 (convergence failure only
on Linux). In dctran.c make it impossible for a transient simulation to run far past its end time and fix an infinite loop attempting to remove the automatically-inserted ending breakpoint. In outitf.c fix memory corruption if the simulation does over-run (change suggested by Holger Vogt).
This commit is contained in:
parent
e5c162f126
commit
aaa6798950
|
|
@ -1150,11 +1150,17 @@ vlength2delta(int len)
|
||||||
double timerel = ft_curckt->ci_ckt->CKTtime / ft_curckt->ci_ckt->CKTfinalTime;
|
double timerel = ft_curckt->ci_ckt->CKTtime / ft_curckt->ci_ckt->CKTfinalTime;
|
||||||
/* return an estimate of the appropriate number of time points, if more than 20% of
|
/* return an estimate of the appropriate number of time points, if more than 20% of
|
||||||
the anticipated total time has passed */
|
the anticipated total time has passed */
|
||||||
if (timerel > 0.2)
|
if (timerel > 0.2) {
|
||||||
return (int)(len / timerel) - len + 1;
|
int proposed = (int)(len / timerel) - len + 1;
|
||||||
/* If not, just double the available memory */
|
|
||||||
else
|
if (proposed > 0)
|
||||||
|
return proposed;
|
||||||
|
return 16; // Probably enough as past end of simulation.
|
||||||
|
} else {
|
||||||
|
/* If not, just double the available memory */
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* op */
|
/* op */
|
||||||
else if (ft_curckt->ci_ckt->CKTmode & MODEDCOP) {
|
else if (ft_curckt->ci_ckt->CKTmode & MODEDCOP) {
|
||||||
|
|
|
||||||
|
|
@ -466,9 +466,8 @@ DCtran(CKTcircuit *ckt,
|
||||||
/* gtri - end - wbk - Update event queues/data for accepted timepoint */
|
/* gtri - end - wbk - Update event queues/data for accepted timepoint */
|
||||||
#endif
|
#endif
|
||||||
ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter;
|
ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter;
|
||||||
if(check_autostop("tran") ||
|
if (check_autostop("tran") ||
|
||||||
fabs(ckt->CKTtime - ckt->CKTfinalTime) < ckt->CKTminBreak ||
|
ckt->CKTfinalTime - ckt->CKTtime < ckt->CKTminBreak) {
|
||||||
AlmostEqualUlps( ckt->CKTtime, ckt->CKTfinalTime, 100 ) ) {
|
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
printf(" done: time is %g, final time is %g, and tol is %g\n",
|
printf(" done: time is %g, final time is %g, and tol is %g\n",
|
||||||
ckt->CKTtime, ckt->CKTfinalTime, ckt->CKTminBreak);
|
ckt->CKTtime, ckt->CKTfinalTime, ckt->CKTminBreak);
|
||||||
|
|
@ -590,21 +589,24 @@ resume:
|
||||||
/* gtri - end - wbk - Add Breakpoint stuff */
|
/* gtri - end - wbk - Add Breakpoint stuff */
|
||||||
|
|
||||||
/* gtri - begin - wbk - Modify Breakpoint stuff */
|
/* gtri - begin - wbk - Modify Breakpoint stuff */
|
||||||
/* Throw out any permanent breakpoint times <= current time */
|
/* Throw out any permanent breakpoint with time <= current time or in the
|
||||||
for (;;) {
|
* very near future, unless it the final stop break.
|
||||||
|
*/
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
printf(" brk_pt: %g ckt_time: %g ckt_min_break: %g\n",ckt->CKTbreaks[0], ckt->CKTtime, ckt->CKTminBreak);
|
printf(" brk_pt: %g ckt_time: %g ckt_min_break: %g\n",
|
||||||
|
ckt->CKTbreaks[0], ckt->CKTtime, ckt->CKTminBreak);
|
||||||
#endif
|
#endif
|
||||||
if(AlmostEqualUlps(ckt->CKTbreaks[0], ckt->CKTtime, 100) ||
|
while ((ckt->CKTbreaks[0] <= ckt->CKTtime + ckt->CKTminBreak ||
|
||||||
ckt->CKTbreaks[0] <= ckt->CKTtime + ckt->CKTminBreak) {
|
AlmostEqualUlps(ckt->CKTbreaks[0], ckt->CKTtime, 100)) &&
|
||||||
|
ckt->CKTbreaks[0] < ckt->CKTfinalTime) {
|
||||||
#ifdef STEPDEBUG
|
#ifdef STEPDEBUG
|
||||||
printf("throwing out permanent breakpoint times <= current time (brk pt: %g)\n",ckt->CKTbreaks[0]);
|
printf("throwing out permanent breakpoint times <= current time "
|
||||||
printf(" ckt_time: %g ckt_min_break: %g\n",ckt->CKTtime, ckt->CKTminBreak);
|
"(brk pt: %g)\n",
|
||||||
|
ckt->CKTbreaks[0]);
|
||||||
|
printf(" ckt_time: %g ckt_min_break: %g\n",
|
||||||
|
ckt->CKTtime, ckt->CKTminBreak);
|
||||||
#endif
|
#endif
|
||||||
CKTclrBreak(ckt);
|
CKTclrBreak(ckt);
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Force the breakpoint if appropriate */
|
/* Force the breakpoint if appropriate */
|
||||||
if(ckt->CKTtime + ckt->CKTdelta > ckt->CKTbreaks[0]) {
|
if(ckt->CKTtime + ckt->CKTdelta > ckt->CKTbreaks[0]) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue