49 #include <Xyce_config.h>
60 #include <N_UTL_Expression.h>
81 Temp(getDeviceOptions().temp.getImmutableValue<double>()),
82 charge(1.602176565e-19),
91 h_planck (6.62606957e-34),
92 e_mass (9.10938291e-31),
94 photogenOnFlag(false),
102 photoTstop (1.0e+100),
116 photoA1_ramp_old(0.0),
119 maxPhotoDelta(1.0e+21),
120 photoContinuationFinished (false),
123 maxVoltDelta(3.0*Vt),
124 enableContinuationCalled(false),
125 continuationAlpha (1.0),
126 mobModelName(
"carr"),
127 fieldDependentMobility(false),
128 fieldDependentMobilityGiven(false),
133 dopingSensMod (false),
134 photogenSensMod (false),
135 variablesScaled(false),
171 return(1 - x*x/6.0*(1.0 - 7.0*x*x/60.0));
204 if (x < -700.0) x = -700.0;
205 else if (x > 700.0) x = 700.0;
211 return((y - x*cosh(x))/(y*y));
215 return(-x/3.0*(1.0 - 7.0*x*x/30.0));
220 return((y - x*cosh(x))/(y*y));
250 return(1.0 / (1.0 + exp(x)));
293 y = exp(x); z = y + 1.0;
return(-y/(z*z));
315 (
double n1,
double n2,
double E,
double u,
double h)
318 double dV = E*h/(2.0*Ut);
319 double n = n1*aux2(dV)+n2*aux2(-dV);
320 double dndx = aux1(-dV)*(n2-n1)/h;
321 double J = MU*((n*E)+(Ut*dndx));
323 #ifdef Xyce_DEBUG_DEVICE
324 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
326 Xyce::dout().width(24);
327 Xyce::dout().precision(16);
328 Xyce::dout().setf(std::ios::scientific);
330 Xyce::dout() << std::endl;
331 Xyce::dout() <<
" MU = "<< MU << std::endl;
332 Xyce::dout() <<
" n = "<< n <<
" dndx = "<< dndx <<
" E = "<< E << std::endl;
333 Xyce::dout() <<
" dV = "<< dV <<
" Ut = "<< Ut <<
" Jn = "<< J << std::endl;
334 Xyce::dout() <<
" n1 = "<< n1 <<
" n2 = "<< n2 <<
" (n2-n1) = "<<(n2-n1)<< std::endl;
335 Xyce::dout() <<
" h = "<< h << std::endl;
336 Xyce::dout() <<
" aux1(-dV) = " << aux1(-dV) << std::endl;
337 Xyce::dout() <<
" aux2( dV) = " << aux2( dV) << std::endl;
338 Xyce::dout() <<
" aux2(-dV) = " << aux2( dV) << std::endl;
339 Xyce::dout() << std::endl;
359 (
double n1,
double n2,
double E,
double u,
double h)
362 double dV = E*h/(2.0*Ut);
363 double n = n1*aux2(dV)+n2*aux2(-dV);
364 double dEdv1 = 1.0/h;
365 double ddVdv1 = 1.0/(2.0*Ut);
366 double dNdv1 = n1*( ddVdv1*pd1aux2( dV) ) + n2*(-ddVdv1*pd1aux2(-dV) );
367 double dDNDXdv1 = (n2-n1)/h * (-ddVdv1) * pd1aux1(-dV);
368 double dJdv1 = MU*(dNdv1*E + n*dEdv1 + Ut*dDNDXdv1);
385 (
double n1,
double n2,
double E,
double u,
double h)
388 double dV = E*h/(2.0*Ut);
389 double n = n1*aux2(dV)+n2*aux2(-dV);
390 double dEdv2 = -1.0/h;
391 double ddVdv2 = -1.0/(2.0*Ut);
392 double dNdv2 = n1*( ddVdv2*pd1aux2( dV) ) + n2*(-ddVdv2*pd1aux2(-dV) );
393 double dDNDXdv2 = (n2-n1)/h * (-ddVdv2) * pd1aux1(-dV);
394 double dJdv2 = MU*(dNdv2*E + n*dEdv2 + Ut*dDNDXdv2);
411 (
double n1,
double n2,
double E,
double u,
double h)
414 double dV = E*h/(2.0*Ut);
415 double dNdn1 = aux2( dV);
416 double dDNDXdn1 = -aux1(-dV)/h;
417 double dJdn1 = MU*(dNdn1*E + Ut*dDNDXdn1);
434 (
double n1,
double n2,
double E,
double u,
double h)
437 double dV = E*h/(2.0*Ut);
438 double dNdn2 = aux2(-dV);
439 double dDNDXdn2 = aux1(-dV)/h;
440 double dJdn2 = MU*(dNdn2*E + Ut*dDNDXdn2);
453 (
double p1,
double p2,
double E,
double u,
double h)
456 double dV = E*h/(2.0*Ut);
457 double p = p1*aux2(-dV)+p2*aux2(dV);
458 double dpdx = aux1(-dV)*(p2-p1)/h;
459 double J = MU*(p*E-Ut*dpdx);
461 #ifdef Xyce_DEBUG_DEVICE
462 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
464 Xyce::dout().width(16);
465 Xyce::dout().precision(8);
466 Xyce::dout().setf(std::ios::scientific);
468 Xyce::dout() << std::endl;
469 Xyce::dout() <<
" MU = "<< MU << std::endl;
470 Xyce::dout() <<
" p = "<< p <<
" dpdx = "<<dpdx<<
" E = "<<E <<std::endl;
471 Xyce::dout() <<
" dV = "<< dV <<
" Ut = "<<Ut<<
" Jpx = "<<J<<std::endl;
472 Xyce::dout() <<
" p1 = "<< p1 <<
" p2 = "<<p2<<
" (p2-p1) = "<<(p2-p1)<<std::endl;
473 Xyce::dout() <<
" h = "<< h << std::endl;
474 Xyce::dout() <<
" aux1(-dV) = " << aux1(-dV) << std::endl;
475 Xyce::dout() <<
" aux2( dV) = " << aux2( dV) << std::endl;
476 Xyce::dout() <<
" aux2(-dV) = " << aux2( dV) << std::endl;
477 Xyce::dout() << std::endl;
497 (
double p1,
double p2,
double E,
double u,
double h)
500 double dV = E*h/(2.0*Ut);
501 double p = p1*aux2(-dV)+p2*aux2(dV);
502 double dEdv1 = 1.0/h;
503 double ddVdv1 = 1.0/(2.0*Ut);
504 double dNdv1 = p1*(-ddVdv1*pd1aux2(-dV) ) + p2*(ddVdv1*pd1aux2(dV));
505 double dDNDXdv1 = (p2-p1)/h * (-ddVdv1) * pd1aux1(-dV);
506 double dJdv1 = MU*(dNdv1*E + p*dEdv1 - Ut*dDNDXdv1);
524 (
double p1,
double p2,
double E,
double u,
double h)
527 double dV = E*h/(2.0*Ut);
528 double p = p1*aux2(-dV)+p2*aux2(dV);
529 double dEdv2 = -1.0/h;
530 double ddVdv2 = -1.0/(2.0*Ut);
531 double dNdv2 = p1*(-ddVdv2*pd1aux2(-dV) ) + p2*(ddVdv2*pd1aux2(dV));
532 double dDNDXdv2 = (p2-p1)/h * (-ddVdv2) * pd1aux1(-dV);
533 double dJdv2 = MU*(dNdv2*E + p*dEdv2 - Ut*dDNDXdv2);
551 (
double p1,
double p2,
double E,
double u,
double h)
554 double dV = E*h/(2.0*Ut);
555 double dNdp1 = aux2(-dV);
556 double dDNDXdp1 = -aux1(-dV)/h;
557 double dJdn1 = MU*(dNdp1*E - Ut*dDNDXdp1);
574 (
double p1,
double p2,
double E,
double u,
double h)
577 double dV = E*h/(2.0*Ut);
578 double dNdp2 = aux2( dV);
579 double dDNDXdp2 = aux1(-dV)/h;
580 double dJdn2 = MU*(dNdp2*E - Ut*dDNDXdp2);
597 (
double n1,
double n2,
double E,
double u,
double h,
int z)
599 double charge_number =
static_cast<double>(z);
601 double dV = -E*h/(2.0*Ut);
602 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
603 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
604 double J = MU*((n*E)-Ut*(dndx));
620 double charge_number =
static_cast<double>(z);
641 (
double n1,
double n2,
double E,
double u,
double h,
int z)
643 double charge_number =
static_cast<double>(z);
645 double dV = -E*h/(2.0*Ut);
646 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
647 double dEdv1 = 1.0/h;
648 double ddVdv1 = -1.0/(2.0*Ut);
649 double dNdv1 = charge_number*(n1*charge_number*ddVdv1*pd1aux2(charge_number*dV)
650 -n2*charge_number*ddVdv1*pd1aux2(-charge_number*dV));
651 double dDNDXdv1 = (n2-n1)/h * (-charge_number*ddVdv1) * pd1aux1(-charge_number*dV);
652 double dJdv1 = MU*((dNdv1*E + n*dEdv1) - Ut*dDNDXdv1);
668 (
double n1,
double n2,
double E,
double u,
double h,
int z)
670 double charge_number =
static_cast<double>(z);
672 double dV = -E*h/(2.0*Ut);
673 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
674 double dEdv2 = -1.0/h;
675 double ddVdv2 = 1.0/(2.0*Ut);
676 double dNdv2 = charge_number*(n1*charge_number*ddVdv2*pd1aux2(charge_number*dV)
677 -n2*charge_number*ddVdv2*pd1aux2(-charge_number*dV));
678 double dDNDXdv2 = (n2-n1)/h * (-charge_number*ddVdv2) * pd1aux1(-charge_number*dV);
679 double dJdv2 = MU*((dNdv2*E + n*dEdv2) - Ut*dDNDXdv2);
695 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
697 double dJdv1=dJdV1_qdep (n1, n2, E, u.val(), h, z);
698 double dudv1=u.dx(0);
703 double charge_number =
static_cast<double>(z);
704 double dV = -E*h/(2.0*Ut);
705 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
706 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
707 double dJ = dudv1*((n*E)-Ut*(dndx));
725 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
727 double dJdv2=dJdV2_qdep (n1, n2, E, u.val(), h, z);
728 double dudv2=u.dx(1);
733 double charge_number =
static_cast<double>(z);
734 double dV = -E*h/(2.0*Ut);
735 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
736 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
737 double dJ = dudv2*((n*E)-Ut*(dndx));
755 (
double n1,
double n2,
double E,
double u,
double h,
int z)
757 double charge_number =
static_cast<double>(z);
759 double dV = -E*h/(2.0*Ut);
760 double dNdn1 = charge_number*aux2(charge_number*dV);
761 double dDNDXdn1 = -aux1(-charge_number*dV)/h;
762 double dJdn1 = MU*(dNdn1*E - Ut*dDNDXdn1);
778 (
double n1,
double n2,
double E,
double u,
double h,
int z)
780 double charge_number =
static_cast<double>(z);
782 double dV = -E*h/(2.0*Ut);
783 double dNdn2 = charge_number*aux2(-charge_number*dV);
784 double dDNDXdn2 = aux1(-charge_number*dV)/h;
785 double dJdn2 = MU*(dNdn2*E - Ut*dDNDXdn2);
805 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
807 double dJdn1=dJdn1_qdep (n1, n2, E, u.val(), h, z);
809 if (z < 0) dudn1=u.dx(2);
814 double charge_number =
static_cast<double>(z);
815 double dV = -E*h/(2.0*Ut);
816 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
817 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
819 dJdn1 += dudn1*((n*E)-Ut*(dndx));
839 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
841 double dJdn2=dJdn2_qdep (n1, n2, E, u.val(), h, z);
843 if (z < 0) dudn2=u.dx(3);
848 double charge_number =
static_cast<double>(z);
849 double dV = -E*h/(2.0*Ut);
850 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
851 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
853 dJdn2 += dudn2*((n*E)-Ut*(dndx));
877 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
881 if (z < 0) dudp1=u.dx(4);
886 double charge_number =
static_cast<double>(z);
887 double dV = -E*h/(2.0*Ut);
888 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
889 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
891 dJdp1 += dudp1*((n*E)-Ut*(dndx));
915 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
919 if (z < 0) dudp2=u.dx(5);
924 double charge_number =
static_cast<double>(z);
925 double dV = -E*h/(2.0*Ut);
926 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
927 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
928 dJdp2 += dudp2*((n*E)-Ut*(dndx));
948 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
951 double dudbm1=u.dx(6);
956 double charge_number =
static_cast<double>(z);
957 double dV = -E*h/(2.0*Ut);
958 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
959 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
960 double dJ = dudbm1*((n*E)-Ut*(dndx));
979 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
982 double dudbm2=u.dx(8);
987 double charge_number =
static_cast<double>(z);
988 double dV = -E*h/(2.0*Ut);
989 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
990 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
991 double dJ = dudbm2*((n*E)-Ut*(dndx));
1010 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
1013 double dudpp1=u.dx(7);
1018 double charge_number =
static_cast<double>(z);
1019 double dV = -E*h/(2.0*Ut);
1020 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
1021 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
1022 double dJ = dudpp1*((n*E)-Ut*(dndx));
1041 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
1044 double dudpp2=u.dx(9);
1049 double charge_number =
static_cast<double>(z);
1050 double dV = -E*h/(2.0*Ut);
1051 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
1052 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
1053 double dJ = dudpp2*((n*E)-Ut*(dndx));
1081 double DevicePDEInstance::nsdep (
double x,
double W,
double Dt)
1083 double D = 2.0 * sqrt(Dt);
1084 double Wh = W / 2.0;
1085 return 0.5 * (
erf((Wh + x)/D) +
erf((Wh - x)/D));
1131 double DevicePDEInstance::ngdep
1132 (
double x,
double y,
double W,
double ax,
double ay)
1134 double xprime = fabs(x) - (0.5 * W);
1135 return ((xprime <= 0.0) ? 1.0 : exp(-ax*xprime*xprime))*
1136 ((y > 0.0) ? 0.0 : exp(-ay*y*y));
1174 double DevicePDEInstance::ngdep2
1175 (
double x,
double y,
double ax,
double ay)
1177 double retVal = exp(-ax*x*x)* exp(-ay*y*y);
1192 double t1 = 1.0 / (1.0 + 0.3275911 * fabs(x));
1193 double t2 = t1 * t1;
1194 double t3 = t2 * t1;
1195 double t4 = t3 * t1;
1196 double t5 = t4 * t1;
1197 double result = 1.0 - (0.254829592*t1 - 0.284496736*t2 + 1.421413741*t3 -
1198 1.453152027*t4 + 1.061405429*t5) * exp(-x*x);
1199 return (x < 0.0) ? -result : result;
1214 return 2.0 / sqrt(pi) * exp(-x*x);
1238 std::string pdeString(
"Y%PDE%");
1239 std::string neutString(
"Y%NEUTRON%");
1240 std::string::size_type pos1 =
getName().find(pdeString);
1241 std::string::size_type pos2 =
getName().find(neutString);
1243 if (pos1 != std::string::npos)
1245 std::string tmp1 =
"";
1246 if (pos1 > 0) tmp1 =
getName().substr(0,pos1);
1247 std::string tmp2 =
getName().substr(pos1+6,
getName().length()-1);
1250 else if (pos2 != std::string::npos)
1252 std::string tmp1 =
"";
1253 if (pos2 > 0) tmp1 =
getName().substr(0,pos2);
1254 std::string tmp2 =
getName().substr(pos2+10,
getName().length()-1);
1271 #ifdef Xyce_DEBUG_DEVICE
1274 Xyce::dout() <<
"outputName = "<<
outputName << std::endl;