separate dc current for diffcharge

This commit is contained in:
dwarning 2025-09-20 16:07:12 +02:00
parent b409e7ab27
commit e31ceda0dd
3 changed files with 44 additions and 43 deletions

View File

@ -224,8 +224,8 @@ typedef struct sDIOinstance {
#define DIOconduct DIOstate+2 #define DIOconduct DIOstate+2
#define DIOcapCharge DIOstate+3 #define DIOcapCharge DIOstate+3
#define DIOcapCurrent DIOstate+4 #define DIOcapCurrent DIOstate+4
#define DIOdifCharge DIOstate+5 #define DIOdiffCharge DIOstate+5
#define DIOdifCurrent DIOstate+6 #define DIOdiffCurrent DIOstate+6
#define DIOqth DIOstate+7 /* thermal capacitor charge */ #define DIOqth DIOstate+7 /* thermal capacitor charge */
#define DIOcqth DIOstate+8 /* thermal capacitor current */ #define DIOcqth DIOstate+8 /* thermal capacitor current */
@ -233,7 +233,7 @@ typedef struct sDIOinstance {
#define DIOdeltemp DIOstate+9 /* thermal voltage over rth0 */ #define DIOdeltemp DIOstate+9 /* thermal voltage over rth0 */
#define DIOdIdio_dT DIOstate+10 #define DIOdIdio_dT DIOstate+10
#define DIOnumStates 11 #define DIOnumStates 10
#define DIOsensxp DIOstate+11 /* charge sensitivities and their derivatives. #define DIOsensxp DIOstate+11 /* charge sensitivities and their derivatives.
* +10 for the derivatives - pointer to the * +10 for the derivatives - pointer to the

View File

@ -23,7 +23,7 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
DIOinstance *here; DIOinstance *here;
double arg; double arg;
double capd; double capd;
double cd; double cd, cddc;
double cdeq; double cdeq;
double cdhat; double cdhat;
double ceq; double ceq;
@ -33,7 +33,7 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
double delvd; /* change in diode voltage temporary */ double delvd; /* change in diode voltage temporary */
double evd; double evd;
double evrev; double evrev;
double gd; double gd, gddc;
double geq; double geq;
double gspr; /* area-scaled conductance */ double gspr; /* area-scaled conductance */
double sarg; double sarg;
@ -48,7 +48,7 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
int error; int error;
int SenCond=0; /* sensitivity condition */ int SenCond=0; /* sensitivity condition */
double deplcharge, deplcap; double deplcharge, deplcap;
double difcharge, difcap, cdif=0.0, gdif=0.0; double diffcharge, diffcap, cdiff=0.0, gdiff=0.0;
double tt; double tt;
double vp; double vp;
@ -107,23 +107,23 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
Check=1; Check=1;
if(ckt->CKTmode & MODEINITSMSIG) { if(ckt->CKTmode & MODEINITSMSIG) {
vd= *(ckt->CKTstate0 + here->DIOvoltage); vd= *(ckt->CKTstate0 + here->DIOvoltage);
difcharge= *(ckt->CKTstate0 + here->DIOqdNode); diffcharge= *(ckt->CKTstate0 + here->DIOqdNode);
} else if (ckt->CKTmode & MODEINITTRAN) { } else if (ckt->CKTmode & MODEINITTRAN) {
vd= *(ckt->CKTstate1 + here->DIOvoltage); vd= *(ckt->CKTstate1 + here->DIOvoltage);
difcharge= *(ckt->CKTstate1 + here->DIOqdNode); diffcharge= *(ckt->CKTstate1 + here->DIOqdNode);
} else if ( (ckt->CKTmode & MODEINITJCT) && } else if ( (ckt->CKTmode & MODEINITJCT) &&
(ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC) ) { (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC) ) {
vd=here->DIOinitCond; vd=here->DIOinitCond;
difcharge=0; diffcharge=0;
} else if ( (ckt->CKTmode & MODEINITJCT) && here->DIOoff) { } else if ( (ckt->CKTmode & MODEINITJCT) && here->DIOoff) {
vd=0; vd=0;
difcharge=0; diffcharge=0;
} else if ( ckt->CKTmode & MODEINITJCT) { } else if ( ckt->CKTmode & MODEINITJCT) {
vd=here->DIOtVcrit; vd=here->DIOtVcrit;
difcharge=0; diffcharge=0;
} else if ( ckt->CKTmode & MODEINITFIX && here->DIOoff) { } else if ( ckt->CKTmode & MODEINITFIX && here->DIOoff) {
vd=0; vd=0;
difcharge=0; diffcharge=0;
} else { } else {
#ifndef PREDICTOR #ifndef PREDICTOR
if (ckt->CKTmode & MODEINITPRED) { if (ckt->CKTmode & MODEINITPRED) {
@ -134,12 +134,12 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
*(ckt->CKTstate1 + here->DIOcurrent); *(ckt->CKTstate1 + here->DIOcurrent);
*(ckt->CKTstate0 + here->DIOconduct) = *(ckt->CKTstate0 + here->DIOconduct) =
*(ckt->CKTstate1 + here->DIOconduct); *(ckt->CKTstate1 + here->DIOconduct);
difcharge = DEVpred(ckt,here->DIOdifCharge); diffcharge = DEVpred(ckt,here->DIOdiffCharge);
} else { } else {
#endif /* PREDICTOR */ #endif /* PREDICTOR */
vd = *(ckt->CKTrhsOld+here->DIOposPrimeNode)- vd = *(ckt->CKTrhsOld+here->DIOposPrimeNode)-
*(ckt->CKTrhsOld + here->DIOnegNode); *(ckt->CKTrhsOld + here->DIOnegNode);
difcharge = *(ckt->CKTrhsOld + here->DIOqdNode); diffcharge = *(ckt->CKTrhsOld + here->DIOqdNode);
#ifndef PREDICTOR #ifndef PREDICTOR
} }
#endif /* PREDICTOR */ #endif /* PREDICTOR */
@ -189,25 +189,28 @@ DIOload(GENmodel *inModel, CKTcircuit *ckt)
next1: if (vd >= -3*vte) { next1: if (vd >= -3*vte) {
evd = exp(vd/vte); evd = exp(vd/vte);
cd = csat*(evd-1) + ckt->CKTgmin*vd; cddc = csat*(evd-1) + ckt->CKTgmin*vd;
gd = csat*evd/vte + ckt->CKTgmin; gddc = csat*evd/vte + ckt->CKTgmin;
} else if((!(model->DIObreakdownVoltageGiven)) || } else if((!(model->DIObreakdownVoltageGiven)) ||
vd >= -here->DIOtBrkdwnV) { vd >= -here->DIOtBrkdwnV) {
arg = 3*vte/(vd*CONSTe); arg = 3*vte/(vd*CONSTe);
arg = arg * arg * arg; arg = arg * arg * arg;
cd = -csat*(1+arg) + ckt->CKTgmin*vd; cddc = -csat*(1+arg) + ckt->CKTgmin*vd;
gd = csat*3*arg/vd + ckt->CKTgmin; gddc = csat*3*arg/vd + ckt->CKTgmin;
} else { } else {
evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk); evrev = exp(-(here->DIOtBrkdwnV+vd)/vtebrk);
cd = -csat*evrev + ckt->CKTgmin*vd; cddc = -csat*evrev + ckt->CKTgmin*vd;
gd = csat*evrev/vtebrk + ckt->CKTgmin; gddc = csat*evrev/vtebrk + ckt->CKTgmin;
} }
cd = cddc;
gd = gddc;
if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) || if ((ckt->CKTmode & (MODEDCTRANCURVE | MODETRAN | MODEAC | MODEINITSMSIG)) ||
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) { ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) {
/* /*
@ -231,27 +234,26 @@ next1: if (vd >= -3*vte) {
if (model->DIOsoftRevRecParamGiven) { if (model->DIOsoftRevRecParamGiven) {
if (ckt->CKTmode & MODEINITTRAN) { if (ckt->CKTmode & MODEINITTRAN) {
difcharge = tt * cd; diffcharge = tt * cddc;
difcap = tt * gd; diffcap = tt * gddc;
} }
else { else {
difcharge = *(ckt->CKTstate0 + here->DIOqdNode); diffcharge = *(ckt->CKTstate0 + here->DIOqdNode);
difcap = tt * gd; diffcap = tt * gddc;
} }
} else { } else {
difcharge = tt*cd; diffcharge = tt*cd;
difcap = tt*gd; diffcap = tt*gd;
} }
*(ckt->CKTstate0 + here->DIOdifCharge) = difcharge; *(ckt->CKTstate0 + here->DIOdiffCharge) = diffcharge;
//printf("difcharge = %.7e, difcap = %.7e, cd = %.7e\n", difcharge,difcap,cd);
capd = deplcap + difcap; capd = deplcap + diffcap;
here->DIOcap = capd; here->DIOcap = capd;
@ -292,24 +294,24 @@ next1: if (vd >= -3*vte) {
if (ckt->CKTmode & MODEINITTRAN) { if (ckt->CKTmode & MODEINITTRAN) {
*(ckt->CKTstate1 + here->DIOcapCharge) = *(ckt->CKTstate1 + here->DIOcapCharge) =
*(ckt->CKTstate0 + here->DIOcapCharge); *(ckt->CKTstate0 + here->DIOcapCharge);
*(ckt->CKTstate1 + here->DIOdifCharge) = *(ckt->CKTstate1 + here->DIOdiffCharge) =
*(ckt->CKTstate0 + here->DIOdifCharge); *(ckt->CKTstate0 + here->DIOdiffCharge);
} }
error = NIintegrate(ckt,&geq,&ceq,deplcap,here->DIOcapCharge); error = NIintegrate(ckt,&geq,&ceq,deplcap,here->DIOcapCharge);
if(error) return(error); if(error) return(error);
gd=gd+geq; gd=gd+geq;
cd=cd+*(ckt->CKTstate0 + here->DIOcapCurrent); cd=cd+*(ckt->CKTstate0 + here->DIOcapCurrent);
error = NIintegrate(ckt,&geq,&ceq,difcap,here->DIOdifCharge); error = NIintegrate(ckt,&geq,&ceq,diffcap,here->DIOdiffCharge);
if(error) return(error); if(error) return(error);
gd=gd+geq; gd=gd+geq;
cd=cd+*(ckt->CKTstate0 + here->DIOdifCurrent); cd=cd+*(ckt->CKTstate0 + here->DIOdiffCurrent);
gdif=geq; gdiff=geq;
cdif=*(ckt->CKTstate0 + here->DIOdifCurrent); cdiff=*(ckt->CKTstate0 + here->DIOdiffCurrent);
if (ckt->CKTmode & MODEINITTRAN) { if (ckt->CKTmode & MODEINITTRAN) {
*(ckt->CKTstate1 + here->DIOcapCurrent) = *(ckt->CKTstate1 + here->DIOcapCurrent) =
*(ckt->CKTstate0 + here->DIOcapCurrent); *(ckt->CKTstate0 + here->DIOcapCurrent);
*(ckt->CKTstate1 + here->DIOdifCurrent) = *(ckt->CKTstate1 + here->DIOdiffCurrent) =
*(ckt->CKTstate0 + here->DIOdifCurrent); *(ckt->CKTstate0 + here->DIOdiffCurrent);
} }
} }
} }
@ -352,11 +354,10 @@ next2: *(ckt->CKTstate0 + here->DIOvoltage) = vd;
*(here->DIOposPrimeNegPtr) -= gd; *(here->DIOposPrimeNegPtr) -= gd;
if (model->DIOsoftRevRecParamGiven) { if (model->DIOsoftRevRecParamGiven) {
//printf("cd = %.7e, cdif = %.7e, gdif = %.7e\n", cd, cdif, gdif); *(ckt->CKTrhs + here->DIOqdNode) += tt * (cddc - vp * cdiff) - tt*(gddc-gdiff)*vd;
*(ckt->CKTrhs + here->DIOqdNode) += tt * (cd - vp * cdif) - tt*(gd-gdif)*vd; *(here->DIOqdQdPtr) += tt*(gddc-gdiff);
*(here->DIOqdQdPtr) += tt*(gd-gdif); *(here->DIOqdPosPrimePtr) -= tt*(gddc-gdiff);
*(here->DIOqdPosPrimePtr) -= tt*(gd-gdif); *(here->DIOqdNegPtr) -= tt*(gddc-gdiff);
*(here->DIOqdNegPtr) -= tt*(gd-gdif);
} }
} }
} }

View File

@ -21,7 +21,7 @@ DIOtrunc(GENmodel *inModel, CKTcircuit *ckt, double *timeStep)
for( ; model != NULL; model = DIOnextModel(model)) { for( ; model != NULL; model = DIOnextModel(model)) {
for(here=DIOinstances(model);here!=NULL;here = DIOnextInstance(here)){ for(here=DIOinstances(model);here!=NULL;here = DIOnextInstance(here)){
CKTterr(here->DIOcapCharge,ckt,timeStep); CKTterr(here->DIOcapCharge,ckt,timeStep);
CKTterr(here->DIOdifCharge,ckt,timeStep); CKTterr(here->DIOdiffCharge,ckt,timeStep);
} }
} }
return(OK); return(OK);