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 Nv
= mt
->band
->Nv(fs
[i
].T
);
1295 PetscScalar electron_density
,hole_density
;
1297 for(int j
=0;j
<electrode
.size();j
++)
1298 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
1300 f
[zofs
[z
]+6*i
+0] = Vi
- kb
*fs
[i
].T
/mt
->e
*asinh((Nd
-Na
)/(2*nie
)) + mt
->kb
*fs
[i
].T
/2/mt
->e
*log(Nc
/Nv
)
1301 + mt
->band
->Eg(fs
[i
].T
)/2/mt
->e
1302 + aux
[i
].affinity
-x
[zofs
[z
]+equ_num
*size
+om_equ
];
1306 hole_density
= (-(Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1307 electron_density
= nie
*nie
/hole_density
;
1311 electron_density
= ((Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1312 hole_density
= nie
*nie
/electron_density
;
1314 f
[zofs
[z
]+6*i
+1] = x
[zofs
[z
]+6*i
+1] - electron_density
; //electron density
1315 f
[zofs
[z
]+6*i
+2] = x
[zofs
[z
]+6*i
+2] - hole_density
; //hole density
1317 PetscScalar grad_T
=0;
1318 for(int j
=0;j
<pcell
->nb_num
;j
++)
1320 int nb
= pcell
->nb_array
[j
];
1321 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1322 PetscScalar T_mid
= 0.5*(Tj
+Ti
);
1323 PetscScalar dTdx_mid
= (Tj
-Ti
)/pcell
->ilen
[j
];
1324 PetscScalar kapa
= mt
->thermal
->HeatConduction(T_mid
);
1325 grad_T
+= kapa
*pcell
->elen
[j
]*dTdx_mid
/pcell
->area
;
1326 if(j
==0||j
==pcell
->nb_num
-1)
1328 PetscScalar h
= pbc
->heat_transfer
;
1329 PetscScalar r
= h
*pbc
->T_external
;
1330 grad_T
+= 0.5*pcell
->ilen
[j
]*(r
-0.25*h
*(3*Ti
+Tj
))/pcell
->area
;
1333 f
[zofs
[zone_index
]+6*i
+3] = grad_T
;
1334 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1335 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1337 if(ODE_F
.TimeDependent
==true)
1340 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1342 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1343 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1344 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1345 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1349 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1350 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1356 void SMCZone::F3E_ddm_ombc_interface(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
1359 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1360 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1363 int size
= pzone
->davcell
.size();
1364 PetscScalar kb
= mt
->kb
;
1365 PetscScalar Na
= aux
[i
].Na
;
1366 PetscScalar Nd
= aux
[i
].Nd
;
1367 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
1368 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
1369 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
1370 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3];
1371 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
1372 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
1373 mt
->mapping(&pzone
->danode
[i
],&aux
[i
],ODE_F
.clock
);
1374 PetscScalar nie
= mt
->band
->nie(fs
[i
].T
);
1375 PetscScalar Nc
= mt
->band
->Nc(fs
[i
].T
);
1376 PetscScalar Nv
= mt
->band
->Nv(fs
[i
].T
);
1377 PetscScalar electron_density
,hole_density
;
1379 for(int j
=0;j
<electrode
.size();j
++)
1380 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
1382 f
[zofs
[z
]+6*i
+0] = Vi
- kb
*fs
[i
].T
/mt
->e
*asinh((Nd
-Na
)/(2*nie
)) + mt
->kb
*fs
[i
].T
/2/mt
->e
*log(Nc
/Nv
)
1383 + mt
->band
->Eg(fs
[i
].T
)/2/mt
->e
1384 + aux
[i
].affinity
-x
[zofs
[z
]+equ_num
*size
+om_equ
];
1388 hole_density
= (-(Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1389 electron_density
= nie
*nie
/hole_density
;
1393 electron_density
= ((Nd
-Na
)+sqrt((Nd
-Na
)*(Nd
-Na
)+4*nie
*nie
))/2.0;
1394 hole_density
= nie
*nie
/electron_density
;
1396 f
[zofs
[z
]+6*i
+1] = x
[zofs
[z
]+6*i
+1] - electron_density
; //electron density
1397 f
[zofs
[z
]+6*i
+2] = x
[zofs
[z
]+6*i
+2] - hole_density
; //hole density
1399 PetscScalar grad_T
=0;
1400 for(int j
=0;j
<pcell
->nb_num
;j
++)
1402 int nb
= pcell
->nb_array
[j
];
1403 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1404 PetscScalar T_mid
= 0.5*(Tj
+Ti
);
1405 PetscScalar dTdx_mid
= (Tj
-Ti
)/pcell
->ilen
[j
];
1406 PetscScalar kapa
= mt
->thermal
->HeatConduction(T_mid
);
1407 grad_T
+= kapa
*pcell
->elen
[j
]*dTdx_mid
;
1409 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1410 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
1411 for(int j
=0;j
<ncell
->nb_num
;j
++)
1413 int nb
= ncell
->nb_array
[j
];
1414 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1]; //potential of nb node
1415 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
1416 grad_T
+= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Tj_n
-Ti
);
1419 f
[zofs
[zone_index
]+6*i
+3] = grad_T
;
1420 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1421 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1424 if(ODE_F
.TimeDependent
==true)
1427 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1429 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1430 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1431 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1432 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1433 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
1434 -pz
->aux
[n
].density
*HeatCapacity2
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
1438 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1439 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1440 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*pcell
->area
1441 -pz
->aux
[n
].density
*HeatCapacity2
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*ncell
->area
;
1449 void SMCZone::F3E_ddm_stkbc_segment(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int>& zofs
,DABC
&bc
)
1451 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1452 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1455 int size
= pzone
->davcell
.size();
1456 PetscScalar kb
= mt
->kb
;
1457 PetscScalar e
= mt
->e
;
1458 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
1459 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
1460 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
1461 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
1462 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
1463 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
1466 for(int j
=0;j
<electrode
.size();j
++)
1467 if(electrode
[j
]==pcell
->bc_index
-1)
1472 //Schotty Barrier Lowerring
1473 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
1475 f
[zofs
[z
]+6*i
+0] = x
[zofs
[z
]+6*i
+0] + pbc
->WorkFunction
- deltaVB
- x
[zofs
[z
]+equ_num
*size
+stk_equ
];
1477 PetscScalar Fn
=0,Fp
=0,grad_T
=0;
1478 for(int j
=0;j
<pcell
->nb_num
;j
++)
1480 int nb
= pcell
->nb_array
[j
];
1481 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1482 if(j
==0||j
==pcell
->nb_num
-1)
1484 Fn
+= mt
->band
->SchottyJsn(ni
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
- deltaVB
)*0.5*pcell
->ilen
[j
];
1485 Fp
+= mt
->band
->SchottyJsp(pi
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
+ deltaVB
)*0.5*pcell
->ilen
[j
];
1486 PetscScalar h
= pbc
->heat_transfer
;
1487 PetscScalar r
= h
*pbc
->T_external
;
1488 grad_T
+= 0.5*pcell
->ilen
[j
]*(r
-0.25*h
*(3*Ti
+Tj
));
1492 f
[zofs
[zone_index
]+6*i
+1] = (f
[zofs
[zone_index
]+6*i
+1]+Fn
)/pcell
->area
;
1493 f
[zofs
[zone_index
]+6*i
+2] = (f
[zofs
[zone_index
]+6*i
+2]-Fp
)/pcell
->area
;
1494 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
)/pcell
->area
;
1495 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1496 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1498 if(ODE_F
.TimeDependent
==true)
1501 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1503 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1504 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1505 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1506 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1507 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1508 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1509 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1510 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1514 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1515 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1516 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1517 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1523 void SMCZone::F3E_ddm_stkbc_interface(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int>& zofs
,DABC
&bc
,
1526 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1527 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1530 int size
= pzone
->davcell
.size();
1531 PetscScalar kb
= mt
->kb
;
1532 PetscScalar e
= mt
->e
;
1533 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
1534 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
1535 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
1536 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
1537 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
1538 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
1541 for(int j
=0;j
<electrode
.size();j
++)
1542 if(electrode
[j
]==pcell
->bc_index
-1)
1547 //Schotty Barrier Lowerring
1548 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
1550 f
[zofs
[z
]+6*i
+0] = x
[zofs
[z
]+6*i
+0] + pbc
->WorkFunction
- deltaVB
- x
[zofs
[z
]+equ_num
*size
+stk_equ
];
1552 PetscScalar Fn
=0,Fp
=0,grad_T
=0;
1553 for(int j
=0;j
<pcell
->nb_num
;j
++)
1555 int nb
= pcell
->nb_array
[j
];
1556 if(j
==0||j
==pcell
->nb_num
-1)
1558 Fn
+= mt
->band
->SchottyJsn(ni
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
- deltaVB
)*0.5*pcell
->ilen
[j
];
1559 Fp
+= mt
->band
->SchottyJsp(pi
,Ti
,pbc
->WorkFunction
-aux
[i
].affinity
+ deltaVB
)*0.5*pcell
->ilen
[j
];
1563 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1564 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
1565 for(int j
=0;j
<ncell
->nb_num
;j
++)
1567 int nb
= ncell
->nb_array
[j
];
1568 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1]; //potential of nb node
1569 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(fs
[i
].T
);//(0.5*(Ti+Tj_n));
1570 grad_T
+= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Tj_n
-Ti
);
1573 f
[zofs
[zone_index
]+6*i
+1] = (f
[zofs
[zone_index
]+6*i
+1]+Fn
)/pcell
->area
;
1574 f
[zofs
[zone_index
]+6*i
+2] = (f
[zofs
[zone_index
]+6*i
+2]-Fp
)/pcell
->area
;
1575 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
);
1576 f
[zofs
[zone_index
]+6*i
+4] = ni
*(Tn
- Ti
);
1577 f
[zofs
[zone_index
]+6*i
+5] = pi
*(Tp
- Ti
);
1579 if(ODE_F
.TimeDependent
==true)
1582 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1584 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1585 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1586 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1587 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1588 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1589 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1590 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1591 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1592 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
1593 -pz
->aux
[n
].density
*HeatCapacity2
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
1597 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1598 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1599 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1600 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1601 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*pcell
->area
1602 -pz
->aux
[n
].density
*HeatCapacity2
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*ncell
->area
;
1609 void SMCZone::F3E_ddm_insulator_gate(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
)
1611 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1612 InsulatorContactBC
*pbc
= dynamic_cast<InsulatorContactBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1614 int size
= pzone
->davcell
.size();
1615 PetscScalar kb
= mt
->kb
;
1616 PetscScalar e
= mt
->e
;
1617 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1618 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1619 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1620 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1621 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1622 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1623 PetscScalar grad_P
= 0, grad_T
= 0;
1625 for(int j
=0;j
<electrode
.size();j
++)
1626 if(electrode
[j
]==pcell
->bc_index
-1)
1628 for(int j
=0;j
<pcell
->nb_num
;j
++)
1630 int nb
= pcell
->nb_array
[j
];
1631 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
1632 PetscScalar Tj
= x
[zofs
[zone_index
]+6*nb
+3]; //lattice temperature of nb node
1634 if(j
==0||j
==pcell
->nb_num
-1)
1636 PetscScalar vgate
= x
[zofs
[zone_index
]+equ_num
*size
+ins_equ
] - pbc
->WorkFunction
;
1637 PetscScalar q
= e
*pbc
->QF
; //sigma is the surface change density
1638 PetscScalar Thick
= pbc
->Thick
;
1639 PetscScalar eps_ox
= mt
->eps0
*pbc
->eps
;
1640 PetscScalar eps
= aux
[i
].eps
;
1641 PetscScalar r
=q
/eps
+ eps_ox
/eps
/Thick
*vgate
;
1642 PetscScalar s
=eps_ox
/eps
/Thick
;
1643 grad_P
+= 0.5*pcell
->ilen
[j
]*(r
-0.25*s
*(3*Vi
+Vj
));
1645 PetscScalar h
= pbc
->heat_transfer
;
1646 grad_T
+= 0.5*pcell
->ilen
[j
]*(h
*pbc
->T_external
-0.25*h
*(3*Ti
+Tj
));
1650 f
[zofs
[zone_index
]+6*i
+0] = (f
[zofs
[zone_index
]+6*i
+0]+grad_P
)/pcell
->area
1651 + e
/aux
[i
].eps
*((pi
-aux
[i
].Na
)+(aux
[i
].Nd
-ni
));
1652 f
[zofs
[zone_index
]+6*i
+1] = f
[zofs
[zone_index
]+6*i
+1]/pcell
->area
;
1653 f
[zofs
[zone_index
]+6*i
+2] = f
[zofs
[zone_index
]+6*i
+2]/pcell
->area
;
1654 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
)/pcell
->area
;
1655 f
[zofs
[zone_index
]+6*i
+4] = f
[zofs
[zone_index
]+6*i
+4]/pcell
->area
;
1656 f
[zofs
[zone_index
]+6*i
+5] = f
[zofs
[zone_index
]+6*i
+5]/pcell
->area
;
1658 if(ODE_F
.TimeDependent
==true)
1661 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1663 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1664 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1665 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1666 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1667 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
;
1668 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
;
1669 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1670 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1671 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1672 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1673 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1674 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1678 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1679 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1680 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1681 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1682 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1683 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1690 void SMCZone::F3E_ddm_interface(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
1693 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1694 InsulatorInterfaceBC
*pbc
= dynamic_cast<InsulatorInterfaceBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
1695 PetscScalar kb
= mt
->kb
;
1696 PetscScalar e
= mt
->e
;
1697 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1698 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1699 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1700 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1701 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1702 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1704 PetscScalar grad_P
= 0,grad_T
=0;
1705 //semiconductor-insulator interface
1706 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1707 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
1708 for(int j
=0;j
<ncell
->nb_num
;j
++)
1710 int nb
= ncell
->nb_array
[j
];
1711 PetscScalar Vj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+0]; //potential of nb node
1712 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1]; //potential of nb node
1713 grad_P
+= pz
->aux
[n
].eps
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Vj_n
-Vi
);
1714 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
1715 grad_T
+= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
]*(Tj_n
-Ti
);
1717 PetscScalar L
= (pcell
->ilen
[0]+pcell
->ilen
[pcell
->nb_num
-1])/2.0;
1720 f
[zofs
[zone_index
]+6*i
+0] = (aux
[i
].eps
*f
[zofs
[zone_index
]+6*i
+0]+grad_P
)
1721 + e
*((pi
-aux
[i
].Na
)+(aux
[i
].Nd
-ni
))*pcell
->area
+ pbc
->QF
*L
;
1722 f
[zofs
[zone_index
]+6*i
+1] = f
[zofs
[zone_index
]+6*i
+1]/pcell
->area
;
1723 f
[zofs
[zone_index
]+6*i
+2] = f
[zofs
[zone_index
]+6*i
+2]/pcell
->area
;
1724 f
[zofs
[zone_index
]+6*i
+3] = (f
[zofs
[zone_index
]+6*i
+3]+grad_T
);
1725 f
[zofs
[zone_index
]+6*i
+4] = f
[zofs
[zone_index
]+6*i
+4]/pcell
->area
;
1726 f
[zofs
[zone_index
]+6*i
+5] = f
[zofs
[zone_index
]+6*i
+5]/pcell
->area
;
1728 if(ODE_F
.TimeDependent
==true)
1731 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1733 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1734 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1735 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1736 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1737 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
;
1738 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
;
1739 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1740 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1741 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1742 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1743 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
1744 -pz
->aux
[n
].density
*HeatCapacity2
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
1745 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1746 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1750 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1751 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1752 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
1753 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
1754 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity1
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*pcell
->area
1755 -pz
->aux
[n
].density
*HeatCapacity2
*(Ti
-fs
[i
].T
)/ODE_F
.dt
*ncell
->area
;
1756 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1757 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1764 void SMCZone::F3E_ddm_homojunction(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
1767 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
1768 PetscScalar kb
= mt
->kb
;
1769 PetscScalar e
= mt
->e
;
1770 PetscScalar Vi
= x
[zofs
[zone_index
]+6*i
+0]; //potential of node i
1771 PetscScalar ni
= x
[zofs
[zone_index
]+6*i
+1]; //electron density of node i
1772 PetscScalar pi
= x
[zofs
[zone_index
]+6*i
+2]; //hole density of node i
1773 PetscScalar Ti
= x
[zofs
[zone_index
]+6*i
+3]; //lattice temperature of node i
1774 PetscScalar Tn
= x
[zofs
[zone_index
]+6*i
+4]/ni
;
1775 PetscScalar Tp
= x
[zofs
[zone_index
]+6*i
+5]/pi
;
1776 if(zone_index
> pz
->pzone
->zone_index
)
1778 f
[zofs
[zone_index
]+6*i
+0] = Vi
- x
[zofs
[pz
->zone_index
]+6*n
+0];
1779 f
[zofs
[zone_index
]+6*i
+1] = ni
- x
[zofs
[pz
->zone_index
]+6*n
+1];
1780 f
[zofs
[zone_index
]+6*i
+2] = pi
- x
[zofs
[pz
->zone_index
]+6*n
+2];
1781 f
[zofs
[zone_index
]+6*i
+3] = Ti
- x
[zofs
[pz
->zone_index
]+6*n
+3];
1782 f
[zofs
[zone_index
]+6*i
+4] = x
[zofs
[zone_index
]+6*i
+4] - x
[zofs
[pz
->zone_index
]+6*n
+4];
1783 f
[zofs
[zone_index
]+6*i
+5] = x
[zofs
[zone_index
]+6*i
+5] - x
[zofs
[pz
->zone_index
]+6*n
+5];
1787 //process half cell in local zone
1788 mt
->mapping(&pzone
->danode
[i
],&aux
[i
],ODE_F
.clock
);
1790 PetscScalar Na
= aux
[i
].Na
;
1791 PetscScalar Nd
= aux
[i
].Nd
;
1792 PetscScalar grad_P
=0,grad_T
=0;
1793 PetscScalar Fphi
=0,Fn
=0,Fp
=0,Sn
=0,Sp
=0;
1795 Fphi
= f
[zofs
[zone_index
]+6*i
+0];
1796 Fn
= f
[zofs
[zone_index
]+6*i
+1];
1797 Fp
= f
[zofs
[zone_index
]+6*i
+2];
1798 grad_T
=f
[zofs
[zone_index
]+6*i
+3];
1799 Sn
= f
[zofs
[zone_index
]+6*i
+4];
1800 Sp
= f
[zofs
[zone_index
]+6*i
+5];
1801 //process another half cell in dornor zone
1802 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
1804 Fphi
+= f
[zofs
[pz
->zone_index
]+6*n
+0];
1805 Fn
+= f
[zofs
[pz
->zone_index
]+6*n
+1];
1806 Fp
+= f
[zofs
[pz
->zone_index
]+6*n
+2];
1807 grad_T
+=f
[zofs
[pz
->zone_index
]+6*n
+3];
1808 Sn
+= f
[zofs
[pz
->zone_index
]+6*n
+4];
1809 Sp
+= f
[zofs
[pz
->zone_index
]+6*n
+5];
1811 PetscScalar area
= pcell
->area
+ncell
->area
;
1812 f
[zofs
[zone_index
]+6*i
+0] = Fphi
/area
+ e
/aux
[i
].eps
*(pi
-ni
+Nd
-Na
);
1813 f
[zofs
[zone_index
]+6*i
+1] = Fn
/area
;
1814 f
[zofs
[zone_index
]+6*i
+2] = Fp
/area
;
1815 f
[zofs
[zone_index
]+6*i
+3] = grad_T
/area
;
1816 f
[zofs
[zone_index
]+6*i
+4] = Sn
/area
;
1817 f
[zofs
[zone_index
]+6*i
+5] = Sp
/area
;
1819 if(ODE_F
.TimeDependent
==true)
1822 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
1824 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
1825 PetscScalar nt
= (2-r
)/(1-r
)*ni
-1.0/(r
*(1-r
))*fs
[i
].n
+(1-r
)/r
*fs
[i
].n_last
;
1826 PetscScalar pt
= (2-r
)/(1-r
)*pi
-1.0/(r
*(1-r
))*fs
[i
].p
+(1-r
)/r
*fs
[i
].p_last
;
1827 PetscScalar Tt
= (2-r
)/(1-r
)*Ti
-1.0/(r
*(1-r
))*fs
[i
].T
+(1-r
)/r
*fs
[i
].T_last
;
1828 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
;
1829 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
;
1830 f
[zofs
[zone_index
]+6*i
+1] += -nt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1831 f
[zofs
[zone_index
]+6*i
+2] += -pt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1832 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1833 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*Tt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1834 f
[zofs
[zone_index
]+6*i
+4] += -Wnt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1835 f
[zofs
[zone_index
]+6*i
+5] += -Wpt
/(ODE_F
.dt_last
+ODE_F
.dt
);
1839 f
[zofs
[zone_index
]+6*i
+1] += -(ni
-fs
[i
].n
)/ODE_F
.dt
;
1840 f
[zofs
[zone_index
]+6*i
+2] += -(pi
-fs
[i
].p
)/ODE_F
.dt
;
1841 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
1842 f
[zofs
[zone_index
]+6*i
+3] += -aux
[i
].density
*HeatCapacity
*(Ti
-fs
[i
].T
)/ODE_F
.dt
;
1843 f
[zofs
[zone_index
]+6*i
+4] += -(1.5*ni
*kb
*Tn
- 1.5*fs
[i
].n
*kb
*fs
[i
].Tn
)/ODE_F
.dt
;
1844 f
[zofs
[zone_index
]+6*i
+5] += -(1.5*pi
*kb
*Tp
- 1.5*fs
[i
].p
*kb
*fs
[i
].Tp
)/ODE_F
.dt
;
1852 void SMCZone::F3E_om_electrode(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
1855 int size
= pzone
->davcell
.size();
1856 int bc_index
= electrode
[i
];
1857 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* > (bc
.Get_pointer(bc_index
));
1858 PetscScalar e
= mt
->e
;
1859 PetscScalar current
=0;
1861 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
1863 int node
=bc
[bc_index
].psegment
->node_array
[j
];
1864 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
1865 PetscScalar Vi
= x
[zofs
[zone_index
]+6*node
+0]; //potential of node i
1866 current
+= DeviceDepth
*(f
[zofs
[zone_index
]+6*node
+1]-f
[zofs
[zone_index
]+6*node
+2]);
1867 for(int k
=0;k
<pcell
->nb_num
;k
++)
1869 int nb
= pcell
->nb_array
[k
];
1870 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
1871 //displacement current
1872 current
+= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
*((Vi
-Vj
)-(fs
[node
].P
-fs
[nb
].P
))/pcell
->ilen
[k
]/ODE_F
.dt
;
1875 //if the electrode connect to another electrode
1876 if(pbc
->inner_connect
!=-1)
1878 int connect_to
= pbc
->inner_connect
;
1879 int connect_zone
= pbc
->connect_zone
;
1880 int connect_elec
=-1;
1881 SMCZone
* pz
= dynamic_cast <SMCZone
* > (pbc
->pzonedata
);
1882 for(int j
=0;j
<pz
->electrode
.size();j
++)
1884 if(bc
[pz
->electrode
[j
]].BCType
==OhmicContact
)
1886 OhmicBC
*om_bc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pz
->electrode
[j
]));
1887 if(om_bc
->inner_connect
==bc_index
) connect_elec
=j
;
1890 int connect_index
=zofs
[connect_zone
]+equ_num
*pz
->pzone
->davcell
.size()+connect_elec
;
1891 if(bc_index
< connect_to
)
1893 f
[zofs
[zone_index
]+equ_num
*size
+i
]+=x
[zofs
[zone_index
]+equ_num
*size
+i
]; //voltage equation
1894 f
[connect_index
]+=current
; //current equation
1898 f
[zofs
[zone_index
]+equ_num
*size
+i
]+=current
; //current equation
1899 f
[connect_index
]+=-x
[zofs
[zone_index
]+equ_num
*size
+i
];//voltage equation
1901 pbc
->Set_Current_new(current
);
1903 //the electrode has an external voltage circult
1904 else if(pbc
->electrode_type
==VoltageBC
)
1906 PetscScalar V
= pbc
->Vapp
;
1907 PetscScalar R
= pbc
->R
;
1908 PetscScalar C
= pbc
->C
;
1909 PetscScalar L
= pbc
->L
;
1910 PetscScalar In
= pbc
->current
;
1911 PetscScalar Icn
= pbc
->cap_current
;
1912 PetscScalar Pn
= pbc
->potential
;
1913 PetscScalar P
= x
[zofs
[zone_index
]+equ_num
*size
+i
];
1914 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
1915 -(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
*Pn
-L
/ODE_F
.dt
*(In
+Icn
);
1916 pbc
->Set_Current_new(current
);
1918 //the electrode has an external current circult
1919 else if(pbc
->electrode_type
==CurrentBC
)
1921 PetscScalar I
= pbc
->Iapp
;
1922 PetscScalar C
= pbc
->C
;
1923 f
[zofs
[zone_index
]+equ_num
*size
+i
]=current
- I
;
1924 pbc
->Set_Current_new(I
);
1926 pbc
->Set_Potential_new(x
[zofs
[zone_index
]+equ_num
*size
+i
]);
1929 void SMCZone::F3E_stk_electrode(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
1932 int size
= pzone
->davcell
.size();
1933 int bc_index
= electrode
[i
];
1934 SchottkyBC
*pbc
= dynamic_cast <SchottkyBC
* > (bc
.Get_pointer(bc_index
));
1936 PetscScalar current
=0;
1937 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
1939 int node
= bc
[bc_index
].psegment
->node_array
[j
];
1940 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
1941 PetscScalar Vi
= x
[zofs
[zone_index
]+6*node
+0]; //electron density of node i
1942 PetscScalar ni
= x
[zofs
[zone_index
]+6*node
+1]; //electron density of node i
1943 PetscScalar pi
= x
[zofs
[zone_index
]+6*node
+2]; //hole density of node i
1944 PetscScalar Ti
= x
[zofs
[zone_index
]+6*node
+3];
1945 mt
->mapping(&pzone
->danode
[node
],&aux
[node
],ODE_F
.clock
);
1946 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[node
].eps
,sqrt(aux
[node
].Ex
*aux
[node
].Ex
+aux
[node
].Ey
*aux
[node
].Ey
));
1947 PetscScalar Jsn
= mt
->band
->SchottyJsn(ni
,Ti
,pbc
->WorkFunction
-aux
[node
].affinity
-deltaVB
);
1948 PetscScalar Jsp
= mt
->band
->SchottyJsp(pi
,Ti
,pbc
->WorkFunction
-aux
[node
].affinity
+deltaVB
);
1949 current
+= -Jsn
*0.5*pcell
->ilen
[0]*DeviceDepth
;
1950 current
+= -Jsp
*0.5*pcell
->ilen
[0]*DeviceDepth
;
1951 current
+= -Jsn
*0.5*pcell
->ilen
[pcell
->nb_num
-1]*DeviceDepth
;
1952 current
+= -Jsp
*0.5*pcell
->ilen
[pcell
->nb_num
-1]*DeviceDepth
;
1953 for(int k
=0;k
<pcell
->nb_num
;k
++)
1955 int nb
= pcell
->nb_array
[k
];
1956 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
1957 //displacement current
1958 current
+= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
*((Vi
-Vj
)-(fs
[node
].P
-fs
[nb
].P
))/pcell
->ilen
[k
]/ODE_F
.dt
;
1961 if(pbc
->electrode_type
==VoltageBC
)
1963 PetscScalar R
= pbc
->R
;
1964 PetscScalar C
= pbc
->C
;
1965 PetscScalar L
= pbc
->L
;
1966 PetscScalar V
= pbc
->Vapp
;
1967 PetscScalar In
= pbc
->current
;
1968 PetscScalar Icn
= pbc
->cap_current
;
1969 PetscScalar Pn
= pbc
->potential
;
1970 PetscScalar P
= x
[zofs
[zone_index
]+equ_num
*size
+i
];
1971 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
1972 -(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
*Pn
-L
/ODE_F
.dt
*(In
+Icn
);
1973 pbc
->Set_Current_new(current
);
1975 else if(pbc
->electrode_type
==CurrentBC
)
1977 PetscScalar I
= pbc
->Iapp
;
1978 PetscScalar C
= pbc
->C
;
1979 f
[zofs
[zone_index
]+equ_num
*size
+i
]=current
- I
;
1980 pbc
->Set_Current_new(I
);
1982 pbc
->Set_Potential_new(x
[zofs
[zone_index
]+equ_num
*size
+i
]);
1986 void SMCZone::F3E_ins_electrode(int i
,PetscScalar
*x
,PetscScalar
*f
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
1989 int size
= pzone
->davcell
.size();
1990 int bc_index
= electrode
[i
];
1991 InsulatorContactBC
*pbc
= dynamic_cast <InsulatorContactBC
* > (bc
.Get_pointer(bc_index
));
1993 PetscScalar current
=0;
1994 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
1996 int node
= bc
[bc_index
].psegment
->node_array
[j
];
1997 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
1998 PetscScalar Vi
= x
[zofs
[zone_index
]+6*node
+0]; //electron density of node i
1999 for(int k
=0;k
<pcell
->nb_num
;k
++)
2001 int nb
= pcell
->nb_array
[k
];
2002 PetscScalar Vj
= x
[zofs
[zone_index
]+6*nb
+0]; //potential of nb node
2003 //displacement current
2004 current
+= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
*((Vi
-Vj
)-(fs
[node
].P
-fs
[nb
].P
))/pcell
->ilen
[k
]/ODE_F
.dt
;
2007 if(pbc
->electrode_type
==VoltageBC
)
2009 PetscScalar R
= pbc
->R
;
2010 PetscScalar C
= pbc
->C
;
2011 PetscScalar L
= pbc
->L
;
2012 PetscScalar V
= pbc
->Vapp
;
2013 PetscScalar In
= pbc
->current
;
2014 PetscScalar Icn
= pbc
->cap_current
;
2015 PetscScalar Pn
= pbc
->potential
;
2016 PetscScalar P
= x
[zofs
[zone_index
]+equ_num
*size
+i
];
2017 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
2018 -(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
*Pn
-L
/ODE_F
.dt
*(In
+Icn
);
2019 pbc
->Set_Current_new(current
);
2021 pbc
->Set_Potential_new(x
[zofs
[zone_index
]+equ_num
*size
+i
]);
2026 void SMCZone::J3E_ddm_inner(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
)
2029 PetscInt index
[6],col
[6];
2030 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2032 PetscScalar kb
= mt
->kb
;
2033 PetscScalar e
= mt
->e
;
2034 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2035 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2036 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2037 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3];
2038 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2039 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2040 PetscScalar area
= pcell
->area
;
2042 //--------------------------------
2043 index
[0] = zofs
[z
]+6*i
+0;
2044 index
[1] = zofs
[z
]+6*i
+1;
2045 index
[2] = zofs
[z
]+6*i
+2;
2046 index
[3] = zofs
[z
]+6*i
+3;
2047 index
[4] = zofs
[z
]+6*i
+4;
2048 index
[5] = zofs
[z
]+6*i
+5;
2050 //--------------------------------
2051 for(int j
=0;j
<pcell
->nb_num
;j
++)
2053 int nb
= pcell
->nb_array
[j
];
2054 col
[0] = zofs
[z
]+6*nb
+0;
2055 col
[1] = zofs
[z
]+6*nb
+1;
2056 col
[2] = zofs
[z
]+6*nb
+2;
2057 col
[3] = zofs
[z
]+6*nb
+3;
2058 col
[4] = zofs
[z
]+6*nb
+4;
2059 col
[5] = zofs
[z
]+6*nb
+5;
2060 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2062 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2065 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2067 A
.m
[1] += -e
/aux
[i
].eps
; //dfun(0)/dn(i)
2068 A
.m
[2] += e
/aux
[i
].eps
; //dfun(0)/dp(i)
2070 if(ODE_F
.TimeDependent
==true)
2073 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2075 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2076 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2077 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2078 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2079 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2080 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2081 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2085 A
.m
[7] += -1/ODE_F
.dt
;
2086 A
.m
[14] += -1/ODE_F
.dt
;
2087 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2088 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2089 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2090 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2094 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2099 void SMCZone::J3E_ddm_neumannbc(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
)
2102 PetscInt index
[6],col
[6];
2103 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2104 NeumannBC
*pbc
= dynamic_cast <NeumannBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2106 PetscScalar kb
= mt
->kb
;
2107 PetscScalar e
= mt
->e
;
2108 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2109 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2110 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2111 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3];
2112 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2113 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2114 PetscScalar area
= pcell
->area
;
2115 PetscScalar d_grad_T_dTi
= 0;
2116 //--------------------------------
2117 index
[0] = zofs
[z
]+6*i
+0;
2118 index
[1] = zofs
[z
]+6*i
+1;
2119 index
[2] = zofs
[z
]+6*i
+2;
2120 index
[3] = zofs
[z
]+6*i
+3;
2121 index
[4] = zofs
[z
]+6*i
+4;
2122 index
[5] = zofs
[z
]+6*i
+5;
2124 //--------------------------------
2125 for(int j
=0;j
<pcell
->nb_num
;j
++)
2127 int nb
= pcell
->nb_array
[j
];
2128 col
[0] = zofs
[z
]+6*nb
+0;
2129 col
[1] = zofs
[z
]+6*nb
+1;
2130 col
[2] = zofs
[z
]+6*nb
+2;
2131 col
[3] = zofs
[z
]+6*nb
+3;
2132 col
[4] = zofs
[z
]+6*nb
+4;
2133 col
[5] = zofs
[z
]+6*nb
+5;
2134 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2136 if(j
==0||j
==pcell
->nb_num
-1)
2138 PetscScalar h
= pbc
->heat_transfer
;
2139 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/pcell
->area
;
2140 A
.m
[21] += -0.5*pcell
->ilen
[j
]*0.25*h
/pcell
->area
;
2142 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2145 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2147 A
.m
[1] += -e
/aux
[i
].eps
; //dfun(0)/dn(i)
2148 A
.m
[2] += e
/aux
[i
].eps
; //dfun(0)/dp(i)
2150 A
.m
[21]+= d_grad_T_dTi
;
2152 if(ODE_F
.TimeDependent
==true)
2155 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2157 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2158 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2159 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2160 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2161 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2162 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2163 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2167 A
.m
[7] += -1/ODE_F
.dt
;
2168 A
.m
[14] += -1/ODE_F
.dt
;
2169 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2170 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2171 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2172 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2176 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2182 void SMCZone::J3E_ddm_ombc_segment(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
)
2186 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2187 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2189 PetscScalar kb
= mt
->kb
;
2190 PetscScalar e
= mt
->e
;
2191 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2192 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2193 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2194 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2195 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2196 PetscScalar area
= pcell
->area
;
2197 PetscScalar d_grad_T_dTi
= 0;
2198 index
[0] = zofs
[z
]+6*i
+0;
2199 index
[1] = zofs
[z
]+6*i
+1;
2200 index
[2] = zofs
[z
]+6*i
+2;
2201 index
[3] = zofs
[z
]+6*i
+3;
2202 index
[4] = zofs
[z
]+6*i
+4;
2203 index
[5] = zofs
[z
]+6*i
+5;
2205 for(int j
=0;j
<pcell
->nb_num
;j
++)
2207 int nb
= pcell
->nb_array
[j
];
2208 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2209 PetscScalar kapa
= mt
->thermal
->HeatConduction(0.5*(Ti
+Tj
));
2210 //-------------------------------------
2211 d_grad_T_dTi
+= -kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
]/area
;
2212 //-------------------------------------
2213 PetscScalar d_grad_T_dTj
= kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
]/area
; //dfun(3)/dT(r)
2214 if(j
==0||j
==pcell
->nb_num
-1)
2216 PetscScalar h
= pbc
->heat_transfer
;
2217 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/pcell
->area
;
2218 d_grad_T_dTj
+= -0.5*pcell
->ilen
[j
]*0.25*h
/pcell
->area
;
2220 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[z
]+6*nb
+3,d_grad_T_dTj
,INSERT_VALUES
);
2224 A
.m
[21] = d_grad_T_dTi
; //dfun(3)/dT(i)
2231 if(ODE_F
.TimeDependent
==true)
2234 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2236 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2237 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2238 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2242 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2243 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2246 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2250 int size
= pzone
->davcell
.size();
2252 for(int j
=0;j
<electrode
.size();j
++)
2253 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
2255 MatSetValue(*jac
,zofs
[zone_index
]+6*i
+0,zofs
[zone_index
]+equ_num
*size
+om_equ
,-1,INSERT_VALUES
);
2259 void SMCZone::J3E_ddm_ombc_interface(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
,
2264 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2265 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2267 PetscScalar kb
= mt
->kb
;
2268 PetscScalar e
= mt
->e
;
2269 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2270 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2271 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2272 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2273 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2274 PetscScalar area
= pcell
->area
;
2275 PetscScalar d_grad_T_dTi
= 0;
2276 index
[0] = zofs
[z
]+6*i
+0;
2277 index
[1] = zofs
[z
]+6*i
+1;
2278 index
[2] = zofs
[z
]+6*i
+2;
2279 index
[3] = zofs
[z
]+6*i
+3;
2280 index
[4] = zofs
[z
]+6*i
+4;
2281 index
[5] = zofs
[z
]+6*i
+5;
2283 for(int j
=0;j
<pcell
->nb_num
;j
++)
2285 int nb
= pcell
->nb_array
[j
];
2286 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2287 PetscScalar kapa
= mt
->thermal
->HeatConduction(0.5*(Ti
+Tj
));
2288 //-------------------------------------
2289 d_grad_T_dTi
+= -kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
];
2290 //-------------------------------------
2291 PetscScalar d_grad_T_dTj
= kapa
*pcell
->elen
[j
]/pcell
->ilen
[j
]; //dfun(3)/dT(r)
2292 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[z
]+6*nb
+3,d_grad_T_dTj
,INSERT_VALUES
);
2294 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2295 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
2296 for(int j
=0;j
<ncell
->nb_num
;j
++)
2298 int nb
= ncell
->nb_array
[j
];
2299 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1];
2300 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
2301 d_grad_T_dTi
+= -kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2302 PetscScalar d_grad_T_dTj
= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2303 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[pz
->pzone
->zone_index
]+2*nb
+1,d_grad_T_dTj
,INSERT_VALUES
);
2307 A
.m
[21] = d_grad_T_dTi
; //dfun(3)/dT(i)
2315 if(ODE_F
.TimeDependent
==true)
2318 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2320 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2321 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2322 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2323 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
2324 -pz
->aux
[n
].density
*HeatCapacity2
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
2328 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2329 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2330 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
*pcell
->area
2331 -pz
->aux
[n
].density
*HeatCapacity2
/ODE_F
.dt
*ncell
->area
;
2335 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2339 int size
= pzone
->davcell
.size();
2341 for(int j
=0;j
<electrode
.size();j
++)
2342 if(electrode
[j
]==pcell
->bc_index
-1) { om_equ
=j
; break; }
2344 MatSetValue(*jac
,zofs
[zone_index
]+6*i
+0,zofs
[zone_index
]+equ_num
*size
+om_equ
,-1,INSERT_VALUES
);
2348 void SMCZone::J3E_ddm_stkbc_segment(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
)
2351 PetscInt index
[6],col
[6];
2352 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2353 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2356 int size
= pzone
->davcell
.size();
2358 PetscScalar kb
= mt
->kb
;
2359 PetscScalar e
= mt
->e
;
2360 PetscScalar VB
= pbc
->WorkFunction
-aux
[i
].affinity
;
2361 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
2362 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2363 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2364 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2366 PetscScalar area
= pcell
->area
;
2367 PetscScalar d_grad_T_dTi
= 0;
2368 PetscScalar d_Fn_dni
= 0;
2369 PetscScalar d_Fn_dTi
= 0;
2370 PetscScalar d_Fp_dpi
= 0;
2371 PetscScalar d_Fp_dTi
= 0;
2372 //--------------------------------
2373 index
[0] = zofs
[z
]+6*i
+0;
2374 index
[1] = zofs
[z
]+6*i
+1;
2375 index
[2] = zofs
[z
]+6*i
+2;
2376 index
[3] = zofs
[z
]+6*i
+3;
2377 index
[4] = zofs
[z
]+6*i
+4;
2378 index
[5] = zofs
[z
]+6*i
+5;
2379 //--------------------------------
2380 for(int j
=0;j
<pcell
->nb_num
;j
++)
2382 int nb
= pcell
->nb_array
[j
];
2383 PetscScalar nj
= x
[zofs
[z
]+6*nb
+1]; //electron density of nb node
2384 PetscScalar pj
= x
[zofs
[z
]+6*nb
+2]; //hole density of nb node
2385 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2386 col
[0] = zofs
[z
]+6*nb
+0;
2387 col
[1] = zofs
[z
]+6*nb
+1;
2388 col
[2] = zofs
[z
]+6*nb
+2;
2389 col
[3] = zofs
[z
]+6*nb
+3;
2390 col
[4] = zofs
[z
]+6*nb
+4;
2391 col
[5] = zofs
[z
]+6*nb
+5;
2392 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2395 if(j
==0||j
==pcell
->nb_num
-1)
2397 d_Fn_dni
+= mt
->band
->pdSchottyJsn_pdn (ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2398 d_Fn_dTi
+= mt
->band
->pdSchottyJsn_pdTl(ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2399 d_Fp_dpi
+= mt
->band
->pdSchottyJsp_pdp (pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2400 d_Fp_dTi
+= mt
->band
->pdSchottyJsp_pdTl(pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2401 PetscScalar h
= pbc
->heat_transfer
;
2402 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/pcell
->area
;
2403 A
.m
[21] += -0.5*pcell
->ilen
[j
]*0.25*h
/pcell
->area
;
2418 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2421 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2426 A
.m
[7] += d_Fn_dni
; //dfun(1)/dn(i)
2429 A
.m
[14]+= -d_Fp_dpi
; //dfun(2)/dp(i)
2430 A
.m
[15]+= -d_Fp_dTi
;
2432 A
.m
[21]+= d_grad_T_dTi
; //dfun(3)/dT(i)
2447 if(ODE_F
.TimeDependent
==true)
2450 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2452 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2453 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2454 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2455 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2456 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2460 A
.m
[7] += -1/ODE_F
.dt
;
2461 A
.m
[14] += -1/ODE_F
.dt
;
2462 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2463 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2466 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2469 for(int j
=0;j
<electrode
.size();j
++)
2470 if(electrode
[j
]==pcell
->bc_index
-1)
2475 MatSetValue(*jac
,zofs
[zone_index
]+6*i
,zofs
[zone_index
]+equ_num
*size
+stk_equ
,-1.0,INSERT_VALUES
);
2479 void SMCZone::J3E_ddm_stkbc_interface(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
,ODE_Formula
&ODE_F
, vector
<int> &zofs
,DABC
&bc
,
2483 PetscInt index
[6],col
[6];
2484 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2485 SchottkyBC
*pbc
= dynamic_cast<SchottkyBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2488 int size
= pzone
->davcell
.size();
2489 PetscScalar area
= pcell
->area
;
2491 Set_Vec6(scale
,area
,area
,area
,1.0,area
,area
);
2493 PetscScalar kb
= mt
->kb
;
2494 PetscScalar e
= mt
->e
;
2495 PetscScalar VB
= pbc
->WorkFunction
-aux
[i
].affinity
;
2496 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[i
].eps
,sqrt(aux
[i
].Ex
*aux
[i
].Ex
+aux
[i
].Ey
*aux
[i
].Ey
));
2497 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2498 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2499 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2501 PetscScalar d_grad_T_dTi
= 0;
2502 PetscScalar d_Fn_dni
= 0;
2503 PetscScalar d_Fn_dTi
= 0;
2504 PetscScalar d_Fp_dpi
= 0;
2505 PetscScalar d_Fp_dTi
= 0;
2506 //--------------------------------
2507 index
[0] = zofs
[z
]+6*i
+0;
2508 index
[1] = zofs
[z
]+6*i
+1;
2509 index
[2] = zofs
[z
]+6*i
+2;
2510 index
[3] = zofs
[z
]+6*i
+3;
2511 index
[4] = zofs
[z
]+6*i
+4;
2512 index
[5] = zofs
[z
]+6*i
+5;
2513 //--------------------------------
2514 for(int j
=0;j
<pcell
->nb_num
;j
++)
2516 int nb
= pcell
->nb_array
[j
];
2517 PetscScalar nj
= x
[zofs
[z
]+6*nb
+1]; //electron density of nb node
2518 PetscScalar pj
= x
[zofs
[z
]+6*nb
+2]; //hole density of nb node
2519 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2520 col
[0] = zofs
[z
]+6*nb
+0;
2521 col
[1] = zofs
[z
]+6*nb
+1;
2522 col
[2] = zofs
[z
]+6*nb
+2;
2523 col
[3] = zofs
[z
]+6*nb
+3;
2524 col
[4] = zofs
[z
]+6*nb
+4;
2525 col
[5] = zofs
[z
]+6*nb
+5;
2526 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2529 if(j
==0||j
==pcell
->nb_num
-1)
2531 d_Fn_dni
+= mt
->band
->pdSchottyJsn_pdn (ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2532 d_Fn_dTi
+= mt
->band
->pdSchottyJsn_pdTl(ni
,Ti
,VB
-deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2533 d_Fp_dpi
+= mt
->band
->pdSchottyJsp_pdp (pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2534 d_Fp_dTi
+= mt
->band
->pdSchottyJsp_pdTl(pi
,Ti
,VB
+deltaVB
)*0.5*pcell
->ilen
[j
]/pcell
->area
;
2549 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2552 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2553 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
2554 for(int j
=0;j
<ncell
->nb_num
;j
++)
2556 int nb
= ncell
->nb_array
[j
];
2557 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1];
2558 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(fs
[i
].T
);//(0.5*(Ti+Tj_n));
2559 d_grad_T_dTi
+= -kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2560 PetscScalar d_grad_T_dTj
= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2561 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[pz
->pzone
->zone_index
]+2*nb
+1,d_grad_T_dTj
,INSERT_VALUES
);
2564 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2569 A
.m
[7] += d_Fn_dni
; //dfun(1)/dn(i)
2572 A
.m
[14]+= -d_Fp_dpi
; //dfun(2)/dp(i)
2573 A
.m
[15]+= -d_Fp_dTi
;
2575 A
.m
[21]+= d_grad_T_dTi
; //dfun(3)/dT(i)
2591 if(ODE_F
.TimeDependent
==true)
2594 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2596 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2597 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2598 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2599 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2600 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2601 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
2602 -pz
->aux
[n
].density
*HeatCapacity2
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
2606 A
.m
[7] += -1/ODE_F
.dt
;
2607 A
.m
[14] += -1/ODE_F
.dt
;
2608 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2609 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2610 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
*pcell
->area
2611 -pz
->aux
[n
].density
*HeatCapacity2
/ODE_F
.dt
*ncell
->area
;
2615 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2618 for(int j
=0;j
<electrode
.size();j
++)
2619 if(electrode
[j
]==pcell
->bc_index
-1)
2624 MatSetValue(*jac
,zofs
[zone_index
]+6*i
,zofs
[zone_index
]+equ_num
*size
+stk_equ
,-1.0,INSERT_VALUES
);
2628 void SMCZone::J3E_ddm_insulator_gate(int i
,PetscScalar
*x
, Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
)
2631 PetscInt index
[6],col
[6];
2632 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2633 InsulatorContactBC
*pbc
= dynamic_cast<InsulatorContactBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2636 int size
= pzone
->davcell
.size();
2637 PetscScalar kb
= mt
->kb
;
2638 PetscScalar e
= mt
->e
;
2639 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2640 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2641 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2642 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2643 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2644 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2646 PetscScalar area
= pcell
->area
;
2647 PetscScalar d_grad_P_dVi
= 0;
2648 PetscScalar d_grad_P_dVapp
= 0;
2649 PetscScalar d_grad_T_dTi
= 0;
2651 for(int j
=0;j
<electrode
.size();j
++)
2652 if(electrode
[j
]==pcell
->bc_index
-1)
2654 //--------------------------------
2655 index
[0] = zofs
[z
]+6*i
+0;
2656 index
[1] = zofs
[z
]+6*i
+1;
2657 index
[2] = zofs
[z
]+6*i
+2;
2658 index
[3] = zofs
[z
]+6*i
+3;
2659 index
[4] = zofs
[z
]+6*i
+4;
2660 index
[5] = zofs
[z
]+6*i
+5;
2661 //--------------------------------
2662 for(int j
=0;j
<pcell
->nb_num
;j
++)
2664 int nb
= pcell
->nb_array
[j
];
2665 PetscScalar Vj
= x
[zofs
[z
]+6*nb
+0]; //potential of nb node
2666 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3]; //lattice temperature of nb node
2667 col
[0] = zofs
[z
]+6*nb
+0;
2668 col
[1] = zofs
[z
]+6*nb
+1;
2669 col
[2] = zofs
[z
]+6*nb
+2;
2670 col
[3] = zofs
[z
]+6*nb
+3;
2671 col
[4] = zofs
[z
]+6*nb
+4;
2672 col
[5] = zofs
[z
]+6*nb
+5;
2674 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2676 if(j
==0||j
==pcell
->nb_num
-1)
2678 PetscScalar Thick
= pbc
->Thick
;
2679 PetscScalar eps_ox
= mt
->eps0
*pbc
->eps
;
2680 PetscScalar eps
= aux
[i
].eps
;
2681 PetscScalar s
=eps_ox
/eps
/Thick
;
2682 d_grad_P_dVi
+= -0.5*pcell
->ilen
[j
]*0.25*s
*3/area
;
2683 d_grad_P_dVapp
+= 0.5*pcell
->ilen
[j
]*s
/area
;
2684 A
.m
[0]+= -0.5*pcell
->ilen
[j
]*0.25*s
/area
;
2685 PetscScalar h
= pbc
->heat_transfer
;
2686 d_grad_T_dTi
+= -0.5*pcell
->ilen
[j
]*0.25*h
*3/area
;
2687 A
.m
[21] += -0.5*pcell
->ilen
[j
]*0.25*h
/area
;
2689 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2692 //fun(0) is the poisson's equation
2693 //fun(1) is the continuous equation of electron
2694 //fun(2) is the continuous equation of hole
2696 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2698 A
.m
[0] += d_grad_P_dVi
;
2699 A
.m
[1] += -e
/aux
[i
].eps
; //df(phi)/dn(i)
2700 A
.m
[2] += e
/aux
[i
].eps
; //df(phi)/dp(i)
2702 A
.m
[21]+= d_grad_T_dTi
;
2704 if(ODE_F
.TimeDependent
==true)
2707 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2709 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2710 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2711 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2712 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2713 A
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2714 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2715 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2719 A
.m
[7] += -1/ODE_F
.dt
;
2720 A
.m
[14] += -1/ODE_F
.dt
;
2721 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2722 A
.m
[21] += -aux
[i
].density
*HeatCapacity
/ODE_F
.dt
;
2723 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2724 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2727 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2728 MatSetValue(*jac
,zofs
[z
]+6*i
,zofs
[z
]+equ_num
*size
+ins_equ
,d_grad_P_dVapp
,INSERT_VALUES
);
2733 void SMCZone::J3E_ddm_interface(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
,
2737 PetscInt index
[6],col
[6];
2738 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2739 InsulatorInterfaceBC
*pbc
= dynamic_cast<InsulatorInterfaceBC
* >(bc
.Get_pointer(pcell
->bc_index
-1));
2741 PetscScalar kb
= mt
->kb
;
2742 PetscScalar e
= mt
->e
;
2743 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2744 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2745 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2746 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2747 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2748 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2750 PetscScalar area
= pcell
->area
;
2751 PetscScalar d_grad_P_dVi
= 0;
2752 PetscScalar d_grad_T_dTi
= 0;
2754 Set_Vec6(scale
,1.0,area
,area
,1.0,area
,area
);
2755 //--------------------------------
2756 index
[0] = zofs
[z
]+6*i
+0;
2757 index
[1] = zofs
[z
]+6*i
+1;
2758 index
[2] = zofs
[z
]+6*i
+2;
2759 index
[3] = zofs
[z
]+6*i
+3;
2760 index
[4] = zofs
[z
]+6*i
+4;
2761 index
[5] = zofs
[z
]+6*i
+5;
2762 //--------------------------------
2763 for(int j
=0;j
<pcell
->nb_num
;j
++)
2765 int nb
= pcell
->nb_array
[j
];
2767 PetscScalar Vj
= x
[zofs
[z
]+6*nb
+0]; //potential of nb node
2768 PetscScalar Tj
= x
[zofs
[z
]+6*nb
+3];
2769 PetscScalar kapa
= mt
->thermal
->HeatConduction(0.5*(Ti
+Tj
));
2770 d_grad_P_dVi
+= -aux
[i
].eps
*pcell
->elen
[j
]/pcell
->ilen
[j
];
2771 col
[0] = zofs
[z
]+6*nb
+0;
2772 col
[1] = zofs
[z
]+6*nb
+1;
2773 col
[2] = zofs
[z
]+6*nb
+2;
2774 col
[3] = zofs
[z
]+6*nb
+3;
2775 col
[4] = zofs
[z
]+6*nb
+4;
2776 col
[5] = zofs
[z
]+6*nb
+5;
2777 MatGetValues(*jtmp
,6,index
,6,col
,A
.m
);
2779 A
.m
[0] = aux
[i
].eps
*pcell
->elen
[j
]/pcell
->ilen
[j
]; //dfun(0)/dP(r)
2780 A
.m
[1] = 0; //dfun(0)/dn(r)
2781 A
.m
[2] = 0; //dfun(0)/dp(r)
2782 A
.m
[3] = 0; //dfun(0)/dT(r)
2785 MatSetValues(*jac
,6,index
,6,col
,A
.m
,INSERT_VALUES
);
2788 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2789 pz
->mt
->mapping(&pz
->pzone
->danode
[n
],&pz
->aux
[n
],ODE_F
.clock
);
2790 for(int j
=0;j
<ncell
->nb_num
;j
++)
2792 int nb
= ncell
->nb_array
[j
];
2793 PetscScalar Tj_n
= x
[zofs
[pz
->pzone
->zone_index
]+2*nb
+1];
2794 PetscScalar kapa
= pz
->mt
->thermal
->HeatConduction(0.5*(Ti
+Tj_n
));
2795 d_grad_P_dVi
+= -pz
->aux
[n
].eps
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2796 PetscScalar d_grad_P_dVj
= pz
->aux
[n
].eps
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2797 MatSetValue(*jac
,zofs
[z
]+6*i
+0,zofs
[pz
->pzone
->zone_index
]+2*nb
+0,d_grad_P_dVj
,INSERT_VALUES
);
2798 d_grad_T_dTi
+= -kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2799 PetscScalar d_grad_T_dTj
= kapa
*ncell
->elen
[j
]/ncell
->ilen
[j
];
2800 MatSetValue(*jac
,zofs
[z
]+6*i
+3,zofs
[pz
->pzone
->zone_index
]+2*nb
+1,d_grad_T_dTj
,INSERT_VALUES
);
2803 //fun(0) is the poisson's equation
2804 //fun(1) is the continuous equation of electron
2805 //fun(2) is the continuous equation of hole
2807 MatGetValues(*jtmp
,6,index
,6,index
,A
.m
);
2809 A
.m
[0] = d_grad_P_dVi
; //dfun(0)/dP(i)
2810 A
.m
[1] = -e
*pcell
->area
; //dfun(0)/dn(i)
2811 A
.m
[2] = e
*pcell
->area
; //dfun(0)/dp(i)
2812 A
.m
[3] = 0.0; //dfun(0)/dT(i)
2816 A
.m
[21]+= d_grad_T_dTi
;
2819 if(ODE_F
.TimeDependent
==true)
2822 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2824 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2825 A
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2826 A
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2827 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2828 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2829 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*pcell
->area
2830 -pz
->aux
[n
].density
*HeatCapacity2
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
)*ncell
->area
;
2831 A
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2832 A
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2836 A
.m
[7] += -1/ODE_F
.dt
;
2837 A
.m
[14] += -1/ODE_F
.dt
;
2838 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2839 PetscScalar HeatCapacity2
= pz
->mt
->thermal
->HeatCapacity(Ti
);
2840 A
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
*pcell
->area
2841 -pz
->aux
[n
].density
*HeatCapacity2
/ODE_F
.dt
*ncell
->area
;
2842 A
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2843 A
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2846 MatSetValues(*jac
,6,index
,6,index
,A
.m
,INSERT_VALUES
);
2851 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
)
2854 PetscInt index
[6],indexn
[6],col
[6];
2855 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(i
);
2857 PetscScalar kb
= mt
->kb
;
2858 PetscScalar e
= mt
->e
;
2859 PetscScalar Vi
= x
[zofs
[z
]+6*i
+0]; //potential of node i
2860 PetscScalar ni
= x
[zofs
[z
]+6*i
+1]; //electron density of node i
2861 PetscScalar pi
= x
[zofs
[z
]+6*i
+2]; //hole density of node i
2862 PetscScalar Ti
= x
[zofs
[z
]+6*i
+3]; //lattice temperature of node i
2863 PetscScalar Tn
= x
[zofs
[z
]+6*i
+4]/ni
;
2864 PetscScalar Tp
= x
[zofs
[z
]+6*i
+5]/pi
;
2865 //--------------------------------
2866 index
[0] = zofs
[z
]+6*i
+0;
2867 index
[1] = zofs
[z
]+6*i
+1;
2868 index
[2] = zofs
[z
]+6*i
+2;
2869 index
[3] = zofs
[z
]+6*i
+3;
2870 index
[4] = zofs
[z
]+6*i
+4;
2871 index
[5] = zofs
[z
]+6*i
+5;
2872 //--------------------------------
2873 const VoronoiCell
* ncell
= pz
->pzone
->davcell
.GetPointer(n
);
2874 indexn
[0] = zofs
[pz
->zone_index
]+6*n
+0;
2875 indexn
[1] = zofs
[pz
->zone_index
]+6*n
+1;
2876 indexn
[2] = zofs
[pz
->zone_index
]+6*n
+2;
2877 indexn
[3] = zofs
[pz
->zone_index
]+6*n
+3;
2878 indexn
[4] = zofs
[pz
->zone_index
]+6*n
+4;
2879 indexn
[5] = zofs
[pz
->zone_index
]+6*n
+5;
2880 //--------------------------------
2881 PetscScalar area
= pcell
->area
+ ncell
->area
;
2882 //--------------------------------
2883 if(zone_index
> pz
->pzone
->zone_index
)
2886 MatSetValues(*jac
,6,index
,6,index
,AJ
.m
,INSERT_VALUES
);
2888 MatSetValues(*jac
,6,index
,6,indexn
,AJ
.m
,INSERT_VALUES
);
2891 //--------------------------------
2892 for(int j
=0;j
<pcell
->nb_num
;j
++)
2894 int nb
= pcell
->nb_array
[j
];
2895 col
[0] = zofs
[z
]+6*nb
+0;
2896 col
[1] = zofs
[z
]+6*nb
+1;
2897 col
[2] = zofs
[z
]+6*nb
+2;
2898 col
[3] = zofs
[z
]+6*nb
+3;
2899 col
[4] = zofs
[z
]+6*nb
+4;
2900 col
[5] = zofs
[z
]+6*nb
+5;
2901 MatGetValues(*jtmp
,6,index
,6,col
,A1
.m
);
2902 //-------------------------------------
2904 MatSetValues(*jac
,6,index
,6,col
,A1
.m
,INSERT_VALUES
);
2907 //process another half cell in dornor zone
2908 for(int j
=0;j
<ncell
->nb_num
;j
++)
2910 int nb
= ncell
->nb_array
[j
];
2911 col
[0] = zofs
[pz
->zone_index
]+6*nb
+0;
2912 col
[1] = zofs
[pz
->zone_index
]+6*nb
+1;
2913 col
[2] = zofs
[pz
->zone_index
]+6*nb
+2;
2914 col
[3] = zofs
[pz
->zone_index
]+6*nb
+3;
2915 col
[4] = zofs
[pz
->zone_index
]+6*nb
+4;
2916 col
[5] = zofs
[pz
->zone_index
]+6*nb
+5;
2917 MatGetValues(*jtmp
,6,indexn
,6,col
,A2
.m
);
2919 MatSetValues(*jac
,6,index
,6,col
,A2
.m
,INSERT_VALUES
);
2922 //fun(0) is the poisson's equation
2923 //fun(1) is the continuous equation of electron
2924 //fun(2) is the continuous equation of hole
2925 MatGetValues(*jtmp
,6,index
,6,index
,A1
.m
);
2926 MatGetValues(*jtmp
,6,indexn
,6,indexn
,A2
.m
);
2929 AJ
.m
[1] += -e
/aux
[i
].eps
; //dfun(0)/dn(i)
2930 AJ
.m
[2] += e
/aux
[i
].eps
; //dfun(0)/dp(i)
2932 if(ODE_F
.TimeDependent
==true)
2935 if(ODE_F
.BDF_Type
==BDF2
&&ODE_F
.BDF2_restart
==false)
2937 PetscScalar r
= ODE_F
.dt_last
/(ODE_F
.dt_last
+ODE_F
.dt
);
2938 AJ
.m
[7] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2939 AJ
.m
[14] += -(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2940 PetscScalar HeatCapacity
= mt
->thermal
->HeatCapacity(Ti
);
2941 AJ
.m
[21] += -aux
[i
].density
*HeatCapacity
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2942 AJ
.m
[28] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2943 AJ
.m
[35] += -1.5*kb
*(2-r
)/(1-r
)/(ODE_F
.dt_last
+ODE_F
.dt
);
2947 AJ
.m
[7] += -1/ODE_F
.dt
;
2948 AJ
.m
[14] += -1/ODE_F
.dt
;
2949 PetscScalar HeatCapacity1
= mt
->thermal
->HeatCapacity(Ti
);
2950 AJ
.m
[21] += -aux
[i
].density
*HeatCapacity1
/ODE_F
.dt
;
2951 AJ
.m
[28] += -1.5*kb
/ODE_F
.dt
;
2952 AJ
.m
[35] += -1.5*kb
/ODE_F
.dt
;
2955 MatSetValues(*jac
,6,index
,6,index
,AJ
.m
,INSERT_VALUES
);
2959 void SMCZone::J3E_om_electrode(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
2962 int size
= pzone
->davcell
.size();
2963 int bc_index
= electrode
[i
];
2964 OhmicBC
*pbc
= dynamic_cast <OhmicBC
* > (bc
.Get_pointer(bc_index
));
2965 PetscScalar A1
[6],A2
[6],J
[6];
2966 PetscInt index
[6],col
[6];
2967 int matrix_row
= zofs
[zone_index
]+equ_num
*size
+i
;
2969 if(pbc
->inner_connect
!=-1)
2971 int connect_to
= pbc
->inner_connect
;
2972 int connect_zone
= pbc
->connect_zone
;
2973 int connect_elec
=-1;
2974 SMCZone
* pz
= dynamic_cast <SMCZone
* > (pbc
->pzonedata
);
2975 for(int j
=0;j
<pz
->electrode
.size();j
++)
2977 if(bc
[pz
->electrode
[j
]].BCType
==OhmicContact
)
2979 OhmicBC
*om_bc
= dynamic_cast <OhmicBC
* >(bc
.Get_pointer(pz
->electrode
[j
]));
2980 if(om_bc
->inner_connect
==bc_index
) connect_elec
=j
;
2983 connect_index
=zofs
[connect_zone
]+equ_num
*pz
->pzone
->davcell
.size()+connect_elec
;
2985 PetscScalar R
= pbc
->R
;
2986 PetscScalar C
= pbc
->C
;
2987 PetscScalar L
= pbc
->L
;
2988 PetscScalar kb
= mt
->kb
;
2989 PetscScalar e
= mt
->e
;
2991 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
2992 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
2994 for(int n
=0;n
<bc
[bc_index
].psegment
->node_array
.size();n
++)
2996 int node
=bc
[bc_index
].psegment
->node_array
[n
];
2997 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
2998 PetscScalar dJdisp_dVi
=0,dJdisp_dVr
=0;
2999 index
[0] = zofs
[zone_index
]+6*node
+0;
3000 index
[1] = zofs
[zone_index
]+6*node
+1;
3001 index
[2] = zofs
[zone_index
]+6*node
+2;
3002 index
[3] = zofs
[zone_index
]+6*node
+3;
3003 index
[4] = zofs
[zone_index
]+6*node
+4;
3004 index
[5] = zofs
[zone_index
]+6*node
+5;
3005 for(int j
=0;j
<pcell
->nb_num
;j
++)
3007 int nb
= pcell
->nb_array
[j
];
3008 col
[0] = zofs
[zone_index
]+6*nb
+0;
3009 col
[1] = zofs
[zone_index
]+6*nb
+1;
3010 col
[2] = zofs
[zone_index
]+6*nb
+2;
3011 col
[3] = zofs
[zone_index
]+6*nb
+3;
3012 col
[4] = zofs
[zone_index
]+6*nb
+4;
3013 col
[5] = zofs
[zone_index
]+6*nb
+5;
3015 MatGetValues(*jtmp
,1,&index
[1],6,col
,A1
);
3016 MatGetValues(*jtmp
,1,&index
[2],6,col
,A2
);
3018 //for displacement current
3019 dJdisp_dVi
+= aux
[node
].eps
/pcell
->ilen
[j
]/ODE_F
.dt
*pcell
->elen
[j
];
3020 dJdisp_dVr
= -aux
[node
].eps
/pcell
->ilen
[j
]/ODE_F
.dt
*pcell
->elen
[j
];
3021 if(pbc
->inner_connect
!=-1)
3023 int connect_to
= pbc
->inner_connect
;
3024 if(bc_index
< connect_to
)
3026 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3027 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3028 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3029 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3030 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3031 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3032 MatSetValues(*jac
,1,&connect_index
,6,col
,J
,ADD_VALUES
);
3036 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3037 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3038 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3039 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3040 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3041 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3042 MatSetValues(*jac
,1,&matrix_row
,6,col
,J
,ADD_VALUES
);
3045 else if(pbc
->electrode_type
==VoltageBC
)
3047 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3048 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3049 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3050 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3051 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3052 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3053 MatSetValues(*jac
,1,&matrix_row
,6,col
,J
,ADD_VALUES
);
3055 else if(pbc
->electrode_type
==CurrentBC
)
3057 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3058 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3059 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3060 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3061 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3062 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3063 MatSetValues(*jac
,1,&matrix_row
,6,col
,J
,ADD_VALUES
);
3066 MatGetValues(*jtmp
,1,&index
[1],6,index
,A1
);
3067 MatGetValues(*jtmp
,1,&index
[2],6,index
,A2
);
3068 if(pbc
->inner_connect
!=-1)
3070 int connect_to
= pbc
->inner_connect
;
3071 if(bc_index
< connect_to
)
3073 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3074 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3075 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3076 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3077 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3078 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3079 MatSetValues(*jac
,1,&connect_index
,6,index
,J
,ADD_VALUES
);
3083 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVr
)*DeviceDepth
;
3084 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3085 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3086 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3087 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3088 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3089 MatSetValues(*jac
,1,&matrix_row
,6,index
,J
,ADD_VALUES
);
3092 else if(pbc
->electrode_type
==VoltageBC
)
3094 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVi
)*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3095 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3096 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3097 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3098 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3099 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
*(L
/ODE_F
.dt
+R
);
3100 MatSetValues(*jac
,1,&matrix_row
,6,index
,J
,ADD_VALUES
);
3102 else if(pbc
->electrode_type
==CurrentBC
)
3104 J
[0]=(A1
[0]-A2
[0]+dJdisp_dVi
)*DeviceDepth
;
3105 J
[1]=(A1
[1]-A2
[1])*DeviceDepth
;
3106 J
[2]=(A1
[2]-A2
[2])*DeviceDepth
;
3107 J
[3]=(A1
[3]-A2
[3])*DeviceDepth
;
3108 J
[4]=(A1
[4]-A2
[4])*DeviceDepth
;
3109 J
[5]=(A1
[5]-A2
[5])*DeviceDepth
;
3110 MatSetValues(*jac
,1,&matrix_row
,6,index
,J
,ADD_VALUES
);
3114 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3115 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3116 if(pbc
->inner_connect
!=-1)
3118 int connect_to
= pbc
->inner_connect
;
3119 if(bc_index
< connect_to
)
3121 MatSetValue(*jac
,matrix_row
,matrix_row
,1.0,ADD_VALUES
);
3125 MatSetValue(*jac
,connect_index
,matrix_row
,-1.0,ADD_VALUES
);
3128 else if(pbc
->electrode_type
==VoltageBC
)
3129 MatSetValue(*jac
,matrix_row
,matrix_row
,1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
,INSERT_VALUES
); //dJ/dP
3134 void SMCZone::J3E_stk_electrode(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
3137 int size
= pzone
->davcell
.size();
3138 int bc_index
= electrode
[i
];
3139 SchottkyBC
*pbc
= dynamic_cast <SchottkyBC
* > (bc
.Get_pointer(bc_index
));
3140 int matrix_row
= zofs
[zone_index
]+equ_num
*size
+i
;
3141 PetscScalar R
= pbc
->R
;
3142 PetscScalar C
= pbc
->C
;
3143 PetscScalar L
= pbc
->L
;
3144 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
3146 int node
= bc
[bc_index
].psegment
->node_array
[j
];
3147 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
3148 PetscScalar VB
= pbc
->WorkFunction
-aux
[node
].affinity
;
3149 PetscScalar deltaVB
=mt
->band
->SchottyBarrierLowerring(aux
[node
].eps
,sqrt(aux
[node
].Ex
*aux
[node
].Ex
+aux
[node
].Ey
*aux
[node
].Ey
));
3150 PetscScalar ni
= x
[zofs
[zone_index
]+6*node
+1]; //electron density of node i
3151 PetscScalar pi
= x
[zofs
[zone_index
]+6*node
+2]; //hole density of node i
3152 PetscScalar dJ_dni
= -mt
->band
->pdSchottyJsn_pdn(ni
,fs
[node
].T
,VB
-deltaVB
)*0.5*pcell
->ilen
[0]
3153 -mt
->band
->pdSchottyJsn_pdn(ni
,fs
[node
].T
,VB
-deltaVB
)*0.5*pcell
->ilen
[pcell
->nb_num
-1];
3154 PetscScalar dJ_dpi
= -mt
->band
->pdSchottyJsp_pdp(pi
,fs
[node
].T
,VB
+deltaVB
)*0.5*pcell
->ilen
[0]
3155 -mt
->band
->pdSchottyJsp_pdp(pi
,fs
[node
].T
,VB
+deltaVB
)*0.5*pcell
->ilen
[pcell
->nb_num
-1];
3157 //for displacement current
3158 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3159 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3160 for(int k
=0;k
<pcell
->nb_num
;k
++)
3162 int nb
= pcell
->nb_array
[k
];
3163 PetscScalar dI_dVi
= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3164 PetscScalar dI_dVr
= -DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3165 if(pbc
->electrode_type
==VoltageBC
)
3167 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+0,dI_dVi
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3168 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*nb
+0,dI_dVr
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3170 else if(pbc
->electrode_type
==CurrentBC
)
3172 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+0,dI_dVi
,ADD_VALUES
);
3173 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*nb
+0,dI_dVr
,ADD_VALUES
);
3176 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3177 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3179 if(pbc
->electrode_type
==VoltageBC
)
3181 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+1,DeviceDepth
*dJ_dni
*(L
/ODE_F
.dt
+R
),INSERT_VALUES
);
3182 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+2,DeviceDepth
*dJ_dpi
*(L
/ODE_F
.dt
+R
),INSERT_VALUES
);
3184 else if(pbc
->electrode_type
==CurrentBC
)
3186 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+1,DeviceDepth
*dJ_dni
,INSERT_VALUES
);
3187 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+2,DeviceDepth
*dJ_dpi
,INSERT_VALUES
);
3190 if(pbc
->electrode_type
==VoltageBC
)
3191 MatSetValue(*jac
,matrix_row
,matrix_row
,1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
,INSERT_VALUES
); //dJ/dP
3195 void SMCZone::J3E_ins_electrode(int i
,PetscScalar
*x
,Mat
*jac
,Mat
*jtmp
, ODE_Formula
&ODE_F
, vector
<int> & zofs
, DABC
&bc
, PetscScalar DeviceDepth
)
3198 int size
= pzone
->davcell
.size();
3199 int bc_index
= electrode
[i
];
3200 InsulatorContactBC
*pbc
= dynamic_cast <InsulatorContactBC
* > (bc
.Get_pointer(bc_index
));
3201 int matrix_row
= zofs
[zone_index
]+equ_num
*size
+i
;
3202 PetscScalar R
= pbc
->R
;
3203 PetscScalar C
= pbc
->C
;
3204 PetscScalar L
= pbc
->L
;
3206 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3207 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3208 for(int j
=0;j
<bc
[bc_index
].psegment
->node_array
.size();j
++)
3210 int node
= bc
[bc_index
].psegment
->node_array
[j
];
3211 const VoronoiCell
* pcell
= pzone
->davcell
.GetPointer(node
);
3213 //for displacement current
3215 for(int k
=0;k
<pcell
->nb_num
;k
++)
3217 int nb
= pcell
->nb_array
[k
];
3218 PetscScalar dI_dVi
= DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3219 PetscScalar dI_dVr
= -DeviceDepth
*pcell
->elen
[k
]*aux
[node
].eps
/pcell
->ilen
[k
]/ODE_F
.dt
;
3220 if(pbc
->electrode_type
==VoltageBC
)
3222 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*node
+0,dI_dVi
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3223 MatSetValue(*jac
,matrix_row
,zofs
[zone_index
]+6*nb
+0,dI_dVr
*(L
/ODE_F
.dt
+R
),ADD_VALUES
);
3228 MatAssemblyBegin(*jac
,MAT_FLUSH_ASSEMBLY
);
3229 MatAssemblyEnd(*jac
,MAT_FLUSH_ASSEMBLY
);
3231 if(pbc
->electrode_type
==VoltageBC
)
3232 MatSetValue(*jac
,matrix_row
,matrix_row
,1+(L
/ODE_F
.dt
+R
)*C
/ODE_F
.dt
,INSERT_VALUES
); //dJ/dP
3236 void SMCZone::F3E_efield_update(PetscScalar
*x
,vector
<int> & zofs
, DABC
&bc
, vector
<BZoneData
*>zonedata
)
3238 PetscScalar P_x
=0,P_y
=0,w
=0;
3239 //calculate Ex Ey with least-squares gradient construction
3240 for(int i
=0; i
<pzone
->davcell
.size();i
++)
3243 VoronoiCell
*pcell
= pzone
->davcell
.GetPointer(i
);
3244 for(int k
=0;k
<pcell
->nb_num
;k
++)
3246 const VoronoiCell
*ncell
= pzone
->davcell
.GetPointer(pcell
->nb_array
[k
]);
3247 PetscScalar dx
= ncell
->x
- pcell
->x
;
3248 PetscScalar dy
= ncell
->y
- pcell
->y
;
3249 PetscScalar dP
= x
[zofs
[zone_index
]+6*pcell
->nb_array
[k
]+0] - x
[zofs
[zone_index
]+6*i
+0];
3250 w
=1.0/sqrt(dx
*dx
+dy
*dy
);
3254 if(pcell
->bc_index
&&bc
[pcell
->bc_index
-1].BCType
==InsulatorInterface
)
3256 InsulatorInterfaceBC
*pbc
;
3257 pbc
= dynamic_cast<InsulatorInterfaceBC
*>(bc
.Get_pointer(pcell
->bc_index
-1));
3258 int n_zone
= pbc
->pinterface
->Find_neighbor_zone_index(zone_index
);
3259 int n_node
= pbc
->pinterface
->Find_neighbor_node_index(zone_index
,i
);
3260 ISZone
* pz
= dynamic_cast<ISZone
*>(zonedata
[n_zone
]);
3261 const VoronoiCell
* dcell
= pz
->pzone
->davcell
.GetPointer(n_node
);
3262 for(int k
=1;k
<dcell
->nb_num
-1;k
++)
3264 const VoronoiCell
*ncell
= pz
->pzone
->davcell
.GetPointer(dcell
->nb_array
[k
]);
3265 PetscScalar dx
= ncell
->x
- dcell
->x
;
3266 PetscScalar dy
= ncell
->y
- dcell
->y
;
3267 PetscScalar dP
= x
[zofs
[n_zone
]+2*dcell
->nb_array
[k
]]- x
[zofs
[n_zone
]+2*n_node
];
3268 w
=1.0/sqrt(dx
*dx
+dy
*dy
);
3273 aux
[i
].Ex
= -(pcell
->sc
*P_x
-pcell
->sb
*P_y
);
3274 aux
[i
].Ey
= -(pcell
->sa
*P_y
-pcell
->sb
*P_x
);