1 /*****************************************************************************/
2 /* 8888888 88888888 88888888 */
5 /* 8 88888888 88888888 */
8 /* 888888 888888888 888888888 */
10 /* A Two-Dimensional General Purpose Semiconductor Simulator. */
13 /* Last update: May 15, 2007 */
17 /* NINT, No.69 P.O.Box, Xi'an City, China */
19 /*****************************************************************************/
30 void SMCZone::F3E_Tri_ddm(Tri
*ptri
,PetscScalar
*x
,PetscScalar
*f
, vector
<int> &zofs
)
32 PetscScalar grad_P
,sn
,sp
,kapa
,grad_T
,H
=0,S
;
33 PetscScalar Epn
,Epp
,Etn
,Etp
;
34 int A
= ptri
->node
[0];
35 int B
= ptri
->node
[1];
36 int C
= ptri
->node
[2];
37 PetscScalar xa
= pzone
->danode
[ptri
->node
[0]].x
;
38 PetscScalar xb
= pzone
->danode
[ptri
->node
[1]].x
;
39 PetscScalar xc
= pzone
->danode
[ptri
->node
[2]].x
;
40 PetscScalar ya
= pzone
->danode
[ptri
->node
[0]].y
;
41 PetscScalar yb
= pzone
->danode
[ptri
->node
[1]].y
;
42 PetscScalar yc
= pzone
->danode
[ptri
->node
[2]].y
;
43 PetscScalar tri_area
= ptri
->area
;
44 PetscScalar Sax
= (xc
-xb
)/ptri
->edge_len
[0];
45 PetscScalar Say
= (yc
-yb
)/ptri
->edge_len
[0];
46 PetscScalar Sbx
= (xa
-xc
)/ptri
->edge_len
[1];
47 PetscScalar Sby
= (ya
-yc
)/ptri
->edge_len
[1];
48 PetscScalar Scx
= (xb
-xa
)/ptri
->edge_len
[2];
49 PetscScalar Scy
= (yb
-ya
)/ptri
->edge_len
[2];
50 PetscScalar Wab
= ptri
->d
[1]/((ptri
->d
[1]+ptri
->d
[2])*sin(ptri
->angle
[2])*sin(ptri
->angle
[2]));
51 PetscScalar Wac
= ptri
->d
[2]/((ptri
->d
[1]+ptri
->d
[2])*sin(ptri
->angle
[1])*sin(ptri
->angle
[1]));
52 PetscScalar Wbc
= ptri
->d
[2]/((ptri
->d
[0]+ptri
->d
[2])*sin(ptri
->angle
[0])*sin(ptri
->angle
[0]));
53 PetscScalar Wba
= ptri
->d
[0]/((ptri
->d
[0]+ptri
->d
[2])*sin(ptri
->angle
[2])*sin(ptri
->angle
[2]));
54 PetscScalar Wca
= ptri
->d
[0]/((ptri
->d
[0]+ptri
->d
[1])*sin(ptri
->angle
[1])*sin(ptri
->angle
[1]));
55 PetscScalar Wcb
= ptri
->d
[1]/((ptri
->d
[0]+ptri
->d
[1])*sin(ptri
->angle
[0])*sin(ptri
->angle
[0]));
56 PetscScalar Ma
= -cos(ptri
->angle
[0]);
57 PetscScalar Mb
= -cos(ptri
->angle
[1]);
58 PetscScalar Mc
= -cos(ptri
->angle
[2]);
60 PetscScalar e
= mt
->e
;
61 PetscScalar kb
= mt
->kb
;
62 PetscScalar Tl
= (fs
[A
].T
+fs
[B
].T
+fs
[C
].T
)/3.0;
64 PetscScalar Va
= x
[zofs
[zone_index
]+6*A
+0]; //potential of node A
65 PetscScalar na
= x
[zofs
[zone_index
]+6*A
+1]; //electron density of node A
66 PetscScalar pa
= x
[zofs
[zone_index
]+6*A
+2]; //hole density of node A
67 PetscScalar Ta
= x
[zofs
[zone_index
]+6*A
+3]; //Lattice Temperature of node A
68 PetscScalar Tna
= x
[zofs
[zone_index
]+6*A
+4]/na
; //elec temperature of node A
69 PetscScalar Tpa
= x
[zofs
[zone_index
]+6*A
+5]/pa
; //hole temperature of node A
70 mt
->mapping(&pzone
->danode
[A
],&aux
[A
],0);
71 PetscScalar nia
= mt
->band
->nie(Ta
);
72 PetscScalar Ra
= mt
->band
->Recomb(pa
,na
,Ta
);
73 PetscScalar Ra_SHR
= mt
->band
->R_SHR(pa
,na
,Ta
);
74 PetscScalar Ra_AUG
= mt
->band
->R_Auger(pa
,na
,Ta
);
75 PetscScalar Ra_DIR
= mt
->band
->R_Direct(pa
,na
,Ta
);
77 PetscScalar Nca
= mt
->band
->Nc(fs
[A
].T
);
78 PetscScalar Nva
= mt
->band
->Nv(fs
[A
].T
);
79 PetscScalar Ega
= mt
->band
->Eg(fs
[A
].T
);
80 PetscScalar Eca
= -(e
*Va
+ aux
[A
].affinity
+ mt
->band
->EgNarrowToEc(fs
[A
].T
) + kb
*fs
[A
].T
*(log(Nca
)-1.5*log(fs
[A
].T
)));
81 PetscScalar Eva
= -(e
*Va
+ aux
[A
].affinity
- mt
->band
->EgNarrowToEv(fs
[A
].T
) - kb
*fs
[A
].T
*(log(Nva
)-1.5*log(fs
[A
].T
)) + Ega
);
83 PetscScalar Nca
= mt
->band
->Nc(Ta
);
84 PetscScalar Nva
= mt
->band
->Nv(Ta
);
85 PetscScalar Ega
= mt
->band
->Eg(Ta
);
86 PetscScalar Eca
= -(e
*Va
+ aux
[A
].affinity
+ mt
->band
->EgNarrowToEc(Ta
) + kb
*Ta
*(log(Nca
)-1.5*log(Ta
)));
87 PetscScalar Eva
= -(e
*Va
+ aux
[A
].affinity
- mt
->band
->EgNarrowToEv(Ta
) - kb
*Ta
*(log(Nva
)-1.5*log(Ta
)) + Ega
);
89 PetscScalar tao_ena
= mt
->band
->ElecEnergyRelaxTime(Tna
,Ta
);
90 PetscScalar tao_epa
= mt
->band
->HoleEnergyRelaxTime(Tpa
,Ta
);
92 PetscScalar Vb
= x
[zofs
[zone_index
]+6*B
+0]; //potential of node B
93 PetscScalar nb
= x
[zofs
[zone_index
]+6*B
+1]; //electron density of node B
94 PetscScalar pb
= x
[zofs
[zone_index
]+6*B
+2]; //hole density of node B
95 PetscScalar Tb
= x
[zofs
[zone_index
]+6*B
+3]; //Temperature of node B
96 PetscScalar Tnb
= x
[zofs
[zone_index
]+6*B
+4]/nb
; //elec temperature of node B
97 PetscScalar Tpb
= x
[zofs
[zone_index
]+6*B
+5]/pb
; //hole temperature of node B
98 mt
->mapping(&pzone
->danode
[B
],&aux
[B
],0);
99 PetscScalar nib
= mt
->band
->nie(Tb
);
100 PetscScalar Rb
= mt
->band
->Recomb(pb
,nb
,Tb
);
101 PetscScalar Rb_SHR
= mt
->band
->R_SHR(pb
,nb
,Tb
);
102 PetscScalar Rb_AUG
= mt
->band
->R_Auger(pb
,nb
,Tb
);
103 PetscScalar Rb_DIR
= mt
->band
->R_Direct(pb
,nb
,Tb
);
105 PetscScalar Ncb
= mt
->band
->Nc(fs
[B
].T
);
106 PetscScalar Nvb
= mt
->band
->Nv(fs
[B
].T
);
107 PetscScalar Egb
= mt
->band
->Eg(fs
[B
].T
);
108 PetscScalar Ecb
= -(e
*Vb
+ aux
[B
].affinity
+ mt
->band
->EgNarrowToEc(fs
[B
].T
) + kb
*fs
[B
].T
*(log(Ncb
)-1.5*log(fs
[B
].T
)));
109 PetscScalar Evb
= -(e
*Vb
+ aux
[B
].affinity
- mt
->band
->EgNarrowToEv(fs
[B
].T
) - kb
*fs
[B
].T
*(log(Nvb
)-1.5*log(fs
[B
].T
))+ Egb
);
111 PetscScalar Ncb
= mt
->band
->Nc(Tb
);
112 PetscScalar Nvb
= mt
->band
->Nv(Tb
);
113 PetscScalar Egb
= mt
->band
->Eg(Tb
);
114 PetscScalar Ecb
= -(e
*Vb
+ aux
[B
].affinity
+ mt
->band
->EgNarrowToEc(Tb
) + kb
*Tb
*(log(Ncb
)-1.5*log(Tb
)));
115 PetscScalar Evb
= -(e
*Vb
+ aux
[B
].affinity
- mt
->band
->EgNarrowToEv(Tb
) - kb
*Tb
*(log(Nvb
)-1.5*log(Tb
))+ Egb
);
117 PetscScalar tao_enb
= mt
->band
->ElecEnergyRelaxTime(Tnb
,Tb
);
118 PetscScalar tao_epb
= mt
->band
->HoleEnergyRelaxTime(Tpb
,Tb
);
120 PetscScalar Vc
= x
[zofs
[zone_index
]+6*C
+0]; //potential of node C
121 PetscScalar nc
= x
[zofs
[zone_index
]+6*C
+1]; //electron density of node C
122 PetscScalar pc
= x
[zofs
[zone_index
]+6*C
+2]; //hole density of node C
123 PetscScalar Tc
= x
[zofs
[zone_index
]+6*C
+3]; //Temperature of node C
124 PetscScalar Tnc
= x
[zofs
[zone_index
]+6*C
+4]/nc
; //Temperature of node C
125 PetscScalar Tpc
= x
[zofs
[zone_index
]+6*C
+5]/pc
; //Temperature of node C
126 mt
->mapping(&pzone
->danode
[C
],&aux
[C
],0);
127 PetscScalar nic
= mt
->band
->nie(Tc
);
128 PetscScalar Rc
= mt
->band
->Recomb(pc
,nc
,Tc
);
129 PetscScalar Rc_SHR
= mt
->band
->R_SHR(pc
,nc
,Tc
);
130 PetscScalar Rc_AUG
= mt
->band
->R_Auger(pc
,nc
,Tc
);
131 PetscScalar Rc_DIR
= mt
->band
->R_Direct(pc
,nc
,Tc
);
133 PetscScalar Ncc
= mt
->band
->Nc(fs
[C
].T
);
134 PetscScalar Nvc
= mt
->band
->Nv(fs
[C
].T
);
135 PetscScalar Egc
= mt
->band
->Eg(fs
[C
].T
);
136 PetscScalar Ecc
= -(e
*Vc
+ aux
[C
].affinity
+ mt
->band
->EgNarrowToEc(fs
[C
].T
) + kb
*fs
[C
].T
*(log(Ncc
)-1.5*log(fs
[C
].T
)));
137 PetscScalar Evc
= -(e
*Vc
+ aux
[C
].affinity
- mt
->band
->EgNarrowToEv(fs
[C
].T
) - kb
*fs
[C
].T
*(log(Nvc
)-1.5*log(fs
[C
].T
))+ Egc
);
139 PetscScalar Ncc
= mt
->band
->Nc(Tc
);
140 PetscScalar Nvc
= mt
->band
->Nv(Tc
);
141 PetscScalar Egc
= mt
->band
->Eg(Tc
);
142 PetscScalar Ecc
= -(e
*Vc
+ aux
[C
].affinity
+ mt
->band
->EgNarrowToEc(Tc
) + kb
*Tc
*(log(Ncc
)-1.5*log(Tc
)));
143 PetscScalar Evc
= -(e
*Vc
+ aux
[C
].affinity
- mt
->band
->EgNarrowToEv(Tc
) - kb
*Tc
*(log(Nvc
)-1.5*log(Tc
))+ Egc
);
145 PetscScalar tao_enc
= mt
->band
->ElecEnergyRelaxTime(Tnc
,Tc
);
146 PetscScalar tao_epc
= mt
->band
->HoleEnergyRelaxTime(Tpc
,Tc
);
148 PetscScalar Ex
= -((yb
-yc
)*Va
+ (yc
-ya
)*Vb
+(ya
-yb
)*Vc
)/(2*tri_area
);
149 PetscScalar Ey
= -((xc
-xb
)*Va
+ (xa
-xc
)*Vb
+(xb
-xa
)*Vc
)/(2*tri_area
);
150 PetscScalar E
= sqrt(Ex
*Ex
+Ey
*Ey
+1e-20);
151 PetscScalar Eg
= mt
->band
->Eg((Ta
+Tb
+Tc
)/3.0);
153 PetscScalar Ga
=0,Gb
=0,Gc
=0,G
=0;
154 PetscScalar IIn
=0,IIp
=0;
156 PetscScalar Epnc
=0,Etnc
=0;
157 PetscScalar Eppc
=0,Etpc
=0;
158 PetscScalar Epna
=0,Etna
=0;
159 PetscScalar Eppa
=0,Etpa
=0;
160 PetscScalar Epnb
=0,Etnb
=0;
161 PetscScalar Eppb
=0,Etpb
=0;
162 PetscScalar Jna_norm
,Jpa_norm
;
163 PetscScalar Jnb_norm
,Jpb_norm
;
164 PetscScalar Jnc_norm
,Jpc_norm
;
166 PetscScalar Jnc
= In(kb
, e
, -Eca
/e
, -Ecb
/e
, na
, nb
, Tna
,Tnb
, ptri
->edge_len
[2]);
167 PetscScalar Jpc
= Ip(kb
, e
, -Eva
/e
, -Evb
/e
, pa
, pb
, Tpa
,Tpb
, ptri
->edge_len
[2]);
168 PetscScalar Jna
= In(kb
, e
, -Ecb
/e
, -Ecc
/e
, nb
, nc
, Tnb
,Tnc
, ptri
->edge_len
[0]);
169 PetscScalar Jpa
= Ip(kb
, e
, -Evb
/e
, -Evc
/e
, pb
, pc
, Tpb
,Tpc
, ptri
->edge_len
[0]);
170 PetscScalar Jnb
= In(kb
, e
, -Ecc
/e
, -Eca
/e
, nc
, na
, Tnc
,Tna
, ptri
->edge_len
[1]);
171 PetscScalar Jpb
= Ip(kb
, e
, -Evc
/e
, -Eva
/e
, pc
, pa
, Tpc
,Tpa
, ptri
->edge_len
[1]);
172 PetscScalar Jn_scale
= dmax(dmax(fabs(Jna
),fabs(Jnb
)),dmax(fabs(Jnc
),nia
*nia
));
173 PetscScalar Jp_scale
= dmax(dmax(fabs(Jpa
),fabs(Jpb
)),dmax(fabs(Jpc
),nia
*nia
));
182 if(HighFieldMobility
)
184 if(EJModel
|| IIType
==EdotJ
|| IIType
==TempII
)
186 PetscScalar Jncx
= ((Wca
+Wcb
)*Scx
- Wca
*Mb
*Sax
- Wcb
*Ma
*Sbx
)*Jnc
187 + (Wca
*Sax
- Wca
*Mb
*Scx
)*Jna
188 + (Wcb
*Sbx
- Wcb
*Ma
*Scx
)*Jnb
;
189 PetscScalar Jncy
= ((Wca
+Wcb
)*Scy
- Wca
*Mb
*Say
- Wcb
*Ma
*Sby
)*Jnc
190 + (Wca
*Say
- Wca
*Mb
*Scy
)*Jna
191 + (Wcb
*Sby
- Wcb
*Ma
*Scy
)*Jnb
;
192 PetscScalar Jpcx
= ((Wca
+Wcb
)*Scx
- Wca
*Mb
*Sax
- Wcb
*Ma
*Sbx
)*Jpc
193 + (Wca
*Sax
- Wca
*Mb
*Scx
)*Jpa
194 + (Wcb
*Sbx
- Wcb
*Ma
*Scx
)*Jpb
;
195 PetscScalar Jpcy
= ((Wca
+Wcb
)*Scy
- Wca
*Mb
*Say
- Wcb
*Ma
*Sby
)*Jpc
196 + (Wca
*Say
- Wca
*Mb
*Scy
)*Jpa
197 + (Wcb
*Sby
- Wcb
*Ma
*Scy
)*Jpb
;
198 Jnc_norm
= sqrt(Jncx
*Jncx
+ Jncy
*Jncy
+ 1e-100);
199 Jpc_norm
= sqrt(Jpcx
*Jpcx
+ Jpcy
*Jpcy
+ 1e-100);
200 Epnc
= (Ex
*Jncx
+ Ey
*Jncy
)/Jnc_norm
;
201 Etnc
= (Ex
*Jncy
- Ey
*Jncx
)/Jnc_norm
;
202 Eppc
= (Ex
*Jpcx
+ Ey
*Jpcy
)/Jpc_norm
;
203 Etpc
= (Ex
*Jpcy
- Ey
*Jpcx
)/Jpc_norm
;
207 Epnc
= fabs(Eca
-Ecb
)/e
/ptri
->edge_len
[2]; //parallel electrical field for electron
208 Eppc
= fabs(Eva
-Evb
)/e
/ptri
->edge_len
[2]; //parallel electrical field for hole
209 //transvers electrical field for electron and hole
210 Etnc
= fabs(Eca
+ ptri
->edge_len
[1]*cos(ptri
->angle
[0])*(Ecb
-Eca
)/ptri
->edge_len
[2] - Ecc
)
211 /(ptri
->edge_len
[1]*sin(ptri
->angle
[0]))/e
;
212 Etpc
= fabs(Eva
+ ptri
->edge_len
[1]*cos(ptri
->angle
[0])*(Evb
-Eva
)/ptri
->edge_len
[2] - Evc
)
213 /(ptri
->edge_len
[1]*sin(ptri
->angle
[0]))/e
;
216 mt
->mapping(&pzone
->danode
[A
],&aux
[A
],0);
217 aux
[A
].mun
= mt
->mob
->ElecMob(pa
,na
,Ta
,dmax(0,Epnc
),fabs(Etnc
),1);
218 aux
[A
].mup
= mt
->mob
->HoleMob(pa
,na
,Ta
,dmax(0,Eppc
),fabs(Etpc
),1);
220 mt
->mapping(&pzone
->danode
[B
],&aux
[B
],0);
221 aux
[B
].mun
= mt
->mob
->ElecMob(pb
,nb
,Tb
,dmax(0,Epnc
),fabs(Etnc
),1);
222 aux
[B
].mup
= mt
->mob
->HoleMob(pb
,nb
,Tb
,dmax(0,Eppc
),fabs(Etpc
),1);
225 mun
= 0.5*(aux
[A
].mun
+aux
[B
].mun
);
226 mup
= 0.5*(aux
[A
].mup
+aux
[B
].mup
);
231 IIn
= mt
->gen
->ElecGenRate(0.5*(Ta
+Tb
),dmax(0,Epnc
),Eg
);
232 IIp
= mt
->gen
->HoleGenRate(0.5*(Ta
+Tb
),dmax(0,Eppc
),Eg
);
233 Gc
= IIn
*mun
*Jnc_norm
*Jn_scale
+ IIp
*mup
*Jpc_norm
*Jp_scale
;
237 IIn
= mt
->gen
->ElecGenRateEBM(0.5*(Tna
+Tnb
),0.5*(Ta
+Tb
),Eg
);
238 IIp
= mt
->gen
->HoleGenRateEBM(0.5*(Tpa
+Tpb
),0.5*(Ta
+Tb
),Eg
);
239 Gc
= IIn
*mun
*Jnc_norm
*Jn_scale
+ IIp
*mup
*Jpc_norm
*Jp_scale
;
243 IIn
= mt
->gen
->ElecGenRate(0.5*(Ta
+Tb
),fabs(Va
-Vb
)/ptri
->edge_len
[2],Eg
);
244 IIp
= mt
->gen
->HoleGenRate(0.5*(Ta
+Tb
),fabs(Va
-Vb
)/ptri
->edge_len
[2],Eg
);
245 Gc
= IIn
*mun
*fabs(Jnc
)*Jn_scale
+ IIp
*mup
*fabs(Jpc
)*Jp_scale
;
248 grad_P
= (Vb
-Va
)/ptri
->edge_len
[2];
249 kapa
= mt
->thermal
->HeatConduction(0.5*(Ta
+Tb
));
250 grad_T
= kapa
*(Tb
-Ta
)/ptri
->edge_len
[2];
252 sn
= Sn(kb
, e
, -Eca
/e
, -Ecb
/e
, na
, nb
, Tna
,Tnb
, ptri
->edge_len
[2]);
253 sp
= Sp(kb
, e
, -Eva
/e
, -Evb
/e
, pa
, pb
, Tpa
,Tpb
, ptri
->edge_len
[2]);
255 f
[zofs
[zone_index
]+6*A
+0] += grad_P
*ptri
->d
[2];
256 f
[zofs
[zone_index
]+6*A
+1] += mun
*Jnc
*Jn_scale
*ptri
->d
[2] + Gc
*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
257 f
[zofs
[zone_index
]+6*A
+2] += - mup
*Jpc
*Jp_scale
*ptri
->d
[2] + Gc
*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
258 f
[zofs
[zone_index
]+6*A
+3] += grad_T
*ptri
->d
[2];
259 f
[zofs
[zone_index
]+6*A
+4] += - mun
*sn
*ptri
->d
[2] + 0.5*(Va
-Vb
)*mun
*Jnc
*Jn_scale
*ptri
->d
[2];
260 f
[zofs
[zone_index
]+6*A
+5] += - mup
*sp
*ptri
->d
[2] + 0.5*(Va
-Vb
)*mup
*Jpc
*Jp_scale
*ptri
->d
[2];
262 f
[zofs
[zone_index
]+6*B
+0] += - grad_P
*ptri
->d
[2];
263 f
[zofs
[zone_index
]+6*B
+1] += - mun
*Jnc
*Jn_scale
*ptri
->d
[2] + Gc
*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
264 f
[zofs
[zone_index
]+6*B
+2] += mup
*Jpc
*Jp_scale
*ptri
->d
[2] + Gc
*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
265 f
[zofs
[zone_index
]+6*B
+3] += - grad_T
*ptri
->d
[2];
266 f
[zofs
[zone_index
]+6*B
+4] += mun
*sn
*ptri
->d
[2] + 0.5*(Va
-Vb
)*mun
*Jnc
*Jn_scale
*ptri
->d
[2];
267 f
[zofs
[zone_index
]+6*B
+5] += mup
*sp
*ptri
->d
[2] + 0.5*(Va
-Vb
)*mup
*Jpc
*Jp_scale
*ptri
->d
[2];
270 if(HighFieldMobility
)
272 if(EJModel
|| IIType
==EdotJ
|| IIType
==TempII
)
274 PetscScalar Jnax
= ((Wab
+Wac
)*Sax
- Wab
*Mc
*Sbx
- Wac
*Mb
*Scx
)*Jna
275 + (Wab
*Sbx
- Wab
*Mc
*Sax
)*Jnb
276 + (Wac
*Scx
- Wac
*Mb
*Sax
)*Jnc
;
277 PetscScalar Jnay
= ((Wab
+Wac
)*Say
- Wab
*Mc
*Sby
- Wac
*Mb
*Scy
)*Jna
278 + (Wab
*Sby
- Wab
*Mc
*Say
)*Jnb
279 + (Wac
*Scy
- Wac
*Mb
*Say
)*Jnc
;
280 PetscScalar Jpax
= ((Wab
+Wac
)*Sax
- Wab
*Mc
*Sbx
- Wac
*Mb
*Scx
)*Jpa
281 + (Wab
*Sbx
- Wab
*Mc
*Sax
)*Jpb
282 + (Wac
*Scx
- Wac
*Mb
*Sax
)*Jpc
;
283 PetscScalar Jpay
= ((Wab
+Wac
)*Say
- Wab
*Mc
*Sby
- Wac
*Mb
*Scy
)*Jpa
284 + (Wab
*Sby
- Wab
*Mc
*Say
)*Jpb
285 + (Wac
*Scy
- Wac
*Mb
*Say
)*Jpc
;
286 Jna_norm
= sqrt(Jnax
*Jnax
+ Jnay
*Jnay
+ 1e-100);
287 Jpa_norm
= sqrt(Jpax
*Jpax
+ Jpay
*Jpay
+ 1e-100);
288 Epna
= (Ex
*Jnax
+ Ey
*Jnay
)/Jna_norm
;
289 Etna
= (Ex
*Jnay
- Ey
*Jnax
)/Jna_norm
;
290 Eppa
= (Ex
*Jpax
+ Ey
*Jpay
)/Jpa_norm
;
291 Etpa
= (Ex
*Jpay
- Ey
*Jpax
)/Jpa_norm
;
295 Epna
= fabs(Ecb
-Ecc
)/e
/ptri
->edge_len
[0]; //parallel electrical field for electron
296 Eppa
= fabs(Evb
-Evc
)/e
/ptri
->edge_len
[0]; //parallel electrical field for hole
297 //transvers electrical field for electron and hole
298 Etna
= fabs(Ecb
+ ptri
->edge_len
[2]*cos(ptri
->angle
[1])*(Ecc
-Ecb
)/ptri
->edge_len
[0] - Eca
)
299 /(ptri
->edge_len
[2]*sin(ptri
->angle
[1]))/e
;
300 Etpa
= fabs(Evb
+ ptri
->edge_len
[2]*cos(ptri
->angle
[1])*(Evc
-Evb
)/ptri
->edge_len
[0] - Eva
)
301 /(ptri
->edge_len
[2]*sin(ptri
->angle
[1]))/e
;
303 mt
->mapping(&pzone
->danode
[B
],&aux
[B
],0);
304 aux
[B
].mun
= mt
->mob
->ElecMob(pb
,nb
,Tb
,dmax(0,Epna
),fabs(Etna
),1);
305 aux
[B
].mup
= mt
->mob
->HoleMob(pb
,nb
,Tb
,dmax(0,Eppa
),fabs(Etpa
),1);
307 mt
->mapping(&pzone
->danode
[C
],&aux
[C
],0);
308 aux
[C
].mun
= mt
->mob
->ElecMob(pc
,nc
,Tc
,dmax(0,Epna
),fabs(Etna
),1);
309 aux
[C
].mup
= mt
->mob
->HoleMob(pc
,nc
,Tc
,dmax(0,Eppa
),fabs(Etpa
),1);
312 mun
= 0.5*(aux
[B
].mun
+aux
[C
].mun
);
313 mup
= 0.5*(aux
[B
].mup
+aux
[C
].mup
);
319 IIn
= mt
->gen
->ElecGenRate(0.5*(Tb
+Tc
),dmax(0,Epna
),Eg
);
320 IIp
= mt
->gen
->HoleGenRate(0.5*(Tb
+Tc
),dmax(0,Eppa
),Eg
);
321 Ga
= IIn
*mun
*Jna_norm
*Jn_scale
+ IIp
*mup
*Jpa_norm
*Jp_scale
;
325 IIn
= mt
->gen
->ElecGenRateEBM(0.5*(Tnb
+Tnc
),0.5*(Tb
+Tc
),Eg
);
326 IIp
= mt
->gen
->HoleGenRateEBM(0.5*(Tpb
+Tpc
),0.5*(Tb
+Tc
),Eg
);
327 Ga
= IIn
*mun
*Jna_norm
*Jn_scale
+ IIp
*mup
*Jpa_norm
*Jp_scale
;
331 IIn
= mt
->gen
->ElecGenRate(0.5*(Tb
+Tc
),fabs(Vb
-Vc
)/ptri
->edge_len
[0],Eg
);
332 IIp
= mt
->gen
->HoleGenRate(0.5*(Tb
+Tc
),fabs(Vb
-Vc
)/ptri
->edge_len
[0],Eg
);
333 Ga
= IIn
*mun
*fabs(Jna
)*Jn_scale
+ IIp
*mup
*fabs(Jpa
)*Jp_scale
;
337 grad_P
= (Vc
-Vb
)/ptri
->edge_len
[0];
338 kapa
= mt
->thermal
->HeatConduction(0.5*(Tb
+Tc
));
339 grad_T
= kapa
*(Tc
-Tb
)/ptri
->edge_len
[0];
341 sn
= Sn(kb
, e
, -Ecb
/e
, -Ecc
/e
, nb
, nc
, Tnb
,Tnc
, ptri
->edge_len
[0]);
342 sp
= Sp(kb
, e
, -Evb
/e
, -Evc
/e
, pb
, pc
, Tpb
,Tpc
, ptri
->edge_len
[0]);
344 f
[zofs
[zone_index
]+6*B
+0] += grad_P
*ptri
->d
[0];
345 f
[zofs
[zone_index
]+6*B
+1] += mun
*Jna
*Jn_scale
*ptri
->d
[0] + Ga
*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
346 f
[zofs
[zone_index
]+6*B
+2] += - mup
*Jpa
*Jp_scale
*ptri
->d
[0] + Ga
*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
347 f
[zofs
[zone_index
]+6*B
+3] += grad_T
*ptri
->d
[0];
348 f
[zofs
[zone_index
]+6*B
+4] += - mun
*sn
*ptri
->d
[0] + 0.5*(Vb
-Vc
)*mun
*Jna
*Jn_scale
*ptri
->d
[0];
349 f
[zofs
[zone_index
]+6*B
+5] += - mup
*sp
*ptri
->d
[0] + 0.5*(Vb
-Vc
)*mup
*Jpa
*Jp_scale
*ptri
->d
[0];
351 f
[zofs
[zone_index
]+6*C
+0] += - grad_P
*ptri
->d
[0];
352 f
[zofs
[zone_index
]+6*C
+1] += - mun
*Jna
*Jn_scale
*ptri
->d
[0] + Ga
*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
353 f
[zofs
[zone_index
]+6*C
+2] += mup
*Jpa
*Jp_scale
*ptri
->d
[0] + Ga
*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
354 f
[zofs
[zone_index
]+6*C
+3] += - grad_T
*ptri
->d
[0];
355 f
[zofs
[zone_index
]+6*C
+4] += mun
*sn
*ptri
->d
[0] + 0.5*(Vb
-Vc
)*mun
*Jna
*Jn_scale
*ptri
->d
[0];
356 f
[zofs
[zone_index
]+6*C
+5] += mup
*sp
*ptri
->d
[0] + 0.5*(Vb
-Vc
)*mup
*Jpa
*Jp_scale
*ptri
->d
[0];
360 if(HighFieldMobility
)
362 if(EJModel
|| IIType
==EdotJ
|| IIType
==TempII
)
364 PetscScalar Jnbx
= ((Wbc
+Wba
)*Sbx
- Wbc
*Ma
*Scx
- Wba
*Mc
*Sax
)*Jnb
365 + (Wbc
*Scx
- Wbc
*Ma
*Sbx
)*Jnc
366 + (Wba
*Sax
- Wba
*Mc
*Sbx
)*Jna
;
367 PetscScalar Jnby
= ((Wbc
+Wba
)*Sby
- Wbc
*Ma
*Scy
- Wba
*Mc
*Say
)*Jnb
368 + (Wbc
*Scy
- Wbc
*Ma
*Sby
)*Jnc
369 + (Wba
*Say
- Wba
*Mc
*Sby
)*Jna
;
370 PetscScalar Jpbx
= ((Wbc
+Wba
)*Sbx
- Wbc
*Ma
*Scx
- Wba
*Mc
*Sax
)*Jpb
371 + (Wbc
*Scx
- Wbc
*Ma
*Sbx
)*Jpc
372 + (Wba
*Sax
- Wba
*Mc
*Sbx
)*Jpa
;
373 PetscScalar Jpby
= ((Wbc
+Wba
)*Sby
- Wbc
*Ma
*Scy
- Wba
*Mc
*Say
)*Jpb
374 + (Wbc
*Scy
- Wbc
*Ma
*Sby
)*Jpc
375 + (Wba
*Say
- Wba
*Mc
*Sby
)*Jpa
;
376 Jnb_norm
= sqrt(Jnbx
*Jnbx
+ Jnby
*Jnby
+ 1e-100);
377 Jpb_norm
= sqrt(Jpbx
*Jpbx
+ Jpby
*Jpby
+ 1e-100);
378 Epnb
= (Ex
*Jnbx
+ Ey
*Jnby
)/Jnb_norm
;
379 Etnb
= (Ex
*Jnby
- Ey
*Jnbx
)/Jnb_norm
;
380 Eppb
= (Ex
*Jpbx
+ Ey
*Jpby
)/Jpb_norm
;
381 Etpb
= (Ex
*Jpby
- Ey
*Jpbx
)/Jpb_norm
;
386 Epnb
= fabs(Ecc
-Eca
)/e
/ptri
->edge_len
[1]; //parallel electrical field for electron
387 Eppb
= fabs(Evc
-Eva
)/e
/ptri
->edge_len
[1]; //parallel electrical field for hole
388 //transvers electrical field for electron and hole
389 Etnb
= fabs(Ecc
+ ptri
->edge_len
[0]*cos(ptri
->angle
[2])*(Eca
-Ecc
)/ptri
->edge_len
[1] - Ecb
)
390 /(ptri
->edge_len
[0]*sin(ptri
->angle
[2]))/e
;
391 Etpb
= fabs(Evc
+ ptri
->edge_len
[0]*cos(ptri
->angle
[2])*(Eva
-Evc
)/ptri
->edge_len
[1] - Evb
)
392 /(ptri
->edge_len
[0]*sin(ptri
->angle
[2]))/e
;
394 mt
->mapping(&pzone
->danode
[C
],&aux
[C
],0);
395 aux
[C
].mun
= mt
->mob
->ElecMob(pc
,nc
,Tc
,dmax(0,Epnb
),fabs(Etnb
),1);
396 aux
[C
].mup
= mt
->mob
->HoleMob(pc
,nc
,Tc
,dmax(0,Eppb
),fabs(Etpb
),1);
398 mt
->mapping(&pzone
->danode
[A
],&aux
[A
],0);
399 aux
[A
].mun
= mt
->mob
->ElecMob(pa
,na
,Ta
,dmax(0,Epnb
),fabs(Etnb
),1);
400 aux
[A
].mup
= mt
->mob
->HoleMob(pa
,na
,Ta
,dmax(0,Eppb
),fabs(Etpb
),1);
403 mun
= 0.5*(aux
[C
].mun
+aux
[A
].mun
);
404 mup
= 0.5*(aux
[C
].mup
+aux
[A
].mup
);
410 IIn
= mt
->gen
->ElecGenRate(0.5*(Tc
+Ta
),dmax(0,Epnb
),Eg
);
411 IIp
= mt
->gen
->HoleGenRate(0.5*(Tc
+Ta
),dmax(0,Eppb
),Eg
);
412 Gb
= IIn
*mun
*Jnb_norm
*Jn_scale
+ IIp
*mup
*Jpb_norm
*Jp_scale
;
416 IIn
= mt
->gen
->ElecGenRateEBM(0.5*(Tnc
+Tna
),0.5*(Tc
+Ta
),Eg
);
417 IIp
= mt
->gen
->HoleGenRateEBM(0.5*(Tpc
+Tpa
),0.5*(Tc
+Ta
),Eg
);
418 Gb
= IIn
*mun
*Jnb_norm
*Jn_scale
+ IIp
*mup
*Jpb_norm
*Jp_scale
;
422 IIn
= mt
->gen
->ElecGenRate(0.5*(Tc
+Ta
),fabs(Vc
-Va
)/ptri
->edge_len
[1],Eg
);
423 IIp
= mt
->gen
->HoleGenRate(0.5*(Tc
+Ta
),fabs(Vc
-Va
)/ptri
->edge_len
[1],Eg
);
424 Gb
= IIn
*mun
*fabs(Jnb
)*Jn_scale
+ IIp
*mup
*fabs(Jpb
)*Jp_scale
;
428 grad_P
= (Va
-Vc
)/ptri
->edge_len
[1];
429 kapa
= mt
->thermal
->HeatConduction(0.5*(Tc
+Ta
));
430 grad_T
= kapa
*(Ta
-Tc
)/ptri
->edge_len
[1];
432 sn
= Sn(kb
, e
, -Ecc
/e
, -Eca
/e
, nc
, na
, Tnc
,Tna
, ptri
->edge_len
[1]);
433 sp
= Sp(kb
, e
, -Evc
/e
, -Eva
/e
, pc
, pa
, Tpc
,Tpa
, ptri
->edge_len
[1]);
435 f
[zofs
[zone_index
]+6*C
+0] += grad_P
*ptri
->d
[1];
436 f
[zofs
[zone_index
]+6*C
+1] += mun
*Jnb
*Jn_scale
*ptri
->d
[1] + Gb
*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
437 f
[zofs
[zone_index
]+6*C
+2] += - mup
*Jpb
*Jp_scale
*ptri
->d
[1] + Gb
*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
438 f
[zofs
[zone_index
]+6*C
+3] += grad_T
*ptri
->d
[1];
439 f
[zofs
[zone_index
]+6*C
+4] += - mun
*sn
*ptri
->d
[1] + 0.5*(Vc
-Va
)*mun
*Jnb
*Jn_scale
*ptri
->d
[1];
440 f
[zofs
[zone_index
]+6*C
+5] += - mup
*sp
*ptri
->d
[1] + 0.5*(Vc
-Va
)*mup
*Jpb
*Jp_scale
*ptri
->d
[1];
442 f
[zofs
[zone_index
]+6*A
+0] += - grad_P
*ptri
->d
[1];
443 f
[zofs
[zone_index
]+6*A
+1] += - mun
*Jnb
*Jn_scale
*ptri
->d
[1] + Gb
*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
444 f
[zofs
[zone_index
]+6*A
+2] += mup
*Jpb
*Jp_scale
*ptri
->d
[1] + Gb
*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
445 f
[zofs
[zone_index
]+6*A
+3] += - grad_T
*ptri
->d
[1];
446 f
[zofs
[zone_index
]+6*A
+4] += mun
*sn
*ptri
->d
[1] + 0.5*(Vc
-Va
)*mun
*Jnb
*Jn_scale
*ptri
->d
[1];
447 f
[zofs
[zone_index
]+6*A
+5] += mup
*sp
*ptri
->d
[1] + 0.5*(Vc
-Va
)*mup
*Jpb
*Jp_scale
*ptri
->d
[1];
449 //---------------------------------------------------------------------------
450 // G-R item and heat source for each node
451 //---------------------------------------------------------------------------
453 S
= 0.25*ptri
->d
[2]*ptri
->edge_len
[2] + 0.25*ptri
->d
[1]*ptri
->edge_len
[1];
454 PetscScalar Hna
= (Ra_AUG
-G
)*(Ega
+1.5*kb
*Tpa
) - 1.5*kb
*Tna
*(Ra_SHR
+Ra_DIR
-G
) - 1.5*kb
*na
*(Tna
-Ta
)/tao_ena
;
455 PetscScalar Hpa
= (Ra_AUG
-G
)*(Ega
+1.5*kb
*Tna
) - 1.5*kb
*Tpa
*(Ra_SHR
+Ra_DIR
-G
) - 1.5*kb
*pa
*(Tpa
-Ta
)/tao_epa
;
456 PetscScalar Ha
= Ra_SHR
*(Ega
+1.5*kb
*Tna
+1.5*kb
*Tpa
) + 1.5*kb
*na
*(Tna
-Ta
)/tao_ena
+ 1.5*kb
*pa
*(Tpa
-Ta
)/tao_epa
;
457 f
[zofs
[zone_index
]+6*A
+1] += (G
-Ra
)*S
;
458 f
[zofs
[zone_index
]+6*A
+2] += (G
-Ra
)*S
;
459 f
[zofs
[zone_index
]+6*A
+3] += Ha
*S
;
460 f
[zofs
[zone_index
]+6*A
+4] += Hna
*S
;
461 f
[zofs
[zone_index
]+6*A
+5] += Hpa
*S
;
463 S
= 0.25*ptri
->d
[0]*ptri
->edge_len
[0] + 0.25*ptri
->d
[2]*ptri
->edge_len
[2];
464 PetscScalar Hnb
= (Rb_AUG
-G
)*(Egb
+1.5*kb
*Tpb
) - 1.5*kb
*Tnb
*(Rb_SHR
+Rb_DIR
-G
) - 1.5*kb
*nb
*(Tnb
-Tb
)/tao_enb
;
465 PetscScalar Hpb
= (Rb_AUG
-G
)*(Egb
+1.5*kb
*Tnb
) - 1.5*kb
*Tpb
*(Rb_SHR
+Rb_DIR
-G
) - 1.5*kb
*pb
*(Tpb
-Tb
)/tao_epb
;
466 PetscScalar Hb
= Rb_SHR
*(Egb
+1.5*kb
*Tnb
+1.5*kb
*Tpb
) + 1.5*kb
*nb
*(Tnb
-Tb
)/tao_enb
+ 1.5*kb
*pb
*(Tpb
-Tb
)/tao_epb
;
467 f
[zofs
[zone_index
]+6*B
+1] += (G
-Rb
)*S
;
468 f
[zofs
[zone_index
]+6*B
+2] += (G
-Rb
)*S
;
469 f
[zofs
[zone_index
]+6*B
+3] += Hb
*S
;
470 f
[zofs
[zone_index
]+6*B
+4] += Hnb
*S
;
471 f
[zofs
[zone_index
]+6*B
+5] += Hpb
*S
;
473 S
= 0.25*ptri
->d
[1]*ptri
->edge_len
[1] + 0.25*ptri
->d
[0]*ptri
->edge_len
[0];
474 PetscScalar Hnc
= (Rc_AUG
-G
)*(Egc
+1.5*kb
*Tpc
) - 1.5*kb
*Tnc
*(Rc_SHR
+Rc_DIR
-G
) - 1.5*kb
*nc
*(Tnc
-Tc
)/tao_enc
;
475 PetscScalar Hpc
= (Rc_AUG
-G
)*(Egc
+1.5*kb
*Tnc
) - 1.5*kb
*Tpc
*(Rc_SHR
+Rc_DIR
-G
) - 1.5*kb
*pc
*(Tpc
-Tc
)/tao_epc
;
476 PetscScalar Hc
= Rc_SHR
*(Egc
+1.5*kb
*Tnc
+1.5*kb
*Tpc
) + 1.5*kb
*nc
*(Tnc
-Tc
)/tao_enc
+ 1.5*kb
*pc
*(Tpc
-Tc
)/tao_epc
;
477 f
[zofs
[zone_index
]+6*C
+1] += (G
-Rc
)*S
;
478 f
[zofs
[zone_index
]+6*C
+2] += (G
-Rc
)*S
;
479 f
[zofs
[zone_index
]+6*C
+3] += Hc
*S
;
480 f
[zofs
[zone_index
]+6*C
+4] += Hnc
*S
;
481 f
[zofs
[zone_index
]+6*C
+5] += Hpc
*S
;
487 void SMCZone::J3E_Tri_ddm(Tri
*ptri
,PetscScalar
*x
,Mat
*jtmp
, vector
<int> & zofs
)
490 int A
= ptri
->node
[0];
491 int B
= ptri
->node
[1];
492 int C
= ptri
->node
[2];
493 PetscScalar xa
= pzone
->danode
[ptri
->node
[0]].x
;
494 PetscScalar xb
= pzone
->danode
[ptri
->node
[1]].x
;
495 PetscScalar xc
= pzone
->danode
[ptri
->node
[2]].x
;
496 PetscScalar ya
= pzone
->danode
[ptri
->node
[0]].y
;
497 PetscScalar yb
= pzone
->danode
[ptri
->node
[1]].y
;
498 PetscScalar yc
= pzone
->danode
[ptri
->node
[2]].y
;
499 PetscScalar tri_area
= ptri
->area
;
500 PetscScalar Sax
= (xc
-xb
)/ptri
->edge_len
[0];
501 PetscScalar Say
= (yc
-yb
)/ptri
->edge_len
[0];
502 PetscScalar Sbx
= (xa
-xc
)/ptri
->edge_len
[1];
503 PetscScalar Sby
= (ya
-yc
)/ptri
->edge_len
[1];
504 PetscScalar Scx
= (xb
-xa
)/ptri
->edge_len
[2];
505 PetscScalar Scy
= (yb
-ya
)/ptri
->edge_len
[2];
506 PetscScalar Wab
= ptri
->d
[1]/((ptri
->d
[1]+ptri
->d
[2])*sin(ptri
->angle
[2])*sin(ptri
->angle
[2]));
507 PetscScalar Wac
= ptri
->d
[2]/((ptri
->d
[1]+ptri
->d
[2])*sin(ptri
->angle
[1])*sin(ptri
->angle
[1]));
508 PetscScalar Wbc
= ptri
->d
[2]/((ptri
->d
[0]+ptri
->d
[2])*sin(ptri
->angle
[0])*sin(ptri
->angle
[0]));
509 PetscScalar Wba
= ptri
->d
[0]/((ptri
->d
[0]+ptri
->d
[2])*sin(ptri
->angle
[2])*sin(ptri
->angle
[2]));
510 PetscScalar Wca
= ptri
->d
[0]/((ptri
->d
[0]+ptri
->d
[1])*sin(ptri
->angle
[1])*sin(ptri
->angle
[1]));
511 PetscScalar Wcb
= ptri
->d
[1]/((ptri
->d
[0]+ptri
->d
[1])*sin(ptri
->angle
[0])*sin(ptri
->angle
[0]));
512 PetscScalar Ma
= -cos(ptri
->angle
[0]);
513 PetscScalar Mb
= -cos(ptri
->angle
[1]);
514 PetscScalar Mc
= -cos(ptri
->angle
[2]);
516 PetscScalar e
= mt
->e
;
517 PetscScalar kb
= mt
->kb
;
519 //the indepedent variable number
520 adtl::AutoDScalar::numdir
=18;
521 //synchronize with material database
522 mt
->set_ad_num(adtl::AutoDScalar::numdir
);
525 AutoDScalar sn
,sp
,F
[6];
526 PetscInt index1
[6],index2
[6],index3
[6];
527 index1
[0] = zofs
[z
]+6*A
+0;
528 index1
[1] = zofs
[z
]+6*A
+1;
529 index1
[2] = zofs
[z
]+6*A
+2;
530 index1
[3] = zofs
[z
]+6*A
+3;
531 index1
[4] = zofs
[z
]+6*A
+4;
532 index1
[5] = zofs
[z
]+6*A
+5;
534 index2
[0] = zofs
[z
]+6*B
+0;
535 index2
[1] = zofs
[z
]+6*B
+1;
536 index2
[2] = zofs
[z
]+6*B
+2;
537 index2
[3] = zofs
[z
]+6*B
+3;
538 index2
[4] = zofs
[z
]+6*B
+4;
539 index2
[5] = zofs
[z
]+6*B
+5;
541 index3
[0] = zofs
[z
]+6*C
+0;
542 index3
[1] = zofs
[z
]+6*C
+1;
543 index3
[2] = zofs
[z
]+6*C
+2;
544 index3
[3] = zofs
[z
]+6*C
+3;
545 index3
[4] = zofs
[z
]+6*C
+4;
546 index3
[5] = zofs
[z
]+6*C
+5;
547 //---------------------------------------------------------------------------
548 AutoDScalar Va
= x
[zofs
[zone_index
]+6*A
+0]; //potential of node A
549 AutoDScalar na
= x
[zofs
[zone_index
]+6*A
+1]; //electron density of node A
550 AutoDScalar pa
= x
[zofs
[zone_index
]+6*A
+2]; //hole density of node A
551 AutoDScalar Ta
= x
[zofs
[zone_index
]+6*A
+3]; //Lattice Temperature of node A
552 AutoDScalar naTna
= x
[zofs
[zone_index
]+6*A
+4]; //na*Tna of node A
553 AutoDScalar paTpa
= x
[zofs
[zone_index
]+6*A
+5]; //pa*Tpa of node A
554 Va
.setADValue (0,1.0);
555 na
.setADValue (1,1.0);
556 pa
.setADValue (2,1.0);
557 Ta
.setADValue (3,1.0);
558 naTna
.setADValue(4,1.0);
559 paTpa
.setADValue(5,1.0);
560 AutoDScalar Tna
= naTna
/na
; // get Tna
561 AutoDScalar Tpa
= paTpa
/pa
; // get Tpa
562 mt
->mapping(&pzone
->danode
[A
],&aux
[A
],0);
563 AutoDScalar nia
= mt
->band
->nie(Ta
);
564 AutoDScalar Ra
= mt
->band
->Recomb(pa
,na
,Ta
);
565 AutoDScalar Ra_SHR
= mt
->band
->R_SHR(pa
,na
,Ta
);
566 AutoDScalar Ra_AUG
= mt
->band
->R_Auger(pa
,na
,Ta
);
567 AutoDScalar Ra_DIR
= mt
->band
->R_Direct(pa
,na
,Ta
);
569 PetscScalar Nca
= mt
->band
->Nc(fs
[A
].T
);
570 PetscScalar Nva
= mt
->band
->Nv(fs
[A
].T
);
571 PetscScalar Ega
= mt
->band
->Eg(fs
[A
].T
);
572 AutoDScalar Eca
= -(e
*Va
+ aux
[A
].affinity
+ mt
->band
->EgNarrowToEc(fs
[A
].T
) + kb
*fs
[A
].T
*(log(Nca
)-1.5*log(fs
[A
].T
)));
573 AutoDScalar Eva
= -(e
*Va
+ aux
[A
].affinity
- mt
->band
->EgNarrowToEv(fs
[A
].T
) - kb
*fs
[A
].T
*(log(Nva
)-1.5*log(fs
[A
].T
)) + Ega
);
575 AutoDScalar Nca
= mt
->band
->Nc(Ta
);
576 AutoDScalar Nva
= mt
->band
->Nv(Ta
);
577 AutoDScalar Ega
= mt
->band
->Eg(Ta
);
578 AutoDScalar Eca
= -(e
*Va
+ aux
[A
].affinity
+ mt
->band
->EgNarrowToEc(Ta
) + kb
*Ta
*(log(Nca
)-1.5*log(Ta
)));
579 AutoDScalar Eva
= -(e
*Va
+ aux
[A
].affinity
- mt
->band
->EgNarrowToEv(Ta
) - kb
*Ta
*(log(Nva
)-1.5*log(Ta
)) + Ega
);
581 AutoDScalar tao_ena
= mt
->band
->ElecEnergyRelaxTime(Tna
,Ta
);
582 AutoDScalar tao_epa
= mt
->band
->HoleEnergyRelaxTime(Tpa
,Ta
);
585 AutoDScalar Vb
= x
[zofs
[zone_index
]+6*B
+0]; //potential of node B
586 AutoDScalar nb
= x
[zofs
[zone_index
]+6*B
+1]; //electron density of node B
587 AutoDScalar pb
= x
[zofs
[zone_index
]+6*B
+2]; //hole density of node B
588 AutoDScalar Tb
= x
[zofs
[zone_index
]+6*B
+3]; //Temperature of node B
589 AutoDScalar nbTnb
= x
[zofs
[zone_index
]+6*B
+4]; //nb*Tnb of node B
590 AutoDScalar pbTpb
= x
[zofs
[zone_index
]+6*B
+5]; //pb*Tpb of node B
591 Vb
.setADValue (6,1.0);
592 nb
.setADValue (7,1.0);
593 pb
.setADValue (8,1.0);
594 Tb
.setADValue (9,1.0);
595 nbTnb
.setADValue(10,1.0);
596 pbTpb
.setADValue(11,1.0);
597 AutoDScalar Tnb
= nbTnb
/nb
; // get Tnb
598 AutoDScalar Tpb
= pbTpb
/pb
; // get Tpb
599 mt
->mapping(&pzone
->danode
[B
],&aux
[B
],0);
600 AutoDScalar nib
= mt
->band
->nie(Tb
);
601 AutoDScalar Rb
= mt
->band
->Recomb(pb
,nb
,Tb
);
602 AutoDScalar Rb_SHR
= mt
->band
->R_SHR(pb
,nb
,Tb
);
603 AutoDScalar Rb_AUG
= mt
->band
->R_Auger(pb
,nb
,Tb
);
604 AutoDScalar Rb_DIR
= mt
->band
->R_Direct(pb
,nb
,Tb
);
606 PetscScalar Ncb
= mt
->band
->Nc(fs
[B
].T
);
607 PetscScalar Nvb
= mt
->band
->Nv(fs
[B
].T
);
608 PetscScalar Egb
= mt
->band
->Eg(fs
[B
].T
);
609 AutoDScalar Ecb
= -(e
*Vb
+ aux
[B
].affinity
+ mt
->band
->EgNarrowToEc(fs
[B
].T
)+ kb
*fs
[B
].T
*(log(Ncb
)-1.5*log(fs
[B
].T
)));
610 AutoDScalar Evb
= -(e
*Vb
+ aux
[B
].affinity
- mt
->band
->EgNarrowToEv(fs
[B
].T
)- kb
*fs
[B
].T
*(log(Nvb
)-1.5*log(fs
[B
].T
))+ Egb
);
612 AutoDScalar Ncb
= mt
->band
->Nc(Tb
);
613 AutoDScalar Nvb
= mt
->band
->Nv(Tb
);
614 AutoDScalar Egb
= mt
->band
->Eg(Tb
);
615 AutoDScalar Ecb
= -(e
*Vb
+ aux
[B
].affinity
+ mt
->band
->EgNarrowToEc(Tb
)+ kb
*Tb
*(log(Ncb
)-1.5*log(Tb
)));
616 AutoDScalar Evb
= -(e
*Vb
+ aux
[B
].affinity
- mt
->band
->EgNarrowToEv(Tb
)- kb
*Tb
*(log(Nvb
)-1.5*log(Tb
))+ Egb
);
618 AutoDScalar tao_enb
= mt
->band
->ElecEnergyRelaxTime(Tnb
,Tb
);
619 AutoDScalar tao_epb
= mt
->band
->HoleEnergyRelaxTime(Tpb
,Tb
);
621 AutoDScalar Vc
= x
[zofs
[zone_index
]+6*C
+0]; //potential of node C
622 AutoDScalar nc
= x
[zofs
[zone_index
]+6*C
+1]; //electron density of node C
623 AutoDScalar pc
= x
[zofs
[zone_index
]+6*C
+2]; //hole density of node C
624 AutoDScalar Tc
= x
[zofs
[zone_index
]+6*C
+3]; //Temperature of node C
625 AutoDScalar ncTnc
= x
[zofs
[zone_index
]+6*C
+4]; //nc*Tnc of node C
626 AutoDScalar pcTpc
= x
[zofs
[zone_index
]+6*C
+5]; //pc*Tpc of node C
627 Vc
.setADValue (12,1.0);
628 nc
.setADValue (13,1.0);
629 pc
.setADValue (14,1.0);
630 Tc
.setADValue (15,1.0);
631 ncTnc
.setADValue(16,1.0);
632 pcTpc
.setADValue(17,1.0);
633 AutoDScalar Tnc
= ncTnc
/nc
; // get Tnb
634 AutoDScalar Tpc
= pcTpc
/pc
; // get Tpb
635 mt
->mapping(&pzone
->danode
[C
],&aux
[C
],0);
636 AutoDScalar nic
= mt
->band
->nie(Tc
);
637 AutoDScalar Rc
= mt
->band
->Recomb(pc
,nc
,Tc
);
638 AutoDScalar Rc_SHR
= mt
->band
->R_SHR(pc
,nc
,Tc
);
639 AutoDScalar Rc_AUG
= mt
->band
->R_Auger(pc
,nc
,Tc
);
640 AutoDScalar Rc_DIR
= mt
->band
->R_Direct(pc
,nc
,Tc
);
642 PetscScalar Ncc
= mt
->band
->Nc(fs
[C
].T
);
643 PetscScalar Nvc
= mt
->band
->Nv(fs
[C
].T
);
644 PetscScalar Egc
= mt
->band
->Eg(fs
[C
].T
);
645 AutoDScalar Ecc
= -(e
*Vc
+ aux
[C
].affinity
+ mt
->band
->EgNarrowToEc(fs
[C
].T
)+ kb
*fs
[C
].T
*(log(Ncc
)-1.5*log(fs
[C
].T
)));
646 AutoDScalar Evc
= -(e
*Vc
+ aux
[C
].affinity
- mt
->band
->EgNarrowToEv(fs
[C
].T
)- kb
*fs
[C
].T
*(log(Nvc
)-1.5*log(fs
[C
].T
))+ Egc
);
648 AutoDScalar Ncc
= mt
->band
->Nc(Tc
);
649 AutoDScalar Nvc
= mt
->band
->Nv(Tc
);
650 AutoDScalar Egc
= mt
->band
->Eg(Tc
);
651 AutoDScalar Ecc
= -(e
*Vc
+ aux
[C
].affinity
+ mt
->band
->EgNarrowToEc(Tc
)+ kb
*Tc
*(log(Ncc
)-1.5*log(Tc
)));
652 AutoDScalar Evc
= -(e
*Vc
+ aux
[C
].affinity
- mt
->band
->EgNarrowToEv(Tc
)- kb
*Tc
*(log(Nvc
)-1.5*log(Tc
))+ Egc
);
654 AutoDScalar tao_enc
= mt
->band
->ElecEnergyRelaxTime(Tnc
,Tc
);
655 AutoDScalar tao_epc
= mt
->band
->HoleEnergyRelaxTime(Tpc
,Tc
);
658 AutoDScalar Ex
= -((yb
-yc
)*Va
+ (yc
-ya
)*Vb
+(ya
-yb
)*Vc
)/(2*tri_area
);
659 AutoDScalar Ey
= -((xc
-xb
)*Va
+ (xa
-xc
)*Vb
+(xb
-xa
)*Vc
)/(2*tri_area
);
660 AutoDScalar Eg
= mt
->band
->Eg((Ta
+Tb
+Tc
)/3.0);
661 AutoDScalar Hn
,Hp
,Ga
=0,Gb
=0,Gc
=0,G
=0;
662 AutoDScalar IIn
=0,IIp
=0;
664 AutoDScalar Epnc
=0,Etnc
=0;
665 AutoDScalar Eppc
=0,Etpc
=0;
666 AutoDScalar Epna
=0,Etna
=0;
667 AutoDScalar Eppa
=0,Etpa
=0;
668 AutoDScalar Epnb
=0,Etnb
=0;
669 AutoDScalar Eppb
=0,Etpb
=0;
670 AutoDScalar Jna_norm
,Jpa_norm
;
671 AutoDScalar Jnb_norm
,Jpb_norm
;
672 AutoDScalar Jnc_norm
,Jpc_norm
;
673 AutoDScalar grad_P
,kapa
,grad_T
,T_mid
;
675 AutoDScalar Jnc
= In(kb
, e
, -Eca
/e
, -Ecb
/e
, na
, nb
, Tna
,Tnb
, ptri
->edge_len
[2]);
676 AutoDScalar Jpc
= Ip(kb
, e
, -Eva
/e
, -Evb
/e
, pa
, pb
, Tpa
,Tpb
, ptri
->edge_len
[2]);
677 AutoDScalar Jna
= In(kb
, e
, -Ecb
/e
, -Ecc
/e
, nb
, nc
, Tnb
,Tnc
, ptri
->edge_len
[0]);
678 AutoDScalar Jpa
= Ip(kb
, e
, -Evb
/e
, -Evc
/e
, pb
, pc
, Tpb
,Tpc
, ptri
->edge_len
[0]);
679 AutoDScalar Jnb
= In(kb
, e
, -Ecc
/e
, -Eca
/e
, nc
, na
, Tnc
,Tna
, ptri
->edge_len
[1]);
680 AutoDScalar Jpb
= Ip(kb
, e
, -Evc
/e
, -Eva
/e
, pc
, pa
, Tpc
,Tpa
, ptri
->edge_len
[1]);
681 PetscScalar Jn_scale
= dmax(dmax(fabs(Jna
.getValue()),fabs(Jnb
.getValue())),
682 dmax(fabs(Jnc
.getValue()),nia
.getValue()*nia
.getValue()));
683 PetscScalar Jp_scale
= dmax(dmax(fabs(Jpa
.getValue()),fabs(Jpb
.getValue())),
684 dmax(fabs(Jpc
.getValue()),nia
.getValue()*nia
.getValue()));
692 //---------------------------------------------------------------------------
694 //---------------------------------------------------------------------------
695 if(HighFieldMobility
)
697 if(EJModel
|| IIType
==EdotJ
|| IIType
==TempII
)
699 AutoDScalar Jncx
= ((Wca
+Wcb
)*Scx
- Wca
*Mb
*Sax
- Wcb
*Ma
*Sbx
)*Jnc
700 + (Wca
*Sax
- Wca
*Mb
*Scx
)*Jna
701 + (Wcb
*Sbx
- Wcb
*Ma
*Scx
)*Jnb
;
702 AutoDScalar Jncy
= ((Wca
+Wcb
)*Scy
- Wca
*Mb
*Say
- Wcb
*Ma
*Sby
)*Jnc
703 + (Wca
*Say
- Wca
*Mb
*Scy
)*Jna
704 + (Wcb
*Sby
- Wcb
*Ma
*Scy
)*Jnb
;
705 AutoDScalar Jpcx
= ((Wca
+Wcb
)*Scx
- Wca
*Mb
*Sax
- Wcb
*Ma
*Sbx
)*Jpc
706 + (Wca
*Sax
- Wca
*Mb
*Scx
)*Jpa
707 + (Wcb
*Sbx
- Wcb
*Ma
*Scx
)*Jpb
;
708 AutoDScalar Jpcy
= ((Wca
+Wcb
)*Scy
- Wca
*Mb
*Say
- Wcb
*Ma
*Sby
)*Jpc
709 + (Wca
*Say
- Wca
*Mb
*Scy
)*Jpa
710 + (Wcb
*Sby
- Wcb
*Ma
*Scy
)*Jpb
;
711 Jnc_norm
= sqrt(Jncx
*Jncx
+ Jncy
*Jncy
+ 1e-100);
712 Jpc_norm
= sqrt(Jpcx
*Jpcx
+ Jpcy
*Jpcy
+ 1e-100);
713 Epnc
= (Ex
*Jncx
+ Ey
*Jncy
)/Jnc_norm
;
714 Etnc
= (Ex
*Jncy
- Ey
*Jncx
)/Jnc_norm
;
715 Eppc
= (Ex
*Jpcx
+ Ey
*Jpcy
)/Jpc_norm
;
716 Etpc
= (Ex
*Jpcy
- Ey
*Jpcx
)/Jpc_norm
;
720 Epnc
= fabs(Eca
-Ecb
)/e
/ptri
->edge_len
[2]; //parallel electrical field for electron
721 Eppc
= fabs(Eva
-Evb
)/e
/ptri
->edge_len
[2]; //parallel electrical field for hole
722 //transvers electrical field for electron and hole
723 Etnc
= fabs(Eca
+ ptri
->edge_len
[1]*cos(ptri
->angle
[0])*(Ecb
-Eca
)/ptri
->edge_len
[2] - Ecc
)
724 /(ptri
->edge_len
[1]*sin(ptri
->angle
[0]))/e
;
725 Etpc
= fabs(Eva
+ ptri
->edge_len
[1]*cos(ptri
->angle
[0])*(Evb
-Eva
)/ptri
->edge_len
[2] - Evc
)
726 /(ptri
->edge_len
[1]*sin(ptri
->angle
[0]))/e
;
729 mt
->mapping(&pzone
->danode
[A
],&aux
[A
],0);
730 AutoDScalar munCA
= mt
->mob
->ElecMob(pa
,na
,Ta
,adtl::fmax(0,Epnc
),fabs(Etnc
),1);
731 AutoDScalar mupCA
= mt
->mob
->HoleMob(pa
,na
,Ta
,adtl::fmax(0,Eppc
),fabs(Etpc
),1);
733 mt
->mapping(&pzone
->danode
[B
],&aux
[B
],0);
734 AutoDScalar munCB
= mt
->mob
->ElecMob(pb
,nb
,Tb
,adtl::fmax(0,Epnc
),fabs(Etnc
),1);
735 AutoDScalar mupCB
= mt
->mob
->HoleMob(pb
,nb
,Tb
,adtl::fmax(0,Eppc
),fabs(Etpc
),1);
737 mun
= 0.5*(munCA
+munCB
);
738 mup
= 0.5*(mupCA
+mupCB
);
742 mun
= 0.5*(aux
[A
].mun
+aux
[B
].mun
);
743 mup
= 0.5*(aux
[A
].mup
+aux
[B
].mup
);
747 grad_P
= (Vb
-Va
)/ptri
->edge_len
[2];
748 kapa
= mt
->thermal
->HeatConduction(T_mid
);
749 grad_T
= kapa
*(Tb
-Ta
)/ptri
->edge_len
[2];
750 sn
= Sn(kb
, e
, -Eca
/e
, -Ecb
/e
, na
, nb
, Tna
,Tnb
, ptri
->edge_len
[2]);
751 sp
= Sp(kb
, e
, -Eva
/e
, -Evb
/e
, pa
, pb
, Tpa
,Tpb
, ptri
->edge_len
[2]);
753 //---------------------------------------------------------------------------
755 Hn
= 0.5*(Va
-Vb
)*mun
*Jnc
*Jn_scale
*ptri
->d
[2];
756 Hp
= 0.5*(Va
-Vb
)*mup
*Jpc
*Jp_scale
*ptri
->d
[2];
761 IIn
= mt
->gen
->ElecGenRate(0.5*(Ta
+Tb
),adtl::fmax(0,Epnc
),Eg
);
762 IIp
= mt
->gen
->HoleGenRate(0.5*(Ta
+Tb
),adtl::fmax(0,Eppc
),Eg
);
763 Gc
= IIn
*mun
*Jnc_norm
*Jn_scale
+ IIp
*mup
*Jpc_norm
*Jp_scale
;
767 IIn
= mt
->gen
->ElecGenRateEBM(0.5*(Tna
+Tnb
),0.5*(Ta
+Tb
),Eg
);
768 IIp
= mt
->gen
->HoleGenRateEBM(0.5*(Tpa
+Tpb
),0.5*(Ta
+Tb
),Eg
);
769 Gc
= IIn
*mun
*Jnc_norm
*Jn_scale
+ IIp
*mup
*Jpc_norm
*Jp_scale
;
773 IIn
= mt
->gen
->ElecGenRate(T_mid
,fabs(Va
-Vb
)/ptri
->edge_len
[2],Eg
);
774 IIp
= mt
->gen
->HoleGenRate(T_mid
,fabs(Va
-Vb
)/ptri
->edge_len
[2],Eg
);
775 Gc
= IIn
*mun
*fabs(Jnc
)*Jn_scale
+ IIp
*mup
*fabs(Jpc
)*Jp_scale
;
784 J1
.m
[1*6+i
] = Gc
.getADValue(0+i
)*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
785 J1
.m
[2*6+i
] = Gc
.getADValue(0+i
)*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
786 J1
.m
[4*6+i
] = Hn
.getADValue(0+i
);
787 J1
.m
[5*6+i
] = Hp
.getADValue(0+i
);
789 J2
.m
[1*6+i
] = Gc
.getADValue(6+i
)*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
790 J2
.m
[2*6+i
] = Gc
.getADValue(6+i
)*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
791 J2
.m
[4*6+i
] = Hn
.getADValue(6+i
);
792 J2
.m
[5*6+i
] = Hp
.getADValue(6+i
);
794 J3
.m
[1*6+i
] = Gc
.getADValue(12+i
)*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
795 J3
.m
[2*6+i
] = Gc
.getADValue(12+i
)*0.25*ptri
->d
[2]*ptri
->edge_len
[2];
796 J3
.m
[4*6+i
] = Hn
.getADValue(12+i
);
797 J3
.m
[5*6+i
] = Hp
.getADValue(12+i
);
799 MatSetValues(*jtmp
,6,index1
,6,index1
,J1
.m
,ADD_VALUES
);
800 MatSetValues(*jtmp
,6,index1
,6,index2
,J2
.m
,ADD_VALUES
);
801 MatSetValues(*jtmp
,6,index1
,6,index3
,J3
.m
,ADD_VALUES
);
802 MatSetValues(*jtmp
,6,index2
,6,index1
,J1
.m
,ADD_VALUES
);
803 MatSetValues(*jtmp
,6,index2
,6,index2
,J2
.m
,ADD_VALUES
);
804 MatSetValues(*jtmp
,6,index2
,6,index3
,J3
.m
,ADD_VALUES
);
805 //---------------------------------------------------------------------------
807 F
[0] = grad_P
*ptri
->d
[2];
808 F
[1] = mun
*Jnc
*Jn_scale
*ptri
->d
[2];
809 F
[2] = - mup
*Jpc
*Jp_scale
*ptri
->d
[2];
810 F
[3] = grad_T
*ptri
->d
[2];
811 F
[4] = - mun
*sn
*ptri
->d
[2];
812 F
[5] = - mup
*sp
*ptri
->d
[2];
816 J1
.m
[6*i
+j
] = F
[i
].getADValue(0+j
);
817 J2
.m
[6*i
+j
] = F
[i
].getADValue(6+j
);
818 J3
.m
[6*i
+j
] = F
[i
].getADValue(12+j
);
821 MatSetValues(*jtmp
,6,index1
,6,index1
,J1
.m
,ADD_VALUES
);
822 MatSetValues(*jtmp
,6,index1
,6,index2
,J2
.m
,ADD_VALUES
);
823 MatSetValues(*jtmp
,6,index1
,6,index3
,J3
.m
,ADD_VALUES
);
824 MatSetValues(*jtmp
,6,index2
,6,index1
,(-J1
).m
,ADD_VALUES
);
825 MatSetValues(*jtmp
,6,index2
,6,index2
,(-J2
).m
,ADD_VALUES
);
826 MatSetValues(*jtmp
,6,index2
,6,index3
,(-J3
).m
,ADD_VALUES
);
829 //---------------------------------------------------------------------------
831 //---------------------------------------------------------------------------
832 if(HighFieldMobility
)
834 if(EJModel
|| IIType
==EdotJ
|| IIType
==TempII
)
836 AutoDScalar Jnax
= ((Wab
+Wac
)*Sax
- Wab
*Mc
*Sbx
- Wac
*Mb
*Scx
)*Jna
837 + (Wab
*Sbx
- Wab
*Mc
*Sax
)*Jnb
838 + (Wac
*Scx
- Wac
*Mb
*Sax
)*Jnc
;
839 AutoDScalar Jnay
= ((Wab
+Wac
)*Say
- Wab
*Mc
*Sby
- Wac
*Mb
*Scy
)*Jna
840 + (Wab
*Sby
- Wab
*Mc
*Say
)*Jnb
841 + (Wac
*Scy
- Wac
*Mb
*Say
)*Jnc
;
842 AutoDScalar Jpax
= ((Wab
+Wac
)*Sax
- Wab
*Mc
*Sbx
- Wac
*Mb
*Scx
)*Jpa
843 + (Wab
*Sbx
- Wab
*Mc
*Sax
)*Jpb
844 + (Wac
*Scx
- Wac
*Mb
*Sax
)*Jpc
;
845 AutoDScalar Jpay
= ((Wab
+Wac
)*Say
- Wab
*Mc
*Sby
- Wac
*Mb
*Scy
)*Jpa
846 + (Wab
*Sby
- Wab
*Mc
*Say
)*Jpb
847 + (Wac
*Scy
- Wac
*Mb
*Say
)*Jpc
;
848 Jna_norm
= sqrt(Jnax
*Jnax
+ Jnay
*Jnay
+ 1e-100);
849 Jpa_norm
= sqrt(Jpax
*Jpax
+ Jpay
*Jpay
+ 1e-100);
850 Epna
= (Ex
*Jnax
+ Ey
*Jnay
)/Jna_norm
;
851 Etna
= (Ex
*Jnay
- Ey
*Jnax
)/Jna_norm
;
852 Eppa
= (Ex
*Jpax
+ Ey
*Jpay
)/Jpa_norm
;
853 Etpa
= (Ex
*Jpay
- Ey
*Jpax
)/Jpa_norm
;
857 Epna
= fabs(Ecb
-Ecc
)/e
/ptri
->edge_len
[0]; //parallel electrical field for electron
858 Eppa
= fabs(Evb
-Evc
)/e
/ptri
->edge_len
[0]; //parallel electrical field for hole
859 //transvers electrical field for electron and hole
860 Etna
= fabs(Ecb
+ ptri
->edge_len
[2]*cos(ptri
->angle
[1])*(Ecc
-Ecb
)/ptri
->edge_len
[0] - Eca
)
861 /(ptri
->edge_len
[2]*sin(ptri
->angle
[1]))/e
;
862 Etpa
= fabs(Evb
+ ptri
->edge_len
[2]*cos(ptri
->angle
[1])*(Evc
-Evb
)/ptri
->edge_len
[0] - Eva
)
863 /(ptri
->edge_len
[2]*sin(ptri
->angle
[1]))/e
;
865 mt
->mapping(&pzone
->danode
[B
],&aux
[B
],0);
866 AutoDScalar munAB
= mt
->mob
->ElecMob(pb
,nb
,Tb
,adtl::fmax(0,Epna
),fabs(Etna
),1);
867 AutoDScalar mupAB
= mt
->mob
->HoleMob(pb
,nb
,Tb
,adtl::fmax(0,Eppa
),fabs(Etpa
),1);
869 mt
->mapping(&pzone
->danode
[C
],&aux
[C
],0);
870 AutoDScalar munAC
= mt
->mob
->ElecMob(pc
,nc
,Tc
,adtl::fmax(0,Epna
),fabs(Etna
),1);
871 AutoDScalar mupAC
= mt
->mob
->HoleMob(pc
,nc
,Tc
,adtl::fmax(0,Eppa
),fabs(Etpa
),1);
873 mun
= 0.5*(munAB
+munAC
);
874 mup
= 0.5*(mupAB
+mupAC
);
878 mun
= 0.5*(aux
[B
].mun
+aux
[C
].mun
);
879 mup
= 0.5*(aux
[B
].mup
+aux
[C
].mup
);
882 grad_P
= (Vc
-Vb
)/ptri
->edge_len
[0];
883 kapa
= mt
->thermal
->HeatConduction(T_mid
);
884 grad_T
= kapa
*(Tc
-Tb
)/ptri
->edge_len
[0];
886 sn
= Sn(kb
, e
, -Ecb
/e
, -Ecc
/e
, nb
, nc
, Tnb
,Tnc
, ptri
->edge_len
[0]);
887 sp
= Sp(kb
, e
, -Evb
/e
, -Evc
/e
, pb
, pc
, Tpb
,Tpc
, ptri
->edge_len
[0]);
888 //---------------------------------------------------------------------------
890 Hn
= 0.5*(Vb
-Vc
)*mun
*Jna
*Jn_scale
*ptri
->d
[0];
891 Hp
= 0.5*(Vb
-Vc
)*mup
*Jpa
*Jp_scale
*ptri
->d
[0];
896 IIn
= mt
->gen
->ElecGenRate(0.5*(Tb
+Tc
),adtl::fmax(0,Epna
),Eg
);
897 IIp
= mt
->gen
->HoleGenRate(0.5*(Tb
+Tc
),adtl::fmax(0,Eppa
),Eg
);
898 Ga
= IIn
*mun
*Jna_norm
*Jn_scale
+ IIp
*mup
*Jpa_norm
*Jp_scale
;
902 IIn
= mt
->gen
->ElecGenRateEBM(0.5*(Tnb
+Tnc
),0.5*(Tb
+Tc
),Eg
);
903 IIp
= mt
->gen
->HoleGenRateEBM(0.5*(Tpb
+Tpc
),0.5*(Tb
+Tc
),Eg
);
904 Ga
= IIn
*mun
*Jna_norm
*Jn_scale
+ IIp
*mup
*Jpa_norm
*Jp_scale
;
908 IIn
= mt
->gen
->ElecGenRate(T_mid
,fabs(Vb
-Vc
)/ptri
->edge_len
[0],Eg
);
909 IIp
= mt
->gen
->HoleGenRate(T_mid
,fabs(Vb
-Vc
)/ptri
->edge_len
[0],Eg
);
910 Ga
= IIn
*mun
*fabs(Jna
)*Jn_scale
+ IIp
*mup
*fabs(Jpa
)*Jp_scale
;
918 J1
.m
[1*6+i
] = Ga
.getADValue(0+i
)*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
919 J1
.m
[2*6+i
] = Ga
.getADValue(0+i
)*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
920 J1
.m
[4*6+i
] = Hn
.getADValue(0+i
);
921 J1
.m
[5*6+i
] = Hp
.getADValue(0+i
);
923 J2
.m
[1*6+i
] = Ga
.getADValue(6+i
)*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
924 J2
.m
[2*6+i
] = Ga
.getADValue(6+i
)*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
925 J2
.m
[4*6+i
] = Hn
.getADValue(6+i
);
926 J2
.m
[5*6+i
] = Hp
.getADValue(6+i
);
928 J3
.m
[1*6+i
] = Ga
.getADValue(12+i
)*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
929 J3
.m
[2*6+i
] = Ga
.getADValue(12+i
)*0.25*ptri
->d
[0]*ptri
->edge_len
[0];
930 J3
.m
[4*6+i
] = Hn
.getADValue(12+i
);
931 J3
.m
[5*6+i
] = Hp
.getADValue(12+i
);
933 MatSetValues(*jtmp
,6,index2
,6,index1
,J1
.m
,ADD_VALUES
);
934 MatSetValues(*jtmp
,6,index2
,6,index2
,J2
.m
,ADD_VALUES
);
935 MatSetValues(*jtmp
,6,index2
,6,index3
,J3
.m
,ADD_VALUES
);
936 MatSetValues(*jtmp
,6,index3
,6,index1
,J1
.m
,ADD_VALUES
);
937 MatSetValues(*jtmp
,6,index3
,6,index2
,J2
.m
,ADD_VALUES
);
938 MatSetValues(*jtmp
,6,index3
,6,index3
,J3
.m
,ADD_VALUES
);
939 //---------------------------------------------------------------------------
941 F
[0] = grad_P
*ptri
->d
[0];
942 F
[1] = mun
*Jna
*Jn_scale
*ptri
->d
[0];
943 F
[2] = - mup
*Jpa
*Jp_scale
*ptri
->d
[0];
944 F
[3] = grad_T
*ptri
->d
[0];
945 F
[4] = - mun
*sn
*ptri
->d
[0];
946 F
[5] = - mup
*sp
*ptri
->d
[0];
951 J1
.m
[6*i
+j
] = F
[i
].getADValue(0+j
);
952 J2
.m
[6*i
+j
] = F
[i
].getADValue(6+j
);
953 J3
.m
[6*i
+j
] = F
[i
].getADValue(12+j
);
956 MatSetValues(*jtmp
,6,index2
,6,index1
,J1
.m
,ADD_VALUES
);
957 MatSetValues(*jtmp
,6,index2
,6,index2
,J2
.m
,ADD_VALUES
);
958 MatSetValues(*jtmp
,6,index2
,6,index3
,J3
.m
,ADD_VALUES
);
959 MatSetValues(*jtmp
,6,index3
,6,index1
,(-J1
).m
,ADD_VALUES
);
960 MatSetValues(*jtmp
,6,index3
,6,index2
,(-J2
).m
,ADD_VALUES
);
961 MatSetValues(*jtmp
,6,index3
,6,index3
,(-J3
).m
,ADD_VALUES
);
963 //---------------------------------------------------------------------------
965 //---------------------------------------------------------------------------
966 if(HighFieldMobility
)
968 if(EJModel
|| IIType
==EdotJ
|| IIType
==TempII
)
970 AutoDScalar Jnbx
= ((Wbc
+Wba
)*Sbx
- Wbc
*Ma
*Scx
- Wba
*Mc
*Sax
)*Jnb
971 + (Wbc
*Scx
- Wbc
*Ma
*Sbx
)*Jnc
972 + (Wba
*Sax
- Wba
*Mc
*Sbx
)*Jna
;
973 AutoDScalar Jnby
= ((Wbc
+Wba
)*Sby
- Wbc
*Ma
*Scy
- Wba
*Mc
*Say
)*Jnb
974 + (Wbc
*Scy
- Wbc
*Ma
*Sby
)*Jnc
975 + (Wba
*Say
- Wba
*Mc
*Sby
)*Jna
;
976 AutoDScalar Jpbx
= ((Wbc
+Wba
)*Sbx
- Wbc
*Ma
*Scx
- Wba
*Mc
*Sax
)*Jpb
977 + (Wbc
*Scx
- Wbc
*Ma
*Sbx
)*Jpc
978 + (Wba
*Sax
- Wba
*Mc
*Sbx
)*Jpa
;
979 AutoDScalar Jpby
= ((Wbc
+Wba
)*Sby
- Wbc
*Ma
*Scy
- Wba
*Mc
*Say
)*Jpb
980 + (Wbc
*Scy
- Wbc
*Ma
*Sby
)*Jpc
981 + (Wba
*Say
- Wba
*Mc
*Sby
)*Jpa
;
982 Jnb_norm
= sqrt(Jnbx
*Jnbx
+ Jnby
*Jnby
+ 1e-100);
983 Jpb_norm
= sqrt(Jpbx
*Jpbx
+ Jpby
*Jpby
+ 1e-100);
984 Epnb
= (Ex
*Jnbx
+ Ey
*Jnby
)/Jnb_norm
;
985 Etnb
= (Ex
*Jnby
- Ey
*Jnbx
)/Jnb_norm
;
986 Eppb
= (Ex
*Jpbx
+ Ey
*Jpby
)/Jpb_norm
;
987 Etpb
= (Ex
*Jpby
- Ey
*Jpbx
)/Jpb_norm
;
991 Epnb
= fabs(Ecc
-Eca
)/e
/ptri
->edge_len
[1]; //parallel electrical field for electron
992 Eppb
= fabs(Evc
-Eva
)/e
/ptri
->edge_len
[1]; //parallel electrical field for hole
993 //transvers electrical field for electron and hole
994 Etnb
= fabs(Ecc
+ ptri
->edge_len
[0]*cos(ptri
->angle
[2])*(Eca
-Ecc
)/ptri
->edge_len
[1] - Ecb
)
995 /(ptri
->edge_len
[0]*sin(ptri
->angle
[2]))/e
;
996 Etpb
= fabs(Evc
+ ptri
->edge_len
[0]*cos(ptri
->angle
[2])*(Eva
-Evc
)/ptri
->edge_len
[1] - Evb
)
997 /(ptri
->edge_len
[0]*sin(ptri
->angle
[2]))/e
;
999 mt
->mapping(&pzone
->danode
[C
],&aux
[C
],0);
1000 AutoDScalar munBC
= mt
->mob
->ElecMob(pc
,nc
,Tc
,adtl::fmax(0,Epnb
),fabs(Etnb
),1);
1001 AutoDScalar mupBC
= mt
->mob
->HoleMob(pc
,nc
,Tc
,adtl::fmax(0,Eppb
),fabs(Etpb
),1);
1003 mt
->mapping(&pzone
->danode
[A
],&aux
[A
],0);
1004 AutoDScalar munBA
= mt
->mob
->ElecMob(pa
,na
,Ta
,adtl::fmax(0,Epnb
),fabs(Etnb
),1);
1005 AutoDScalar mupBA
= mt
->mob
->HoleMob(pa
,na
,Ta
,adtl::fmax(0,Eppb
),fabs(Etpb
),1);
1007 mun
= 0.5*(munBC
+munBA
);
1008 mup
= 0.5*(mupBC
+mupBA
);
1012 mun
= 0.5*(aux
[C
].mun
+aux
[A
].mun
);
1013 mup
= 0.5*(aux
[C
].mup
+aux
[A
].mup
);
1015 T_mid
= 0.5*(Tc
+Ta
);
1016 grad_P
= (Va
-Vc
)/ptri
->edge_len
[1];
1017 kapa
= mt
->thermal
->HeatConduction(T_mid
);
1018 grad_T
= kapa
*(Ta
-Tc
)/ptri
->edge_len
[1];
1020 sn
= Sn(kb
, e
, -Ecc
/e
, -Eca
/e
, nc
, na
, Tnc
,Tna
, ptri
->edge_len
[1]);
1021 sp
= Sp(kb
, e
, -Evc
/e
, -Eva
/e
, pc
, pa
, Tpc
,Tpa
, ptri
->edge_len
[1]);
1022 //---------------------------------------------------------------------------
1024 Hn
= 0.5*(Vc
-Va
)*mun
*Jnb
*Jn_scale
*ptri
->d
[1];
1025 Hp
= 0.5*(Vc
-Va
)*mup
*Jpb
*Jp_scale
*ptri
->d
[1];
1026 if(ImpactIonization
)
1030 IIn
= mt
->gen
->ElecGenRate(0.5*(Tc
+Ta
),adtl::fmax(0,Epnb
),Eg
);
1031 IIp
= mt
->gen
->HoleGenRate(0.5*(Tc
+Ta
),adtl::fmax(0,Eppb
),Eg
);
1032 Gb
= IIn
*mun
*Jnb_norm
*Jn_scale
+ IIp
*mup
*Jpb_norm
*Jp_scale
;
1036 IIn
= mt
->gen
->ElecGenRateEBM(0.5*(Tnc
+Tna
),0.5*(Tc
+Ta
),Eg
);
1037 IIp
= mt
->gen
->HoleGenRateEBM(0.5*(Tpc
+Tpa
),0.5*(Tc
+Ta
),Eg
);
1038 Gb
= IIn
*mun
*Jnb_norm
*Jn_scale
+ IIp
*mup
*Jpb_norm
*Jp_scale
;
1042 IIn
= mt
->gen
->ElecGenRate(T_mid
,fabs(Vc
-Va
)/ptri
->edge_len
[1],Eg
);
1043 IIp
= mt
->gen
->HoleGenRate(T_mid
,fabs(Vc
-Va
)/ptri
->edge_len
[1],Eg
);
1044 Gb
= IIn
*mun
*fabs(Jnb
)*Jn_scale
+ IIp
*mup
*fabs(Jpb
)*Jp_scale
;
1050 for(int i
=0;i
<6;i
++)
1052 J1
.m
[1*6+i
] = Gb
.getADValue(0+i
)*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
1053 J1
.m
[2*6+i
] = Gb
.getADValue(0+i
)*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
1054 J1
.m
[4*6+i
] = Hn
.getADValue(0+i
);
1055 J1
.m
[5*6+i
] = Hp
.getADValue(0+i
);
1057 J2
.m
[1*6+i
] = Gb
.getADValue(6+i
)*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
1058 J2
.m
[2*6+i
] = Gb
.getADValue(6+i
)*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
1059 J2
.m
[4*6+i
] = Hn
.getADValue(6+i
);
1060 J2
.m
[5*6+i
] = Hp
.getADValue(6+i
);
1062 J3
.m
[1*6+i
] = Gb
.getADValue(12+i
)*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
1063 J3
.m
[2*6+i
] = Gb
.getADValue(12+i
)*0.25*ptri
->d
[1]*ptri
->edge_len
[1];
1064 J3
.m
[4*6+i
] = Hn
.getADValue(12+i
);
1065 J3
.m
[5*6+i
] = Hp
.getADValue(12+i
);
1067 MatSetValues(*jtmp
,6,index3
,6,index1
,J1
.m
,ADD_VALUES
);
1068 MatSetValues(*jtmp
,6,index3
,6,index2
,J2
.m
,ADD_VALUES
);
1069 MatSetValues(*jtmp
,6,index3
,6,index3
,J3
.m
,ADD_VALUES
);
1070 MatSetValues(*jtmp
,6,index1
,6,index1
,J1
.m
,ADD_VALUES
);
1071 MatSetValues(*jtmp
,6,index1
,6,index2
,J2
.m
,ADD_VALUES
);
1072 MatSetValues(*jtmp
,6,index1
,6,index3
,J3
.m
,ADD_VALUES
);
1073 //---------------------------------------------------------------------------
1075 F
[0] = grad_P
*ptri
->d
[1];
1076 F
[1] = mun
*Jnb
*Jn_scale
*ptri
->d
[1];
1077 F
[2] = - mup
*Jpb
*Jp_scale
*ptri
->d
[1];
1078 F
[3] = grad_T
*ptri
->d
[1];
1079 F
[4] = - mun
*sn
*ptri
->d
[1];
1080 F
[5] = - mup
*sp
*ptri
->d
[1];
1081 //---------------------------------------------------------------------------
1082 for(int i
=0;i
<6;i
++)
1083 for(int j
=0;j
<6;j
++)
1085 J1
.m
[6*i
+j
] = F
[i
].getADValue(0+j
);
1086 J2
.m
[6*i
+j
] = F
[i
].getADValue(6+j
);
1087 J3
.m
[6*i
+j
] = F
[i
].getADValue(12+j
);
1090 MatSetValues(*jtmp
,6,index3
,6,index1
,J1
.m
,ADD_VALUES
);
1091 MatSetValues(*jtmp
,6,index3
,6,index2
,J2
.m
,ADD_VALUES
);
1092 MatSetValues(*jtmp
,6,index3
,6,index3
,J3
.m
,ADD_VALUES
);
1093 MatSetValues(*jtmp
,6,index1
,6,index1
,(-J1
).m
,ADD_VALUES
);
1094 MatSetValues(*jtmp
,6,index1
,6,index2
,(-J2
).m
,ADD_VALUES
);
1095 MatSetValues(*jtmp
,6,index1
,6,index3
,(-J3
).m
,ADD_VALUES
);
1098 //---------------------------------------------------------------------------
1099 // G-R item and heat source for each node
1100 //---------------------------------------------------------------------------
1102 S
= 0.25*ptri
->d
[2]*ptri
->edge_len
[2] + 0.25*ptri
->d
[1]*ptri
->edge_len
[1];
1103 AutoDScalar Hna
= (Ra_AUG
-G
)*(Ega
+1.5*kb
*Tpa
) - 1.5*kb
*Tna
*(Ra_SHR
+Ra_DIR
-G
) - 1.5*kb
*na
*(Tna
-Ta
)/tao_ena
;
1104 AutoDScalar Hpa
= (Ra_AUG
-G
)*(Ega
+1.5*kb
*Tna
) - 1.5*kb
*Tpa
*(Ra_SHR
+Ra_DIR
-G
) - 1.5*kb
*pa
*(Tpa
-Ta
)/tao_epa
;
1105 AutoDScalar Ha
= Ra_SHR
*(Ega
+1.5*kb
*Tna
+1.5*kb
*Tpa
) + 1.5*kb
*na
*(Tna
-Ta
)/tao_ena
+ 1.5*kb
*pa
*(Tpa
-Ta
)/tao_epa
;
1112 for(int i
=0;i
<6;i
++)
1113 for(int j
=0;j
<6;j
++)
1115 J1
.m
[6*i
+j
] = F
[i
].getADValue(0+j
);
1117 MatSetValues(*jtmp
,6,index1
,6,index1
,J1
.m
,ADD_VALUES
);
1119 S
= 0.25*ptri
->d
[0]*ptri
->edge_len
[0] + 0.25*ptri
->d
[2]*ptri
->edge_len
[2];
1120 AutoDScalar Hnb
= (Rb_AUG
-G
)*(Egb
+1.5*kb
*Tpb
) - 1.5*kb
*Tnb
*(Rb_SHR
+Rb_DIR
-G
) - 1.5*kb
*nb
*(Tnb
-Tb
)/tao_enb
;
1121 AutoDScalar Hpb
= (Rb_AUG
-G
)*(Egb
+1.5*kb
*Tnb
) - 1.5*kb
*Tpb
*(Rb_SHR
+Rb_DIR
-G
) - 1.5*kb
*pb
*(Tpb
-Tb
)/tao_epb
;
1122 AutoDScalar Hb
= Rb_SHR
*(Egb
+1.5*kb
*Tnb
+1.5*kb
*Tpb
) + 1.5*kb
*nb
*(Tnb
-Tb
)/tao_enb
+ 1.5*kb
*pb
*(Tpb
-Tb
)/tao_epb
;
1129 for(int i
=0;i
<6;i
++)
1130 for(int j
=0;j
<6;j
++)
1132 J2
.m
[6*i
+j
] = F
[i
].getADValue(6+j
);
1134 MatSetValues(*jtmp
,6,index2
,6,index2
,J2
.m
,ADD_VALUES
);
1136 S
= 0.25*ptri
->d
[1]*ptri
->edge_len
[1] + 0.25*ptri
->d
[0]*ptri
->edge_len
[0];
1137 AutoDScalar Hnc
= (Rc_AUG
-G
)*(Egc
+1.5*kb
*Tpc
) - 1.5*kb
*Tnc
*(Rc_SHR
+Rc_DIR
-G
) - 1.5*kb
*nc
*(Tnc
-Tc
)/tao_enc
;
1138 AutoDScalar Hpc
= (Rc_AUG
-G
)*(Egc
+1.5*kb
*Tnc
) - 1.5*kb
*Tpc
*(Rc_SHR
+Rc_DIR
-G
) - 1.5*kb
*pc
*(Tpc
-Tc
)/tao_epc
;
1139 AutoDScalar Hc
= Rc_SHR
*(Egc
+1.5*kb
*Tnc
+1.5*kb
*Tpc
) + 1.5*kb
*nc
*(Tnc
-Tc
)/tao_enc
+ 1.5*kb
*pc
*(Tpc
-Tc
)/tao_epc
;
1146 for(int i
=0;i
<6;i
++)
1147 for(int j
=0;j
<6;j
++)
1149 J3
.m
[6*i
+j
] = F
[i
].getADValue(12+j
);
1151 MatSetValues(*jtmp
,6,index3
,6,index3
,J3
.m
,ADD_VALUES
);
1156 //-----------------------------------------------------------------------------
1158 //-----------------------------------------------------------------------------
1160 void SMCZone::F3E_ddm_inner(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
)
1162 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1163 PetscScalar kb
= mt
->kb
;
1164 PetscScalar e
= mt
->e
;
1165 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1166 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1167 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1168 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1169 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1170 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1172 f
[zofs
[zone_index
]+6*i
+0] = f
[zofs
[zone_index
]+6*i
+0]/pcell
->area
+ e
/aux
[i
].eps
*((pi
-aux
[i
].Na
)+(aux
[i
].Nd
-ni
));
1173 f
[zofs
[zone_index
]+6*i
+1] = f
[zofs
[zone_index
]+6*i
+1]/pcell
->area
;
1174 f
[zofs
[zone_index
]+6*i
+2] = f
[zofs
[zone_index
]+6*i
+2]/pcell
->area
;
1175 f
[zofs
[zone_index
]+6*i
+3] = f
[zofs
[zone_index
]+6*i
+3]/pcell
->area
;
1176 f
[zofs
[zone_index
]+6*i
+4] = f
[zofs
[zone_index
]+6*i
+4]/pcell
->area
;
1177 f
[zofs
[zone_index
]+6*i
+5] = f
[zofs
[zone_index
]+6*i
+5]/pcell
->area
;
1179 if(ODE_F
.TimeDependent
==true)
1182 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1184 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1185 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1186 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1187 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1188 PetscScalar Wnt
= (2-r
)/(1-r
)*1.5*ni
*kb
*Tn
-1.0/(r
*(1-r
))*1.5*fs
[i
].n
*kb
*fs
[i
].Tn
+(1-r
)/r
*1.5*fs
[i
].n_last
*kb
*fs
[i
].Tn_last
;
1189 PetscScalar Wpt
= (2-r
)/(1-r
)*1.5*pi
*kb
*Tp
-1.0/(r
*(1-r
))*1.5*fs
[i
].p
*kb
*fs
[i
].Tp
+(1-r
)/r
*1.5*fs
[i
].p_last
*kb
*fs
[i
].Tp_last
;
1190 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1191 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1192 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1193 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1194 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1195 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1199 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1200 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1201 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1202 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1203 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1204 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1212 void SMCZone::F3E_ddm_neumannbc(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
,DABC
&bc
)
1214 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1215 NeumannBC
*pbc
= dynamic_cast <NeumannBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1216 PetscScalar kb
= mt
->kb
;
1217 PetscScalar e
= mt
->e
;
1218 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1219 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1220 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1221 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1222 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1223 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1225 PetscScalar grad_T
=0;
1226 for(int j
=0;j
<pcell
->nb_num
;j
++)
1228 int nb
= pcell
->nb_array
[j
];
1229 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1230 if(j
==0||j
==pcell
->nb_num
-1)
1232 PetscScalar h
= pbc
->heat_transfer
;
1233 PetscScalar r
= h
*pbc
->T_external
;
1234 grad_T
+= 0.5*pcell
->ilen
[j
]*(r
-0.25*h
*(3*Ti
+Tj
));
1237 f
[zofs
[zone_index
]+6*i
+0] = f
[zofs
[zone_index
]+6*i
+0]/pcell
->area
+ e
/aux
[i
].eps
*((pi
-aux
[i
].Na
)+(aux
[i
].Nd
-ni
));
1238 f
[zofs
[zone_index
]+6*i
+1] = f
[zofs
[zone_index
]+6*i
+1]/pcell
->area
;
1239 f
[zofs
[zone_index
]+6*i
+2] = f
[zofs
[zone_index
]+6*i
+2]/pcell
->area
;
1240 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
)/pcell
->area
;
1241 f
[zofs
[zone_index
]+6*i
+4] = f
[zofs
[zone_index
]+6*i
+4]/pcell
->area
;
1242 f
[zofs
[zone_index
]+6*i
+5] = f
[zofs
[zone_index
]+6*i
+5]/pcell
->area
;
1244 if(ODE_F
.TimeDependent
==true)
1247 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1249 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1250 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1251 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1252 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1253 PetscScalar Wnt
= (2-r
)/(1-r
)*1.5*ni
*kb
*Tn
-1.0/(r
*(1-r
))*1.5*fs
[i
].n
*kb
*fs
[i
].Tn
+(1-r
)/r
*1.5*fs
[i
].n_last
*kb
*fs
[i
].Tn_last
;
1254 PetscScalar Wpt
= (2-r
)/(1-r
)*1.5*pi
*kb
*Tp
-1.0/(r
*(1-r
))*1.5*fs
[i
].p
*kb
*fs
[i
].Tp
+(1-r
)/r
*1.5*fs
[i
].p_last
*kb
*fs
[i
].Tp_last
;
1255 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1256 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1257 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1258 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1259 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1260 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1264 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1265 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1266 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1267 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1268 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1269 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1275 void SMCZone::F3E_ddm_ombc_segment(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
)
1277 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1278 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1281 int size
= pzone
->davcell
.size();
1282 PetscScalar kb
= mt
->kb
;
1283 PetscScalar Na
= aux
[i
].Na
;
1284 PetscScalar Nd
= aux
[i
].Nd
;
1285 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
1286 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
1287 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
1288 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3];
1289 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
1290 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
1291 mt
->mapping(&pzone
->danode
[i
],&aux
[i
],ODE_F
.clock
);
1292 PetscScalar nie
= mt
->band
->nie(fs
[i
].T
);
1293 PetscScalar Nc
= mt
->band
->Nc(fs
[i
].T
);
1294 PetscScalar electron_density
,hole_density
;
1296 for(int j
=0;j
<electrode
.size();j
++)
1297 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
1299 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
)
1300 + aux
[i
].affinity
+ mt
->band
->EgNarrowToEc(fs
[i
].T
)
1301 - x
[zofs
[z
]+equ_num
*size
+om_equ
];
1305 hole_density
= (-(Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1306 electron_density
= nie
*nie
/hole_density
;
1310 electron_density
= ((Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1311 hole_density
= nie
*nie
/electron_density
;
1313 f
[zofs
[z
]+6*i
+1] = x
[zofs
[z
]+6*i
+1] - electron_density
; //electron density
1314 f
[zofs
[z
]+6*i
+2] = x
[zofs
[z
]+6*i
+2] - hole_density
; //hole density
1316 PetscScalar grad_T
=0;
1317 for(int j
=0;j
<pcell
->nb_num
;j
++)
1319 int nb
= pcell
->nb_array
[j
];
1320 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1321 PetscScalar T_mid
= 0.5*(Tj
+Ti
);
1322 PetscScalar dTdx_mid
= (Tj
-Ti
)/pcell
->ilen
[j
];
1323 PetscScalar kapa
= mt
->thermal
->HeatConduction(T_mid
);
1324 grad_T
+= kapa
*pcell
->elen
[j
]*dTdx_mid
/pcell
->area
;
1325 if(j
==0||j
==pcell
->nb_num
-1)
1327 PetscScalar h
= pbc
->heat_transfer
;
1328 PetscScalar r
= h
*pbc
->T_external
;
1329 grad_T
+= 0.5*pcell
->ilen
[j
]*(r
-0.25*h
*(3*Ti
+Tj
))/pcell
->area
;
1332 f
[zofs
[zone_index
]+6*i
+3] = grad_T
;
1333 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1334 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1336 if(ODE_F
.TimeDependent
==true)
1339 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1341 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1342 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1343 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1344 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1348 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1349 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1355 void SMCZone::F3E_ddm_ombc_interface(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
1358 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1359 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1362 int size
= pzone
->davcell
.size();
1363 PetscScalar kb
= mt
->kb
;
1364 PetscScalar Na
= aux
[i
].Na
;
1365 PetscScalar Nd
= aux
[i
].Nd
;
1366 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
1367 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
1368 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
1369 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3];
1370 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
1371 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
1372 mt
->mapping(&pzone
->danode
[i
],&aux
[i
],ODE_F
.clock
);
1373 PetscScalar nie
= mt
->band
->nie(fs
[i
].T
);
1374 PetscScalar Nc
= mt
->band
->Nc(fs
[i
].T
);
1375 PetscScalar electron_density
,hole_density
;
1377 for(int j
=0;j
<electrode
.size();j
++)
1378 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
1380 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
)
1381 + aux
[i
].affinity
+ mt
->band
->EgNarrowToEc(fs
[i
].T
)
1382 - x
[zofs
[z
]+equ_num
*size
+om_equ
];
1386 hole_density
= (-(Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1387 electron_density
= nie
*nie
/hole_density
;
1391 electron_density
= ((Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1392 hole_density
= nie
*nie
/electron_density
;
1394 f
[zofs
[z
]+6*i
+1] = x
[zofs
[z
]+6*i
+1] - electron_density
; //electron density
1395 f
[zofs
[z
]+6*i
+2] = x
[zofs
[z
]+6*i
+2] - hole_density
; //hole density
1397 PetscScalar grad_T
=0;
1398 for(int j
=0;j
<pcell
->nb_num
;j
++)
1400 int nb
= pcell
->nb_array
[j
];
1401 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1402 PetscScalar T_mid
= 0.5*(Tj
+Ti
);
1403 PetscScalar dTdx_mid
= (Tj
-Ti
)/pcell
->ilen
[j
];
1404 PetscScalar kapa
= mt
->thermal
->HeatConduction(T_mid
);
1405 grad_T
+= kapa
*pcell
->elen
[j
]*dTdx_mid
;
1407 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1408 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
1409 for(int j
=0;j
<ncell
->nb_num
;j
++)
1411 int nb
= ncell
->nb_array
[j
];
1412 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1]; //potential of nb node
1413 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
1414 grad_T
+= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Tj_n
-Ti
);
1417 f
[zofs
[zone_index
]+6*i
+3] = grad_T
;
1418 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1419 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1422 if(ODE_F
.TimeDependent
==true)
1425 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1427 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1428 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1429 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1430 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1431 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
1432 -pz
->aux
[n
].density
*HeatCapacity2
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
1436 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1437 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1438 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*pcell
->area
1439 -pz
->aux
[n
].density
*HeatCapacity2
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*ncell
->area
;
1447 void SMCZone::F3E_ddm_stkbc_segment(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int>& zofs
,DABC
&bc
)
1449 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1450 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1453 int size
= pzone
->davcell
.size();
1454 PetscScalar kb
= mt
->kb
;
1455 PetscScalar e
= mt
->e
;
1456 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
1457 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
1458 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
1459 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
1460 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
1461 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
1464 for(int j
=0;j
<electrode
.size();j
++)
1465 if(electrode
[j
]==pcell
->bc_index
-1)
1470 //Schotty Barrier Lowerring
1471 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
1473 f
[zofs
[z
]+6*i
+0] = x
[zofs
[z
]+6*i
+0] + pbc
->WorkFunction
- deltaVB
- x
[zofs
[z
]+equ_num
*size
+stk_equ
];
1475 PetscScalar Fn
=0,Fp
=0,grad_T
=0;
1476 for(int j
=0;j
<pcell
->nb_num
;j
++)
1478 int nb
= pcell
->nb_array
[j
];
1479 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1480 if(j
==0||j
==pcell
->nb_num
-1)
1482 Fn
+= mt
->band
->SchottyJsn(ni
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
- deltaVB
)*0.5*pcell
->ilen
[j
];
1483 Fp
+= mt
->band
->SchottyJsp(pi
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
+ deltaVB
)*0.5*pcell
->ilen
[j
];
1484 PetscScalar h
= pbc
->heat_transfer
;
1485 PetscScalar r
= h
*pbc
->T_external
;
1486 grad_T
+= 0.5*pcell
->ilen
[j
]*(r
-0.25*h
*(3*Ti
+Tj
));
1490 f
[zofs
[zone_index
]+6*i
+1] = (f
[zofs
[zone_index
]+6*i
+1]+Fn
)/pcell
->area
;
1491 f
[zofs
[zone_index
]+6*i
+2] = (f
[zofs
[zone_index
]+6*i
+2]-Fp
)/pcell
->area
;
1492 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
)/pcell
->area
;
1493 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1494 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1496 if(ODE_F
.TimeDependent
==true)
1499 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1501 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1502 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1503 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1504 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1505 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1506 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1507 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1508 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1512 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1513 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1514 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1515 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1521 void SMCZone::F3E_ddm_stkbc_interface(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int>& zofs
,DABC
&bc
,
1524 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1525 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1528 int size
= pzone
->davcell
.size();
1529 PetscScalar kb
= mt
->kb
;
1530 PetscScalar e
= mt
->e
;
1531 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
1532 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
1533 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
1534 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
1535 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
1536 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
1539 for(int j
=0;j
<electrode
.size();j
++)
1540 if(electrode
[j
]==pcell
->bc_index
-1)
1545 //Schotty Barrier Lowerring
1546 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
1548 f
[zofs
[z
]+6*i
+0] = x
[zofs
[z
]+6*i
+0] + pbc
->WorkFunction
- deltaVB
- x
[zofs
[z
]+equ_num
*size
+stk_equ
];
1550 PetscScalar Fn
=0,Fp
=0,grad_T
=0;
1551 for(int j
=0;j
<pcell
->nb_num
;j
++)
1553 int nb
= pcell
->nb_array
[j
];
1554 if(j
==0||j
==pcell
->nb_num
-1)
1556 Fn
+= mt
->band
->SchottyJsn(ni
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
- deltaVB
)*0.5*pcell
->ilen
[j
];
1557 Fp
+= mt
->band
->SchottyJsp(pi
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
+ deltaVB
)*0.5*pcell
->ilen
[j
];
1561 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1562 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
1563 for(int j
=0;j
<ncell
->nb_num
;j
++)
1565 int nb
= ncell
->nb_array
[j
];
1566 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1]; //potential of nb node
1567 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(fs
[i
].T
);//(0.5*(Ti+Tj_n));
1568 grad_T
+= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Tj_n
-Ti
);
1571 f
[zofs
[zone_index
]+6*i
+1] = (f
[zofs
[zone_index
]+6*i
+1]+Fn
)/pcell
->area
;
1572 f
[zofs
[zone_index
]+6*i
+2] = (f
[zofs
[zone_index
]+6*i
+2]-Fp
)/pcell
->area
;
1573 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
);
1574 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1575 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1577 if(ODE_F
.TimeDependent
==true)
1580 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1582 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1583 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1584 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1585 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1586 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1587 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1588 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1589 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1590 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
1591 -pz
->aux
[n
].density
*HeatCapacity2
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
1595 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1596 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1597 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1598 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1599 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*pcell
->area
1600 -pz
->aux
[n
].density
*HeatCapacity2
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*ncell
->area
;
1607 void SMCZone::F3E_ddm_insulator_gate(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
)
1609 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1610 InsulatorContactBC
*pbc
= dynamic_cast<InsulatorContactBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1612 int size
= pzone
->davcell
.size();
1613 PetscScalar kb
= mt
->kb
;
1614 PetscScalar e
= mt
->e
;
1615 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1616 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1617 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1618 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1619 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1620 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1621 PetscScalar grad_P
= 0, grad_T
= 0;
1623 for(int j
=0;j
<electrode
.size();j
++)
1624 if(electrode
[j
]==pcell
->bc_index
-1)
1626 for(int j
=0;j
<pcell
->nb_num
;j
++)
1628 int nb
= pcell
->nb_array
[j
];
1629 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
1630 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1632 if(j
==0||j
==pcell
->nb_num
-1)
1634 PetscScalar vgate
= x
[zofs
[zone_index
]+equ_num
*size
+ins_equ
] - pbc
->WorkFunction
;
1635 PetscScalar q
= e
*pbc
->QF
; //sigma is the surface change density
1636 PetscScalar Thick
= pbc
->Thick
;
1637 PetscScalar eps_ox
= mt
->eps0
*pbc
->eps
;
1638 PetscScalar eps
= aux
[i
].eps
;
1639 PetscScalar r
=q
/eps
+ eps_ox
/eps
/Thick
*vgate
;
1640 PetscScalar s
=eps_ox
/eps
/Thick
;
1641 grad_P
+= 0.5*pcell
->ilen
[j
]*(r
-0.25*s
*(3*Vi
+Vj
));
1643 PetscScalar h
= pbc
->heat_transfer
;
1644 grad_T
+= 0.5*pcell
->ilen
[j
]*(h
*pbc
->T_external
-0.25*h
*(3*Ti
+Tj
));
1648 f
[zofs
[zone_index
]+6*i
+0] = (f
[zofs
[zone_index
]+6*i
+0]+grad_P
)/pcell
->area
1649 + e
/aux
[i
].eps
*((pi
-aux
[i
].Na
)+(aux
[i
].Nd
-ni
));
1650 f
[zofs
[zone_index
]+6*i
+1] = f
[zofs
[zone_index
]+6*i
+1]/pcell
->area
;
1651 f
[zofs
[zone_index
]+6*i
+2] = f
[zofs
[zone_index
]+6*i
+2]/pcell
->area
;
1652 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
)/pcell
->area
;
1653 f
[zofs
[zone_index
]+6*i
+4] = f
[zofs
[zone_index
]+6*i
+4]/pcell
->area
;
1654 f
[zofs
[zone_index
]+6*i
+5] = f
[zofs
[zone_index
]+6*i
+5]/pcell
->area
;
1656 if(ODE_F
.TimeDependent
==true)
1659 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1661 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1662 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1663 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1664 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1665 PetscScalar Wnt
= (2-r
)/(1-r
)*1.5*ni
*kb
*Tn
-1.0/(r
*(1-r
))*1.5*fs
[i
].n
*kb
*fs
[i
].Tn
+(1-r
)/r
*1.5*fs
[i
].n_last
*kb
*fs
[i
].Tn_last
;
1666 PetscScalar Wpt
= (2-r
)/(1-r
)*1.5*pi
*kb
*Tp
-1.0/(r
*(1-r
))*1.5*fs
[i
].p
*kb
*fs
[i
].Tp
+(1-r
)/r
*1.5*fs
[i
].p_last
*kb
*fs
[i
].Tp_last
;
1667 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1668 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1669 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1670 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1671 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1672 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1676 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1677 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1678 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1679 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1680 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1681 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1688 void SMCZone::F3E_ddm_interface(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
1691 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1692 InsulatorInterfaceBC
*pbc
= dynamic_cast<InsulatorInterfaceBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1693 PetscScalar kb
= mt
->kb
;
1694 PetscScalar e
= mt
->e
;
1695 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1696 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1697 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1698 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1699 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1700 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1702 PetscScalar grad_P
= 0,grad_T
=0;
1703 //semiconductor-insulator interface
1704 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1705 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
1706 for(int j
=0;j
<ncell
->nb_num
;j
++)
1708 int nb
= ncell
->nb_array
[j
];
1709 PetscScalar Vj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+0]; //potential of nb node
1710 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1]; //potential of nb node
1711 grad_P
+= pz
->aux
[n
].eps
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Vj_n
-Vi
);
1712 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
1713 grad_T
+= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Tj_n
-Ti
);
1715 PetscScalar L
= (pcell
->ilen
[0]+pcell
->ilen
[pcell
->nb_num
-1])/2.0;
1718 f
[zofs
[zone_index
]+6*i
+0] = (aux
[i
].eps
*f
[zofs
[zone_index
]+6*i
+0]+grad_P
)
1719 + e
*((pi
-aux
[i
].Na
)+(aux
[i
].Nd
-ni
))*pcell
->area
+ pbc
->QF
*L
;
1720 f
[zofs
[zone_index
]+6*i
+1] = f
[zofs
[zone_index
]+6*i
+1]/pcell
->area
;
1721 f
[zofs
[zone_index
]+6*i
+2] = f
[zofs
[zone_index
]+6*i
+2]/pcell
->area
;
1722 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
);
1723 f
[zofs
[zone_index
]+6*i
+4] = f
[zofs
[zone_index
]+6*i
+4]/pcell
->area
;
1724 f
[zofs
[zone_index
]+6*i
+5] = f
[zofs
[zone_index
]+6*i
+5]/pcell
->area
;
1726 if(ODE_F
.TimeDependent
==true)
1729 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1731 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1732 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1733 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1734 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1735 PetscScalar Wnt
= (2-r
)/(1-r
)*1.5*ni
*kb
*Tn
-1.0/(r
*(1-r
))*1.5*fs
[i
].n
*kb
*fs
[i
].Tn
+(1-r
)/r
*1.5*fs
[i
].n_last
*kb
*fs
[i
].Tn_last
;
1736 PetscScalar Wpt
= (2-r
)/(1-r
)*1.5*pi
*kb
*Tp
-1.0/(r
*(1-r
))*1.5*fs
[i
].p
*kb
*fs
[i
].Tp
+(1-r
)/r
*1.5*fs
[i
].p_last
*kb
*fs
[i
].Tp_last
;
1737 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1738 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1739 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1740 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1741 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
1742 -pz
->aux
[n
].density
*HeatCapacity2
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
1743 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1744 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1748 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1749 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1750 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1751 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1752 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*pcell
->area
1753 -pz
->aux
[n
].density
*HeatCapacity2
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*ncell
->area
;
1754 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1755 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1762 void SMCZone::F3E_ddm_homojunction(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
1765 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1766 PetscScalar kb
= mt
->kb
;
1767 PetscScalar e
= mt
->e
;
1768 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1769 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1770 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1771 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1772 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1773 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1774 if(zone_index
> pz
->pzone
->zone_index
)
1776 f
[zofs
[zone_index
]+6*i
+0] = Vi
- x
[zofs
[pz
->zone_index
]+6*n
+0];
1777 f
[zofs
[zone_index
]+6*i
+1] = ni
- x
[zofs
[pz
->zone_index
]+6*n
+1];
1778 f
[zofs
[zone_index
]+6*i
+2] = pi
- x
[zofs
[pz
->zone_index
]+6*n
+2];
1779 f
[zofs
[zone_index
]+6*i
+3] = Ti
- x
[zofs
[pz
->zone_index
]+6*n
+3];
1780 f
[zofs
[zone_index
]+6*i
+4] = x
[zofs
[zone_index
]+6*i
+4] - x
[zofs
[pz
->zone_index
]+6*n
+4];
1781 f
[zofs
[zone_index
]+6*i
+5] = x
[zofs
[zone_index
]+6*i
+5] - x
[zofs
[pz
->zone_index
]+6*n
+5];
1785 //process half cell in local zone
1786 mt
->mapping(&pzone
->danode
[i
],&aux
[i
],ODE_F
.clock
);
1788 PetscScalar Na
= aux
[i
].Na
;
1789 PetscScalar Nd
= aux
[i
].Nd
;
1790 PetscScalar grad_P
=0,grad_T
=0;
1791 PetscScalar Fphi
=0,Fn
=0,Fp
=0,Sn
=0,Sp
=0;
1793 Fphi
= f
[zofs
[zone_index
]+6*i
+0];
1794 Fn
= f
[zofs
[zone_index
]+6*i
+1];
1795 Fp
= f
[zofs
[zone_index
]+6*i
+2];
1796 grad_T
=f
[zofs
[zone_index
]+6*i
+3];
1797 Sn
= f
[zofs
[zone_index
]+6*i
+4];
1798 Sp
= f
[zofs
[zone_index
]+6*i
+5];
1799 //process another half cell in dornor zone
1800 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1802 Fphi
+= f
[zofs
[pz
->zone_index
]+6*n
+0];
1803 Fn
+= f
[zofs
[pz
->zone_index
]+6*n
+1];
1804 Fp
+= f
[zofs
[pz
->zone_index
]+6*n
+2];
1805 grad_T
+=f
[zofs
[pz
->zone_index
]+6*n
+3];
1806 Sn
+= f
[zofs
[pz
->zone_index
]+6*n
+4];
1807 Sp
+= f
[zofs
[pz
->zone_index
]+6*n
+5];
1809 PetscScalar area
= pcell
->area
+ncell
->area
;
1810 f
[zofs
[zone_index
]+6*i
+0] = Fphi
/area
+ e
/aux
[i
].eps
*(pi
-ni
+Nd
-Na
);
1811 f
[zofs
[zone_index
]+6*i
+1] = Fn
/area
;
1812 f
[zofs
[zone_index
]+6*i
+2] = Fp
/area
;
1813 f
[zofs
[zone_index
]+6*i
+3] = grad_T
/area
;
1814 f
[zofs
[zone_index
]+6*i
+4] = Sn
/area
;
1815 f
[zofs
[zone_index
]+6*i
+5] = Sp
/area
;
1817 if(ODE_F
.TimeDependent
==true)
1820 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1822 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1823 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1824 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1825 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1826 PetscScalar Wnt
= (2-r
)/(1-r
)*1.5*ni
*kb
*Tn
-1.0/(r
*(1-r
))*1.5*fs
[i
].n
*kb
*fs
[i
].Tn
+(1-r
)/r
*1.5*fs
[i
].n_last
*kb
*fs
[i
].Tn_last
;
1827 PetscScalar Wpt
= (2-r
)/(1-r
)*1.5*pi
*kb
*Tp
-1.0/(r
*(1-r
))*1.5*fs
[i
].p
*kb
*fs
[i
].Tp
+(1-r
)/r
*1.5*fs
[i
].p_last
*kb
*fs
[i
].Tp_last
;
1828 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1829 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1830 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1831 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1832 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1833 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1837 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1838 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1839 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1840 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1841 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1842 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1850 void SMCZone::F3E_om_electrode(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
1853 int size
= pzone
->davcell
.size();
1854 int bc_index
= electrode
[i
];
1855 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* > (bc
.Get_pointer(bc_index
));
1856 PetscScalar e
= mt
->e
;
1857 PetscScalar current
=0;
1859 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
1861 int node
=bc
[bc_index
].psegment
->node_array
[j
];
1862 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
1863 PetscScalar Vi
= x
[zofs
[zone_index
]+6*node
+0]; //potential of node i
1864 current
+= DeviceDepth
*(f
[zofs
[zone_index
]+6*node
+1]-f
[zofs
[zone_index
]+6*node
+2]);
1865 for(int k
=0;k
<pcell
->nb_num
;k
++)
1867 int nb
= pcell
->nb_array
[k
];
1868 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
1869 //displacement current
1870 current
+= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
*((Vi
-Vj
)-(fs
[node
].P
-fs
[nb
].P
))/pcell
->ilen
[k
]/ODE_F
.dt
;
1873 //if the electrode connect to another electrode
1874 if(pbc
->inner_connect
!=-1)
1876 int connect_to
= pbc
->inner_connect
;
1877 int connect_zone
= pbc
->connect_zone
;
1878 int connect_elec
=-1;
1879 SMCZone
* pz
= dynamic_cast <SMCZone
* > (pbc
->pzonedata
);
1880 for(int j
=0;j
<pz
->electrode
.size();j
++)
1882 if(bc
[pz
->electrode
[j
]].BCType
==OhmicContact
)
1884 OhmicBC
*om_bc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pz
->electrode
[j
]));
1885 if(om_bc
->inner_connect
==bc_index
) connect_elec
=j
;
1888 int connect_index
=zofs
[connect_zone
]+equ_num
*pz
->pzone
->davcell
.size()+connect_elec
;
1889 if(bc_index
< connect_to
)
1891 f
[zofs
[zone_index
]+equ_num
*size
+i
]+=x
[zofs
[zone_index
]+equ_num
*size
+i
]; //voltage equation
1892 f
[connect_index
]+=current
; //current equation
1896 f
[zofs
[zone_index
]+equ_num
*size
+i
]+=current
; //current equation
1897 f
[connect_index
]+=-x
[zofs
[zone_index
]+equ_num
*size
+i
];//voltage equation
1899 pbc
->Set_Current_new(current
);
1901 //the electrode has an external voltage circult
1902 else if(pbc
->electrode_type
==VoltageBC
)
1904 PetscScalar V
= pbc
->Vapp
;
1905 PetscScalar R
= pbc
->R
;
1906 PetscScalar C
= pbc
->C
;
1907 PetscScalar L
= pbc
->L
;
1908 PetscScalar In
= pbc
->current
;
1909 PetscScalar Icn
= pbc
->cap_current
;
1910 PetscScalar Pn
= pbc
->potential
;
1911 PetscScalar P
= x
[zofs
[zone_index
]+equ_num
*size
+i
];
1912 f
[zofs
[zone_index
]+equ_num
*size
+i
]=(L
/ODE_F
.dt
+R
)*current
-V
+(1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
)*P
1913 -(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
*Pn
-L
/ODE_F
.dt
*(In
+Icn
);
1914 pbc
->Set_Current_new(current
);
1916 //the electrode has an external current circult
1917 else if(pbc
->electrode_type
==CurrentBC
)
1919 PetscScalar I
= pbc
->Iapp
;
1920 PetscScalar C
= pbc
->C
;
1921 f
[zofs
[zone_index
]+equ_num
*size
+i
]=current
- I
;
1922 pbc
->Set_Current_new(I
);
1924 pbc
->Set_Potential_new(x
[zofs
[zone_index
]+equ_num
*size
+i
]);
1927 void SMCZone::F3E_stk_electrode(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
1930 int size
= pzone
->davcell
.size();
1931 int bc_index
= electrode
[i
];
1932 SchottkyBC
*pbc
= dynamic_cast <SchottkyBC
* > (bc
.Get_pointer(bc_index
));
1934 PetscScalar current
=0;
1935 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
1937 int node
= bc
[bc_index
].psegment
->node_array
[j
];
1938 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
1939 PetscScalar Vi
= x
[zofs
[zone_index
]+6*node
+0]; //electron density of node i
1940 PetscScalar ni
= x
[zofs
[zone_index
]+6*node
+1]; //electron density of node i
1941 PetscScalar pi
= x
[zofs
[zone_index
]+6*node
+2]; //hole density of node i
1942 PetscScalar Ti
= x
[zofs
[zone_index
]+6*node
+3];
1943 mt
->mapping(&pzone
->danode
[node
],&aux
[node
],ODE_F
.clock
);
1944 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[node
].eps
,sqrt(aux
[node
].Ex
*aux
[node
].Ex
+aux
[node
].Ey
*aux
[node
].Ey
));
1945 PetscScalar Jsn
= mt
->band
->SchottyJsn(ni
,Ti
,pbc
->WorkFunction
-aux
[node
].affinity
-deltaVB
);
1946 PetscScalar Jsp
= mt
->band
->SchottyJsp(pi
,Ti
,pbc
->WorkFunction
-aux
[node
].affinity
+deltaVB
);
1947 current
+= -Jsn
*0.5*pcell
->ilen
[0]*DeviceDepth
;
1948 current
+= -Jsp
*0.5*pcell
->ilen
[0]*DeviceDepth
;
1949 current
+= -Jsn
*0.5*pcell
->ilen
[pcell
->nb_num
-1]*DeviceDepth
;
1950 current
+= -Jsp
*0.5*pcell
->ilen
[pcell
->nb_num
-1]*DeviceDepth
;
1951 for(int k
=0;k
<pcell
->nb_num
;k
++)
1953 int nb
= pcell
->nb_array
[k
];
1954 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
1955 //displacement current
1956 current
+= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
*((Vi
-Vj
)-(fs
[node
].P
-fs
[nb
].P
))/pcell
->ilen
[k
]/ODE_F
.dt
;
1959 if(pbc
->electrode_type
==VoltageBC
)
1961 PetscScalar R
= pbc
->R
;
1962 PetscScalar C
= pbc
->C
;
1963 PetscScalar L
= pbc
->L
;
1964 PetscScalar V
= pbc
->Vapp
;
1965 PetscScalar In
= pbc
->current
;
1966 PetscScalar Icn
= pbc
->cap_current
;
1967 PetscScalar Pn
= pbc
->potential
;
1968 PetscScalar P
= x
[zofs
[zone_index
]+equ_num
*size
+i
];
1969 f
[zofs
[zone_index
]+equ_num
*size
+i
]=(L
/ODE_F
.dt
+R
)*current
-V
+(1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
)*P
1970 -(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
*Pn
-L
/ODE_F
.dt
*(In
+Icn
);
1971 pbc
->Set_Current_new(current
);
1973 else if(pbc
->electrode_type
==CurrentBC
)
1975 PetscScalar I
= pbc
->Iapp
;
1976 PetscScalar C
= pbc
->C
;
1977 f
[zofs
[zone_index
]+equ_num
*size
+i
]=current
- I
;
1978 pbc
->Set_Current_new(I
);
1980 pbc
->Set_Potential_new(x
[zofs
[zone_index
]+equ_num
*size
+i
]);
1984 void SMCZone::F3E_ins_electrode(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
1987 int size
= pzone
->davcell
.size();
1988 int bc_index
= electrode
[i
];
1989 InsulatorContactBC
*pbc
= dynamic_cast <InsulatorContactBC
* > (bc
.Get_pointer(bc_index
));
1991 PetscScalar current
=0;
1992 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
1994 int node
= bc
[bc_index
].psegment
->node_array
[j
];
1995 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
1996 PetscScalar Vi
= x
[zofs
[zone_index
]+6*node
+0]; //electron density of node i
1997 for(int k
=0;k
<pcell
->nb_num
;k
++)
1999 int nb
= pcell
->nb_array
[k
];
2000 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
2001 //displacement current
2002 current
+= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
*((Vi
-Vj
)-(fs
[node
].P
-fs
[nb
].P
))/pcell
->ilen
[k
]/ODE_F
.dt
;
2005 if(pbc
->electrode_type
==VoltageBC
)
2007 PetscScalar R
= pbc
->R
;
2008 PetscScalar C
= pbc
->C
;
2009 PetscScalar L
= pbc
->L
;
2010 PetscScalar V
= pbc
->Vapp
;
2011 PetscScalar In
= pbc
->current
;
2012 PetscScalar Icn
= pbc
->cap_current
;
2013 PetscScalar Pn
= pbc
->potential
;
2014 PetscScalar P
= x
[zofs
[zone_index
]+equ_num
*size
+i
];
2015 f
[zofs
[zone_index
]+equ_num
*size
+i
]=(L
/ODE_F
.dt
+R
)*current
-V
+(1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
)*P
2016 -(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
*Pn
-L
/ODE_F
.dt
*(In
+Icn
);
2017 pbc
->Set_Current_new(current
);
2019 pbc
->Set_Potential_new(x
[zofs
[zone_index
]+equ_num
*size
+i
]);
2024 void SMCZone::J3E_ddm_inner(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
)
2027 PetscInt index
[6],col
[6];
2028 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2030 PetscScalar kb
= mt
->kb
;
2031 PetscScalar e
= mt
->e
;
2032 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2033 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2034 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2035 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3];
2036 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2037 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2038 PetscScalar area
= pcell
->area
;
2040 //--------------------------------
2041 index
[0] = zofs
[z
]+6*i
+0;
2042 index
[1] = zofs
[z
]+6*i
+1;
2043 index
[2] = zofs
[z
]+6*i
+2;
2044 index
[3] = zofs
[z
]+6*i
+3;
2045 index
[4] = zofs
[z
]+6*i
+4;
2046 index
[5] = zofs
[z
]+6*i
+5;
2048 //--------------------------------
2049 for(int j
=0;j
<pcell
->nb_num
;j
++)
2051 int nb
= pcell
->nb_array
[j
];
2052 col
[0] = zofs
[z
]+6*nb
+0;
2053 col
[1] = zofs
[z
]+6*nb
+1;
2054 col
[2] = zofs
[z
]+6*nb
+2;
2055 col
[3] = zofs
[z
]+6*nb
+3;
2056 col
[4] = zofs
[z
]+6*nb
+4;
2057 col
[5] = zofs
[z
]+6*nb
+5;
2058 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2060 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2063 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2065 A
.m
[1] += -e
/aux
[i
].eps
; //dfun(0)/dn(i)
2066 A
.m
[2] += e
/aux
[i
].eps
; //dfun(0)/dp(i)
2068 if(ODE_F
.TimeDependent
==true)
2071 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2073 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2074 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2075 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2076 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2077 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2078 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2079 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2083 A
.m
[7] += -1/ODE_F
.dt
;
2084 A
.m
[14] += -1/ODE_F
.dt
;
2085 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2086 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2087 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2088 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2092 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2097 void SMCZone::J3E_ddm_neumannbc(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
)
2100 PetscInt index
[6],col
[6];
2101 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2102 NeumannBC
*pbc
= dynamic_cast <NeumannBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2104 PetscScalar kb
= mt
->kb
;
2105 PetscScalar e
= mt
->e
;
2106 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2107 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2108 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2109 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3];
2110 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2111 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2112 PetscScalar area
= pcell
->area
;
2113 PetscScalar d_grad_T_dTi
= 0;
2114 //--------------------------------
2115 index
[0] = zofs
[z
]+6*i
+0;
2116 index
[1] = zofs
[z
]+6*i
+1;
2117 index
[2] = zofs
[z
]+6*i
+2;
2118 index
[3] = zofs
[z
]+6*i
+3;
2119 index
[4] = zofs
[z
]+6*i
+4;
2120 index
[5] = zofs
[z
]+6*i
+5;
2122 //--------------------------------
2123 for(int j
=0;j
<pcell
->nb_num
;j
++)
2125 int nb
= pcell
->nb_array
[j
];
2126 col
[0] = zofs
[z
]+6*nb
+0;
2127 col
[1] = zofs
[z
]+6*nb
+1;
2128 col
[2] = zofs
[z
]+6*nb
+2;
2129 col
[3] = zofs
[z
]+6*nb
+3;
2130 col
[4] = zofs
[z
]+6*nb
+4;
2131 col
[5] = zofs
[z
]+6*nb
+5;
2132 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2134 if(j
==0||j
==pcell
->nb_num
-1)
2136 PetscScalar h
= pbc
->heat_transfer
;
2137 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/pcell
->area
;
2138 A
.m
[21] += -0.5*pcell
->ilen
[j
]*0.25*h
/pcell
->area
;
2140 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2143 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2145 A
.m
[1] += -e
/aux
[i
].eps
; //dfun(0)/dn(i)
2146 A
.m
[2] += e
/aux
[i
].eps
; //dfun(0)/dp(i)
2148 A
.m
[21]+= d_grad_T_dTi
;
2150 if(ODE_F
.TimeDependent
==true)
2153 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2155 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2156 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2157 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2158 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2159 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2160 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2161 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2165 A
.m
[7] += -1/ODE_F
.dt
;
2166 A
.m
[14] += -1/ODE_F
.dt
;
2167 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2168 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2169 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2170 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2174 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2180 void SMCZone::J3E_ddm_ombc_segment(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
)
2184 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2185 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2187 PetscScalar kb
= mt
->kb
;
2188 PetscScalar e
= mt
->e
;
2189 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2190 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2191 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2192 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2193 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2194 PetscScalar area
= pcell
->area
;
2195 PetscScalar d_grad_T_dTi
= 0;
2196 index
[0] = zofs
[z
]+6*i
+0;
2197 index
[1] = zofs
[z
]+6*i
+1;
2198 index
[2] = zofs
[z
]+6*i
+2;
2199 index
[3] = zofs
[z
]+6*i
+3;
2200 index
[4] = zofs
[z
]+6*i
+4;
2201 index
[5] = zofs
[z
]+6*i
+5;
2203 for(int j
=0;j
<pcell
->nb_num
;j
++)
2205 int nb
= pcell
->nb_array
[j
];
2206 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2207 PetscScalar kapa
= mt
->thermal
->HeatConduction(0.5*(Ti
+Tj
));
2208 //-------------------------------------
2209 d_grad_T_dTi
+= -kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
]/area
;
2210 //-------------------------------------
2211 PetscScalar d_grad_T_dTj
= kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
]/area
; //dfun(3)/dT(r)
2212 if(j
==0||j
==pcell
->nb_num
-1)
2214 PetscScalar h
= pbc
->heat_transfer
;
2215 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/pcell
->area
;
2216 d_grad_T_dTj
+= -0.5*pcell
->ilen
[j
]*0.25*h
/pcell
->area
;
2218 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[z
]+6*nb
+3,d_grad_T_dTj
,INSERT_VALUES
);
2222 A
.m
[21] = d_grad_T_dTi
; //dfun(3)/dT(i)
2229 if(ODE_F
.TimeDependent
==true)
2232 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2234 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2235 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2236 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2240 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2241 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2244 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2248 int size
= pzone
->davcell
.size();
2250 for(int j
=0;j
<electrode
.size();j
++)
2251 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
2253 MatSetValue(*jac
,zofs
[zone_index
]+6*i
+0,zofs
[zone_index
]+equ_num
*size
+om_equ
,-1,INSERT_VALUES
);
2257 void SMCZone::J3E_ddm_ombc_interface(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
,
2262 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2263 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2265 PetscScalar kb
= mt
->kb
;
2266 PetscScalar e
= mt
->e
;
2267 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2268 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2269 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2270 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2271 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2272 PetscScalar area
= pcell
->area
;
2273 PetscScalar d_grad_T_dTi
= 0;
2274 index
[0] = zofs
[z
]+6*i
+0;
2275 index
[1] = zofs
[z
]+6*i
+1;
2276 index
[2] = zofs
[z
]+6*i
+2;
2277 index
[3] = zofs
[z
]+6*i
+3;
2278 index
[4] = zofs
[z
]+6*i
+4;
2279 index
[5] = zofs
[z
]+6*i
+5;
2281 for(int j
=0;j
<pcell
->nb_num
;j
++)
2283 int nb
= pcell
->nb_array
[j
];
2284 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2285 PetscScalar kapa
= mt
->thermal
->HeatConduction(0.5*(Ti
+Tj
));
2286 //-------------------------------------
2287 d_grad_T_dTi
+= -kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
];
2288 //-------------------------------------
2289 PetscScalar d_grad_T_dTj
= kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
]; //dfun(3)/dT(r)
2290 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[z
]+6*nb
+3,d_grad_T_dTj
,INSERT_VALUES
);
2292 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2293 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
2294 for(int j
=0;j
<ncell
->nb_num
;j
++)
2296 int nb
= ncell
->nb_array
[j
];
2297 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1];
2298 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
2299 d_grad_T_dTi
+= -kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2300 PetscScalar d_grad_T_dTj
= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2301 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[pz
->pzone
->zone_index
]+2*nb
+1,d_grad_T_dTj
,INSERT_VALUES
);
2305 A
.m
[21] = d_grad_T_dTi
; //dfun(3)/dT(i)
2313 if(ODE_F
.TimeDependent
==true)
2316 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2318 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2319 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2320 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2321 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
2322 -pz
->aux
[n
].density
*HeatCapacity2
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
2326 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2327 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2328 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
*pcell
->area
2329 -pz
->aux
[n
].density
*HeatCapacity2
/ODE_F
.dt
*ncell
->area
;
2333 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2337 int size
= pzone
->davcell
.size();
2339 for(int j
=0;j
<electrode
.size();j
++)
2340 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
2342 MatSetValue(*jac
,zofs
[zone_index
]+6*i
+0,zofs
[zone_index
]+equ_num
*size
+om_equ
,-1,INSERT_VALUES
);
2346 void SMCZone::J3E_ddm_stkbc_segment(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
)
2349 PetscInt index
[6],col
[6];
2350 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2351 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2354 int size
= pzone
->davcell
.size();
2356 PetscScalar kb
= mt
->kb
;
2357 PetscScalar e
= mt
->e
;
2358 PetscScalar VB
= pbc
->WorkFunction
-aux
[i
].affinity
;
2359 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
2360 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2361 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2362 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2364 PetscScalar area
= pcell
->area
;
2365 PetscScalar d_grad_T_dTi
= 0;
2366 PetscScalar d_Fn_dni
= 0;
2367 PetscScalar d_Fn_dTi
= 0;
2368 PetscScalar d_Fp_dpi
= 0;
2369 PetscScalar d_Fp_dTi
= 0;
2370 //--------------------------------
2371 index
[0] = zofs
[z
]+6*i
+0;
2372 index
[1] = zofs
[z
]+6*i
+1;
2373 index
[2] = zofs
[z
]+6*i
+2;
2374 index
[3] = zofs
[z
]+6*i
+3;
2375 index
[4] = zofs
[z
]+6*i
+4;
2376 index
[5] = zofs
[z
]+6*i
+5;
2377 //--------------------------------
2378 for(int j
=0;j
<pcell
->nb_num
;j
++)
2380 int nb
= pcell
->nb_array
[j
];
2381 PetscScalar nj
= x
[zofs
[z
]+6*nb
+1]; //electron density of nb node
2382 PetscScalar pj
= x
[zofs
[z
]+6*nb
+2]; //hole density of nb node
2383 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2384 col
[0] = zofs
[z
]+6*nb
+0;
2385 col
[1] = zofs
[z
]+6*nb
+1;
2386 col
[2] = zofs
[z
]+6*nb
+2;
2387 col
[3] = zofs
[z
]+6*nb
+3;
2388 col
[4] = zofs
[z
]+6*nb
+4;
2389 col
[5] = zofs
[z
]+6*nb
+5;
2390 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2393 if(j
==0||j
==pcell
->nb_num
-1)
2395 d_Fn_dni
+= mt
->band
->pdSchottyJsn_pdn (ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2396 d_Fn_dTi
+= mt
->band
->pdSchottyJsn_pdTl(ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2397 d_Fp_dpi
+= mt
->band
->pdSchottyJsp_pdp (pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2398 d_Fp_dTi
+= mt
->band
->pdSchottyJsp_pdTl(pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2399 PetscScalar h
= pbc
->heat_transfer
;
2400 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/pcell
->area
;
2401 A
.m
[21] += -0.5*pcell
->ilen
[j
]*0.25*h
/pcell
->area
;
2416 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2419 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2424 A
.m
[7] += d_Fn_dni
; //dfun(1)/dn(i)
2427 A
.m
[14]+= -d_Fp_dpi
; //dfun(2)/dp(i)
2428 A
.m
[15]+= -d_Fp_dTi
;
2430 A
.m
[21]+= d_grad_T_dTi
; //dfun(3)/dT(i)
2445 if(ODE_F
.TimeDependent
==true)
2448 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2450 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2451 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2452 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2453 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2454 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2458 A
.m
[7] += -1/ODE_F
.dt
;
2459 A
.m
[14] += -1/ODE_F
.dt
;
2460 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2461 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2464 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2467 for(int j
=0;j
<electrode
.size();j
++)
2468 if(electrode
[j
]==pcell
->bc_index
-1)
2473 MatSetValue(*jac
,zofs
[zone_index
]+6*i
,zofs
[zone_index
]+equ_num
*size
+stk_equ
,-1.0,INSERT_VALUES
);
2477 void SMCZone::J3E_ddm_stkbc_interface(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
,
2481 PetscInt index
[6],col
[6];
2482 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2483 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2486 int size
= pzone
->davcell
.size();
2487 PetscScalar area
= pcell
->area
;
2489 Set_Vec6(scale
,area
,area
,area
,1.0,area
,area
);
2491 PetscScalar kb
= mt
->kb
;
2492 PetscScalar e
= mt
->e
;
2493 PetscScalar VB
= pbc
->WorkFunction
-aux
[i
].affinity
;
2494 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
2495 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2496 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2497 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2499 PetscScalar d_grad_T_dTi
= 0;
2500 PetscScalar d_Fn_dni
= 0;
2501 PetscScalar d_Fn_dTi
= 0;
2502 PetscScalar d_Fp_dpi
= 0;
2503 PetscScalar d_Fp_dTi
= 0;
2504 //--------------------------------
2505 index
[0] = zofs
[z
]+6*i
+0;
2506 index
[1] = zofs
[z
]+6*i
+1;
2507 index
[2] = zofs
[z
]+6*i
+2;
2508 index
[3] = zofs
[z
]+6*i
+3;
2509 index
[4] = zofs
[z
]+6*i
+4;
2510 index
[5] = zofs
[z
]+6*i
+5;
2511 //--------------------------------
2512 for(int j
=0;j
<pcell
->nb_num
;j
++)
2514 int nb
= pcell
->nb_array
[j
];
2515 PetscScalar nj
= x
[zofs
[z
]+6*nb
+1]; //electron density of nb node
2516 PetscScalar pj
= x
[zofs
[z
]+6*nb
+2]; //hole density of nb node
2517 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2518 col
[0] = zofs
[z
]+6*nb
+0;
2519 col
[1] = zofs
[z
]+6*nb
+1;
2520 col
[2] = zofs
[z
]+6*nb
+2;
2521 col
[3] = zofs
[z
]+6*nb
+3;
2522 col
[4] = zofs
[z
]+6*nb
+4;
2523 col
[5] = zofs
[z
]+6*nb
+5;
2524 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2527 if(j
==0||j
==pcell
->nb_num
-1)
2529 d_Fn_dni
+= mt
->band
->pdSchottyJsn_pdn (ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2530 d_Fn_dTi
+= mt
->band
->pdSchottyJsn_pdTl(ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2531 d_Fp_dpi
+= mt
->band
->pdSchottyJsp_pdp (pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2532 d_Fp_dTi
+= mt
->band
->pdSchottyJsp_pdTl(pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2547 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2550 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2551 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
2552 for(int j
=0;j
<ncell
->nb_num
;j
++)
2554 int nb
= ncell
->nb_array
[j
];
2555 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1];
2556 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(fs
[i
].T
);//(0.5*(Ti+Tj_n));
2557 d_grad_T_dTi
+= -kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2558 PetscScalar d_grad_T_dTj
= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2559 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[pz
->pzone
->zone_index
]+2*nb
+1,d_grad_T_dTj
,INSERT_VALUES
);
2562 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2567 A
.m
[7] += d_Fn_dni
; //dfun(1)/dn(i)
2570 A
.m
[14]+= -d_Fp_dpi
; //dfun(2)/dp(i)
2571 A
.m
[15]+= -d_Fp_dTi
;
2573 A
.m
[21]+= d_grad_T_dTi
; //dfun(3)/dT(i)
2589 if(ODE_F
.TimeDependent
==true)
2592 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2594 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2595 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2596 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2597 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2598 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2599 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
2600 -pz
->aux
[n
].density
*HeatCapacity2
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
2604 A
.m
[7] += -1/ODE_F
.dt
;
2605 A
.m
[14] += -1/ODE_F
.dt
;
2606 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2607 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2608 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
*pcell
->area
2609 -pz
->aux
[n
].density
*HeatCapacity2
/ODE_F
.dt
*ncell
->area
;
2613 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2616 for(int j
=0;j
<electrode
.size();j
++)
2617 if(electrode
[j
]==pcell
->bc_index
-1)
2622 MatSetValue(*jac
,zofs
[zone_index
]+6*i
,zofs
[zone_index
]+equ_num
*size
+stk_equ
,-1.0,INSERT_VALUES
);
2626 void SMCZone::J3E_ddm_insulator_gate(int i
,PetscScalar
*x
, Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
)
2629 PetscInt index
[6],col
[6];
2630 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2631 InsulatorContactBC
*pbc
= dynamic_cast<InsulatorContactBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2634 int size
= pzone
->davcell
.size();
2635 PetscScalar kb
= mt
->kb
;
2636 PetscScalar e
= mt
->e
;
2637 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2638 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2639 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2640 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2641 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2642 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2644 PetscScalar area
= pcell
->area
;
2645 PetscScalar d_grad_P_dVi
= 0;
2646 PetscScalar d_grad_P_dVapp
= 0;
2647 PetscScalar d_grad_T_dTi
= 0;
2649 for(int j
=0;j
<electrode
.size();j
++)
2650 if(electrode
[j
]==pcell
->bc_index
-1)
2652 //--------------------------------
2653 index
[0] = zofs
[z
]+6*i
+0;
2654 index
[1] = zofs
[z
]+6*i
+1;
2655 index
[2] = zofs
[z
]+6*i
+2;
2656 index
[3] = zofs
[z
]+6*i
+3;
2657 index
[4] = zofs
[z
]+6*i
+4;
2658 index
[5] = zofs
[z
]+6*i
+5;
2659 //--------------------------------
2660 for(int j
=0;j
<pcell
->nb_num
;j
++)
2662 int nb
= pcell
->nb_array
[j
];
2663 PetscScalar Vj
= x
[zofs
[z
]+6*nb
+0]; //potential of nb node
2664 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2665 col
[0] = zofs
[z
]+6*nb
+0;
2666 col
[1] = zofs
[z
]+6*nb
+1;
2667 col
[2] = zofs
[z
]+6*nb
+2;
2668 col
[3] = zofs
[z
]+6*nb
+3;
2669 col
[4] = zofs
[z
]+6*nb
+4;
2670 col
[5] = zofs
[z
]+6*nb
+5;
2672 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2674 if(j
==0||j
==pcell
->nb_num
-1)
2676 PetscScalar Thick
= pbc
->Thick
;
2677 PetscScalar eps_ox
= mt
->eps0
*pbc
->eps
;
2678 PetscScalar eps
= aux
[i
].eps
;
2679 PetscScalar s
=eps_ox
/eps
/Thick
;
2680 d_grad_P_dVi
+= -0.5*pcell
->ilen
[j
]*0.25*s
*3/area
;
2681 d_grad_P_dVapp
+= 0.5*pcell
->ilen
[j
]*s
/area
;
2682 A
.m
[0]+= -0.5*pcell
->ilen
[j
]*0.25*s
/area
;
2683 PetscScalar h
= pbc
->heat_transfer
;
2684 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/area
;
2685 A
.m
[21] += -0.5*pcell
->ilen
[j
]*0.25*h
/area
;
2687 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2690 //fun(0) is the poisson's equation
2691 //fun(1) is the continuous equation of electron
2692 //fun(2) is the continuous equation of hole
2694 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2696 A
.m
[0] += d_grad_P_dVi
;
2697 A
.m
[1] += -e
/aux
[i
].eps
; //df(phi)/dn(i)
2698 A
.m
[2] += e
/aux
[i
].eps
; //df(phi)/dp(i)
2700 A
.m
[21]+= d_grad_T_dTi
;
2702 if(ODE_F
.TimeDependent
==true)
2705 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2707 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2708 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2709 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2710 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2711 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2712 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2713 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2717 A
.m
[7] += -1/ODE_F
.dt
;
2718 A
.m
[14] += -1/ODE_F
.dt
;
2719 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2720 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2721 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2722 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2725 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2726 MatSetValue(*jac
,zofs
[z
]+6*i
,zofs
[z
]+equ_num
*size
+ins_equ
,d_grad_P_dVapp
,INSERT_VALUES
);
2731 void SMCZone::J3E_ddm_interface(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
2735 PetscInt index
[6],col
[6];
2736 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2737 InsulatorInterfaceBC
*pbc
= dynamic_cast<InsulatorInterfaceBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2739 PetscScalar kb
= mt
->kb
;
2740 PetscScalar e
= mt
->e
;
2741 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2742 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2743 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2744 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2745 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2746 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2748 PetscScalar area
= pcell
->area
;
2749 PetscScalar d_grad_P_dVi
= 0;
2750 PetscScalar d_grad_T_dTi
= 0;
2752 Set_Vec6(scale
,1.0,area
,area
,1.0,area
,area
);
2753 //--------------------------------
2754 index
[0] = zofs
[z
]+6*i
+0;
2755 index
[1] = zofs
[z
]+6*i
+1;
2756 index
[2] = zofs
[z
]+6*i
+2;
2757 index
[3] = zofs
[z
]+6*i
+3;
2758 index
[4] = zofs
[z
]+6*i
+4;
2759 index
[5] = zofs
[z
]+6*i
+5;
2760 //--------------------------------
2761 for(int j
=0;j
<pcell
->nb_num
;j
++)
2763 int nb
= pcell
->nb_array
[j
];
2765 PetscScalar Vj
= x
[zofs
[z
]+6*nb
+0]; //potential of nb node
2766 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3];
2767 PetscScalar kapa
= mt
->thermal
->HeatConduction(0.5*(Ti
+Tj
));
2768 d_grad_P_dVi
+= -aux
[i
].eps
*pcell
->elen
[j
]/pcell
->ilen
[j
];
2769 col
[0] = zofs
[z
]+6*nb
+0;
2770 col
[1] = zofs
[z
]+6*nb
+1;
2771 col
[2] = zofs
[z
]+6*nb
+2;
2772 col
[3] = zofs
[z
]+6*nb
+3;
2773 col
[4] = zofs
[z
]+6*nb
+4;
2774 col
[5] = zofs
[z
]+6*nb
+5;
2775 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2777 A
.m
[0] = aux
[i
].eps
*pcell
->elen
[j
]/pcell
->ilen
[j
]; //dfun(0)/dP(r)
2778 A
.m
[1] = 0; //dfun(0)/dn(r)
2779 A
.m
[2] = 0; //dfun(0)/dp(r)
2780 A
.m
[3] = 0; //dfun(0)/dT(r)
2783 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2786 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2787 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
2788 for(int j
=0;j
<ncell
->nb_num
;j
++)
2790 int nb
= ncell
->nb_array
[j
];
2791 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1];
2792 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
2793 d_grad_P_dVi
+= -pz
->aux
[n
].eps
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2794 PetscScalar d_grad_P_dVj
= pz
->aux
[n
].eps
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2795 MatSetValue(*jac
,zofs
[z
]+6*i
+0,zofs
[pz
->pzone
->zone_index
]+2*nb
+0,d_grad_P_dVj
,INSERT_VALUES
);
2796 d_grad_T_dTi
+= -kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2797 PetscScalar d_grad_T_dTj
= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2798 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[pz
->pzone
->zone_index
]+2*nb
+1,d_grad_T_dTj
,INSERT_VALUES
);
2801 //fun(0) is the poisson's equation
2802 //fun(1) is the continuous equation of electron
2803 //fun(2) is the continuous equation of hole
2805 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2807 A
.m
[0] = d_grad_P_dVi
; //dfun(0)/dP(i)
2808 A
.m
[1] = -e
*pcell
->area
; //dfun(0)/dn(i)
2809 A
.m
[2] = e
*pcell
->area
; //dfun(0)/dp(i)
2810 A
.m
[3] = 0.0; //dfun(0)/dT(i)
2814 A
.m
[21]+= d_grad_T_dTi
;
2817 if(ODE_F
.TimeDependent
==true)
2820 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2822 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2823 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2824 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2825 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2826 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2827 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
2828 -pz
->aux
[n
].density
*HeatCapacity2
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
2829 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2830 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2834 A
.m
[7] += -1/ODE_F
.dt
;
2835 A
.m
[14] += -1/ODE_F
.dt
;
2836 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2837 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2838 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
*pcell
->area
2839 -pz
->aux
[n
].density
*HeatCapacity2
/ODE_F
.dt
*ncell
->area
;
2840 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2841 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2844 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2849 void SMCZone::J3E_ddm_homojunction(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, SMCZone
*pz
, int n
)
2852 PetscInt index
[6],indexn
[6],col
[6];
2853 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2855 PetscScalar kb
= mt
->kb
;
2856 PetscScalar e
= mt
->e
;
2857 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2858 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2859 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2860 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2861 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2862 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2863 //--------------------------------
2864 index
[0] = zofs
[z
]+6*i
+0;
2865 index
[1] = zofs
[z
]+6*i
+1;
2866 index
[2] = zofs
[z
]+6*i
+2;
2867 index
[3] = zofs
[z
]+6*i
+3;
2868 index
[4] = zofs
[z
]+6*i
+4;
2869 index
[5] = zofs
[z
]+6*i
+5;
2870 //--------------------------------
2871 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2872 indexn
[0] = zofs
[pz
->zone_index
]+6*n
+0;
2873 indexn
[1] = zofs
[pz
->zone_index
]+6*n
+1;
2874 indexn
[2] = zofs
[pz
->zone_index
]+6*n
+2;
2875 indexn
[3] = zofs
[pz
->zone_index
]+6*n
+3;
2876 indexn
[4] = zofs
[pz
->zone_index
]+6*n
+4;
2877 indexn
[5] = zofs
[pz
->zone_index
]+6*n
+5;
2878 //--------------------------------
2879 PetscScalar area
= pcell
->area
+ ncell
->area
;
2880 //--------------------------------
2881 if(zone_index
> pz
->pzone
->zone_index
)
2884 MatSetValues(*jac
,6,index
,6,index
,AJ
.m
,INSERT_VALUES
);
2886 MatSetValues(*jac
,6,index
,6,indexn
,AJ
.m
,INSERT_VALUES
);
2889 //--------------------------------
2890 for(int j
=0;j
<pcell
->nb_num
;j
++)
2892 int nb
= pcell
->nb_array
[j
];
2893 col
[0] = zofs
[z
]+6*nb
+0;
2894 col
[1] = zofs
[z
]+6*nb
+1;
2895 col
[2] = zofs
[z
]+6*nb
+2;
2896 col
[3] = zofs
[z
]+6*nb
+3;
2897 col
[4] = zofs
[z
]+6*nb
+4;
2898 col
[5] = zofs
[z
]+6*nb
+5;
2899 MatGetValues(*jtmp
,6,index
,6,col
,A1
.m
);
2900 //-------------------------------------
2902 MatSetValues(*jac
,6,index
,6,col
,A1
.m
,INSERT_VALUES
);
2905 //process another half cell in dornor zone
2906 for(int j
=0;j
<ncell
->nb_num
;j
++)
2908 int nb
= ncell
->nb_array
[j
];
2909 col
[0] = zofs
[pz
->zone_index
]+6*nb
+0;
2910 col
[1] = zofs
[pz
->zone_index
]+6*nb
+1;
2911 col
[2] = zofs
[pz
->zone_index
]+6*nb
+2;
2912 col
[3] = zofs
[pz
->zone_index
]+6*nb
+3;
2913 col
[4] = zofs
[pz
->zone_index
]+6*nb
+4;
2914 col
[5] = zofs
[pz
->zone_index
]+6*nb
+5;
2915 MatGetValues(*jtmp
,6,indexn
,6,col
,A2
.m
);
2917 MatSetValues(*jac
,6,index
,6,col
,A2
.m
,INSERT_VALUES
);
2920 //fun(0) is the poisson's equation
2921 //fun(1) is the continuous equation of electron
2922 //fun(2) is the continuous equation of hole
2923 MatGetValues(*jtmp
,6,index
,6,index
,A1
.m
);
2924 MatGetValues(*jtmp
,6,indexn
,6,indexn
,A2
.m
);
2927 AJ
.m
[1] += -e
/aux
[i
].eps
; //dfun(0)/dn(i)
2928 AJ
.m
[2] += e
/aux
[i
].eps
; //dfun(0)/dp(i)
2930 if(ODE_F
.TimeDependent
==true)
2933 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2935 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2936 AJ
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2937 AJ
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2938 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2939 AJ
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2940 AJ
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2941 AJ
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2945 AJ
.m
[7] += -1/ODE_F
.dt
;
2946 AJ
.m
[14] += -1/ODE_F
.dt
;
2947 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2948 AJ
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
;
2949 AJ
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2950 AJ
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2953 MatSetValues(*jac
,6,index
,6,index
,AJ
.m
,INSERT_VALUES
);
2957 void SMCZone::J3E_om_electrode(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
2960 int size
= pzone
->davcell
.size();
2961 int bc_index
= electrode
[i
];
2962 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* > (bc
.Get_pointer(bc_index
));
2963 PetscScalar A1
[6],A2
[6],J
[6];
2964 PetscInt index
[6],col
[6];
2965 int matrix_row
= zofs
[zone_index
]+equ_num
*size
+i
;
2967 if(pbc
->inner_connect
!=-1)
2969 int connect_to
= pbc
->inner_connect
;
2970 int connect_zone
= pbc
->connect_zone
;
2971 int connect_elec
=-1;
2972 SMCZone
* pz
= dynamic_cast <SMCZone
* > (pbc
->pzonedata
);
2973 for(int j
=0;j
<pz
->electrode
.size();j
++)
2975 if(bc
[pz
->electrode
[j
]].BCType
==OhmicContact
)
2977 OhmicBC
*om_bc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pz
->electrode
[j
]));
2978 if(om_bc
->inner_connect
==bc_index
) connect_elec
=j
;
2981 connect_index
=zofs
[connect_zone
]+equ_num
*pz
->pzone
->davcell
.size()+connect_elec
;
2983 PetscScalar R
= pbc
->R
;
2984 PetscScalar C
= pbc
->C
;
2985 PetscScalar L
= pbc
->L
;
2986 PetscScalar kb
= mt
->kb
;
2987 PetscScalar e
= mt
->e
;
2989 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
2990 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
2992 for(int n
=0;n
<bc
[bc_index
].psegment
->node_array
.size();n
++)
2994 int node
=bc
[bc_index
].psegment
->node_array
[n
];
2995 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
2996 PetscScalar dJdisp_dVi
=0,dJdisp_dVr
=0;
2997 index
[0] = zofs
[zone_index
]+6*node
+0;
2998 index
[1] = zofs
[zone_index
]+6*node
+1;
2999 index
[2] = zofs
[zone_index
]+6*node
+2;
3000 index
[3] = zofs
[zone_index
]+6*node
+3;
3001 index
[4] = zofs
[zone_index
]+6*node
+4;
3002 index
[5] = zofs
[zone_index
]+6*node
+5;
3003 for(int j
=0;j
<pcell
->nb_num
;j
++)
3005 int nb
= pcell
->nb_array
[j
];
3006 col
[0] = zofs
[zone_index
]+6*nb
+0;
3007 col
[1] = zofs
[zone_index
]+6*nb
+1;
3008 col
[2] = zofs
[zone_index
]+6*nb
+2;
3009 col
[3] = zofs
[zone_index
]+6*nb
+3;
3010 col
[4] = zofs
[zone_index
]+6*nb
+4;
3011 col
[5] = zofs
[zone_index
]+6*nb
+5;
3013 MatGetValues(*jtmp
,1,&index
[1],6,col
,A1
);
3014 MatGetValues(*jtmp
,1,&index
[2],6,col
,A2
);
3016 //for displacement current
3017 dJdisp_dVi
+= aux
[node
].eps
/pcell
->ilen
[j
]/ODE_F
.dt
*pcell
->elen
[j
];
3018 dJdisp_dVr
= -aux
[node
].eps
/pcell
->ilen
[j
]/ODE_F
.dt
*pcell
->elen
[j
];
3019 if(pbc
->inner_connect
!=-1)
3021 int connect_to
= pbc
->inner_connect
;
3022 if(bc_index
< connect_to
)
3024 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3025 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3026 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3027 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3028 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3029 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3030 MatSetValues(*jac
,1,&connect_index
,6,col
,J
,ADD_VALUES
);
3034 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3035 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3036 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3037 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3038 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3039 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3040 MatSetValues(*jac
,1,&matrix_row
,6,col
,J
,ADD_VALUES
);
3043 else if(pbc
->electrode_type
==VoltageBC
)
3045 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3046 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3047 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3048 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3049 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3050 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3051 MatSetValues(*jac
,1,&matrix_row
,6,col
,J
,ADD_VALUES
);
3053 else if(pbc
->electrode_type
==CurrentBC
)
3055 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3056 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3057 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3058 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3059 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3060 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3061 MatSetValues(*jac
,1,&matrix_row
,6,col
,J
,ADD_VALUES
);
3064 MatGetValues(*jtmp
,1,&index
[1],6,index
,A1
);
3065 MatGetValues(*jtmp
,1,&index
[2],6,index
,A2
);
3066 if(pbc
->inner_connect
!=-1)
3068 int connect_to
= pbc
->inner_connect
;
3069 if(bc_index
< connect_to
)
3071 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3072 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3073 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3074 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3075 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3076 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3077 MatSetValues(*jac
,1,&connect_index
,6,index
,J
,ADD_VALUES
);
3081 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3082 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3083 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3084 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3085 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3086 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3087 MatSetValues(*jac
,1,&matrix_row
,6,index
,J
,ADD_VALUES
);
3090 else if(pbc
->electrode_type
==VoltageBC
)
3092 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVi
)*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3093 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3094 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3095 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3096 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3097 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3098 MatSetValues(*jac
,1,&matrix_row
,6,index
,J
,ADD_VALUES
);
3100 else if(pbc
->electrode_type
==CurrentBC
)
3102 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVi
)*DeviceDepth
;
3103 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3104 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3105 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3106 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3107 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3108 MatSetValues(*jac
,1,&matrix_row
,6,index
,J
,ADD_VALUES
);
3112 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3113 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3114 if(pbc
->inner_connect
!=-1)
3116 int connect_to
= pbc
->inner_connect
;
3117 if(bc_index
< connect_to
)
3119 MatSetValue(*jac
,matrix_row
,matrix_row
,1.0,ADD_VALUES
);
3123 MatSetValue(*jac
,connect_index
,matrix_row
,-1.0,ADD_VALUES
);
3126 else if(pbc
->electrode_type
==VoltageBC
)
3127 MatSetValue(*jac
,matrix_row
,matrix_row
,1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
,INSERT_VALUES
); //dJ/dP
3132 void SMCZone::J3E_stk_electrode(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
3135 int size
= pzone
->davcell
.size();
3136 int bc_index
= electrode
[i
];
3137 SchottkyBC
*pbc
= dynamic_cast <SchottkyBC
* > (bc
.Get_pointer(bc_index
));
3138 int matrix_row
= zofs
[zone_index
]+equ_num
*size
+i
;
3139 PetscScalar R
= pbc
->R
;
3140 PetscScalar C
= pbc
->C
;
3141 PetscScalar L
= pbc
->L
;
3142 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
3144 int node
= bc
[bc_index
].psegment
->node_array
[j
];
3145 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
3146 PetscScalar VB
= pbc
->WorkFunction
-aux
[node
].affinity
;
3147 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[node
].eps
,sqrt(aux
[node
].Ex
*aux
[node
].Ex
+aux
[node
].Ey
*aux
[node
].Ey
));
3148 PetscScalar ni
= x
[zofs
[zone_index
]+6*node
+1]; //electron density of node i
3149 PetscScalar pi
= x
[zofs
[zone_index
]+6*node
+2]; //hole density of node i
3150 PetscScalar dJ_dni
= -mt
->band
->pdSchottyJsn_pdn(ni
,fs
[node
].T
,VB
-deltaVB
)*0.5*pcell
->ilen
[0]
3151 -mt
->band
->pdSchottyJsn_pdn(ni
,fs
[node
].T
,VB
-deltaVB
)*0.5*pcell
->ilen
[pcell
->nb_num
-1];
3152 PetscScalar dJ_dpi
= -mt
->band
->pdSchottyJsp_pdp(pi
,fs
[node
].T
,VB
+deltaVB
)*0.5*pcell
->ilen
[0]
3153 -mt
->band
->pdSchottyJsp_pdp(pi
,fs
[node
].T
,VB
+deltaVB
)*0.5*pcell
->ilen
[pcell
->nb_num
-1];
3155 //for displacement current
3156 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3157 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3158 for(int k
=0;k
<pcell
->nb_num
;k
++)
3160 int nb
= pcell
->nb_array
[k
];
3161 PetscScalar dI_dVi
= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3162 PetscScalar dI_dVr
= -DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3163 if(pbc
->electrode_type
==VoltageBC
)
3165 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+0,dI_dVi
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3166 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*nb
+0,dI_dVr
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3168 else if(pbc
->electrode_type
==CurrentBC
)
3170 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+0,dI_dVi
,ADD_VALUES
);
3171 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*nb
+0,dI_dVr
,ADD_VALUES
);
3174 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3175 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3177 if(pbc
->electrode_type
==VoltageBC
)
3179 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+1,DeviceDepth
*dJ_dni
*(L
/ODE_F
.dt
+R
),INSERT_VALUES
);
3180 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+2,DeviceDepth
*dJ_dpi
*(L
/ODE_F
.dt
+R
),INSERT_VALUES
);
3182 else if(pbc
->electrode_type
==CurrentBC
)
3184 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+1,DeviceDepth
*dJ_dni
,INSERT_VALUES
);
3185 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+2,DeviceDepth
*dJ_dpi
,INSERT_VALUES
);
3188 if(pbc
->electrode_type
==VoltageBC
)
3189 MatSetValue(*jac
,matrix_row
,matrix_row
,1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
,INSERT_VALUES
); //dJ/dP
3193 void SMCZone::J3E_ins_electrode(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
3196 int size
= pzone
->davcell
.size();
3197 int bc_index
= electrode
[i
];
3198 InsulatorContactBC
*pbc
= dynamic_cast <InsulatorContactBC
* > (bc
.Get_pointer(bc_index
));
3199 int matrix_row
= zofs
[zone_index
]+equ_num
*size
+i
;
3200 PetscScalar R
= pbc
->R
;
3201 PetscScalar C
= pbc
->C
;
3202 PetscScalar L
= pbc
->L
;
3204 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3205 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3206 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
3208 int node
= bc
[bc_index
].psegment
->node_array
[j
];
3209 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
3211 //for displacement current
3213 for(int k
=0;k
<pcell
->nb_num
;k
++)
3215 int nb
= pcell
->nb_array
[k
];
3216 PetscScalar dI_dVi
= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3217 PetscScalar dI_dVr
= -DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3218 if(pbc
->electrode_type
==VoltageBC
)
3220 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+0,dI_dVi
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3221 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*nb
+0,dI_dVr
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3226 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3227 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3229 if(pbc
->electrode_type
==VoltageBC
)
3230 MatSetValue(*jac
,matrix_row
,matrix_row
,1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
,INSERT_VALUES
); //dJ/dP
3234 void SMCZone::F3E_efield_update(PetscScalar
*x
,vector
<int> & zofs
, DABC
&bc
, vector
<BZoneData
*>zonedata
)
3236 PetscScalar P_x
=0,P_y
=0,w
=0;
3237 //calculate Ex Ey with least-squares gradient construction
3238 for(int i
=0; i
<pzone
->davcell
.size();i
++)
3241 VoronoiCell
*pcell
= pzone
->davcell
.GetPointer(i
);
3242 for(int k
=0;k
<pcell
->nb_num
;k
++)
3244 const VoronoiCell
*ncell
= pzone
->davcell
.GetPointer(pcell
->nb_array
[k
]);
3245 PetscScalar dx
= ncell
->x
- pcell
->x
;
3246 PetscScalar dy
= ncell
->y
- pcell
->y
;
3247 PetscScalar dP
= x
[zofs
[zone_index
]+6*pcell
->nb_array
[k
]+0] - x
[zofs
[zone_index
]+6*i
+0];
3248 w
=1.0/sqrt(dx
*dx
+dy
*dy
);
3252 if(pcell
->bc_index
&&bc
[pcell
->bc_index
-1].BCType
==InsulatorInterface
)
3254 InsulatorInterfaceBC
*pbc
;
3255 pbc
= dynamic_cast<InsulatorInterfaceBC
*>(bc
.Get_pointer(pcell
->bc_index
-1));
3256 int n_zone
= pbc
->pinterface
->Find_neighbor_zone_index(zone_index
);
3257 int n_node
= pbc
->pinterface
->Find_neighbor_node_index(zone_index
,i
);
3258 ISZone
* pz
= dynamic_cast<ISZone
*>(zonedata
[n_zone
]);
3259 const VoronoiCell
* dcell
= pz
->pzone
->davcell
.GetPointer(n_node
);
3260 for(int k
=1;k
<dcell
->nb_num
-1;k
++)
3262 const VoronoiCell
*ncell
= pz
->pzone
->davcell
.GetPointer(dcell
->nb_array
[k
]);
3263 PetscScalar dx
= ncell
->x
- dcell
->x
;
3264 PetscScalar dy
= ncell
->y
- dcell
->y
;
3265 PetscScalar dP
= x
[zofs
[n_zone
]+2*dcell
->nb_array
[k
]]- x
[zofs
[n_zone
]+2*n_node
];
3266 w
=1.0/sqrt(dx
*dx
+dy
*dy
);
3271 aux
[i
].Ex
= -(pcell
->sc
*P_x
-pcell
->sb
*P_y
);
3272 aux
[i
].Ey
= -(pcell
->sa
*P_y
-pcell
->sb
*P_x
);