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),
169 return(1 - x*x/6.0*(1.0 - 7.0*x*x/60.0));
202 if (x < -700.0) x = -700.0;
203 else if (x > 700.0) x = 700.0;
209 return((y - x*cosh(x))/(y*y));
213 return(-x/3.0*(1.0 - 7.0*x*x/30.0));
218 return((y - x*cosh(x))/(y*y));
248 return(1.0 / (1.0 + exp(x)));
291 y = exp(x); z = y + 1.0;
return(-y/(z*z));
313 (
double n1,
double n2,
double E,
double u,
double h)
316 double dV = E*h/(2.0*Ut);
317 double n = n1*aux2(dV)+n2*aux2(-dV);
318 double dndx = aux1(-dV)*(n2-n1)/h;
319 double J = MU*((n*E)+(Ut*dndx));
321 #ifdef Xyce_DEBUG_DEVICE
322 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
324 Xyce::dout().width(24);
325 Xyce::dout().precision(16);
326 Xyce::dout().setf(std::ios::scientific);
328 Xyce::dout() << std::endl;
329 Xyce::dout() <<
" MU = "<< MU << std::endl;
330 Xyce::dout() <<
" n = "<< n <<
" dndx = "<< dndx <<
" E = "<< E << std::endl;
331 Xyce::dout() <<
" dV = "<< dV <<
" Ut = "<< Ut <<
" Jn = "<< J << std::endl;
332 Xyce::dout() <<
" n1 = "<< n1 <<
" n2 = "<< n2 <<
" (n2-n1) = "<<(n2-n1)<< std::endl;
333 Xyce::dout() <<
" h = "<< h << std::endl;
334 Xyce::dout() <<
" aux1(-dV) = " << aux1(-dV) << std::endl;
335 Xyce::dout() <<
" aux2( dV) = " << aux2( dV) << std::endl;
336 Xyce::dout() <<
" aux2(-dV) = " << aux2( dV) << std::endl;
337 Xyce::dout() << std::endl;
357 (
double n1,
double n2,
double E,
double u,
double h)
360 double dV = E*h/(2.0*Ut);
361 double n = n1*aux2(dV)+n2*aux2(-dV);
362 double dEdv1 = 1.0/h;
363 double ddVdv1 = 1.0/(2.0*Ut);
364 double dNdv1 = n1*( ddVdv1*pd1aux2( dV) ) + n2*(-ddVdv1*pd1aux2(-dV) );
365 double dDNDXdv1 = (n2-n1)/h * (-ddVdv1) * pd1aux1(-dV);
366 double dJdv1 = MU*(dNdv1*E + n*dEdv1 + Ut*dDNDXdv1);
383 (
double n1,
double n2,
double E,
double u,
double h)
386 double dV = E*h/(2.0*Ut);
387 double n = n1*aux2(dV)+n2*aux2(-dV);
388 double dEdv2 = -1.0/h;
389 double ddVdv2 = -1.0/(2.0*Ut);
390 double dNdv2 = n1*( ddVdv2*pd1aux2( dV) ) + n2*(-ddVdv2*pd1aux2(-dV) );
391 double dDNDXdv2 = (n2-n1)/h * (-ddVdv2) * pd1aux1(-dV);
392 double dJdv2 = MU*(dNdv2*E + n*dEdv2 + Ut*dDNDXdv2);
409 (
double n1,
double n2,
double E,
double u,
double h)
412 double dV = E*h/(2.0*Ut);
413 double dNdn1 = aux2( dV);
414 double dDNDXdn1 = -aux1(-dV)/h;
415 double dJdn1 = MU*(dNdn1*E + Ut*dDNDXdn1);
432 (
double n1,
double n2,
double E,
double u,
double h)
435 double dV = E*h/(2.0*Ut);
436 double dNdn2 = aux2(-dV);
437 double dDNDXdn2 = aux1(-dV)/h;
438 double dJdn2 = MU*(dNdn2*E + Ut*dDNDXdn2);
451 (
double p1,
double p2,
double E,
double u,
double h)
454 double dV = E*h/(2.0*Ut);
455 double p = p1*aux2(-dV)+p2*aux2(dV);
456 double dpdx = aux1(-dV)*(p2-p1)/h;
457 double J = MU*(p*E-Ut*dpdx);
459 #ifdef Xyce_DEBUG_DEVICE
460 if (getDeviceOptions().debugLevel > 1 && getSolverState().debugTimeFlag)
462 Xyce::dout().width(16);
463 Xyce::dout().precision(8);
464 Xyce::dout().setf(std::ios::scientific);
466 Xyce::dout() << std::endl;
467 Xyce::dout() <<
" MU = "<< MU << std::endl;
468 Xyce::dout() <<
" p = "<< p <<
" dpdx = "<<dpdx<<
" E = "<<E <<std::endl;
469 Xyce::dout() <<
" dV = "<< dV <<
" Ut = "<<Ut<<
" Jpx = "<<J<<std::endl;
470 Xyce::dout() <<
" p1 = "<< p1 <<
" p2 = "<<p2<<
" (p2-p1) = "<<(p2-p1)<<std::endl;
471 Xyce::dout() <<
" h = "<< h << std::endl;
472 Xyce::dout() <<
" aux1(-dV) = " << aux1(-dV) << std::endl;
473 Xyce::dout() <<
" aux2( dV) = " << aux2( dV) << std::endl;
474 Xyce::dout() <<
" aux2(-dV) = " << aux2( dV) << std::endl;
475 Xyce::dout() << std::endl;
495 (
double p1,
double p2,
double E,
double u,
double h)
498 double dV = E*h/(2.0*Ut);
499 double p = p1*aux2(-dV)+p2*aux2(dV);
500 double dEdv1 = 1.0/h;
501 double ddVdv1 = 1.0/(2.0*Ut);
502 double dNdv1 = p1*(-ddVdv1*pd1aux2(-dV) ) + p2*(ddVdv1*pd1aux2(dV));
503 double dDNDXdv1 = (p2-p1)/h * (-ddVdv1) * pd1aux1(-dV);
504 double dJdv1 = MU*(dNdv1*E + p*dEdv1 - Ut*dDNDXdv1);
522 (
double p1,
double p2,
double E,
double u,
double h)
525 double dV = E*h/(2.0*Ut);
526 double p = p1*aux2(-dV)+p2*aux2(dV);
527 double dEdv2 = -1.0/h;
528 double ddVdv2 = -1.0/(2.0*Ut);
529 double dNdv2 = p1*(-ddVdv2*pd1aux2(-dV) ) + p2*(ddVdv2*pd1aux2(dV));
530 double dDNDXdv2 = (p2-p1)/h * (-ddVdv2) * pd1aux1(-dV);
531 double dJdv2 = MU*(dNdv2*E + p*dEdv2 - Ut*dDNDXdv2);
549 (
double p1,
double p2,
double E,
double u,
double h)
552 double dV = E*h/(2.0*Ut);
553 double dNdp1 = aux2(-dV);
554 double dDNDXdp1 = -aux1(-dV)/h;
555 double dJdn1 = MU*(dNdp1*E - Ut*dDNDXdp1);
572 (
double p1,
double p2,
double E,
double u,
double h)
575 double dV = E*h/(2.0*Ut);
576 double dNdp2 = aux2( dV);
577 double dDNDXdp2 = aux1(-dV)/h;
578 double dJdn2 = MU*(dNdp2*E - Ut*dDNDXdp2);
595 (
double n1,
double n2,
double E,
double u,
double h,
int z)
597 double charge_number =
static_cast<double>(z);
599 double dV = -E*h/(2.0*Ut);
600 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
601 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
602 double J = MU*((n*E)-Ut*(dndx));
618 double charge_number =
static_cast<double>(z);
639 (
double n1,
double n2,
double E,
double u,
double h,
int z)
641 double charge_number =
static_cast<double>(z);
643 double dV = -E*h/(2.0*Ut);
644 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
645 double dEdv1 = 1.0/h;
646 double ddVdv1 = -1.0/(2.0*Ut);
647 double dNdv1 = charge_number*(n1*charge_number*ddVdv1*pd1aux2(charge_number*dV)
648 -n2*charge_number*ddVdv1*pd1aux2(-charge_number*dV));
649 double dDNDXdv1 = (n2-n1)/h * (-charge_number*ddVdv1) * pd1aux1(-charge_number*dV);
650 double dJdv1 = MU*((dNdv1*E + n*dEdv1) - Ut*dDNDXdv1);
666 (
double n1,
double n2,
double E,
double u,
double h,
int z)
668 double charge_number =
static_cast<double>(z);
670 double dV = -E*h/(2.0*Ut);
671 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
672 double dEdv2 = -1.0/h;
673 double ddVdv2 = 1.0/(2.0*Ut);
674 double dNdv2 = charge_number*(n1*charge_number*ddVdv2*pd1aux2(charge_number*dV)
675 -n2*charge_number*ddVdv2*pd1aux2(-charge_number*dV));
676 double dDNDXdv2 = (n2-n1)/h * (-charge_number*ddVdv2) * pd1aux1(-charge_number*dV);
677 double dJdv2 = MU*((dNdv2*E + n*dEdv2) - Ut*dDNDXdv2);
693 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
695 double dJdv1=dJdV1_qdep (n1, n2, E, u.val(), h, z);
696 double dudv1=u.dx(0);
701 double charge_number =
static_cast<double>(z);
702 double dV = -E*h/(2.0*Ut);
703 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
704 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
705 double dJ = dudv1*((n*E)-Ut*(dndx));
723 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
725 double dJdv2=dJdV2_qdep (n1, n2, E, u.val(), h, z);
726 double dudv2=u.dx(1);
731 double charge_number =
static_cast<double>(z);
732 double dV = -E*h/(2.0*Ut);
733 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
734 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
735 double dJ = dudv2*((n*E)-Ut*(dndx));
753 (
double n1,
double n2,
double E,
double u,
double h,
int z)
755 double charge_number =
static_cast<double>(z);
757 double dV = -E*h/(2.0*Ut);
758 double dNdn1 = charge_number*aux2(charge_number*dV);
759 double dDNDXdn1 = -aux1(-charge_number*dV)/h;
760 double dJdn1 = MU*(dNdn1*E - Ut*dDNDXdn1);
776 (
double n1,
double n2,
double E,
double u,
double h,
int z)
778 double charge_number =
static_cast<double>(z);
780 double dV = -E*h/(2.0*Ut);
781 double dNdn2 = charge_number*aux2(-charge_number*dV);
782 double dDNDXdn2 = aux1(-charge_number*dV)/h;
783 double dJdn2 = MU*(dNdn2*E - Ut*dDNDXdn2);
803 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
805 double dJdn1=dJdn1_qdep (n1, n2, E, u.val(), h, z);
807 if (z < 0) dudn1=u.dx(2);
812 double charge_number =
static_cast<double>(z);
813 double dV = -E*h/(2.0*Ut);
814 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
815 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
817 dJdn1 += dudn1*((n*E)-Ut*(dndx));
837 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
839 double dJdn2=dJdn2_qdep (n1, n2, E, u.val(), h, z);
841 if (z < 0) dudn2=u.dx(3);
846 double charge_number =
static_cast<double>(z);
847 double dV = -E*h/(2.0*Ut);
848 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
849 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
851 dJdn2 += dudn2*((n*E)-Ut*(dndx));
875 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
879 if (z < 0) dudp1=u.dx(4);
884 double charge_number =
static_cast<double>(z);
885 double dV = -E*h/(2.0*Ut);
886 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
887 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
889 dJdp1 += dudp1*((n*E)-Ut*(dndx));
913 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
917 if (z < 0) dudp2=u.dx(5);
922 double charge_number =
static_cast<double>(z);
923 double dV = -E*h/(2.0*Ut);
924 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
925 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
926 dJdp2 += dudp2*((n*E)-Ut*(dndx));
946 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
949 double dudbm1=u.dx(6);
954 double charge_number =
static_cast<double>(z);
955 double dV = -E*h/(2.0*Ut);
956 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
957 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
958 double dJ = dudbm1*((n*E)-Ut*(dndx));
977 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
980 double dudbm2=u.dx(8);
985 double charge_number =
static_cast<double>(z);
986 double dV = -E*h/(2.0*Ut);
987 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
988 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
989 double dJ = dudbm2*((n*E)-Ut*(dndx));
1008 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
1011 double dudpp1=u.dx(7);
1016 double charge_number =
static_cast<double>(z);
1017 double dV = -E*h/(2.0*Ut);
1018 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
1019 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
1020 double dJ = dudpp1*((n*E)-Ut*(dndx));
1039 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
1042 double dudpp2=u.dx(9);
1047 double charge_number =
static_cast<double>(z);
1048 double dV = -E*h/(2.0*Ut);
1049 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
1050 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
1051 double dJ = dudpp2*((n*E)-Ut*(dndx));
1079 double DevicePDEInstance::nsdep (
double x,
double W,
double Dt)
1081 double D = 2.0 * sqrt(Dt);
1082 double Wh = W / 2.0;
1083 return 0.5 * (
erf((Wh + x)/D) +
erf((Wh - x)/D));
1129 double DevicePDEInstance::ngdep
1130 (
double x,
double y,
double W,
double ax,
double ay)
1132 double xprime = fabs(x) - (0.5 * W);
1133 return ((xprime <= 0.0) ? 1.0 : exp(-ax*xprime*xprime))*
1134 ((y > 0.0) ? 0.0 : exp(-ay*y*y));
1172 double DevicePDEInstance::ngdep2
1173 (
double x,
double y,
double ax,
double ay)
1175 double retVal = exp(-ax*x*x)* exp(-ay*y*y);
1190 double t1 = 1.0 / (1.0 + 0.3275911 * fabs(x));
1191 double t2 = t1 * t1;
1192 double t3 = t2 * t1;
1193 double t4 = t3 * t1;
1194 double t5 = t4 * t1;
1195 double result = 1.0 - (0.254829592*t1 - 0.284496736*t2 + 1.421413741*t3 -
1196 1.453152027*t4 + 1.061405429*t5) * exp(-x*x);
1197 return (x < 0.0) ? -result : result;
1212 return 2.0 / sqrt(pi) * exp(-x*x);