unify temperature limit routine for usage in self-heating model
This commit is contained in:
parent
d898f75d6f
commit
4f689b8f11
|
|
@ -16,6 +16,7 @@ Author: 1985 Thomas L. Quarles
|
||||||
double DEVlimvds(double,double);
|
double DEVlimvds(double,double);
|
||||||
double DEVpnjlim(double,double,double,double,int*);
|
double DEVpnjlim(double,double,double,double,int*);
|
||||||
double DEVfetlim(double,double,double);
|
double DEVfetlim(double,double,double);
|
||||||
|
double DEVlimitlog(double, double, double, int*);
|
||||||
void DEVcmeyer(double,double,double,double,double,double,double,double,double,
|
void DEVcmeyer(double,double,double,double,double,double,double,double,double,
|
||||||
double,double,double*,double*,double*,double,double,double,double);
|
double,double,double*,double*,double*,double,double,double,double);
|
||||||
void DEVqmeyer(double,double,double,double,double,double*,double*,double*,
|
void DEVqmeyer(double,double,double,double,double,double*,double*,double*,
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,36 @@ DEVfetlim(double vnew, double vold, double vto)
|
||||||
return(vnew);
|
return(vnew);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* DEVlimitlog(deltemp, deltemp_old, LIM_TOL, check)
|
||||||
|
* Logarithmic damping the per-iteration change of deltemp beyond LIM_TOL.
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
DEVlimitlog(
|
||||||
|
double deltemp,
|
||||||
|
double deltemp_old,
|
||||||
|
double LIM_TOL,
|
||||||
|
int *check)
|
||||||
|
{
|
||||||
|
*check = 0;
|
||||||
|
if (isnan (deltemp) || isnan (deltemp_old))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n");
|
||||||
|
fprintf(stderr, "New prediction returns to 0.0!\n");
|
||||||
|
deltemp = 0.0;
|
||||||
|
*check = 1;
|
||||||
|
}
|
||||||
|
/* Logarithmic damping of deltemp beyond LIM_TOL */
|
||||||
|
if (deltemp > deltemp_old + LIM_TOL) {
|
||||||
|
deltemp = deltemp_old + LIM_TOL + log10((deltemp-deltemp_old)/LIM_TOL);
|
||||||
|
*check = 1;
|
||||||
|
}
|
||||||
|
else if (deltemp < deltemp_old - LIM_TOL) {
|
||||||
|
deltemp = deltemp_old - LIM_TOL - log10((deltemp_old-deltemp)/LIM_TOL);
|
||||||
|
*check = 1;
|
||||||
|
}
|
||||||
|
return deltemp;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ACM_SourceDrainResistances(
|
ACM_SourceDrainResistances(
|
||||||
int ACM,
|
int ACM,
|
||||||
|
|
|
||||||
|
|
@ -38,36 +38,6 @@ int vbic_4T_et_cf_fj(double *,
|
||||||
double *,double *,double *,double *,double *,double *, double *,
|
double *,double *,double *,double *,double *,double *, double *,
|
||||||
double *,double *);
|
double *,double *);
|
||||||
|
|
||||||
/* VBIClimitlog(deltemp, deltemp_old, LIM_TOL, check)
|
|
||||||
* Logarithmic damping the per-iteration change of deltemp beyond LIM_TOL.
|
|
||||||
*/
|
|
||||||
static double
|
|
||||||
VBIClimitlog(
|
|
||||||
double deltemp,
|
|
||||||
double deltemp_old,
|
|
||||||
double LIM_TOL,
|
|
||||||
int *check)
|
|
||||||
{
|
|
||||||
*check = 0;
|
|
||||||
if (isnan (deltemp) || isnan (deltemp_old))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n");
|
|
||||||
fprintf(stderr, "New prediction returns to 0.0!\n");
|
|
||||||
deltemp = 0.0;
|
|
||||||
*check = 1;
|
|
||||||
}
|
|
||||||
/* Logarithmic damping of deltemp beyond LIM_TOL */
|
|
||||||
if (deltemp > deltemp_old + LIM_TOL) {
|
|
||||||
deltemp = deltemp_old + LIM_TOL + log10((deltemp-deltemp_old)/LIM_TOL);
|
|
||||||
*check = 1;
|
|
||||||
}
|
|
||||||
else if (deltemp < deltemp_old - LIM_TOL) {
|
|
||||||
deltemp = deltemp_old - LIM_TOL - log10((deltemp_old-deltemp)/LIM_TOL);
|
|
||||||
*check = 1;
|
|
||||||
}
|
|
||||||
return deltemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
VBICload(GENmodel *inModel, CKTcircuit *ckt)
|
VBICload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
/* actually load the current resistance value into the
|
/* actually load the current resistance value into the
|
||||||
|
|
@ -720,7 +690,7 @@ VBICload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
here->VBICtVcrit,&ichk5);
|
here->VBICtVcrit,&ichk5);
|
||||||
if (here->VBIC_selfheat) {
|
if (here->VBIC_selfheat) {
|
||||||
ichk6 = 1;
|
ichk6 = 1;
|
||||||
Vrth = VBIClimitlog(Vrth,
|
Vrth = DEVlimitlog(Vrth,
|
||||||
*(ckt->CKTstate0 + here->VBICvrth),100,&ichk6);
|
*(ckt->CKTstate0 + here->VBICvrth),100,&ichk6);
|
||||||
}
|
}
|
||||||
if ((ichk1 == 1) || (ichk2 == 1) || (ichk3 == 1) || (ichk4 == 1) || (ichk5 == 1) || (ichk6 == 1)) icheck=1;
|
if ((ichk1 == 1) || (ichk2 == 1) || (ichk3 == 1) || (ichk4 == 1) || (ichk5 == 1) || (ichk6 == 1)) icheck=1;
|
||||||
|
|
|
||||||
|
|
@ -14,36 +14,6 @@ VDMOS: 2018 Holger Vogt, 2020 Dietmar Warning
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
#include "ngspice/suffix.h"
|
#include "ngspice/suffix.h"
|
||||||
|
|
||||||
/* VDMOSlimitlog(deltemp, deltemp_old, LIM_TOL, check)
|
|
||||||
* Logarithmic damping the per-iteration change of deltemp beyond LIM_TOL.
|
|
||||||
*/
|
|
||||||
static double
|
|
||||||
VDMOSlimitlog(
|
|
||||||
double deltemp,
|
|
||||||
double deltemp_old,
|
|
||||||
double LIM_TOL,
|
|
||||||
int *check)
|
|
||||||
{
|
|
||||||
*check = 0;
|
|
||||||
if (isnan (deltemp) || isnan (deltemp_old))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Alberto says: YOU TURKEY! The limiting function received NaN.\n");
|
|
||||||
fprintf(stderr, "New prediction returns to 0.0!\n");
|
|
||||||
deltemp = 0.0;
|
|
||||||
*check = 1;
|
|
||||||
}
|
|
||||||
/* Logarithmic damping of deltemp beyond LIM_TOL */
|
|
||||||
if (deltemp > deltemp_old + LIM_TOL) {
|
|
||||||
deltemp = deltemp_old + LIM_TOL + log10((deltemp-deltemp_old)/LIM_TOL);
|
|
||||||
*check = 1;
|
|
||||||
}
|
|
||||||
else if (deltemp < deltemp_old - LIM_TOL) {
|
|
||||||
deltemp = deltemp_old - LIM_TOL - log10((deltemp_old-deltemp)/LIM_TOL);
|
|
||||||
*check = 1;
|
|
||||||
}
|
|
||||||
return deltemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
/* actually load the current value into the
|
/* actually load the current value into the
|
||||||
|
|
@ -298,7 +268,7 @@ VDMOSload(GENmodel *inModel, CKTcircuit *ckt)
|
||||||
vgs = vgd + vds;
|
vgs = vgd + vds;
|
||||||
}
|
}
|
||||||
if (selfheat)
|
if (selfheat)
|
||||||
delTemp = VDMOSlimitlog(delTemp,
|
delTemp = DEVlimitlog(delTemp,
|
||||||
*(ckt->CKTstate0 + here->VDMOSdelTemp),100,&Check_th);
|
*(ckt->CKTstate0 + here->VDMOSdelTemp),100,&Check_th);
|
||||||
else
|
else
|
||||||
delTemp = 0.0;
|
delTemp = 0.0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue