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)
This commit is contained in:
rlar 2018-03-30 21:35:56 +02:00
parent f159708362
commit bc12b32542
2 changed files with 10 additions and 0 deletions

View File

@ -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)

View File

@ -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)