From 99bddad73676412c3e2d76e7b92f9f8ba88e55eb Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 27 Dec 2025 15:33:11 +0100 Subject: [PATCH] Enable optional voltage based truncation error correction. This is selectable as 'option newtrunc' (--enable-Predictor is required) Remove --enable-NEWTRUNC Add three option parameters (default): lteTrtol (500), lteReltol (1e-3), lteAbstol (1e-6) Add new error function for TRAP, similar to GEAR (tentative, to be improved), in ckttrun.c Enable PREDICTOR as default with Visual Studio. --- configure.ac | 8 - src/frontend/com_option.c | 17 +- src/frontend/misccoms.c | 3 - src/include/ngspice/cktdefs.h | 9 +- src/include/ngspice/optdefs.h | 4 + src/include/ngspice/tskdefs.h | 4 +- src/spicelib/analysis/cktdojob.c | 7 +- src/spicelib/analysis/cktntask.c | 11 +- src/spicelib/analysis/cktsopt.c | 28 ++- src/spicelib/analysis/ckttrunc.c | 280 +++++++++++++++----------- src/spicelib/devices/devsup.c | 15 +- src/xspice/icm/analog/delay/cfunc.mod | 9 +- visualc/src/include/ngspice/config.h | 5 +- 13 files changed, 229 insertions(+), 171 deletions(-) diff --git a/configure.ac b/configure.ac index 1c5f7aafc..6ecd1a137 100644 --- a/configure.ac +++ b/configure.ac @@ -229,10 +229,6 @@ AC_ARG_ENABLE([predictor], AC_ARG_ENABLE([newpred], [AS_HELP_STRING([--enable-newpred], [Enable NEWPRED whatever it is(?)])]) -# --enable-newtrunc: define NEWTRUNC for the code -AC_ARG_ENABLE([newtrunc], - [AS_HELP_STRING([--enable-newtrunc], [Enable, how we want extrapolate capacitances.])]) - # --enable-sense2: define WANT_SENSE2 for the code AC_ARG_ENABLE([sense2], [AS_HELP_STRING([--enable-sense2], [Use spice2 sensitivity analysis.])]) @@ -1044,10 +1040,6 @@ if test "x$enable_newpred" = xyes; then AC_DEFINE([NEWPRED], [], [Define if you want to discover :)]) AC_MSG_RESULT([NEWPRED enabled]) fi -if test "x$enable_newtrunc" = xyes; then - AC_DEFINE([NEWTRUNC], [], [Do not trigger unwanted traps by default]) - AC_MSG_RESULT([New truncation error calculation enabled]) -fi if test "x$enable_experimental" = xyes; then AC_DEFINE([EXPERIMENTAL_CODE], [], [Define if we want some experimental code]) AC_MSG_RESULT([EXPERIMENTAL_CODE enabled]) diff --git a/src/frontend/com_option.c b/src/frontend/com_option.c index 5ded8146e..9e9dad477 100644 --- a/src/frontend/com_option.c +++ b/src/frontend/com_option.c @@ -77,13 +77,16 @@ com_option(wordlist *wl) printf("gminsteps = %d\n", circuit->CKTnumGminSteps); printf("srcsteps = %d\n", circuit->CKTnumSrcSteps); - printf("\nTruncation error correction:\n"); - printf("trtol = %f\n", circuit->CKTtrtol); -#ifdef NEWTRUNC - printf("ltereltol = %g\n", circuit->CKTlteReltol); - printf("lteabstol = %g\n", circuit->CKTlteAbstol); -#endif /* NEWTRUNC */ - + if (circuit->CKTnewtrunc) { + printf("\nTruncation error correction, voltage based, is selected:\n"); + printf("ltereltol = %g\n", circuit->CKTlteReltol); + printf("lteabstol = %g\n", circuit->CKTlteAbstol); + printf("ltetrtol = %g\n", circuit->CKTlteTrtol); + } + else { + printf("\nTruncation error correction, charge based, is selected:\n"); + printf("trtol = %f\n", circuit->CKTtrtol); + } printf("\nConductances:\n"); printf("gmin (devices) = %g\n", circuit->CKTgmin); printf("diaggmin (stepping) = %g\n", circuit->CKTdiagGmin); diff --git a/src/frontend/misccoms.c b/src/frontend/misccoms.c index b53a7c1e8..c3efbb9cb 100644 --- a/src/frontend/misccoms.c +++ b/src/frontend/misccoms.c @@ -274,9 +274,6 @@ com_version(wordlist *wl) #ifdef PREDICTOR fprintf(cp_out, "** --enable-predictor\n"); #endif -#ifdef NEWTRUNC - fprintf(cp_out, "** --enable-newtrunc\n"); -#endif #ifdef WANT_SENSE2 fprintf(cp_out, "** --enable-sense2\n"); #endif diff --git a/src/include/ngspice/cktdefs.h b/src/include/ngspice/cktdefs.h index 0610b34b1..c12bf91cf 100644 --- a/src/include/ngspice/cktdefs.h +++ b/src/include/ngspice/cktdefs.h @@ -216,11 +216,10 @@ struct CKTcircuit { double CKTreltol; /* --- */ double CKTchgtol; /* --- */ double CKTvoltTol; /* --- */ - /* What is this define for ? */ -#ifdef NEWTRUNC - double CKTlteReltol; - double CKTlteAbstol; -#endif /* NEWTRUNC */ + double CKTlteReltol; /* relative error in voltage based truncation error estimation */ + double CKTlteAbstol; /* absolute error in voltage based truncation error estimation */ + double CKTlteTrtol; /* scaling time step in voltage based truncation error estimation */ + int CKTnewtrunc; /* enable lte (local truncation error) based on voltages */ double CKTgmin; /* .options GMIN */ double CKTgshunt; /* .options RSHUNT */ double CKTcshunt; /* .options CSHUNT */ diff --git a/src/include/ngspice/optdefs.h b/src/include/ngspice/optdefs.h index 3455a2454..25d61eebd 100644 --- a/src/include/ngspice/optdefs.h +++ b/src/include/ngspice/optdefs.h @@ -132,6 +132,10 @@ enum { OPT_KLU_MEMGROW_FACTOR, #endif + OPT_LTERELTOL, + OPT_LTEABSTOL, + OPT_LTETRTOL, + OPT_NEWTRUNC, }; #ifdef XSPICE diff --git a/src/include/ngspice/tskdefs.h b/src/include/ngspice/tskdefs.h index 9d59bd4b4..f59ccec9b 100644 --- a/src/include/ngspice/tskdefs.h +++ b/src/include/ngspice/tskdefs.h @@ -48,10 +48,10 @@ struct TSKtask { double TSKreltol; double TSKchgtol; double TSKvoltTol; -#ifdef NEWTRUNC double TSKlteReltol; double TSKlteAbstol; -#endif /* NEWTRUNC */ + double TSKlteTrtol; + unsigned int TSKnewtrunc:1; /* voltage controlled truncation */ double TSKgmin; double TSKgshunt; /* shunt conductance (CKTdiagGmin) */ double TSKcshunt; /* shunt capacitor to ground */ diff --git a/src/spicelib/analysis/cktdojob.c b/src/spicelib/analysis/cktdojob.c index 627626a2e..b78ca5ff6 100644 --- a/src/spicelib/analysis/cktdojob.c +++ b/src/spicelib/analysis/cktdojob.c @@ -114,14 +114,17 @@ CKTdoJob(CKTcircuit* ckt, int reset, TSKtask* task) ckt->CKTkluMemGrowFactor = task->TSKkluMemGrowFactor ; #endif -#ifdef NEWTRUNC ckt->CKTlteReltol = task->TSKlteReltol; ckt->CKTlteAbstol = task->TSKlteAbstol; -#endif /* NEWTRUNC */ + ckt->CKTlteTrtol = task->TSKlteTrtol; + ckt->CKTnewtrunc = task->TSKnewtrunc; fprintf(stdout, "Doing analysis at TEMP = %f and TNOM = %f\n\n", ckt->CKTtemp - CONSTCtoK, ckt->CKTnomTemp - CONSTCtoK); + if (ckt->CKTnewtrunc) + fprintf(stdout, "Note: Voltage based truncation error correction selected\n"); + /* call altermod and alter on device and model parameters assembled in devtlist and modtlist (if using temper) because we have a new temperature */ inp_evaluate_temper(ft_curckt); diff --git a/src/spicelib/analysis/cktntask.c b/src/spicelib/analysis/cktntask.c index be681b2b6..e143798cf 100644 --- a/src/spicelib/analysis/cktntask.c +++ b/src/spicelib/analysis/cktntask.c @@ -82,11 +82,10 @@ CKTnewTask(CKTcircuit *ckt, TSKtask **taskPtr, IFuid taskName, TSKtask **defPtr) tsk->TSKkluMemGrowFactor = def->TSKkluMemGrowFactor ; #endif -#ifdef NEWTRUNC tsk->TSKlteReltol = def->TSKlteReltol; tsk->TSKlteAbstol = def->TSKlteAbstol; -#endif - + tsk->TSKlteTrtol = def->TSKlteTrtol; + tsk->TSKnewtrunc = def->TSKnewtrunc; } else { #endif /*CDHW*/ @@ -98,11 +97,11 @@ CKTnewTask(CKTcircuit *ckt, TSKtask **taskPtr, IFuid taskName, TSKtask **defPtr) tsk->TSKreltol = 1e-3; tsk->TSKchgtol = 1e-14; tsk->TSKvoltTol = 1e-6; -#ifdef NEWTRUNC tsk->TSKlteReltol = 1e-3; tsk->TSKlteAbstol = 1e-6; -#endif - tsk->TSKtrtol = 7; + tsk->TSKlteTrtol = 500.; + tsk->TSKnewtrunc = 0; + tsk->TSKtrtol = 7.; tsk->TSKbypass = 0; tsk->TSKtranMaxIter = 10; tsk->TSKdcMaxIter = 100; diff --git a/src/spicelib/analysis/cktsopt.c b/src/spicelib/analysis/cktsopt.c index 0c1f723e1..8a1e60b30 100644 --- a/src/spicelib/analysis/cktsopt.c +++ b/src/spicelib/analysis/cktsopt.c @@ -187,7 +187,24 @@ CKTsetOpt(CKTcircuit *ckt, JOB *anal, int opt, IFvalue *val) task->TSKkluMemGrowFactor = (val->rValue == 1.2); break; #endif - + case OPT_LTERELTOL: + task->TSKlteReltol = val->rValue; + break; + case OPT_LTEABSTOL: + task->TSKlteAbstol = val->rValue; + break; + case OPT_LTETRTOL: + task->TSKlteTrtol = val->rValue; + break; + case OPT_NEWTRUNC: +#ifdef PREDICTOR + task->TSKnewtrunc = (val->iValue != 0); +#else + task->TSKnewtrunc = 0; + fprintf(stderr, "Warning: Option 'newtrunc' ignored,\n" + " compilation with preprocessor flag 'PREDICTOR' is required.\n"); +#endif + break; /* gtri - begin - wbk - add new options */ #ifdef XSPICE case OPT_EVT_MAX_OP_ALTER: @@ -230,7 +247,7 @@ CKTsetOpt(CKTcircuit *ckt, JOB *anal, int opt, IFvalue *val) ckt->enh->rshunt_data.gshunt = 1.0 / val->rValue; } else { - printf("WARNING - Rshunt option too small. Ignored.\n"); + fprintf(stderr, "WARNING - Rshunt option too small. Ignored.\n"); } break; #endif @@ -353,9 +370,14 @@ static IFparm OPTtbl[] = { { "klu", OPT_KLU, IF_SET|IF_FLAG, "Set KLU as Direct Linear Solver" }, { "klu_memgrow_factor", OPT_KLU_MEMGROW_FACTOR, IF_SET|IF_REAL, - "KLU Memory Grow Factor (default is 1.2)" } + "KLU Memory Grow Factor (default is 1.2)" }, #endif + { "ltereltol", OPT_LTERELTOL,IF_SET | IF_REAL ,"Relative error tolerence" }, + { "lteabstol", OPT_LTEABSTOL,IF_SET | IF_REAL,"Absolute error tolerence" }, + { "ltetrtol", OPT_LTETRTOL,IF_SET | IF_REAL,"Truncation error overestimation factor" }, + { "newtrunc", OPT_NEWTRUNC,IF_SET | IF_FLAG,"voltage controlled truncation" } + }; int OPTcount = NUMELEMS(OPTtbl); diff --git a/src/spicelib/analysis/ckttrunc.c b/src/spicelib/analysis/ckttrunc.c index 36d3b7464..2d2e0e866 100644 --- a/src/spicelib/analysis/ckttrunc.c +++ b/src/spicelib/analysis/ckttrunc.c @@ -15,173 +15,213 @@ Author: 1985 Thomas L. Quarles #include "ngspice/devdefs.h" #include "ngspice/sperror.h" - +//#define STEPDEBUG int CKTtrunc(CKTcircuit *ckt, double *timeStep) { -#ifndef NEWTRUNC - int i; - double timetemp; + if (ckt->CKTnewtrunc == 0) { + int i; + double timetemp; #ifdef STEPDEBUG - double debugtemp; + double debugtemp; #endif /* STEPDEBUG */ - double startTime; - int error = OK; + double startTime; + int error = OK; - startTime = SPfrontEnd->IFseconds(); + startTime = SPfrontEnd->IFseconds(); - timetemp = HUGE; - for (i=0;iDEVtrunc && ckt->CKThead[i]) { + timetemp = HUGE; + for (i = 0; i < DEVmaxnum; i++) { + if (DEVices[i] && DEVices[i]->DEVtrunc && ckt->CKThead[i]) { #ifdef STEPDEBUG - debugtemp = timetemp; + debugtemp = timetemp; #endif /* STEPDEBUG */ - error = DEVices[i]->DEVtrunc (ckt->CKThead[i], ckt, &timetemp); - if(error) { - ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - - startTime; - return(error); - } + error = DEVices[i]->DEVtrunc(ckt->CKThead[i], ckt, &timetemp); + if (error) { + ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() + - startTime; + return(error); + } #ifdef STEPDEBUG - if(debugtemp != timetemp) { - printf("timestep cut by device type %s from %g to %g\n", + if (debugtemp != timetemp) { + printf("timestep cut by device type %s from %g to %g\n", DEVices[i]->DEVpublic.name, debugtemp, timetemp); - } + } #endif /* STEPDEBUG */ + } } + *timeStep = MIN(2 * *timeStep, timetemp); + + ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime; + return(OK); } - *timeStep = MIN(2 * *timeStep,timetemp); + else { + int i; + CKTnode* node; + double timetemp; + double tmp; + double diff; + double tol; + double startTime; + int size; - ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime; - return(OK); -#else /* NEWTRUNC */ - int i; - CKTnode *node; - double timetemp; - double tmp; - double diff; - double tol; - double startTime; - int size; + startTime = SPfrontEnd->IFseconds(); - startTime = SPfrontEnd->IFseconds(); + timetemp = HUGE; + size = SMPmatSize(ckt->CKTmatrix); +#ifdef STEPDEBUG + printf("\nNEWTRUNC at time %g, delta %g\n", ckt->CKTtime, ckt->CKTdeltaOld[0]); +#endif + node = ckt->CKTnodes; + switch (ckt->CKTintegrateMethod) { - timetemp = HUGE; - size = SMPmatSize(ckt->CKTmatrix); + case TRAPEZOIDAL: #ifdef STEPDEBUG - printf("at time %g, delta %g\n",ckt->CKTtime,ckt->CKTdeltaOld[0]); + printf("TRAP, Order is %d\n", ckt->CKTorder); #endif - node = ckt->CKTnodes; - switch(ckt->CKTintegrateMethod) { - - case TRAPEZOIDAL: - switch(ckt->CKTorder) { - case 1: - for(i=1;iCKTrhs[i]),fabs(ckt->CKTpred[i]))* - ckt->CKTlteReltol+ckt->CKTlteAbstol; - node = node->next; - if(node->type!= SP_VOLTAGE) continue; - diff = ckt->CKTrhs[i]-ckt->CKTpred[i]; + switch (ckt->CKTorder) { + case 1: + for (i = 1; i < size; i++) { + tol = MAX(fabs(ckt->CKTrhs[i]), fabs(ckt->CKTpred[i])) * + ckt->CKTlteReltol + ckt->CKTlteAbstol; + node = node->next; + if (node->type != SP_VOLTAGE) continue; + diff = ckt->CKTrhs[i] - ckt->CKTpred[i]; #ifdef STEPDEBUG - printf("%s: cor=%g, pred=%g ",node->name, - ckt->CKTrhs[i],ckt->CKTpred[i]); + printf("%s: cor=%g, pred=%g ", node->name, + ckt->CKTrhs[i], ckt->CKTpred[i]); #endif - if(diff != 0) { - tmp = ckt->CKTtrtol * tol * 2 /diff; - tmp = ckt->CKTdeltaOld[0]*sqrt(fabs(tmp)); - timetemp = MIN(timetemp,tmp); + if (diff != 0) { + // if (!AlmostEqualUlps(diff, 0, 10)) { + tmp = ckt->CKTlteTrtol * tol * 2 / diff; + tmp = ckt->CKTdeltaOld[0] * fabs(tmp); + timetemp = MIN(timetemp, tmp); #ifdef STEPDEBUG - printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp); + printf("tol = %g, diff = %g, h->%g\n", tol, diff, tmp); #endif - } else { + } + else { #ifdef STEPDEBUG - printf("diff is 0\n"); + printf("diff is 0\n"); #endif + } } + break; + case 2: + for (i = 1; i < size; i++) { + tol = MAX(fabs(ckt->CKTrhs[i]), fabs(ckt->CKTpred[i])) * + ckt->CKTlteReltol + ckt->CKTlteAbstol; + node = node->next; + if (node->type != SP_VOLTAGE) continue; + diff = ckt->CKTrhs[i] - ckt->CKTpred[i]; +#ifdef STEPDEBUG + printf("%s: cor=%g, pred=%g ", node->name, + ckt->CKTrhs[i], ckt->CKTpred[i]); +#endif + if (diff != 0) { + // if (!AlmostEqualUlps(diff, 0, 10)) { + tmp = ckt->CKTlteTrtol * tol * 2 / diff; + tmp = ckt->CKTdeltaOld[0] * sqrt(fabs(tmp)); + timetemp = MIN(timetemp, tmp); +#ifdef STEPDEBUG + printf("tol = %g, diff = %g, h->%g\n", tol, diff, tmp); +#endif + } + else { +#ifdef STEPDEBUG + printf("diff is 0\n"); +#endif + } + } + break; + /* case 2: + for(i=1;iCKTrhs[i]),fabs(ckt->CKTpred[i]))* + ckt->CKTlteReltol+ckt->CKTlteAbstol; + node = node->next; + if(node->type!= SP_VOLTAGE) continue; + diff = ckt->CKTrhs[i]-ckt->CKTpred[i]; + #ifdef STEPDEBUG + printf("%s: cor=%g, pred=%g ",node->name,ckt->CKTrhs[i], + ckt->CKTpred[i]); + #endif + if(diff != 0) { + // if(!AlmostEqualUlps(diff, 0, 10)) { + tmp = tol * ckt->CKTlteTrtol * (ckt->CKTdeltaOld[0] + ckt->CKTdeltaOld[1]) + / (diff * ckt->CKTdelta); + tmp = fabs(tmp); + tmp = exp(log(tmp) / 3); + tmp *= ckt->CKTdelta; + timetemp = MIN(timetemp,tmp); + #ifdef STEPDEBUG + printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp); + #endif + } else { + #ifdef STEPDEBUG + printf("diff is 0\n"); + #endif + } + } + break; */ + default: + return(E_ORDER); + break; + } break; - case 2: - for(i=1;iCKTrhs[i]),fabs(ckt->CKTpred[i]))* - ckt->CKTlteReltol+ckt->CKTlteAbstol; - node = node->next; - if(node->type!= SP_VOLTAGE) continue; - diff = ckt->CKTrhs[i]-ckt->CKTpred[i]; + + case GEAR: { #ifdef STEPDEBUG - printf("%s: cor=%g, pred=%g ",node->name,ckt->CKTrhs[i], - ckt->CKTpred[i]); + printf("GEAR, Order is %d\n", ckt->CKTorder); #endif - if(diff != 0) { - tmp = ckt->CKTdeltaOld[0]*ckt->CKTtrtol * tol * 3 * - (ckt->CKTdeltaOld[0]+ckt->CKTdeltaOld[1])/diff; - tmp = fabs(tmp); - timetemp = MIN(timetemp,tmp); -#ifdef STEPDEBUG - printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp); -#endif - } else { -#ifdef STEPDEBUG - printf("diff is 0\n"); -#endif - } + double delsum = 0; + for (i = 0; i <= ckt->CKTorder; i++) { + delsum += ckt->CKTdeltaOld[i]; } - break; - default: - return(E_ORDER); - break; - - } - break; - - case GEAR: { - double delsum=0; - for(i=0;i<=ckt->CKTorder;i++) { - delsum += ckt->CKTdeltaOld[i]; - } - for(i=1;inext; - if(node->type!= SP_VOLTAGE) continue; - tol = MAX( fabs(ckt->CKTrhs[i]),fabs(ckt->CKTpred[i]))* - ckt->CKTlteReltol+ckt->CKTlteAbstol; - diff = (ckt->CKTrhs[i]-ckt->CKTpred[i]); + for (i = 1; i < size; i++) { + node = node->next; + if (node->type != SP_VOLTAGE) continue; + tol = MAX(fabs(ckt->CKTrhs[i]), fabs(ckt->CKTpred[i])) * + ckt->CKTlteReltol + ckt->CKTlteAbstol; + diff = (ckt->CKTrhs[i] - ckt->CKTpred[i]); #ifdef STEPDEBUG - printf("%s: cor=%g, pred=%g ",node->name,ckt->CKTrhs[i], + printf("%s: cor=%g, pred=%g ", node->name, ckt->CKTrhs[i], ckt->CKTpred[i]); #endif - if(diff != 0) { - tmp = tol*ckt->CKTtrtol*delsum/(diff*ckt->CKTdelta); - tmp = fabs(tmp); - switch(ckt->CKTorder) { + if (diff != 0) { + tmp = tol * ckt->CKTlteTrtol * delsum / (diff * ckt->CKTdelta); + tmp = fabs(tmp); + switch (ckt->CKTorder) { case 0: break; case 1: tmp = sqrt(tmp); break; default: - tmp = exp(log(tmp)/(ckt->CKTorder+1)); + tmp = exp(log(tmp) / (ckt->CKTorder + 1)); break; + } + tmp *= ckt->CKTdelta; + timetemp = MIN(timetemp, tmp); +#ifdef STEPDEBUG + printf("tol = %g, diff = %g, h->%g\n", tol, diff, tmp); +#endif } - tmp *= ckt->CKTdelta; - timetemp = MIN(timetemp,tmp); + else { #ifdef STEPDEBUG - printf("tol = %g, diff = %g, h->%g\n",tol,diff,tmp); -#endif - } else { -#ifdef STEPDEBUG - printf("diff is 0\n"); + printf("diff is 0\n"); #endif + } } } - } - break; + break; - default: - return(E_METHOD); + default: + return(E_METHOD); + } + *timeStep = MIN(2 * *timeStep, timetemp); + ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime; + return(OK); } - *timeStep = MIN(2 * *timeStep,timetemp); - ckt->CKTstat->STATtranTruncTime += SPfrontEnd->IFseconds() - startTime; - return(OK); -#endif /* NEWTRUNC */ } diff --git a/src/spicelib/devices/devsup.c b/src/spicelib/devices/devsup.c index 762199cae..d215b791b 100644 --- a/src/spicelib/devices/devsup.c +++ b/src/spicelib/devices/devsup.c @@ -814,13 +814,16 @@ DEVcap(CKTcircuit *ckt, double vgd, double vgs, double vgb, double covlgd, double DEVpred(CKTcircuit *ckt, int loct) { -#ifndef NEWTRUNC - double xfact; + if (!ckt->CKTnewtrunc) { + double xfact; - xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1]; - return( ( (1+xfact) * *(ckt->CKTstate1+loct) ) - - ( xfact * *(ckt->CKTstate2+loct) ) ); -#endif /* NEWTRUNC */ + xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; + return(((1 + xfact) * *(ckt->CKTstate1 + loct)) - + (xfact * *(ckt->CKTstate2 + loct))); + } + else { + return 1.; + } } diff --git a/src/xspice/icm/analog/delay/cfunc.mod b/src/xspice/icm/analog/delay/cfunc.mod index 0830bcc12..c86bbc82a 100644 --- a/src/xspice/icm/analog/delay/cfunc.mod +++ b/src/xspice/icm/analog/delay/cfunc.mod @@ -142,11 +142,10 @@ struct CKTcircuitmin { double CKTreltol; /* --- */ double CKTchgtol; /* --- */ double CKTvoltTol; /* --- */ - /* What is this define for ? */ -#ifdef NEWTRUNC - double CKTlteReltol; - double CKTlteAbstol; -#endif /* NEWTRUNC */ + double CKTlteReltol; /* relative error in voltage based truncation error estimation */ + double CKTlteAbstol; /* absolute error in voltage based truncation error estimation */ + double CKTlteTrtol; /* scaling time step in voltage based truncation error estimation */ + int CKTnewtrunc; /* enable lte (local truncation error) based on voltages */ double CKTgmin; /* .options GMIN */ double CKTgshunt; /* .options RSHUNT */ double CKTcshunt; /* .options CSHUNT */ diff --git a/visualc/src/include/ngspice/config.h b/visualc/src/include/ngspice/config.h index 18840505a..40d617c05 100644 --- a/visualc/src/include/ngspice/config.h +++ b/visualc/src/include/ngspice/config.h @@ -464,9 +464,6 @@ /* Define if you want to discover :) */ /* #undef NEWPRED */ -/* Do not trigger unwanted traps by default */ -/* #undef NEWTRUNC */ - /* Define if we want NOBYPASS */ /* #undef NOBYPASS */ @@ -490,7 +487,7 @@ #define PACKAGE_VERSION VERSION /* Define if we want predictor algorithm */ -/* #undef PREDICTOR */ +#define PREDICTOR /* Define to 1 if the C compiler supports function prototypes. */ /* #undef PROTOTYPES */