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;
|
||||
/* 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) {
|
||||
|
|
|
|||
|
|
@ -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]) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue