49 #include <Xyce_config.h>
60 #include <N_UTL_Expression.h>
61 #include <N_UTL_Math.h>
82 Temp(getDeviceOptions().temp.getImmutableValue<double>()),
92 h_planck (6.62606957e-34),
93 e_mass (9.10938291e-31),
96 enableContinuationCalled(false),
97 continuationAlpha (1.0),
99 fieldDependentMobility(false),
100 fieldDependentMobilityGiven(false),
105 dopingSensMod (false),
106 photogenSensMod (false),
107 variablesScaled(false),
141 return(1 - x*x/6.0*(1.0 - 7.0*x*x/60.0));
174 if (x < -700.0) x = -700.0;
175 else if (x > 700.0) x = 700.0;
181 return((y - x*cosh(x))/(y*y));
185 return(-x/3.0*(1.0 - 7.0*x*x/30.0));
190 return((y - x*cosh(x))/(y*y));
220 return(1.0 / (1.0 + exp(x)));
263 y = exp(x); z = y + 1.0;
return(-y/(z*z));
285 (
double n1,
double n2,
double E,
double u,
double h)
288 double dV = E*h/(2.0*Ut);
289 double n = n1*aux2(dV)+n2*aux2(-dV);
290 double dndx = aux1(-dV)*(n2-n1)/h;
291 double J = MU*((n*E)+(Ut*dndx));
293 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
295 Xyce::dout().width(24);
296 Xyce::dout().precision(16);
297 Xyce::dout().setf(std::ios::scientific);
299 Xyce::dout() << std::endl;
300 Xyce::dout() <<
" MU = "<< MU << std::endl;
301 Xyce::dout() <<
" n = "<< n <<
" dndx = "<< dndx <<
" E = "<< E << std::endl;
302 Xyce::dout() <<
" dV = "<< dV <<
" Ut = "<< Ut <<
" Jn = "<< J << std::endl;
303 Xyce::dout() <<
" n1 = "<< n1 <<
" n2 = "<< n2 <<
" (n2-n1) = "<<(n2-n1)<< std::endl;
304 Xyce::dout() <<
" h = "<< h << std::endl;
305 Xyce::dout() <<
" aux1(-dV) = " << aux1(-dV) << std::endl;
306 Xyce::dout() <<
" aux2( dV) = " << aux2( dV) << std::endl;
307 Xyce::dout() <<
" aux2(-dV) = " << aux2( dV) << std::endl;
308 Xyce::dout() << std::endl;
327 (
double n1,
double n2,
double E,
double u,
double h)
330 double dV = E*h/(2.0*Ut);
331 double n = n1*aux2(dV)+n2*aux2(-dV);
332 double dEdv1 = 1.0/h;
333 double ddVdv1 = 1.0/(2.0*Ut);
334 double dNdv1 = n1*( ddVdv1*pd1aux2( dV) ) + n2*(-ddVdv1*pd1aux2(-dV) );
335 double dDNDXdv1 = (n2-n1)/h * (-ddVdv1) * pd1aux1(-dV);
336 double dJdv1 = MU*(dNdv1*E + n*dEdv1 + Ut*dDNDXdv1);
353 (
double n1,
double n2,
double E,
double u,
double h)
356 double dV = E*h/(2.0*Ut);
357 double n = n1*aux2(dV)+n2*aux2(-dV);
358 double dEdv2 = -1.0/h;
359 double ddVdv2 = -1.0/(2.0*Ut);
360 double dNdv2 = n1*( ddVdv2*pd1aux2( dV) ) + n2*(-ddVdv2*pd1aux2(-dV) );
361 double dDNDXdv2 = (n2-n1)/h * (-ddVdv2) * pd1aux1(-dV);
362 double dJdv2 = MU*(dNdv2*E + n*dEdv2 + Ut*dDNDXdv2);
379 (
double n1,
double n2,
double E,
double u,
double h)
382 double dV = E*h/(2.0*Ut);
383 double dNdn1 = aux2( dV);
384 double dDNDXdn1 = -aux1(-dV)/h;
385 double dJdn1 = MU*(dNdn1*E + Ut*dDNDXdn1);
402 (
double n1,
double n2,
double E,
double u,
double h)
405 double dV = E*h/(2.0*Ut);
406 double dNdn2 = aux2(-dV);
407 double dDNDXdn2 = aux1(-dV)/h;
408 double dJdn2 = MU*(dNdn2*E + Ut*dDNDXdn2);
421 (
double p1,
double p2,
double E,
double u,
double h)
424 double dV = E*h/(2.0*Ut);
425 double p = p1*aux2(-dV)+p2*aux2(dV);
426 double dpdx = aux1(-dV)*(p2-p1)/h;
427 double J = MU*(p*E-Ut*dpdx);
429 if (DEBUG_DEVICE && isActive(Diag::DEVICE_PARAMETERS) && getSolverState().debugTimeFlag)
431 Xyce::dout().width(16);
432 Xyce::dout().precision(8);
433 Xyce::dout().setf(std::ios::scientific);
435 Xyce::dout() << std::endl;
436 Xyce::dout() <<
" MU = "<< MU << std::endl;
437 Xyce::dout() <<
" p = "<< p <<
" dpdx = "<<dpdx<<
" E = "<<E <<std::endl;
438 Xyce::dout() <<
" dV = "<< dV <<
" Ut = "<<Ut<<
" Jpx = "<<J<<std::endl;
439 Xyce::dout() <<
" p1 = "<< p1 <<
" p2 = "<<p2<<
" (p2-p1) = "<<(p2-p1)<<std::endl;
440 Xyce::dout() <<
" h = "<< h << std::endl;
441 Xyce::dout() <<
" aux1(-dV) = " << aux1(-dV) << std::endl;
442 Xyce::dout() <<
" aux2( dV) = " << aux2( dV) << std::endl;
443 Xyce::dout() <<
" aux2(-dV) = " << aux2( dV) << std::endl;
444 Xyce::dout() << std::endl;
463 (
double p1,
double p2,
double E,
double u,
double h)
466 double dV = E*h/(2.0*Ut);
467 double p = p1*aux2(-dV)+p2*aux2(dV);
468 double dEdv1 = 1.0/h;
469 double ddVdv1 = 1.0/(2.0*Ut);
470 double dNdv1 = p1*(-ddVdv1*pd1aux2(-dV) ) + p2*(ddVdv1*pd1aux2(dV));
471 double dDNDXdv1 = (p2-p1)/h * (-ddVdv1) * pd1aux1(-dV);
472 double dJdv1 = MU*(dNdv1*E + p*dEdv1 - Ut*dDNDXdv1);
490 (
double p1,
double p2,
double E,
double u,
double h)
493 double dV = E*h/(2.0*Ut);
494 double p = p1*aux2(-dV)+p2*aux2(dV);
495 double dEdv2 = -1.0/h;
496 double ddVdv2 = -1.0/(2.0*Ut);
497 double dNdv2 = p1*(-ddVdv2*pd1aux2(-dV) ) + p2*(ddVdv2*pd1aux2(dV));
498 double dDNDXdv2 = (p2-p1)/h * (-ddVdv2) * pd1aux1(-dV);
499 double dJdv2 = MU*(dNdv2*E + p*dEdv2 - Ut*dDNDXdv2);
517 (
double p1,
double p2,
double E,
double u,
double h)
520 double dV = E*h/(2.0*Ut);
521 double dNdp1 = aux2(-dV);
522 double dDNDXdp1 = -aux1(-dV)/h;
523 double dJdn1 = MU*(dNdp1*E - Ut*dDNDXdp1);
540 (
double p1,
double p2,
double E,
double u,
double h)
543 double dV = E*h/(2.0*Ut);
544 double dNdp2 = aux2( dV);
545 double dDNDXdp2 = aux1(-dV)/h;
546 double dJdn2 = MU*(dNdp2*E - Ut*dDNDXdp2);
563 (
double n1,
double n2,
double E,
double u,
double h,
int z)
565 double charge_number =
static_cast<double>(z);
567 double dV = -E*h/(2.0*Ut);
568 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
569 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
570 double J = MU*((n*E)-Ut*(dndx));
586 double charge_number =
static_cast<double>(z);
607 (
double n1,
double n2,
double E,
double u,
double h,
int z)
609 double charge_number =
static_cast<double>(z);
611 double dV = -E*h/(2.0*Ut);
612 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
613 double dEdv1 = 1.0/h;
614 double ddVdv1 = -1.0/(2.0*Ut);
615 double dNdv1 = charge_number*(n1*charge_number*ddVdv1*pd1aux2(charge_number*dV)
616 -n2*charge_number*ddVdv1*pd1aux2(-charge_number*dV));
617 double dDNDXdv1 = (n2-n1)/h * (-charge_number*ddVdv1) * pd1aux1(-charge_number*dV);
618 double dJdv1 = MU*((dNdv1*E + n*dEdv1) - Ut*dDNDXdv1);
634 (
double n1,
double n2,
double E,
double u,
double h,
int z)
636 double charge_number =
static_cast<double>(z);
638 double dV = -E*h/(2.0*Ut);
639 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
640 double dEdv2 = -1.0/h;
641 double ddVdv2 = 1.0/(2.0*Ut);
642 double dNdv2 = charge_number*(n1*charge_number*ddVdv2*pd1aux2(charge_number*dV)
643 -n2*charge_number*ddVdv2*pd1aux2(-charge_number*dV));
644 double dDNDXdv2 = (n2-n1)/h * (-charge_number*ddVdv2) * pd1aux1(-charge_number*dV);
645 double dJdv2 = MU*((dNdv2*E + n*dEdv2) - Ut*dDNDXdv2);
661 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
663 double dJdv1=dJdV1_qdep (n1, n2, E, u.val(), h, z);
664 double dudv1=u.dx(0);
669 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 dndx = aux1(-charge_number*dV)*(n2-n1)/h;
673 double dJ = dudv1*((n*E)-Ut*(dndx));
691 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
693 double dJdv2=dJdV2_qdep (n1, n2, E, u.val(), h, z);
694 double dudv2=u.dx(1);
699 double charge_number =
static_cast<double>(z);
700 double dV = -E*h/(2.0*Ut);
701 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
702 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
703 double dJ = dudv2*((n*E)-Ut*(dndx));
721 (
double n1,
double n2,
double E,
double u,
double h,
int z)
723 double charge_number =
static_cast<double>(z);
725 double dV = -E*h/(2.0*Ut);
726 double dNdn1 = charge_number*aux2(charge_number*dV);
727 double dDNDXdn1 = -aux1(-charge_number*dV)/h;
728 double dJdn1 = MU*(dNdn1*E - Ut*dDNDXdn1);
744 (
double n1,
double n2,
double E,
double u,
double h,
int z)
746 double charge_number =
static_cast<double>(z);
748 double dV = -E*h/(2.0*Ut);
749 double dNdn2 = charge_number*aux2(-charge_number*dV);
750 double dDNDXdn2 = aux1(-charge_number*dV)/h;
751 double dJdn2 = MU*(dNdn2*E - Ut*dDNDXdn2);
771 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
773 double dJdn1=dJdn1_qdep (n1, n2, E, u.val(), h, z);
775 if (z < 0) dudn1=u.dx(2);
780 double charge_number =
static_cast<double>(z);
781 double dV = -E*h/(2.0*Ut);
782 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
783 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
785 dJdn1 += dudn1*((n*E)-Ut*(dndx));
805 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
807 double dJdn2=dJdn2_qdep (n1, n2, E, u.val(), h, z);
809 if (z < 0) dudn2=u.dx(3);
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 dJdn2 += dudn2*((n*E)-Ut*(dndx));
843 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
847 if (z < 0) dudp1=u.dx(4);
852 double charge_number =
static_cast<double>(z);
853 double dV = -E*h/(2.0*Ut);
854 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
855 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
857 dJdp1 += dudp1*((n*E)-Ut*(dndx));
881 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
885 if (z < 0) dudp2=u.dx(5);
890 double charge_number =
static_cast<double>(z);
891 double dV = -E*h/(2.0*Ut);
892 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
893 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
894 dJdp2 += dudp2*((n*E)-Ut*(dndx));
914 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
917 double dudbm1=u.dx(6);
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 double dJ = dudbm1*((n*E)-Ut*(dndx));
945 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
948 double dudbm2=u.dx(8);
953 double charge_number =
static_cast<double>(z);
954 double dV = -E*h/(2.0*Ut);
955 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
956 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
957 double dJ = dudbm2*((n*E)-Ut*(dndx));
976 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
979 double dudpp1=u.dx(7);
984 double charge_number =
static_cast<double>(z);
985 double dV = -E*h/(2.0*Ut);
986 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
987 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
988 double dJ = dudpp1*((n*E)-Ut*(dndx));
1007 (
double n1,
double n2,
double E,
const pdeFadType & u,
double h,
int z)
1010 double dudpp2=u.dx(9);
1015 double charge_number =
static_cast<double>(z);
1016 double dV = -E*h/(2.0*Ut);
1017 double n = charge_number*(n1*aux2(charge_number*dV)+n2*aux2(-charge_number*dV));
1018 double dndx = aux1(-charge_number*dV)*(n2-n1)/h;
1019 double dJ = dudpp2*((n*E)-Ut*(dndx));
1047 double DevicePDEInstance::nsdep (
double x,
double W,
double Dt)
1049 double D = 2.0 * sqrt(Dt);
1050 double Wh = W / 2.0;
1051 return 0.5 * (
erf((Wh + x)/D) +
erf((Wh - x)/D));
1097 double DevicePDEInstance::ngdep
1098 (
double x,
double y,
double W,
double ax,
double ay)
1100 double xprime = fabs(x) - (0.5 *
W);
1101 return ((xprime <= 0.0) ? 1.0 : exp(-ax*xprime*xprime))*
1102 ((y > 0.0) ? 0.0 : exp(-ay*y*y));
1140 double DevicePDEInstance::ngdep2
1141 (
double x,
double y,
double ax,
double ay)
1143 double retVal = exp(-ax*x*x)* exp(-ay*y*y);
1158 double t1 = 1.0 / (1.0 + 0.3275911 * fabs(x));
1159 double t2 = t1 * t1;
1160 double t3 = t2 * t1;
1161 double t4 = t3 * t1;
1162 double t5 = t4 * t1;
1163 double result = 1.0 - (0.254829592*t1 - 0.284496736*t2 + 1.421413741*t3 -
1164 1.453152027*t4 + 1.061405429*t5) * exp(-x*x);
1165 return (x < 0.0) ? -result : result;
1180 return 2.0 / sqrt(pi) * exp(-x*x);
double Jn(double n1, double n2, double E, double u, double h)
double dJdbm1_qdep(double n1, double n2, double E, const pdeFadType &u, double h, int z)
double dJndV2(double n1, double n2, double E, double u, double h)
pdeFadType nMidpoint(pdeFadType &n1, pdeFadType &n2, pdeFadType &E, double h, int z)
Pure virtual class to augment a linear system.
double Jp(double p1, double p2, double E, double u, double h)
DevicePDEInstance(const InstanceBlock &IB, ParametricData< void > ¶metric_data, const FactoryBlock &factory_block)
double dJdp2_qdep(double n1, double n2, double E, const pdeFadType &u, double h, int z)
RetScalarT Vt(Arg1ScalarT U, Arg2ScalarT Ud)
double dJdpp2_qdep(double n1, double n2, double E, const pdeFadType &u, double h, int z)
RetScalarT charge(RetScalarT U, Arg2ScalarT C0, Arg3ScalarT Ud, Arg4ScalarT m, Arg5ScalarT Area)
Sacado::Fad::SFad< double, 10 > pdeFadType
double dJdV2_qdep(double n1, double n2, double E, double u, double h, int z)
const std::string & getName(const C *c)
Returns the name of the specified object.
double dJpdV2(double p1, double p2, double E, double u, double h)
The FactoryBlock contains parameters needed by the device, instance and model creation functions...
BernouliSupport bernSupport
double dJdn1_qdep(double n1, double n2, double E, double u, double h, int z)
Class ParametricData manages the configuration information and the parameter binding map...
double dJndn2(double n1, double n2, double E, double u, double h)
double dJpdn2(double p1, double p2, double E, double u, double h)
double dJdV1_qdep(double n1, double n2, double E, double u, double h, int z)
double dJpdV1(double p1, double p2, double E, double u, double h)
double dJndV1(double n1, double n2, double E, double u, double h)
double J_qdep(double n1, double n2, double E, double u, double h, int z)
double dJdn2_qdep(double n1, double n2, double E, double u, double h, int z)
double dJpdn1(double p1, double p2, double E, double u, double h)
double dJdbm2_qdep(double n1, double n2, double E, const pdeFadType &u, double h, int z)
double dJdpp1_qdep(double n1, double n2, double E, const pdeFadType &u, double h, int z)
InstanceBlock represent a device instance line from the netlist.
std::string setupOutputName(const InstanceName &name)
double dJdp1_qdep(double n1, double n2, double E, const pdeFadType &u, double h, int z)
double dJndn1(double n1, double n2, double E, double u, double h)