45 #include <Xyce_config.h>
48 #include <N_UTL_Math.h>
58 #include <N_ERH_ErrorMgr.h>
60 #include <N_LAS_Matrix.h>
61 #include <N_LAS_Vector.h>
62 #include <N_UTL_FeatureTest.h>
63 #include <N_UTL_ExtendedString.h>
74 .setDescription(
"Area scaling value (scales IS, ISR, IKF, RS, CJ0, and IBV)");
82 .setDescription(
"Device temperature");
87 .setDescription(
"Initial voltage drop across device set to zero");
91 .setDescription(
"Option to solve diode equations with the Lambert-W function");
99 .setDescription(
"Saturation current")
100 .setAnalyticSensitivityAvailable(
true)
107 .setDescription(
"Saturation current")
108 .setAnalyticSensitivityAvailable(
true)
115 .setDescription(
"Parasitic resistance")
116 .setAnalyticSensitivityAvailable(
true)
121 .setOriginalValueStored(
true)
122 .setDescription(
"Emission coefficient")
123 .setAnalyticSensitivityAvailable(
true)
129 .setDescription(
"Recombination current parameter (level 2)")
130 .setAnalyticSensitivityAvailable(
true)
135 .setDescription(
"Emission coefficient for ISR (level 2)")
136 .setAnalyticSensitivityAvailable(
true)
142 .setDescription(
"High-injection \"knee\" current (level 2)")
143 .setAnalyticSensitivityAvailable(
true)
149 .setDescription(
"Transit time")
150 .setAnalyticSensitivityAvailable(
true)
157 .setDescription(
"Zero-bias p-n depletion capacitance")
158 .setAnalyticSensitivityAvailable(
true)
166 .setDescription(
"Zero-bias p-n depletion capacitance")
167 .setAnalyticSensitivityAvailable(
true)
174 .setDescription(
"Zero-bias p-n depletion capacitance")
175 .setAnalyticSensitivityAvailable(
true)
181 .setDescription(
"Potential for p-n junction")
182 .setAnalyticSensitivityAvailable(
true)
187 .setDescription(
"Grading parameter for p-n junction")
188 .setAnalyticSensitivityAvailable(
true)
194 .setDescription(
"Bandgap voltage (barrier height)")
195 .setAnalyticSensitivityAvailable(
true)
200 .setDescription(
"IS temperature exponent")
201 .setAnalyticSensitivityAvailable(
true)
207 .setDescription(
"IKF temperature coefficient (linear) (level 2)")
208 .setAnalyticSensitivityAvailable(
true)
214 .setDescription(
"BV temperature coefficient (linear) (level 2)");
219 .setDescription(
"BV temperature coefficient (quadratic) (level 2)");
224 .setDescription(
"RS temperature coefficient (linear) (level 2)");
229 .setDescription(
"RS temperature coefficient (quadratic) (level 2)");
233 .setDescription(
"Forward-bias depletion capacitance coefficient")
234 .setAnalyticSensitivityAvailable(
true)
241 .setDescription(
"Reverse breakdown \"knee\" voltage")
242 .setAnalyticSensitivityAvailable(
true)
250 .setDescription(
"Reverse breakdown \"knee\" voltage")
251 .setAnalyticSensitivityAvailable(
true)
257 .setDescription(
"Reverse breakdown \"knee\" current")
258 .setAnalyticSensitivityAvailable(
true)
263 .setDescription(
"Reverse current fitting factor")
264 .setAnalyticSensitivityAvailable(
true)
269 .setDescription(
"Reverse breakdown ideality factor (level 2)")
270 .setAnalyticSensitivityAvailable(
true)
276 .setDescription(
"Low-level reverse breakdown \"knee\" current (level 2)")
277 .setAnalyticSensitivityAvailable(
true)
282 .setDescription(
"Low-level reverse breakdown ideality factor (level 2)")
283 .setAnalyticSensitivityAvailable(
true)
289 .setAnalyticSensitivityAvailable(
true)
294 .setDescription(
"Flicker noise coefficient")
295 .setAnalyticSensitivityAvailable(
true)
300 .setDescription(
"Flicker noise exponent")
301 .setAnalyticSensitivityAvailable(
true)
343 :
DeviceInstance(instance_block, configuration.getInstanceParameters(), factory_block),
348 Temp(getDeviceOptions().temp.getImmutableValue<double>()),
350 InitCondGiven(false),
379 APosEquPosNodeOffset(-1),
380 APosEquPriNodeOffset(-1),
381 ANegEquNegNodeOffset(-1),
382 ANegEquPriNodeOffset(-1),
383 APriEquPosNodeOffset(-1),
384 APriEquNegNodeOffset(-1),
385 APriEquPriNodeOffset(-1),
387 fPosEquPosNodePtr(0),
388 fPosEquPriNodePtr(0),
389 fNegEquNegNodePtr(0),
390 fNegEquPriNodePtr(0),
391 fPriEquPosNodePtr(0),
392 fPriEquNegNodePtr(0),
393 fPriEquPriNodePtr(0),
394 qPosEquPosNodePtr(0),
395 qPosEquPriNodePtr(0),
396 qNegEquNegNodePtr(0),
397 qNegEquPriNodePtr(0),
398 qPriEquPosNodePtr(0),
399 qPriEquNegNodePtr(0),
400 qPriEquPriNodePtr(0),
441 if (!
given(
"LAMBERTW"))
481 const std::vector<int> & extLIDVecRef)
486 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
488 Xyce::dout() << std::endl << section_divider << std::endl;
489 Xyce::dout() <<
"In Instance::register LIDs\n\n";
490 Xyce::dout() <<
"name = " <<
getName() << std::endl;
491 Xyce::dout() <<
"number of internal variables: " <<
numIntVars << std::endl;
492 Xyce::dout() <<
"number of external variables: " <<
numExtVars << std::endl;
513 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
515 Xyce::dout() <<
"\nSolution and RHS variables:\n";
516 Xyce::dout() <<
"\nli_Pos = ";
517 Xyce::dout().width(4);
518 Xyce::dout() <<
li_Pos << std::endl;
520 Xyce::dout() <<
"\nli_Neg = ";
521 Xyce::dout().width(4);
522 Xyce::dout() <<
li_Neg << std::endl;
524 Xyce::dout() <<
"\nli_Pri = ";
525 Xyce::dout().width(4);
526 Xyce::dout() <<
li_Pri << std::endl;
532 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
534 Xyce::dout() <<
"\nEnd of Instance::register LIDs\n";
535 Xyce::dout() << section_divider << std::endl;
586 const std::vector<int> & stoLIDVecRef )
598 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS))
600 Xyce::dout() <<
"li_storevd = " <<
li_storevd;
659 std::vector<int> map;
660 std::vector< std::vector<int> > map2;
695 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
750 double Cd_Jdxp = 0.0;
751 Cd_Jdxp = -(
Cd ) * Vd_diff;
803 double Gd_Jdxp = 0.0;
804 Gd_Jdxp = -(
Gd ) * Vd_diff;
931 noiseData.
resize(numSources);
940 std::string(
"_1overf");
987 bool bsuccess =
true;
1035 double Vte = N *
Vt;
1036 double VteR = NR *
Vt;
1065 if ((*flagSolVectorPtr)[
li_Pos] == 0 ||
1066 (*flagSolVectorPtr)[
li_Neg] == 0 ||
1067 (*flagSolVectorPtr)[
li_Pri] == 0)
1106 double Vdtmp = -( BV +
Vd );
1117 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1119 Xyce::dout() << Xyce::section_divider << std::endl;
1120 Xyce::dout() <<
"Instance::updateIntermediateVars " <<
getName()<<std::endl;
1133 if (
Vd >= -3.0 * Vte)
1149 Vrs = (
Id +
Icd)*RS;
1154 if (
Vd >= -3.0 * Vte)
1177 if(
Vd >= -3.0 * Vte) IRfactor = 1.0;
1178 else IRfactor =
tIRF;
1181 if (
Vd >= -3.0 * Vte)
1183 double arg1 =
Vd / Vte;
1185 double evd = exp(arg1);
1189 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1191 Xyce::dout() <<
"Normal exponential regime." << std::endl;
1192 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
1193 Xyce::dout() <<
" Vte = " << Vte << std::endl;
1194 Xyce::dout() <<
" Id = " <<
Id << std::endl;
1195 Xyce::dout() <<
" Gd = " <<
Gd << std::endl;
1203 double arg = 3.0 * Vte / (
Vd *
CONSTe);
1204 arg = arg * arg * arg;
1207 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1209 Xyce::dout() <<
"Linear reverse bias regime." << std::endl;
1210 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
1211 Xyce::dout() <<
" tBrkdwnV = " <<
tBrkdwnV << std::endl;
1212 Xyce::dout() <<
" Id = " <<
Id << std::endl;
1213 Xyce::dout() <<
" Gd = " <<
Gd << std::endl;
1222 double evrev = exp(arg1);
1224 #ifdef Xyce_BREAKDOWN_ORIGINAL
1231 arg2=arg2*arg2*arg2;
1232 double Isat_tBrkdwnV=Isat*(1-arg2);
1237 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1239 Xyce::dout() <<
"Reverse breakdown regime." << std::endl;
1240 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
1241 Xyce::dout() <<
" tBrkdwnV = " <<
tBrkdwnV << std::endl;
1242 Xyce::dout() <<
" Id = " << Id << std::endl;
1243 Xyce::dout() <<
" Gd = " <<
Gd << std::endl;
1252 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1254 Xyce::dout() <<
" Level 2 diode code " << std::endl;
1259 if(
Vd >= -3.0*Vte) IRfactor=1.0;
1260 else IRfactor =
tIRF;
1263 if (
Vd >= -3.0 * Vte)
1265 double arg1 =
Vd / Vte;
1267 double evd = exp(arg1);
1274 Irec = IsatR * (evd - 1.0);
1275 Gd2 = IsatR*evd/VteR;
1282 DKhi = 0.5*Khi*Gd1/(
tIKF+Inorm);
1292 Id = Inorm*Khi + Irec*Kgen;
1293 Gd = Gd1*Khi + Inorm*DKhi + Gd2*Kgen + Irec*DKgen;
1294 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1296 Xyce::dout() <<
"L2 Normal exponential regime." << std::endl;
1297 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
1298 Xyce::dout() <<
" Vte = " << Vte << std::endl;
1299 Xyce::dout() <<
" Id = " <<
Id << std::endl;
1300 Xyce::dout() <<
" Irec= " << Irec << std::endl;
1301 Xyce::dout() <<
" Gd = " <<
Gd << std::endl;
1302 Xyce::dout() <<
" Gd1 = " << Gd1 << std::endl;
1303 Xyce::dout() <<
" Gd2 = " << Gd2 << std::endl;
1304 Xyce::dout() <<
" Khi = " << Khi << std::endl;
1305 Xyce::dout() <<
" Kgen=" << Kgen << std::endl;
1306 Xyce::dout() <<
"DKgen=" <<DKgen << std::endl;
1313 double arg = 3.0 * Vte / (
Vd *
CONSTe);
1314 arg = arg * arg * arg;
1317 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1319 Xyce::dout() <<
"L2 Linear reverse bias regime." << std::endl;
1320 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
1321 Xyce::dout() <<
" tBrkdwnV = " <<
tBrkdwnV << std::endl;
1322 Xyce::dout() <<
" Id = " <<
Id << std::endl;
1323 Xyce::dout() <<
" Gd = " <<
Gd << std::endl;
1332 double evrev = exp(arg1);
1334 #ifdef Xyce_BREAKDOWN_ORIGINAL
1341 arg2=arg2*arg2*arg2;
1342 double Isat_tBrkdwnV=Isat*(1-arg2);
1346 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1348 Xyce::dout() <<
"L2 Reverse breakdown regime." << std::endl;
1349 Xyce::dout() <<
" Vd = " <<
Vd << std::endl;
1350 Xyce::dout() <<
" tBrkdwnV = " <<
tBrkdwnV << std::endl;
1351 Xyce::dout() <<
" Id = " << Id << std::endl;
1352 Xyce::dout() <<
" Gd = " <<
Gd << std::endl;
1369 double arg1 = -M * log(arg);
1371 double sarg = exp(arg1);
1374 Qd = TT *
Id +
tJctPot * Czero * (1.0 - arg * sarg) / (1.0 - M);
1375 Cd = TT *
Gd + Czero * sarg;
1379 double Czof2 = Czero / F2;
1380 double MotJctPot = M /
tJctPot;
1384 Czof2 * (F3 * (
Vc -
tDepCap) + (0.5 * MotJctPot) *
1387 Cd = TT *
Gd + Czof2 * (F3 + MotJctPot *
Vc);
1391 Xyce::dout() <<
"Qd = " <<
Qd << std::endl;
1392 Xyce::dout() <<
"Cd = " <<
Qd << std::endl;
1401 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1403 Xyce::dout() << Xyce::section_divider << std::endl;
1422 double xfc = log( 1.0 -
model_.
FC );
1424 if( temp != -999.0 )
Temp = temp;
1432 double pbfact = -2.0*vt*(1.5*log(fact2)+
CONSTQ*arg);
1438 double pbfact1 = -2.0*vtnom*(1.5*log(fact1)+
CONSTQ*arg1);
1440 double pbo = (
model_.
VJ-pbfact1)/fact1;
1441 double gmaold = (
model_.
VJ-pbo)/pbo;
1448 double gmanew = (
tJctPot-pbo)/pbo;
1477 tempBV =
model_.
BV*(1 + (Temp-TNOM)*
1496 #ifdef Xyce_BREAKDOWN_ORIGINAL
1514 double reltol = 1.0e-3;
1517 double IRfactor =
tIRF;
1520 if( cbv < IRfactor*tSatCur*tempBV/vt )
1522 cbv = IRfactor*tSatCur*tempBV/vt;
1527 double tol = reltol*cbv;
1528 xbv = tempBV-vt*log(1.0+cbv/(IRfactor*tSatCur));
1529 for(
int i = 0; i < 25; ++i )
1531 xbv = tempBV-vt*log(cbv/(IRfactor*tSatCur)+1.0-xbv/vt);
1532 xcbv = IRfactor*tSatCur*(exp((tempBV-xbv)/vt)-1.0+xbv/vt);
1533 if(fabs(xcbv-cbv)<=tol)
break;
1541 double IRFactor=
tIRF;
1547 const int ITER_COUNT_MAX=8;
1550 double arg1=3.0*vte/(
CONSTe*tempBV);
1551 arg1=arg1*arg1*arg1;
1552 cthreshlow=tSatCur*IRFactor*(1-arg1);
1554 exp(-1.0*(3.0*vte-tempBV)/vte);
1556 if(cbv >= cthreshhigh)
1562 else if(cbv <= cthreshlow)
1575 for(iter_count=0; iter_count < ITER_COUNT_MAX; iter_count++)
1577 arg2=3.0*vte/(
CONSTe*xbv);
1578 arg2=arg2*arg2*arg2;
1579 xbv=tempBV-vte*log(cbv/(tSatCur*IRFactor))+vte *
1597 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1599 Xyce::dout() << Xyce::section_divider << std::endl;
1600 Xyce::dout() <<
"Instance::UpdateTemperature" <<
getName() <<std::endl;
1601 Xyce::dout() <<
" IS = " <<
model_.
IS << std::endl;
1602 Xyce::dout() <<
" vtnom = " << vtnom << std::endl;
1603 Xyce::dout() <<
" xfc = " << xfc << std::endl;
1604 Xyce::dout() <<
" TNOM = " << TNOM << std::endl;
1605 Xyce::dout() <<
" vt = " << vt << std::endl;
1606 Xyce::dout() <<
" fact2 = " << fact2 << std::endl;
1607 Xyce::dout() <<
" egfet = " << egfet << std::endl;
1608 Xyce::dout() <<
" arg = " << arg << std::endl;
1609 Xyce::dout() <<
" pbfact = " << pbfact << std::endl;
1610 Xyce::dout() <<
" egfet1 = " << egfet1 << std::endl;
1611 Xyce::dout() <<
" arg1 = " << arg1 << std::endl;
1612 Xyce::dout() <<
" fact1 = " << fact1 << std::endl;
1613 Xyce::dout() <<
" pbfact1 = " << pbfact1 << std::endl;
1614 Xyce::dout() <<
" pbo = " << pbo << std::endl;
1615 Xyce::dout() <<
" gmaold = " << gmaold << std::endl;
1616 Xyce::dout() <<
" gmanew = " << gmanew << std::endl;
1617 Xyce::dout() <<
" tJctCap = " <<
tJctCap << std::endl;
1618 Xyce::dout() <<
" tJctPot = " <<
tJctPot << std::endl;
1619 Xyce::dout() <<
" tSatCur = " << tSatCur << std::endl;
1620 Xyce::dout() <<
" tF1 = " <<
tF1 << std::endl;
1621 Xyce::dout() <<
" tDepCap = " <<
tDepCap << std::endl;
1622 Xyce::dout() <<
" vte = " << vte << std::endl;
1623 Xyce::dout() <<
" tempBV = " << tempBV << std::endl;
1624 Xyce::dout() <<
" tVcrit = " <<
tVcrit << std::endl;
1625 Xyce::dout() <<
" tRS = " <<
tRS << std::endl;
1626 Xyce::dout() <<
" tCOND = " <<
tCOND << std::endl;
1627 Xyce::dout() <<
" tIRF = " <<
tIRF << std::endl;
1628 Xyce::dout() <<
" tBrkdwnV= " <<
tBrkdwnV << std::endl;
1693 double arg1 = (
Vd + Isat*
RS)/Vte;
1695 double evd = exp(arg1);
1696 double lambWArg = Isat*RS*evd/Vte;
1702 Id = -Isat+Vte*(lambWReturn)/RS;
1703 Gd = lambWReturn / ((1 + lambWReturn)*RS);
1722 double FF2 = (1/2 - FF1)*(-2);
1723 double arg = Vte/
RS;
1724 double arg1 = (Isat/arg - 3);
1725 double arg2 = FF1*arg1;
1727 double evd = exp(arg2);
1728 double lambWArg = Isat*evd/arg;
1734 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) &&
getSolverState().debugTimeFlag)
1737 Xyce::dout() <<
"Safe LambertW return" << std::endl;
1739 Xyce::dout() <<
"LambertW argument not in domain" << std::endl;
1741 Xyce::dout() <<
"Arithmetic problems with LambertW" << std::endl;
1744 Id = -Isat*FF1 + FF2*lambWReturn*arg;
1746 double GdFF1 = 1/(-3.0*Vte +
tBrkdwnV);
1747 double GdFF2 = 2 * GdFF1;
1748 double GdW = arg*lambWReturn*GdFF1*arg1/(1 + lambWReturn);
1749 Gd = -Isat*GdFF1 + GdFF2*arg*lambWReturn + FF2*GdW;
1753 Xyce::dout() <<
"lambWArg = " << lambWArg << std::endl;
1754 Xyce::dout() <<
"lambWError = " << lambWError << std::endl;
1755 Xyce::dout() <<
"lambWReturn= " << lambWReturn << std::endl;
1756 Xyce::dout() <<
"Id = " <<
Id << std::endl;
1757 Xyce::dout() <<
"Gd = " <<
Gd << std::endl;
1758 Xyce::dout() <<
"Using lambertwReverseBias" << std::endl;
1823 double evd = exp(arg1);
1824 double lambWArg = Isat*RS*evd/Vte;
1830 Id = -Vte*lambWReturn/
RS;
1831 Gd = lambWReturn / ((1 + lambWReturn)*RS);
1849 if(
M > 0.9 )
M = 0.9;
1852 if(
EG < 0.1 )
EG = 0.1;
1855 if(
FC > 0.95 )
FC = 0.95;
1862 double xfc = log(1.0-
FC);
1863 F2 = exp((1.0+
M)*xfc);
1864 F3 = 1.0-
FC*(1.0+
M);
1880 std::vector<Instance*>::iterator iter;
1884 for (iter=first; iter!=last; ++iter)
1886 (*iter)->processParams();
1904 :
DeviceModel(MB, configuration.getModelParameters(), factory_block),
1956 std::string bad_parameters;
1959 bad_parameters +=
" ISR";
1961 bad_parameters +=
" NR";
1963 bad_parameters +=
" IKF";
1965 bad_parameters +=
" NBV";
1967 bad_parameters +=
" IBVL";
1969 bad_parameters +=
" NBVL";
1971 bad_parameters +=
" TIKF";
1973 bad_parameters +=
" TBV1";
1975 bad_parameters +=
" TBV2";
1977 bad_parameters +=
" TRS1";
1979 bad_parameters +=
" TRS2";
1980 if (!bad_parameters.empty())
1982 UserError0(*
this) <<
"Illegal parameter(s) given for level 1 diode:" << bad_parameters;
2000 std::vector<Instance*>::iterator iterI;
2005 for (iterI = firstI; iterI != lastI; ++iterI)
2022 std::vector<Instance*>::const_iterator iter;
2028 os <<
" name model name Parameters" << std::endl;
2029 for (i=0, iter=first; iter!=last; ++iter, ++i)
2031 os <<
" " << i <<
": " << (*iter)->getName() <<
" ";
2035 os <<
"AREA = " << (*iter)->Area << std::endl;
2036 os <<
" IC = " << (*iter)->InitCond << std::endl;
2037 os <<
"TEMP = " << (*iter)->Temp << std::endl;
2038 os <<
" off = " << (*iter)->off << std::endl;
2064 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
2083 bool bsuccess =
true;
2090 bsuccess = bsuccess && btmp;
2104 bool Master::loadDAEVectors (
double * solVec,
double * fVec,
double *qVec,
double * bVec,
double * storeLeadF,
double * storeLeadQ,
double * leadF,
double * leadQ,
double * junctionV)
2124 double Cd_Jdxp = -( di.
Cd ) * Vd_diff;
2125 double Gd_Jdxp = -( di.
Gd ) * Vd_diff;
2129 dFdxdVp[di.
li_Neg] += Gd_Jdxp;
2130 dFdxdVp[di.
li_Pri] -= Gd_Jdxp;
2134 dQdxdVp[di.
li_Neg] += Cd_Jdxp;
2135 dQdxdVp[di.
li_Pri] -= Cd_Jdxp;
2168 #ifndef Xyce_NONPOINTER_MATRIX_LOAD
2212 .registerDevice(
"d", 1)
2213 .registerDevice(
"d", 2)
2214 .registerModelType(
"d", 1)
2215 .registerModelType(
"d", 2);
2233 template <
typename ScalarT>
2245 if( M > 0.9 ) M = 0.9;
2248 if( EG < 0.1 ) EG = 0.1;
2251 if( FC > 0.95 ) FC = 0.95;
2258 ScalarT xfc = log(1.0-FC);
2259 F2 = exp((1.0+M)*xfc);
2260 F3 = 1.0-FC*(1.0+
M);
2273 template <
typename ScalarT>
2276 const double & temp,
2294 const ScalarT & TNOM,
2296 const ScalarT & CJO,
2301 const ScalarT & XTI,
2303 const ScalarT & COND,
2304 const ScalarT & IRF,
2306 const ScalarT & IKF,
2307 const ScalarT & TIKF,
2308 const ScalarT & ISR,
2309 const ScalarT & IBV,
2312 const bool & BVGiven,
2314 const ScalarT & TBV1,
2315 const ScalarT & TBV2,
2316 const ScalarT & TRS1,
2317 const ScalarT & TRS2,
2324 ScalarT KoverQ =
static_cast<ScalarT
>(
CONSTKoverQ);
2326 ScalarT Eg0 =
static_cast<ScalarT
>(
CONSTEg0);
2328 ScalarT betaEg =
static_cast<ScalarT
>(
CONSTbetaEg);
2329 ScalarT boltz =
static_cast<ScalarT
>(
CONSTboltz);
2330 ScalarT Q =
static_cast<ScalarT
>(
CONSTQ);
2331 ScalarT Eg300 =
static_cast<ScalarT
>(
CONSTEg300);
2332 ScalarT root2 =
static_cast<ScalarT
>(
CONSTroot2);
2333 ScalarT e =
static_cast<ScalarT
>(
CONSTe);
2335 ScalarT vtnom = KoverQ * TNOM;
2337 ScalarT xfc = log( 1.0 - FC );
2339 if( temp != -999.0 ) Temp = temp;
2342 ScalarT vt = KoverQ * Temp;
2343 ScalarT fact2 = Temp / REFTEMP;
2344 ScalarT egfet = Eg0 - (alphaEg*Temp*Temp)/(Temp+betaEg);
2345 ScalarT arg = -egfet/(2.0*boltz*Temp) +
2346 Eg300/(boltz*(REFTEMP+REFTEMP));
2347 ScalarT pbfact = -2.0*vt*(1.5*log(fact2)+Q*arg);
2348 ScalarT egfet1 = Eg0 - (alphaEg*TNOM*TNOM)/
2350 ScalarT arg1 = -egfet1/(2.0*boltz*TNOM) +
2351 Eg300/(2.0*boltz*REFTEMP);
2352 ScalarT fact1 = TNOM/REFTEMP;
2353 ScalarT pbfact1 = -2.0*vtnom*(1.5*log(fact1)+Q*arg1);
2355 ScalarT pbo = (VJ-pbfact1)/fact1;
2356 ScalarT gmaold = (VJ-pbo)/pbo;
2359 (1.0+M*(4.0e-4*(TNOM-REFTEMP) -gmaold));
2361 tJctPot = pbfact+fact2*pbo;
2363 ScalarT gmanew = (tJctPot-pbo)/pbo;
2365 tJctCap *= 1.0 + M*(4.0e-4*(Temp-REFTEMP)-gmanew);
2367 tSatCur = IS*exp(((Temp/TNOM)-1.0)*
2369 XTI/N*log(Temp/TNOM));
2371 tF1 = tJctPot*(1.0-exp((1.0-M)*xfc))/(1.0-M);
2373 tDepCap = FC*tJctPot;
2378 tVcrit = vte*log(vte/(root2*tSatCur));
2381 tIRF = IRF*pow(fact2,1.6);
2386 tSatCurR = ISR*exp((Temp/TNOM - 1.0)*
2388 XTI/NR*log(Temp/TNOM));
2390 tIKF = IKF*(1 + TIKF*(Temp-TNOM));
2392 tempBV = BV*(1 + (Temp-TNOM)*
2393 ( TBV1 + TBV2*(Temp-TNOM) ));
2395 tRS = RS*(1 + (Temp-TNOM)*
2396 ( TRS1 + TRS2*(Temp-TNOM) ));
2399 if(tRS != 0.0) tCOND = 1.0/tRS;
2401 tJctPot = (VJ - egfet1)*fact2 - 3*vt*log(fact2) + egfet;
2403 tJctCap = CJO/(1.0 +
2404 M*(4.0e-4*(Temp-TNOM) + (1-tJctPot/VJ)));
2411 #ifdef Xyce_BREAKDOWN_ORIGINAL
2429 double reltol = 1.0e-3;
2432 double IRfactor = tIRF;
2435 if( cbv < IRfactor*tSatCur*tempBV/vt )
2437 cbv = IRfactor*tSatCur*tempBV/vt;
2442 double tol = reltol*cbv;
2443 xbv = tempBV-vt*log(1.0+cbv/(IRfactor*tSatCur));
2444 for(
int i = 0; i < 25; ++i )
2446 xbv = tempBV-vt*log(cbv/(IRfactor*tSatCur)+1.0-xbv/vt);
2447 xcbv = IRfactor*tSatCur*(exp((tempBV-xbv)/vt)-1.0+xbv/vt);
2448 if(fabs(xcbv-cbv)<=tol)
break;
2456 ScalarT IRFactor=tIRF;
2460 ScalarT cthreshhigh;
2462 const int ITER_COUNT_MAX=8;
2465 ScalarT arg1=3.0*vte/(e*tempBV);
2466 arg1=arg1*arg1*arg1;
2467 cthreshlow=tSatCur*IRFactor*(1-arg1);
2468 cthreshhigh=tSatCur*IRFactor*(1-1.0/(e*e*e)) *
2469 exp(-1.0*(3.0*vte-tempBV)/vte);
2471 if(cbv >= cthreshhigh)
2477 else if(cbv <= cthreshlow)
2490 for(iter_count=0; iter_count < ITER_COUNT_MAX; iter_count++)
2492 arg2=3.0*vte/(e*xbv);
2493 arg2=arg2*arg2*arg2;
2494 xbv=tempBV-vte*log(cbv/(tSatCur*IRFactor))+vte *
2523 template <
typename ScalarT>
2528 const ScalarT & Vpp,
2533 const ScalarT & Temp,
2534 const ScalarT & tJctCap,
2535 const ScalarT & tJctPot,
2536 const ScalarT & tDepCap,
2537 const ScalarT & tF1,
2538 const ScalarT & tSatCur,
2539 const ScalarT & tSatCurR,
2540 const ScalarT & tVcrit,
2541 const ScalarT & tRS,
2542 const ScalarT & tCOND,
2543 const ScalarT & tIRF,
2544 const ScalarT & tIKF,
2545 const ScalarT & tBrkdwnV,
2548 const ScalarT & Area,
2549 const int & lambertWFlag,
2550 const double & gmin,
2576 bool bsuccess =
true;
2591 ScalarT Isat = tSatCur * Area;
2592 ScalarT IsatR = tSatCurR * Area;
2593 ScalarT KoverQ =
static_cast<ScalarT
>(
CONSTKoverQ);
2594 ScalarT
Vt = KoverQ * Temp;
2595 ScalarT Vte = N *
Vt;
2596 ScalarT VteR = NR *
Vt;
2598 Gspr = tCOND * Area;
2608 if(Vd >= -3.0 * Vte) IRfactor = 1.0;
2609 else IRfactor = tIRF;
2612 if (Vd >= -3.0 * Vte)
2614 ScalarT arg1 = Vd / Vte;
2616 ScalarT evd = exp(arg1);
2618 Id = Isat * (evd - 1.0) + gmin * Vd;
2619 Gd = Isat * evd / Vte + gmin;
2622 else if(!tBrkdwnV || (Vd >= -tBrkdwnV))
2624 ScalarT arg = 3.0 * Vte / (Vd *
CONSTe);
2625 arg = arg * arg * arg;
2626 Id = -Isat * (1.0 + arg) + gmin * Vd;
2627 Gd = Isat * 3.0 * arg / Vd + gmin;
2632 ScalarT arg1 = -(tBrkdwnV + Vd) / Vte;
2634 ScalarT evrev = exp(arg1);
2636 #ifdef Xyce_BREAKDOWN_ORIGINAL
2637 Id = -Isat * evrev + gmin * Vd;
2638 Gd = Isat * evrev / Vte + gmin;
2642 ScalarT arg2=3.0*Vte/(
CONSTe*tBrkdwnV);
2643 arg2=arg2*arg2*arg2;
2644 ScalarT Isat_tBrkdwnV=Isat*(1-arg2);
2645 Id = -Isat_tBrkdwnV * evrev + gmin * Vd;
2646 Gd = Isat_tBrkdwnV * evrev / Vte + gmin;
2656 if(Vd >= -3.0*Vte) IRfactor=1.0;
2657 else IRfactor = tIRF;
2660 if (Vd >= -3.0 * Vte)
2662 ScalarT arg1 = Vd / Vte;
2664 ScalarT evd = exp(arg1);
2665 Inorm = Isat * (evd - 1.0) + gmin * Vd;
2666 Gd1 = Isat*evd/Vte + gmin;
2671 Irec = IsatR * (evd - 1.0);
2672 Gd2 = IsatR*evd/VteR;
2678 Khi = sqrt(tIKF/(tIKF+Inorm));
2679 DKhi = 0.5*Khi*Gd1/(tIKF+Inorm);
2685 Kgen = sqrt( pow(((1-Vd/tJctPot)*(1-Vd/tJctPot) + 0.005),M) );
2686 DKgen = -M*(1-Vd/tJctPot)/(tJctPot*Kgen);
2689 Id = Inorm*Khi + Irec*Kgen;
2690 Gd = Gd1*Khi + Inorm*DKhi + Gd2*Kgen + Irec*DKgen;
2693 else if(!tBrkdwnV || (Vd >= -tBrkdwnV))
2695 ScalarT arg = 3.0 * Vte / (Vd *
CONSTe);
2696 arg = arg * arg * arg;
2697 Id = -Isat * (1.0 + arg) + gmin * Vd;
2698 Gd = Isat * 3.0 * arg / Vd + gmin;
2703 ScalarT arg1 = -(tBrkdwnV + Vd) / Vte;
2705 ScalarT evrev = exp(arg1);
2707 #ifdef Xyce_BREAKDOWN_ORIGINAL
2708 Id = -Isat * evrev + gmin * Vd;
2709 Gd = Isat * evrev / Vte + gmin;
2713 ScalarT arg2=3.0*Vte/(
CONSTe*tBrkdwnV);
2714 arg2=arg2*arg2*arg2;
2715 ScalarT Isat_tBrkdwnV=Isat*(1-arg2);
2716 Id = -Isat_tBrkdwnV * evrev + gmin * Vd;
2717 Gd = Isat_tBrkdwnV * evrev / Vte + gmin;
2728 ScalarT Czero = tJctCap * Area;
2732 ScalarT arg = 1.0 - Vc / tJctPot;
2733 ScalarT arg1 = -M * log(arg);
2735 ScalarT sarg = exp(arg1);
2738 Qd = TT * Id + tJctPot * Czero * (1.0 - arg * sarg) / (1.0 - M);
2739 Cd = TT * Gd + Czero * sarg;
2743 ScalarT Czof2 = Czero / F2;
2744 ScalarT MotJctPot = M / tJctPot;
2747 Qd = TT * Id + Czero * tF1 +
2748 Czof2 * (F3 * (Vc - tDepCap) + (0.5 * MotJctPot) *
2749 (Vc * Vc - tDepCap * tDepCap));
2751 Cd = TT * Gd + Czof2 * (F3 + MotJctPot * Vc);
2771 template <
typename ScalarT>
2778 const ScalarT & Vpp,
2782 const ScalarT & tVcrit,
2783 const ScalarT & Vte,
2791 const ScalarT & currVd_old,
2792 const ScalarT & nextVd_old,
2794 const double InitCond,
2795 const bool InitCondGiven,
2799 const bool dotICapplies,
2802 const int & newtonIter,
2803 const bool initJctFlag,
2804 const bool voltageLimiterFlag,
2805 const bool dcopFlag,
2806 const bool locaEnabledFlag
2816 if (newtonIter == 0)
2818 if (initJctFlag && voltageLimiterFlag && !dotICapplies)
2841 if (!(dcopFlag)|| (locaEnabledFlag && dcopFlag))
2843 Vd_old = currVd_old;
2848 Vd_old = nextVd_old;
2853 if (voltageLimiterFlag)
2857 if (newtonIter >= 0)
2860 if (BVGiven && (Vd <
Xycemin(0.0, -BV + 10.0 * Vte)))
2862 double Vdtmp = -( BV + Vd );
2863 Vdtmp = devSupport.
pnjlim(Vdtmp, -(Vd_old+BV), Vte, tVcrit, &ichk);
2867 Vd = devSupport.
pnjlim(Vd, Vd_old, Vte, tVcrit, &ichk);
2869 if (ichk) origFlag =
false;
2886 const std::string &name,
2887 std::vector<double> & dfdp,
2888 std::vector<double> & dqdp,
2889 std::vector<double> & dbdp,
2890 std::vector<int> & Findices,
2891 std::vector<int> & Qindices,
2892 std::vector<int> & Bindices
2896 const Model & mod = *(
dynamic_cast<const Model *
> (e1));
2900 dfdp.resize(3*sizeInstance);
2901 dqdp.resize(3*sizeInstance);
2902 Findices.resize(3*sizeInstance);
2903 Qindices.resize(3*sizeInstance);
2938 std::string paramName = ExtendedString( name ).toUpper();
2940 if (paramName==
"VJ") { VJ.diff(0,1); }
2941 else if (paramName==
"CJO") { CJO.diff(0,1); }
2942 else if (paramName==
"CJ") { CJO.diff(0,1); }
2943 else if (paramName==
"CJ0") { CJO.diff(0,1); }
2944 else if (paramName==
"M") { M.diff(0,1); }
2945 else if (paramName==
"N") { N.diff(0,1); }
2946 else if (paramName==
"IS") { IS.diff(0,1); }
2947 else if (paramName==
"JS") { IS.diff(0,1); }
2948 else if (paramName==
"EG") { EG.diff(0,1); }
2949 else if (paramName==
"XTI") { XTI.diff(0,1); }
2950 else if (paramName==
"RS") { RS.diff(0,1); }
2951 else if (paramName==
"COND") { COND.diff(0,1); }
2952 else if (paramName==
"IRF") { IRF.diff(0,1); }
2953 else if (paramName==
"NR") { NR.diff(0,1); }
2954 else if (paramName==
"IKF") { IKF.diff(0,1); }
2955 else if (paramName==
"TIKF") { TIKF.diff(0,1); }
2956 else if (paramName==
"ISR") { ISR.diff(0,1); }
2957 else if (paramName==
"IBV") { IBV.diff(0,1); }
2958 else if (paramName==
"IBVL") { IBVL.diff(0,1); }
2959 else if (paramName==
"NBV") { NBV.diff(0,1); }
2960 else if (paramName==
"NBVL") { NBVL.diff(0,1); }
2961 else if (paramName==
"BV") { BV.diff(0,1); }
2962 else if (paramName==
"VB") { BV.diff(0,1); }
2963 else if (paramName==
"TT") { TT.diff(0,1); }
2964 else if (paramName==
"FC") { FC.diff(0,1); }
2965 else if (paramName==
"KF") { KF.diff(0,1); }
2966 else if (paramName==
"AF") { AF.diff(0,1); }
2967 else if (paramName==
"TNOM") { TNOM.diff(0,1); }
2969 else if (paramName==
"TBV1") { TBV1.diff(0,1); }
2970 else if (paramName==
"TBV2") { TBV2.diff(0,1); }
2971 else if (paramName==
"TRS1") { TRS1.diff(0,1); }
2972 else if (paramName==
"TRS2") { TRS2.diff(0,1); }
2978 for (std::vector<Instance *>::const_iterator in = mod.
instanceContainer.begin();
2981 double * solVec = (*in)->extData.nextSolVectorRawPtr;
2983 fadType Vpp = solVec[(*in)->li_Pri];
2984 fadType Vn = solVec[(*in)->li_Neg];
2985 fadType Vp = solVec[(*in)->li_Pos];
3008 Temp, tJctCap, tJctPot, tDepCap, tF1, tSatCur, tSatCurR,
3009 tVcrit, tRS, tCOND, tIRF, tIKF, tBrkdwnV,
3010 TNOM, VJ, CJO, M, N, IS, EG, XTI, RS, COND, IRF,
3011 NR, IKF, TIKF, ISR, IBV, BV,
3013 TBV1, TBV2, TRS1, TRS2, FC,
3027 Temp, tJctCap, tJctPot, tDepCap, tF1,
3028 tSatCur, tSatCurR, tVcrit, tRS, tCOND,
3029 tIRF, tIKF, tBrkdwnV,
3031 Area, (*in)->lambertWFlag, (*in)->getDeviceOptions().gmin,
3033 M, BV, IBV, NBV, IBVL, NBVL, N, NR, TT, F2, F3,
3036 Id, Gd, Qd, Cd, Gspr
3043 fadType Ir = Gspr * (Vp - Vpp);
3044 dfdp[iPos] -= -Ir.dx(0);
3045 dfdp[iNeg] -= Id.dx(0);
3046 dfdp[iPri] -= (-Id.dx(0) + Ir.dx(0));
3049 dqdp[iNeg] -= Qd.dx(0);
3050 dqdp[iPri] -= -Qd.dx(0);
3052 Findices[iPos] = (*in)->li_Pos;
3053 Findices[iNeg] = (*in)->li_Neg;
3054 Findices[iPri] = (*in)->li_Pri;
3056 Qindices[iPos] = (*in)->li_Pos;
3057 Qindices[iNeg] = (*in)->li_Neg;
3058 Qindices[iPri] = (*in)->li_Pri;
const InstanceName & getName() const
static std::vector< int > jacMap
bool updateIntermediateVars()
double * qPriEquPosNodePtr
double * nextLeadCurrQCompRawPtr
double * currStoVectorRawPtr
bool updateDependentParameters()
static std::vector< int > jacMap_RS
const DeviceOptions & deviceOptions_
Descriptor & addPar(const char *parName, T default_value, T U::*varPtr)
Adds the parameter description to the parameter map.
double * daeQVectorRawPtr
bool lambertWBreakdownCurrent(double Isat, double Vte, double RS)
double * qPriEquNegNodePtr
double * fPriEquPriNodePtr
double * fPosEquPriNodePtr
double * dFdxdVpVectorRawPtr
static std::vector< std::vector< int > > jacStamp_RS
double * fPriEquNegNodePtr
double pnjlim(double vnew, double vold, double vt, double vcrit, int *icheck)
bool given(const std::string ¶meter_name) const
Pure virtual class to augment a linear system.
Parameter may be specified as time dependent expression from netlist.
void addInternalNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
double * qNegEquNegNodePtr
const std::string & getEncodedName() const
Return the instance name encoded as: [s:]*xname [s:]*Ytype!name [s:]*Utype!name!count.
void registerLIDs(const std::vector< int > &intLIDVecRef, const std::vector< int > &extLIDVecRef)
bool applyLimiters(DeviceSupport &devSupport, const ScalarT &Vp, const ScalarT &Vpp, const ScalarT &Vn, const ScalarT &tVcrit, ScalarT &Vd, ScalarT &Vd_orig, ScalarT &Vd_old, const ScalarT &currVd_old, const ScalarT &nextVd_old, const double InitCond, const bool InitCondGiven, const bool BVGiven, const int off, bool &origFlag, const bool dotICapplies, const int &newtonIter, const bool initJctFlag, const bool voltageLimiterFlag, const bool dcopFlag, const bool locaEnabledFlag)
void registerStateLIDs(const std::vector< int > &staLIDVecRef)
Sacado::Fad::SFad< double, 1 > fadType
void setNumStoreVars(int num_store_vars)
void addBranchDataNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
double * qPriEquPriNodePtr
std::vector< int > li_Neg
InstanceVector::const_iterator getInstanceEnd() const
Returns an iterator to the ending of the vector of all instances created for this device...
Base class for all parameters.
std::vector< int > li_Pos
Parameter is subject to being set to minimum junction capacitance.
RetScalarT Vt(Arg1ScalarT U, Arg2ScalarT Ud)
virtual void registerJacLIDs(const JacobianStamp &jacLIDVec)
virtual void operator()(const ParameterBase &entity, const std::string ¶m, std::vector< double > &dfdp, std::vector< double > &dqdp, std::vector< double > &dbdp, std::vector< int > &Findices, std::vector< int > &Qindices, std::vector< int > &Bindices) const
Parameter is subject to being set to minimum lead resistance.
bool processParams(ScalarT &M, ScalarT &EG, ScalarT &FC, const ScalarT &RS, ScalarT &COND, ScalarT &F2, ScalarT &F3)
Instance(const Configuration &configuration, const InstanceBlock &instance_block, Model &model, const FactoryBlock &factory_block)
double * nextJunctionVCompRawPtr
double * fNegEquNegNodePtr
double * storeLeadCurrQCompRawPtr
int getNumStoreVars() const
InstanceVector::const_iterator getInstanceBegin() const
Returns an iterator to the beginning of the vector of all instances created for this device...
static void loadModelParameters(ParametricData< Model > &model_parameters)
std::vector< Param > params
Parameters from the line.
bool updateTemperature(ScalarT &Temp, ScalarT &tJctCap, ScalarT &tJctPot, ScalarT &tDepCap, ScalarT &tF1, ScalarT &tSatCur, ScalarT &tSatCurR, ScalarT &tVcrit, ScalarT &tRS, ScalarT &tCOND, ScalarT &tIRF, ScalarT &tIKF, ScalarT &tBrkdwnV, const ScalarT &TNOM, const ScalarT &VJ, const ScalarT &CJO, const ScalarT &M, const ScalarT &N, const ScalarT &IS, const ScalarT &EG, const ScalarT &XTI, const ScalarT &RS, const ScalarT &COND, const ScalarT &IRF, const ScalarT &NR, const ScalarT &IKF, const ScalarT &TIKF, const ScalarT &ISR, const ScalarT &IBV, const ScalarT &BV, const bool &BVGiven, const ScalarT &TBV1, const ScalarT &TBV2, const ScalarT &TRS1, const ScalarT &TRS2, const ScalarT &FC, const int level)
std::vector< double > noiseDens
double * qNegEquPriNodePtr
void registerBranchDataLIDs(const std::vector< int > &branchLIDVecRef)
In addition to state vector, Xyce maintains a separate datastructure called a "branch data" vector...
std::vector< std::string > noiseNames
std::vector< Instance * > instanceContainer
void setParams(const std::vector< Param > ¶ms)
const std::string & getName() const
double * daeFVectorRawPtr
static diodeSensitivity diodeSens
double * fPriEquPosNodePtr
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
bool updateTemperature(const double &temp=-999.0)
void getNoiseSources(Xyce::Analysis::NoiseData &noiseData)
const DeviceOptions & getDeviceOptions() const
double * nextStoVectorRawPtr
bool processInstanceParams()
processInstanceParams
int numBranchDataVarsIfAllocated
static Config< T > & addConfiguration()
Adds the device to the Xyce device configuration.
static std::vector< std::vector< int > > jacStamp
Linear::Matrix * dFdxMatrixPtr
const DeviceOptions & getDeviceOptions() const
Returns the device options given during device construction.
The Device class is an interface for device implementations.
void loadNodeSymbols(Util::SymbolTable &symbol_table) const
Populates and returns the store name map.
bool updatePrimaryState()
bool processParams()
processParams
void addStoreNode(Util::SymbolTable &symbol_table, int index, const InstanceName &instance_name, const std::string &lead_name)
const std::vector< std::vector< int > > & jacobianStamp() const
bool lambertWLinearReverseBias(double Isat, double Vte, double RS)
virtual std::ostream & printOutInstances(std::ostream &os) const
const SolverState & solverState_
void setupNoiseSources(Xyce::Analysis::NoiseData &noiseData)
double * dQdxdVpVectorRawPtr
Class Configuration contains device configuration data.
static std::vector< std::vector< int > > jacMap2_RS
std::vector< double > lnNoiseDens
bool updateIntermediateVars(const ScalarT &Vp, const ScalarT &Vpp, const ScalarT &Vn, const ScalarT &Vd, const ScalarT &Temp, const ScalarT &tJctCap, const ScalarT &tJctPot, const ScalarT &tDepCap, const ScalarT &tF1, const ScalarT &tSatCur, const ScalarT &tSatCurR, const ScalarT &tVcrit, const ScalarT &tRS, const ScalarT &tCOND, const ScalarT &tIRF, const ScalarT &tIKF, const ScalarT &tBrkdwnV, const ScalarT &Area, const int &lambertWFlag, const double &gmin, const ScalarT M, const ScalarT BV, const ScalarT IBV, const ScalarT NBV, const ScalarT IBVL, const ScalarT NBVL, const ScalarT N, const ScalarT NR, const ScalarT TT, const ScalarT F2, const ScalarT F3, const int level, ScalarT &Id, ScalarT &Gd, ScalarT &Qd, ScalarT &Cd, ScalarT &Gspr)
static Device * factory(const Configuration &configuration, const FactoryBlock &factory_block)
void jacStampMap(const JacobianStamp &stamp_parent, IdVector &map_parent, JacobianStamp &map2_parent, JacobianStamp &stamp, IdVector &map, JacobianStamp &map2, int from, int to, int original_size)
double * qPosEquPriNodePtr
const SolverState & getSolverState() const
double * nextLeadCurrFCompRawPtr
void lambertw(double x, double &w, int &ierr, double &xi)
virtual bool loadDAEMatrices(Linear::Matrix &dFdx, Linear::Matrix &dQdx)
Populates the device's Jacobian object with these pointers.
void setNumBranchDataVars(int num_branch_data_vars)
virtual bool updateState(double *solVec, double *staVec, double *stoVec)
Updates the devices state information.
#define Xyce_NONPOINTER_MATRIX_LOAD
void noiseSupport(double &noise, double &lnNoise, const int type, const double param, const double temp)
static void loadInstanceParameters(ParametricData< Instance > &instance_parameters)
static std::vector< std::vector< int > > jacMap2
double * qPosEquPosNodePtr
const ExternData & extData
ModelBlock represents a .MODEL line from the netlist.
bool lambertWCurrent(double Isat, double Vte, double RS)
Manages parameter binding for class C.
double * fNegEquPriNodePtr
InstanceBlock represent a device instance line from the netlist.
std::vector< Param > params
void registerJacLIDs(const std::vector< std::vector< int > > &jacLIDVec)
Linear::Matrix * dQdxMatrixPtr
virtual void forEachInstance(DeviceInstanceOp &op) const
Apply a device instance "op" to all instances associated with this model.
int li_branch_data
Index for Lead Current and junction voltage (for power calculations)
ScalarT Xycemin(ScalarT f1, ScalarT f2)
Linear::Vector * flagSolVectorPtr
int getNumNoiseSources() const
double * fPosEquPosNodePtr
int getNumBranchDataVars() const
void setModParams(const std::vector< Param > ¶ms)
virtual bool loadDAEVectors(double *solVec, double *fVec, double *qVec, double *bVec, double *storeLeadF, double *storeLeadQ, double *leadF, double *leadQ, double *junctionV)
Populates the device's ExternData object with these pointers.
double * nextSolVectorRawPtr
int numLeadCurrentStoreVars
void registerStoreLIDs(const std::vector< int > &stoLIDVecRef)