From f9ca6e357148f01b9542ee8d69866528721d7a9b Mon Sep 17 00:00:00 2001 From: Shen Chen Date: Thu, 3 Jul 2008 13:22:23 +0800 Subject: [PATCH] Fix: fixes Ec/Ev in all solver. In triangle elements FXX_Tri_YYY(), Eca, Eva are not the conduction/valence band energy. They are here for the calculation of effective driving field for electrons and holes. They differ from the conduction/valence band energy by the term with log(Nc), which takes care of the change effective DOS. Eca should not be used except when its difference between two nodes. The same comment applies to Ecb/Evb and Ecc/Evc. --- src/solver/ddm1e/semiequ1e.cc | 30 ++++++++++++++++++------------ src/solver/ddm2e/semiequ2e.cc | 28 ++++++++++++++-------------- src/solver/ebm3e/semiequ3e.cc | 14 ++++++++------ src/solver/mix2/semiequ2mix.cc | 24 ++++++++++++------------ 4 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/solver/ddm1e/semiequ1e.cc b/src/solver/ddm1e/semiequ1e.cc index cc0f0e1..36e8c14 100644 --- a/src/solver/ddm1e/semiequ1e.cc +++ b/src/solver/ddm1e/semiequ1e.cc @@ -74,8 +74,14 @@ void SMCZone::F1E_Tri_ddm(Tri *ptri,PetscScalar *x,PetscScalar *f, vector & PetscScalar pa = x[zofs[zone_index]+3*A+2]; //hole density of node A mt->mapping(&pzone->danode[A],&aux[A],0); - PetscScalar Eca = -(e*Va + aux[A].affinity + mt->band->EgNarrowToEc(T)); //conduction band energy level - PetscScalar Eva = -(e*Va + aux[A].affinity + mt->band->EgNarrowToEc(T) + Eg); //valence band energy level + // NOTE: Eca, Eva are not the conduction/valence band energy. + // They are here for the calculation of effective driving field for electrons and holes + // They differ from the conduction/valence band energy by the term with log(Nc), which + // takes care of the change effective DOS. + // Eca should not be used except when its difference between two nodes. + // The same comment applies to Ecb/Evb and Ecc/Evc. + PetscScalar Eca = -(e*Va + aux[A].affinity + mt->band->EgNarrowToEc(T) + kb*T*log(aux[A].Nc)); + PetscScalar Eva = -(e*Va + aux[A].affinity - mt->band->EgNarrowToEv(T) - kb*T*log(aux[A].Nv) +Eg); PetscScalar Ra = mt->band->Recomb(pa,na,fs[A].T); PetscScalar etana; PetscScalar etapa; @@ -98,8 +104,8 @@ void SMCZone::F1E_Tri_ddm(Tri *ptri,PetscScalar *x,PetscScalar *f, vector & PetscScalar nb = x[zofs[zone_index]+3*B+1]; //electron density of node B PetscScalar pb = x[zofs[zone_index]+3*B+2]; //hole density of node B mt->mapping(&pzone->danode[B],&aux[B],0); - PetscScalar Ecb = -(e*Vb + aux[B].affinity + mt->band->EgNarrowToEc(T)); //conduction band energy level - PetscScalar Evb = -(e*Vb + aux[B].affinity + mt->band->EgNarrowToEc(T) + Eg); //valence band energy level + PetscScalar Ecb = -(e*Vb + aux[B].affinity + mt->band->EgNarrowToEc(T) + kb*T*log(aux[B].Nc)); + PetscScalar Evb = -(e*Vb + aux[B].affinity - mt->band->EgNarrowToEv(T) - kb*T*log(aux[B].Nv)+ Eg); PetscScalar Rb = mt->band->Recomb(pb,nb,fs[B].T); PetscScalar etanb; PetscScalar etapb; @@ -122,8 +128,8 @@ void SMCZone::F1E_Tri_ddm(Tri *ptri,PetscScalar *x,PetscScalar *f, vector & PetscScalar nc = x[zofs[zone_index]+3*C+1]; //electron density of node C PetscScalar pc = x[zofs[zone_index]+3*C+2]; //hole density of node C mt->mapping(&pzone->danode[C],&aux[C],0); - PetscScalar Ecc = -(e*Vc + aux[C].affinity + mt->band->EgNarrowToEc(T)); //conduction band energy level - PetscScalar Evc = -(e*Vc + aux[C].affinity + mt->band->EgNarrowToEc(T) + Eg); //valence band energy level + PetscScalar Ecc = -(e*Vc + aux[C].affinity + mt->band->EgNarrowToEc(T) + kb*T*log(aux[C].Nc)); + PetscScalar Evc = -(e*Vc + aux[C].affinity - mt->band->EgNarrowToEv(T) - kb*T*log(aux[C].Nv) + Eg); PetscScalar Rc = mt->band->Recomb(pc,nc,fs[C].T); PetscScalar etanc; PetscScalar etapc; @@ -551,8 +557,8 @@ void SMCZone::J1E_Tri_ddm(Tri *ptri,PetscScalar *x,Mat *jtmp, vector & zofs na.setADValue(1,1.0); pa.setADValue(2,1.0); mt->mapping(&pzone->danode[A],&aux[A],0); - AutoDScalar Eca = -(e*Va + aux[A].affinity + mt->band->EgNarrowToEc(T)); //conduction band energy level - AutoDScalar Eva = -(e*Va + aux[A].affinity + mt->band->EgNarrowToEc(T) + Eg); //valence band energy level + AutoDScalar Eca = -(e*Va + aux[A].affinity + mt->band->EgNarrowToEc(T) + kb*T*log(aux[A].Nc)); + AutoDScalar Eva = -(e*Va + aux[A].affinity - mt->band->EgNarrowToEv(T) - kb*T*log(aux[A].Nv) +Eg); AutoDScalar Ra = mt->band->Recomb(pa,na,TD); PetscScalar etana; PetscScalar etapa; @@ -578,8 +584,8 @@ void SMCZone::J1E_Tri_ddm(Tri *ptri,PetscScalar *x,Mat *jtmp, vector & zofs nb.setADValue(4,1.0); pb.setADValue(5,1.0); mt->mapping(&pzone->danode[B],&aux[B],0); - AutoDScalar Ecb = -(e*Vb + aux[B].affinity + mt->band->EgNarrowToEc(T)); //conduction band energy level - AutoDScalar Evb = -(e*Vb + aux[B].affinity + mt->band->EgNarrowToEc(T) + Eg); //valence band energy level + AutoDScalar Ecb = -(e*Vb + aux[B].affinity + mt->band->EgNarrowToEc(T) + kb*T*log(aux[B].Nc)); + AutoDScalar Evb = -(e*Vb + aux[B].affinity - mt->band->EgNarrowToEv(T) - kb*T*log(aux[B].Nv)+ Eg); AutoDScalar Rb = mt->band->Recomb(pb,nb,TD); PetscScalar etanb; PetscScalar etapb; @@ -605,8 +611,8 @@ void SMCZone::J1E_Tri_ddm(Tri *ptri,PetscScalar *x,Mat *jtmp, vector & zofs nc.setADValue(7,1.0); pc.setADValue(8,1.0); mt->mapping(&pzone->danode[C],&aux[C],0); - AutoDScalar Ecc = -(e*Vc + aux[C].affinity + mt->band->EgNarrowToEc(T)); //conduction band energy level - AutoDScalar Evc = -(e*Vc + aux[C].affinity + mt->band->EgNarrowToEc(T) + Eg); //valence band energy level + AutoDScalar Ecc = -(e*Vc + aux[C].affinity + mt->band->EgNarrowToEc(T) + kb*T*log(aux[C].Nc)); + AutoDScalar Evc = -(e*Vc + aux[C].affinity - mt->band->EgNarrowToEv(T) - kb*T*log(aux[C].Nv) + Eg); AutoDScalar Rc = mt->band->Recomb(pc,nc,TD); PetscScalar etanc; PetscScalar etapc; diff --git a/src/solver/ddm2e/semiequ2e.cc b/src/solver/ddm2e/semiequ2e.cc index 1d6ae0c..5509061 100644 --- a/src/solver/ddm2e/semiequ2e.cc +++ b/src/solver/ddm2e/semiequ2e.cc @@ -1480,8 +1480,8 @@ void SMCZone::F2E_ddm_ombc_segment(int i,PetscScalar *x,PetscScalar *f, ODE_Form if(Fermi) //Fermi { - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T)); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar phip = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; @@ -1492,9 +1492,9 @@ void SMCZone::F2E_ddm_ombc_segment(int i,PetscScalar *x,PetscScalar *f, ODE_Form } else //Boltzmann { - f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/mt->e*log(Nc/nie) - + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) - - x[zofs[z]+equ_num*size+om_equ]; + f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/2/e*log(Nc/Nv) + + mt->band->Eg(fs[i].T)/2/mt->e + + aux[i].affinity -x[zofs[z]+equ_num*size+om_equ]; if(Na>Nd) //p-type { hole_density = (-(Nd-Na)+sqrt((Nd-Na)*(Nd-Na)+4*nie*nie))/2.0; @@ -1581,8 +1581,8 @@ void SMCZone::F2E_ddm_ombc_interface(int i,PetscScalar *x,PetscScalar *f, ODE_Fo if(Fermi) //Fermi { - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T)); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar phip = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; @@ -1593,9 +1593,9 @@ void SMCZone::F2E_ddm_ombc_interface(int i,PetscScalar *x,PetscScalar *f, ODE_Fo } else //Boltzmann { - f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/mt->e*log(Nc/nie) - + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) - - x[zofs[z]+equ_num*size+om_equ]; + f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/2/e*log(Nc/Nv) + + mt->band->Eg(fs[i].T)/2/mt->e + + aux[i].affinity -x[zofs[z]+equ_num*size+om_equ]; if(Na>Nd) //p-type { @@ -2504,8 +2504,8 @@ void SMCZone::J2E_ddm_ombc_segment(int i,PetscScalar *x,Mat *jac,Mat *jtmp,ODE_F PetscScalar Nc = mt->band->Nc(fs[i].T); PetscScalar Nv = mt->band->Nv(fs[i].T); PetscScalar Vi = x[zofs[zone_index]+4*i+0]; //potential of node i - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) ); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar phip = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; @@ -2611,8 +2611,8 @@ void SMCZone::J2E_ddm_ombc_interface(int i,PetscScalar *x,Mat *jac,Mat *jtmp,ODE PetscScalar Nc = mt->band->Nc(fs[i].T); PetscScalar Nv = mt->band->Nv(fs[i].T); PetscScalar Vi = x[zofs[zone_index]+4*i+0]; //potential of node i - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T)); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar phip = x[zofs[zone_index]+equ_num*size+om_equ]; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; diff --git a/src/solver/ebm3e/semiequ3e.cc b/src/solver/ebm3e/semiequ3e.cc index 63a7050..9c984a5 100644 --- a/src/solver/ebm3e/semiequ3e.cc +++ b/src/solver/ebm3e/semiequ3e.cc @@ -1291,14 +1291,15 @@ void SMCZone::F3E_ddm_ombc_segment(int i,PetscScalar *x,PetscScalar *f, ODE_Form mt->mapping(&pzone->danode[i],&aux[i],ODE_F.clock); PetscScalar nie = mt->band->nie(fs[i].T); PetscScalar Nc = mt->band->Nc(fs[i].T); + PetscScalar Nv = mt->band->Nv(fs[i].T); PetscScalar electron_density,hole_density; int om_equ; for(int j=0;jbc_index-1) { om_equ=j; break; } - f[zofs[z]+6*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/mt->e*log(Nc/nie) - + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) - - x[zofs[z]+equ_num*size+om_equ]; + f[zofs[z]+6*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/2/mt->e*log(Nc/Nv) + + mt->band->Eg(fs[i].T)/2/mt->e + + aux[i].affinity -x[zofs[z]+equ_num*size+om_equ]; if(Na>Nd) //p-type { @@ -1372,14 +1373,15 @@ void SMCZone::F3E_ddm_ombc_interface(int i,PetscScalar *x,PetscScalar *f, ODE_Fo mt->mapping(&pzone->danode[i],&aux[i],ODE_F.clock); PetscScalar nie = mt->band->nie(fs[i].T); PetscScalar Nc = mt->band->Nc(fs[i].T); + PetscScalar Nv = mt->band->Nv(fs[i].T); PetscScalar electron_density,hole_density; int om_equ; for(int j=0;jbc_index-1) { om_equ=j; break; } - f[zofs[z]+6*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/mt->e*log(Nc/nie) - + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) - - x[zofs[z]+equ_num*size+om_equ]; + f[zofs[z]+6*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/2/mt->e*log(Nc/Nv) + + mt->band->Eg(fs[i].T)/2/mt->e + + aux[i].affinity -x[zofs[z]+equ_num*size+om_equ]; if(Na>Nd) //p-type { diff --git a/src/solver/mix2/semiequ2mix.cc b/src/solver/mix2/semiequ2mix.cc index 4f4d597..921291f 100644 --- a/src/solver/mix2/semiequ2mix.cc +++ b/src/solver/mix2/semiequ2mix.cc @@ -50,8 +50,8 @@ void SMCZone::F2E_mix_ddm_ombc_segment(int i,PetscScalar *x,PetscScalar *f, ODE_ if(Fermi) //Fermi { - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) ); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = pbc->Vapp; PetscScalar phip = pbc->Vapp; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; @@ -62,8 +62,8 @@ void SMCZone::F2E_mix_ddm_ombc_segment(int i,PetscScalar *x,PetscScalar *f, ODE_ } else { - f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/mt->e*log(Nc/nie) - + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) - pbc->Vapp; + f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + kb*fs[i].T/2/e*log(Nc/Nv) + mt->band->Eg(fs[i].T)/2/mt->e + + aux[i].affinity - pbc->Vapp; if(Na>Nd) //p-type { @@ -141,8 +141,8 @@ void SMCZone::F2E_mix_ddm_ombc_interface(int i,PetscScalar *x,PetscScalar *f, OD if(Fermi) //Fermi { - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) ); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = pbc->Vapp; PetscScalar phip = pbc->Vapp; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; @@ -152,8 +152,8 @@ void SMCZone::F2E_mix_ddm_ombc_interface(int i,PetscScalar *x,PetscScalar *f, OD f[zofs[z]+4*i+2] = pi - Nv*fermi_half(etap); } { - f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + mt->kb*fs[i].T/mt->e*log(Nc/nie) - + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) - pbc->Vapp; + f[zofs[z]+4*i+0] = Vi - kb*fs[i].T/mt->e*asinh((Nd-Na)/(2*nie)) + kb*fs[i].T/2/e*log(Nc/Nv) + mt->band->Eg(fs[i].T)/2/mt->e + + aux[i].affinity - pbc->Vapp; if(Na>Nd) //p-type { @@ -462,8 +462,8 @@ void SMCZone::J2E_mix_ddm_ombc_segment(int i,PetscScalar *x,Mat *jac,Mat *jtmp,O PetscScalar Nc = mt->band->Nc(fs[i].T); PetscScalar Nv = mt->band->Nv(fs[i].T); PetscScalar Vi = x[zofs[zone_index]+4*i+0]; //potential of node i - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) ); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = pbc->Vapp; PetscScalar phip = pbc->Vapp; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; @@ -552,8 +552,8 @@ void SMCZone::J2E_mix_ddm_ombc_interface(int i,PetscScalar *x,Mat *jac,Mat *jtmp PetscScalar Nc = mt->band->Nc(fs[i].T); PetscScalar Nv = mt->band->Nv(fs[i].T); PetscScalar Vi = x[zofs[zone_index]+4*i+0]; //potential of node i - PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) + kb*fs[i].T*log(aux[i].Nc)); - PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) - kb*fs[i].T*log(aux[i].Nv)+ aux[i].Eg); + PetscScalar Ec = -(e*Vi + aux[i].affinity + mt->band->EgNarrowToEc(fs[i].T) ); + PetscScalar Ev = -(e*Vi + aux[i].affinity - mt->band->EgNarrowToEv(fs[i].T) + mt->band->Eg(fs[i].T)); PetscScalar phin = pbc->Vapp; PetscScalar phip = pbc->Vapp; PetscScalar etan = (-e*phin-Ec)/kb/fs[i].T; -- 2.11.4.GIT