48 #include <Xyce_config.h>
59 #if( defined HAVE_FLOAT_H && defined HAVE__ISNAN_AND__FINITE_SUPPORT )
61 #define isnan(x) _isnan(x)
62 #define isinf(x) (!_finite(x))
71 #include <N_UTL_Misc.h>
108 const double turnpt = -exp(-1.), c1 = 1.5, c2 = .75;
109 double r, r2, r3, s, mach_eps, relerr = 1., diff;
123 if( x == 0. )
return;
124 if( x < (1-c2) ) w = x*(1.-x + c1*x*x);
133 w = x*(1.0-x + c1*x*x);
134 xi = log(1.0-x + c1*x*x) - w;
139 if( diff < 0.0 ) diff = -diff;
140 w = -1 + sqrt(2.0*exp(1.))*sqrt(x-turnpt);
141 if( diff == 0.0 )
return;
154 while( relerr > mach_eps && i<maxit)
159 s = 6.*(w+1.0)*(w+1.0);
160 w = w * ( 1.0 + r + r2/(2.0*( w+1.0)) - (2. * w -1.0)*r3/s );
161 if( w * x < 0.0 ) w = -w;
172 if(relerr < 0.0 ) relerr = -relerr;
175 if( i == maxit ) ierr = 2;
191 if(vnew > vold) vnew = Xycemin(vnew,(3.0 * vold) + 2.0);
194 if (vnew < 3.5) vnew = Xycemax(vnew,2.0);
199 if(vnew > vold) vnew = Xycemin(vnew, 4.0);
200 else vnew = Xycemax(vnew,-0.5);
224 if((vnew > vcrit) && (fabs(vnew - vold) > (vt + vt)))
228 arg = 1 + (vnew - vold) / vt;
232 vnew = vold + vt * log(arg);
241 vnew = vt *log(vnew/vt);
274 if((vnew > vcrit) && (fabs(vnew - vold) > (vt + vt)))
278 arg = (vnew - vold) / vt;
282 vnew = vold + vt * (2+log(arg-2));
286 vnew = vold - vt*(2+log(2-arg));
291 vnew = vt *log(vnew/vt);
349 #ifdef Xyce_FETLIM_NAN_CHECK
357 vtsthi = fabs(2*(vold-vto))+2;
358 vtstlo = vtsthi/2 +2;
371 if(-delv >vtstlo) vnew = vold - vtstlo;
375 vnew = Xycemax(vnew,vto+2.0);
381 if(delv >= vtsthi) vnew = vold + vtsthi;
390 vnew = Xycemax(vnew,vto-0.5);
395 vnew = Xycemin(vnew,vto+4.0);
404 if(-delv >vtsthi) vnew = vold - vtsthi;
411 if(delv >vtstlo) vnew = vold + vtstlo;
444 register double *cgs,
445 register double *cgd,
446 register double *cgb,
469 else if (vgbt <= -phi/2)
471 *cgb = -vgbt*cox/phi;
475 *cgb = -vgbt*cox/phi;
476 *cgs = cox/(7.5e-1*phi)*vgbt+cox/1.5;
480 vdbsat = vdsat-(vgs1-vgb1);
488 vddif = 2.0*vdbsat-vdb;
489 vddif1 = vdbsat-vdb-1.0e-12;
490 vddif2 = vddif*vddif;
491 *cgd = cox*(1.0-vdbsat*vdbsat/vddif2)/1.5;
492 *cgs = cox*(1.0-vddif1*vddif1/vddif2)/1.5;
501 else if (vgbt <= -phi/2)
503 *cgb += -vgbt*cox/phi;
507 *cgb += -vgbt*cox/phi;
508 *cgs += cox/(7.5e-1*phi)*vgbt+cox/1.5;
512 vdbsat = vdsat0-(vgs0-vgb0);
520 vddif = 2.0*vdbsat-vdb;
521 vddif1 = vdbsat-vdb-1.0e-12;
522 vddif2 = vddif*vddif;
523 *cgd += cox*(1.0-vdbsat*vdbsat/vddif2)/1.5;
524 *cgs += cox*(1.0-vddif1*vddif1/vddif2)/1.5;
528 *cgs = *cgs *.5 + covlgs;
529 *cgd = *cgd *.5 + covlgd;
530 *cgb = *cgb *.5 + covlgb;
576 else if (vgst <= -phi/2)
578 capgb = -vgst*cox/(2*phi);
584 capgb = -vgst*cox/(2*phi);
585 capgs = vgst*cox/(1.5*phi)+cox/3;
600 vddif = 2.0*vdsat-vds;
602 vddif2 = vddif*vddif;
603 capgd = cox*(1.0-vdsat*vdsat/vddif2)/3;
604 capgs = cox*(1.0-vddif1*vddif1/vddif2)/3;
656 double vdenom, vdenom3;
673 else if (vgst <= -phi/2)
681 dcapgbdvgs=-1.0*cox/(2.0*phi);
687 dcapgsdvgs=cox/(1.5*phi);
693 dcapgbdvgs=-1.0*cox/(2.0*phi);
716 vdenom3=vdenom*vdenom*vdenom;
718 dcapgsdvgs=4.0/3.0*cox*vgdt*vgdt/vdenom3;
720 dcapgsdvgd=-4.0/3.0*cox*vgst*vgdt/vdenom3;
721 dcapgddvgs=-4.0/3.0*cox*vgst*vgdt/vdenom3;
723 dcapgddvgd=4.0/3.0*cox*vgst*vgst/vdenom3;
760 void DeviceSupport::cap (
761 register CKTcircuit *ckt,
808 gcg = (cggb+cbgb)*ckt->CKTag[1];
809 gcd = (cgdb+cbdb)*ckt->CKTag[1];
810 gcs = (cgsb+cbsb)*ckt->CKTag[1];
812 gcgxs = -(1-xqc)*gcg;
814 gcdxs = -(1-xqc)*gcd;
816 gcsxs = -(1-xqc)*gcs;
817 *gcdgb = gcgxd-covlgd*ckt->CKTag[1];
818 *gcddb = gcdxd+(capbd+covlgd)*ckt->CKTag[1];
820 *gcsgb = gcgxs-covlgs*ckt->CKTag[1];
822 *gcssb = gcsxs+(capbs+covlgs)*ckt->CKTag[1];
823 *gcggb = (cggb+covlgd+covlgs+covlgb)*ckt->CKTag[1];
824 *gcgdb = (cgdb-covlgd)*ckt->CKTag[1];
825 *gcgsb = (cgsb-covlgs)*ckt->CKTag[1];
826 *gcbgb = (cbgb-covlgb)*ckt->CKTag[1];
827 *gcbdb = (cbdb-capbd)*ckt->CKTag[1];
828 *gcbsb = (cbsb-capbs)*ckt->CKTag[1];
835 qgate = qgate+qgd+qgs+qgb;
837 *qdrn = xqc*qchan-qgd;
838 *qsrc = (1-xqc)*qchan-qgs;
846 double DeviceSupport::pred
859 xfact = ckt->CKTdelta/ckt->CKTdeltaOld[1];
860 return( ( (1+xfact) * *(ckt->CKTstate1+loct) ) -
861 ( xfact * *(ckt->CKTstate2+loct) ) );
882 if (min <= 0.0) min = 0.3;
883 return ( vds * (alpha*(1.0-min) + min) );
931 (
double vgst,
double alpha,
double vgstConst)
933 return ((alpha)*vgst + (1.0-alpha)*vgstConst);
946 double val =
u.RandomDouble();
952 double interval = 1.0 / numBlocks;
954 for (
int i = 0; i < numBlocks; ++i) {
955 double lowBound = ((double) i) * interval;
956 double highBound = ((double) (i+1)) * interval;
957 if ((val >= lowBound) && (val < highBound)) {
962 return (numBlocks-1);
974 double val =
u.RandomDouble();
989 int retVal =
u.SetSeed( seedIn );
1032 ord =
static_cast<int>( order );
1033 for (i=1 ; i<=ord ; ++i)
1046 ddX += (order-ord)*term;
1048 ans += (order-ord)*term;
1064 double rs,wreturn,xi;
1067 rs=pow(10.0,-order);
1068 lambertw(rs*exp(X+rs),wreturn,ierr,xi);
1076 ddX = wreturn/(1+wreturn)/rs;
1077 return (wreturn/rs);
1098 #if( defined HAVE_NAN_INF_SUPPORT || defined HAVE__ISNAN_AND__FINITE_SUPPORT )
1108 double tol = 1.0e-6;
1111 if (!(x <= tol) && !(x > tol))
1117 if (!(z <= tol) && !(z > tol))
1134 std::vector<double> & x,
1135 std::vector<double> & y,
1136 std::vector<double> & y2)
1144 std::vector<double>
u(n-1,0.0);
1154 for (
int i=1; i<n-1; i++)
1156 sig = (x[i]-x[i-1])/(x[i+1]-x[i-1]);
1157 p = sig*y2[i-1] + 2.0;
1158 y2[i] = (sig-1.0)/p;
1159 u[i] = (y[i+1]-y[i])/(x[i+1]-x[i]) -
1160 (y[i]-y[i-1])/(x[i]-x[i-1]);
1161 u[i] = (6.0*u[i]/(x[i+1]-x[i-1]) - sig*u[i-1])/p;
1164 for (
int l=n-2; l>=0; l--)
1166 y2[l] = y2[l]*y2[l+1]+u[l];
1179 std::vector<double> & xa,
1180 std::vector<double> & ya,
1181 std::vector<double> & y2a,
1197 if (xa[k] > x_position) khi=k;
1201 h = xa[khi] - xa[klo];
1211 a = (xa[khi] - x_position)/h;
1212 b = (x_position - xa[klo])/h;
1214 y_spline = a*ya[klo]+b*ya[khi]+((a*a*a-a)*y2a[klo] + (b*b*b-b)*y2a[khi])*(h*h)/6.0;
1220 if ( (y_spline > ya[klo]) && (y_spline > ya[khi]) )
1222 if (ya[klo] > ya[khi]) y_spline = ya[klo];
1223 else y_spline = ya[khi];
1226 if ( (y_spline < ya[klo]) && (y_spline < ya[khi]) )
1228 if (ya[klo] < ya[khi]) y_spline = ya[klo];
1229 else y_spline = ya[khi];