From bc12b325420a8b0f1d8c7f863a15e1f17c30cf87 Mon Sep 17 00:00:00 2001 From: rlar Date: Fri, 30 Mar 2018 21:35:56 +0200 Subject: [PATCH] spicelib/devices/{sw,csw}, fix CKTtime += CKTdelmin issue don't CKTtrunc when we approach the projected switch point by more than 100 * DBL_EPSILON * CKTtime to make sure VSRC / ISRC has still room to produce values. FIXME, dctran.c might suffer from a similiar, non sw/csw related issue. it might be necessairy to generally replace CKTdelmin by MAX(CKTdelmin, HEADROOM * DBL_EPSILON * CKTtime) --- src/spicelib/devices/csw/cswtrunc.c | 5 +++++ src/spicelib/devices/sw/swtrunc.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/spicelib/devices/csw/cswtrunc.c b/src/spicelib/devices/csw/cswtrunc.c index 7662b12a3..66bd7e02f 100644 --- a/src/spicelib/devices/csw/cswtrunc.c +++ b/src/spicelib/devices/csw/cswtrunc.c @@ -17,6 +17,7 @@ CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) CSWmodel *model = (CSWmodel *) inModel; CSWinstance *here; double lastChange, maxChange, maxStep, ref; + const double reltime = 100 * DBL_EPSILON; for (; model; model = CSWnextModel(model)) for (here = CSWinstances(model); here; here = CSWnextInstance(here)) { @@ -29,6 +30,8 @@ CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) maxChange = (ref - ckt->CKTstate0[here->CSWctrlvalue]) * 0.75; maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0]; + if (maxStep < ckt->CKTtime * reltime) + maxStep = ckt->CKTtime * reltime; if (maxStep < ckt->CKTdelmin) maxStep = ckt->CKTdelmin; if (*timeStep > maxStep) @@ -40,6 +43,8 @@ CSWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) maxChange = (ref - ckt->CKTstate0[here->CSWctrlvalue]) * 0.75; maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0]; + if (maxStep < ckt->CKTtime * reltime) + maxStep = ckt->CKTtime * reltime; if (maxStep < ckt->CKTdelmin) maxStep = ckt->CKTdelmin; if (*timeStep > maxStep) diff --git a/src/spicelib/devices/sw/swtrunc.c b/src/spicelib/devices/sw/swtrunc.c index ef3165322..f29199067 100644 --- a/src/spicelib/devices/sw/swtrunc.c +++ b/src/spicelib/devices/sw/swtrunc.c @@ -17,6 +17,7 @@ SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) SWmodel *model = (SWmodel *) inModel; SWinstance *here; double lastChange, maxChange, maxStep, ref; + const double reltime = 100 * DBL_EPSILON; for (; model; model = SWnextModel(model)) for (here = SWinstances(model); here; here = SWnextInstance(here)) { @@ -29,6 +30,8 @@ SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) maxChange = (ref - ckt->CKTstate0[here->SWctrlvalue]) * 0.75; maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0]; + if (maxStep < ckt->CKTtime * reltime) + maxStep = ckt->CKTtime * reltime; if (maxStep < ckt->CKTdelmin) maxStep = ckt->CKTdelmin; if (*timeStep > maxStep) @@ -40,6 +43,8 @@ SWtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep) maxChange = (ref - ckt->CKTstate0[here->SWctrlvalue]) * 0.75; maxStep = maxChange / lastChange * ckt->CKTdeltaOld[0]; + if (maxStep < ckt->CKTtime * reltime) + maxStep = ckt->CKTtime * reltime; if (maxStep < ckt->CKTdelmin) maxStep = ckt->CKTdelmin; if (*timeStep > maxStep)