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:
Giles Atkinson 2022-06-08 10:00:24 +01:00 committed by Holger Vogt
parent e5c162f126
commit aaa6798950
2 changed files with 26 additions and 18 deletions

View File

@ -1150,11 +1150,17 @@ vlength2delta(int len)
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
the anticipated total time has passed */
if (timerel > 0.2)
return (int)(len / timerel) - len + 1;
/* If not, just double the available memory */
else
if (timerel > 0.2) {
int proposed = (int)(len / timerel) - len + 1;
if (proposed > 0)
return proposed;
return 16; // Probably enough as past end of simulation.
} else {
/* If not, just double the available memory */
return len;
}
}
/* op */
else if (ft_curckt->ci_ckt->CKTmode & MODEDCOP) {

View File

@ -466,9 +466,8 @@ DCtran(CKTcircuit *ckt,
/* gtri - end - wbk - Update event queues/data for accepted timepoint */
#endif
ckt->CKTstat->STAToldIter = ckt->CKTstat->STATnumIter;
if(check_autostop("tran") ||
fabs(ckt->CKTtime - ckt->CKTfinalTime) < ckt->CKTminBreak ||
AlmostEqualUlps( ckt->CKTtime, ckt->CKTfinalTime, 100 ) ) {
if (check_autostop("tran") ||
ckt->CKTfinalTime - ckt->CKTtime < ckt->CKTminBreak) {
#ifdef STEPDEBUG
printf(" done: time is %g, final time is %g, and tol is %g\n",
ckt->CKTtime, ckt->CKTfinalTime, ckt->CKTminBreak);
@ -590,21 +589,24 @@ resume:
/* gtri - end - wbk - Add Breakpoint stuff */
/* gtri - begin - wbk - Modify Breakpoint stuff */
/* Throw out any permanent breakpoint times <= current time */
for (;;) {
/* Throw out any permanent breakpoint with time <= current time or in the
* very near future, unless it the final stop break.
*/
#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
if(AlmostEqualUlps(ckt->CKTbreaks[0], ckt->CKTtime, 100) ||
ckt->CKTbreaks[0] <= ckt->CKTtime + ckt->CKTminBreak) {
while ((ckt->CKTbreaks[0] <= ckt->CKTtime + ckt->CKTminBreak ||
AlmostEqualUlps(ckt->CKTbreaks[0], ckt->CKTtime, 100)) &&
ckt->CKTbreaks[0] < ckt->CKTfinalTime) {
#ifdef STEPDEBUG
printf("throwing out permanent breakpoint times <= current time (brk pt: %g)\n",ckt->CKTbreaks[0]);
printf(" ckt_time: %g ckt_min_break: %g\n",ckt->CKTtime, ckt->CKTminBreak);
printf("throwing out permanent breakpoint times <= current time "
"(brk pt: %g)\n",
ckt->CKTbreaks[0]);
printf(" ckt_time: %g ckt_min_break: %g\n",
ckt->CKTtime, ckt->CKTminBreak);
#endif
CKTclrBreak(ckt);
} else {
break;
}
CKTclrBreak(ckt);
}
/* Force the breakpoint if appropriate */
if(ckt->CKTtime + ckt->CKTdelta > ckt->CKTbreaks[0]) {