Xyce  6.1
N_DEV_MaterialSupport.h
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // Copyright Notice
3 //
4 // Copyright 2002 Sandia Corporation. Under the terms
5 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
6 // Government retains certain rights in this software.
7 // Xyce(TM) Parallel Electrical Simulator
8 // Copyright (C) 2002-2015 Sandia Corporation
9 //
10 // This program is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 //-----------------------------------------------------------------------------
23 //-----------------------------------------------------------------------------
24 // Filename : $RCSfile: N_DEV_MaterialSupport.h,v $
25 //
26 // Purpose :
27 //
28 // Special Notes :
29 //
30 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
31 //
32 // Creation Date : 07/19/03
33 //
34 // Revision Information:
35 // ---------------------
36 //
37 // Revision Number: $Revision: 1.33 $
38 //
39 // Revision Date : $Date: 2015/09/01 22:15:04 $
40 //
41 // Current Owner : $Author: erkeite $
42 //-----------------------------------------------------------------------------
43 
44 #ifndef Xyce_N_DEV_MaterialSupport_h
45 #define Xyce_N_DEV_MaterialSupport_h
46 
47 #include <Sacado.hpp>
48 
49 // ---------- Standard Includes ----------
50 #include <N_UTL_Math.h>
51 #include <string>
52 
53 // ---------- Xyce Includes ----------
54 #include <N_DEV_Const.h>
55 #include <N_ERH_ErrorMgr.h>
56 #include <N_UTL_FeatureTest.h>
57 #include <N_UTL_ExtendedString.h>
58 #include <N_UTL_Param.h>
59 
60 // ---------- Forward Declarations ----------
61 
62 namespace Xyce {
63 namespace Device {
64 
65 //-----------------------------------------------------------------------------
66 // Class : MobInfo
67 // Purpose : Mobility function information.
68 // Special Notes :
69 // Creator : Deborah Fixel, SNL, Parallel Computational Sciences
70 // Creation Date : 06/24/03
71 //-----------------------------------------------------------------------------
72 template <typename ScalarT>
73 class MobInfo
74 {
75  public:
77  mobModelName("carr"),
78  materialName("si"),
79  holeFlag(false),
80  fieldDependent(false),
81  N(1.0e15),
82  Na(1.0e15),
83  Nd(1.0e15),
84  T( CONSTREFTEMP ), // 300.15 K
85  refTemp( CONSTREFTEMP ), // 300.15 K
86  p(static_cast<ScalarT>(1.45e10)),
87  n(static_cast<ScalarT>(1.45e10)),
88  epar(static_cast<ScalarT>(0.0)),
89  eperp(static_cast<ScalarT>(1.5e4))
90  {};
91 
92  public:
93  std::string mobModelName;
94  std::string materialName;
95  bool holeFlag;
97  ScalarT N;
98  ScalarT Na;
99  ScalarT Nd;
100  double T;
101  double refTemp;
102  ScalarT p;
103  ScalarT n;
104  ScalarT epar;
105  ScalarT eperp;
106 };
107 
108 namespace MaterialSupport {
109 
110 template <typename ScalarT>
111 ScalarT calcMob (MobInfo<ScalarT> & min);
112 
113 template <typename ScalarT>
114 ScalarT calcAnalyticMob (MobInfo<ScalarT> & min);
115 
116 template <typename ScalarT>
117 ScalarT calcAroraMob (MobInfo<ScalarT> & min);
118 
119 template <typename ScalarT>
120 ScalarT calcCarrierMobOld (MobInfo<ScalarT> & min);
121 
122 template <typename ScalarT>
123 ScalarT calcCarrierMobNew (MobInfo<ScalarT> & min);
124 
125 template <typename ScalarT>
126 ScalarT calcLombardiMob (MobInfo<ScalarT> & min);
127 
128 template <typename ScalarT>
129 ScalarT calcPhilipsMob (MobInfo<ScalarT> & min);
130 
131 template <typename ScalarT>
132 ScalarT calcIIIVMob (MobInfo<ScalarT> & min);
133 
134 template <typename ScalarT>
135 void applyHighFieldMobilityModel(MobInfo<ScalarT> & min, ScalarT & mobil);
136 
137 double workfunc(std::string & metal);
138 double affin(const std::string & material);
139 double bandgap(const std::string & material, double temp);
140 
141 double Ebgn(const std::string & material, const std::string & bgnModel, double dope, bool ntype);
142 double bennetWilsonEbgn ( const std::string & material, double dope, bool ntype);
143 double slotboomEbgn ( const std::string & material, double dope, bool ntype);
144 double jainEbgn ( const std::string & material, double dope, bool ntype);
145 double jain2Ebgn ( const std::string & material, double dope, bool ntype);
146 double jain3Ebgn ( const std::string & material, double dope, bool ntype);
147 
148 double calcLt (bool holeFlag, double conc, std::string material="si");
149 
150 double calcRsrh (const std::string & material,
151  double ni,
152  double n, double p,
153  double tn, double tp);
154 
155 double calcRaug (const std::string & material, double ni, double n, double p);
156 
157 double pdRsrhN (const std::string & material, double ni,
158  double n, double p,
159  double tn, double tp);
160 
161 double pdRsrhP (const std::string & material, double ni,
162  double n, double p,
163  double tn, double tp);
164 
165 double pdRaugN (const std::string & material, double ni, double n, double p);
166 double pdRaugP (const std::string & material, double ni, double n, double p);
167 
168 double getNc (const std::string & material, double temp);
169 double getNv (const std::string & material, double temp);
170 
171 double getNi (const std::string & material, double temp);
172 double getNi_old (const std::string & material, double temp);
173 
174 double getRelPerm (const std::string & material);
175 
176 double getEffectiveMassN (const std::string & material);
177 double getEffectiveMassP (const std::string & material);
178 
179 double get_DOS_EffectiveMassN (const std::string & material);
180 double get_DOS_EffectiveMassP (const std::string & material);
181 
182 double getCarrierThermalVelocity (const std::string & material, const std::string & carrier);
183 
184 
185 // Mobility model functions.
186 //
187 // Note, while many of these list me (Eric Keiter) as creator, I copied a lot
188 // from the Charon mobility models files, which were written mostly by
189 // Debbie Fixel.
190 //
191 
192 // ----------------------------------------------------------------------------
193 // Function : MaterialSupport::calcMob
194 // Purpose : This function returns the mobility of electrons and
195 // holes for various materials.
196 // Special Notes :
197 // Scope : public
198 // Creator : Deborah Fixel, SNL, Parallel Computational Sciences
199 // Creation Date : 6/19/03
200 // ----------------------------------------------------------------------------
201 template <typename ScalarT>
202 ScalarT calcMob(MobInfo<ScalarT> & min)
203 {
204  ScalarT mobil = 0.0;
205 
206  // Makes the mobility string case-insensitive
207  ExtendedString mobility = min.mobModelName;
208  mobility.toLower();
209 
210  if(mobility=="analytic" || mobility=="caughey-thomas") // Barnes?
211  {
212  mobil=calcAnalyticMob (min);
213  }
214  else if(mobility=="arora")
215  {
216  mobil=calcAroraMob (min);
217  }
218  else if(mobility=="carr")
219  {
220  mobil=calcCarrierMobOld (min);
221  }
222  else if(mobility=="carrier") // this one matches Charon
223  {
224  mobil=calcCarrierMobNew (min);
225  }
226  else if(mobility=="surface" || mobility=="lombardi")
227  {
228  mobil=calcLombardiMob (min);
229  }
230  else if(mobility=="philips")
231  {
232  mobil= calcPhilipsMob (min);
233  }
234  else if(mobility=="iii-v")
235  {
236  mobil= calcIIIVMob (min);
237  }
238  else // model not recognized:
239  {
240  Report::UserFatal0() << "Mobility model " << mobility << " not recognized.";
241  }
242 
243  if (min.fieldDependent && std::fabs(min.epar)>0.0)
244  {
245  applyHighFieldMobilityModel(min,mobil);
246  }
247 
248  if (DEBUG_DEVICE && mobil != 0.0 && !(mobil > 0.0) && !(mobil < 0.0))
249  {
250  Report::DevelFatal0().in("MaterialSupport::calcMob") << "Mobility calc = nan.";
251  }
252 
253  return mobil;
254 }
255 
256 // ----------------------------------------------------------------------------
257 // Function : MaterialSupport::calcAnalyticMob
258 // Purpose : This function returns the mobility of electrons and
259 // holes for various materials.
260 // Special Notes :
261 //
262 // This model is from the reference by D.M. Caughey and R.E. Thomas
263 // "Carrier Mobilities in Silicon Empirically Related to
264 // Doping and Field", Proc. IEEE, Vol 55, pp. 2192-2193, 1967.
265 //
266 // Scope : public
267 // Creator : Eric Keiter, SNL
268 // Creation Date : 10/25/12
269 // ----------------------------------------------------------------------------
270 template <typename ScalarT>
272 {
273  ExtendedString mater = min.materialName;
274  mater.toLower();
275  ScalarT mobil=0.0;
276  double mun_min, mup_min;
277  double mun_max, mup_max;
278  double nun, nup, xin, xip, nrefn, nrefp, alphan, alphap;
279 
280  if(mater=="si") // silicon
281  {
282  mun_min = 55.24; mup_min = 49.7;
283  mun_max = 1429.23; mup_max = 479.37;
284  nrefn = 1.072e17; nrefp = 1.606e17;
285  nun = -2.3; nup = -2.2;
286  xin = -3.8; xip = -3.7;
287  alphan = 0.733; alphap = 0.70;
288  }
289  else if(mater=="gaas") // gallium arsenide
290  {
291  mun_min = 0.0; mup_min = 0.0;
292  mun_max = 8500.0; mup_max = 400.0;
293  nrefn = 1.69e17; nrefp = 2.75e17;
294  nun = -1.0; nup = -2.1;
295  xin = 0.0; xip = 0.0;
296  alphan = 0.436; alphap = 0.395;
297  }
298  else if(mater=="sio2") // silicon dioxide
299  {
300  mun_min = 1e1; mup_min = 1e-5;
301  mun_max = 2e1; mup_max = 1e-5;
302  nrefn = 1.072e17; nrefp = 1.606e17;
303  nun = -2.3; nup = -2.2;
304  xin = -3.8; xip = -3.7;
305  alphan = 0.733; alphap = 0.70;
306  }
307  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
308  {
309  mun_min = 497.0; mup_min = 0.0;
310  mun_max = 2.41e4; mup_max = 480.0;
311  nrefn = 1.0e17; nrefp = 1.0e30;
312  nun = 0.0; nup = 0.0;
313  xin = 0.0; xip = 0.0;
314  alphan = 1.0; alphap = 1.0;
315 
316  }
317  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
318  {
319  mun_min = 4000.0; mup_min = 0.0;
320  mun_max = 2.73e4; mup_max = 480.0;
321  nrefn = 3.63e17; nrefp = 1.0e30;
322  nun = 0.0; nup = 0.0;
323  xin = 0.0; xip = 0.0;
324  alphan = 1.0; alphap = 1.0;
325  }
326  else if (mater=="inp")
327  {
328  mun_min = 497.0; mup_min = 0.0;
329  mun_max = 2.41e4; mup_max = 480.0;
330  nrefn = 1.0e17; nrefp = 1.0e30;
331  nun = 0.0; nup = 0.0;
332  xin = 0.0; xip = 0.0;
333  alphan = 1.0; alphap = 1.0;
334  }
335  else if (mater=="ingap")
336  {
337  mun_min = 0.95; mup_min = 0.0;
338  mun_max = 200.0; mup_max = 150.0;
339  nrefn = 1.0e17; nrefp = 1.0e30;
340  nun = 0.0; nup = 0.0;
341  xin = 0.0; xip = 0.0;
342  alphan = 1.0; alphap = 1.0;
343  }
344  else
345  {
346  Report::UserFatal0() << "Analytic (Caughy-Thomas) mobility model not supported for " << mater;
347  }
348 
349  // hole mobility
350  if(min.holeFlag)
351  {
352  mobil = mup_min +
353  (mup_max*pow((min.T/min.refTemp),nup) - mup_min)/
354  (1.0 + pow((min.T/min.refTemp),xip)*pow((min.N/nrefp),alphap));
355  }
356  // electron mobility
357  else
358  {
359  mobil = mun_min +
360  (mun_max*pow((min.T/min.refTemp),nun) - mun_min)/
361  (1.0 + pow((min.T/min.refTemp),xin)*pow((min.N/nrefn),alphan));
362  }
363 
364  return mobil;
365 }
366 
367 // ----------------------------------------------------------------------------
368 // Function : MaterialSupport::calcAroraMob
369 // Purpose : This function returns the mobility of electrons and
370 // holes for various materials.
371 // Special Notes :
372 //
373 // Arora, Hauser, and Roulston,
374 // "Electron and Hole Mobilities in Silicon as a Function of
375 // Concentration and Temperature," IEEE Transactions on Electron
376 // Devices, Vol. ED-29, pp.292-295, 1967.
377 //
378 // Scope : public
379 // Creator : Eric Keiter, SNL
380 // Creation Date : 10/25/12
381 // ----------------------------------------------------------------------------
382 template <typename ScalarT>
384 {
385  ExtendedString mater = min.materialName;
386  mater.toLower();
387  ScalarT mobil=0.0;
388  double mun1_aro, mup1_aro, mun2_aro, mup2_aro, an_arora, ap_arora;
389  double cn_arora, cp_arora, exn1_aro, exp1_aro, exn2_aro, exp2_aro;
390  double exn3_aro, exp3_aro, exn4_aro, exp4_aro;
391  double alphan, alphap;
392 
393  if(mater=="si") // silicon
394  {
395  mun1_aro = 88.0; mup1_aro = 54.3;
396  mun2_aro = 1252.0; mup2_aro = 407.0;
397  an_arora = 0.88; ap_arora = 0.88;
398  cn_arora = 1.26e17; cp_arora = 2.35e17;
399  exn1_aro = -0.57; exp1_aro = -0.57;
400  exn2_aro = -2.33; exp2_aro = -2.33;
401  exn3_aro = 2.4; exp3_aro = 2.4;
402  exn4_aro = -0.146; exp4_aro = -0.146;
403  }
404  else if(mater=="gaas") // gallium arsenide
405  {
406  mun1_aro = 8.5e3; mup1_aro = 4e2;
407  mun2_aro = 0.0; mup2_aro = 0.0;
408  an_arora = 0.0; ap_arora = 0.0;
409  cn_arora = 1.26e17; cp_arora = 2.35e17;
410  exn1_aro = -5.7e-1; exp1_aro = 0.0;
411  exn2_aro = 0.0; exp2_aro = 0.0;
412  exn3_aro = 0.0; exp3_aro = 0.0;
413  exn4_aro = 0.0; exp4_aro = 0.0;
414  }
415  else if(mater=="sio2") // silicon dioxide
416  {
417  mun1_aro = 1e1; mup1_aro = 1e-5;
418  mun2_aro = 2e1; mup2_aro = 2e-5;
419  an_arora = 0.88; ap_arora = 0.88;
420  cn_arora = 1.26e17; cp_arora = 2.35e17;
421  exn1_aro = -0.57; exp1_aro = -0.57;
422  exn2_aro = -2.33; exp2_aro = -2.33;
423  exn3_aro = 2.4; exp3_aro = 2.4;
424  exn4_aro = -0.146; exp4_aro = -0.146;
425  }
426  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
427  {
428  mun1_aro = 2.41e4; mup1_aro = 480.0;
429  mun2_aro = 0.0; mup2_aro = 0.0;
430  an_arora = 1.0; ap_arora = 1.0;
431  cn_arora = 1.0e20; cp_arora = 1.0e20;
432  exn1_aro = 0.0; exp1_aro = 0.0;
433  exn2_aro = 0.0; exp2_aro = 0.0;
434  exn3_aro = 0.0; exp3_aro = 0.0;
435  exn4_aro = 0.0; exp4_aro = 0.0;
436  }
437  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
438  {
439  mun1_aro = 2.73e4; mup1_aro = 480.0;
440  mun2_aro = 0.0; mup2_aro = 0.0;
441  an_arora = 1.0; ap_arora = 1.0;
442  cn_arora = 1.0e20; cp_arora = 1.0e20;
443  exn1_aro = 0.0; exp1_aro = 0.0;
444  exn2_aro = 0.0; exp2_aro = 0.0;
445  exn3_aro = 0.0; exp3_aro = 0.0;
446  exn4_aro = 0.0; exp4_aro = 0.0;
447  }
448  else if (mater=="inp")
449  {
450  mun1_aro = 2.41e4; mup1_aro = 480.0;
451  mun2_aro = 0.0; mup2_aro = 0.0;
452  an_arora = 1.0; ap_arora = 1.0;
453  cn_arora = 1.0e20; cp_arora = 1.0e20;
454  exn1_aro = 0.0; exp1_aro = 0.0;
455  exn2_aro = 0.0; exp2_aro = 0.0;
456  exn3_aro = 0.0; exp3_aro = 0.0;
457  exn4_aro = 0.0; exp4_aro = 0.0;
458  }
459  else if (mater=="ingap")
460  {
461  mun1_aro = 200.0; mup1_aro = 150.0;
462  mun2_aro = 0.0; mup2_aro = 0.0;
463  an_arora = 1.0; ap_arora = 1.0;
464  cn_arora = 1.0e20; cp_arora = 1.0e20;
465  exn1_aro = 0.0; exp1_aro = 0.0;
466  exn2_aro = 0.0; exp2_aro = 0.0;
467  exn3_aro = 0.0; exp3_aro = 0.0;
468  exn4_aro = 0.0; exp4_aro = 0.0;
469  }
470  else
471  {
472  Report::UserFatal0() << "Arora mobility model not supported for " << mater;
473  }
474 
475  alphan = an_arora*pow((min.T/min.refTemp),exn4_aro);
476  alphap = ap_arora*pow((min.T/min.refTemp),exp4_aro);
477 
478  if(min.holeFlag)
479  {
480  mobil = mup1_aro*pow((min.T/min.refTemp),exp1_aro)+
481  (mup2_aro*pow((min.T/min.refTemp),exp2_aro))/
482  (1.0+pow((min.N/cp_arora*pow((min.T/min.refTemp),exp3_aro)),alphap));
483  }
484  else
485  {
486  mobil =
487  mun1_aro*pow((min.T/min.refTemp),exn1_aro)+
488  (mun2_aro*pow((min.T/min.refTemp),exn2_aro))/
489  (1.0+pow((min.N/cn_arora*pow((min.T/min.refTemp),exn3_aro)),alphan));
490  }
491 
492  return mobil;
493 }
494 
495 // old version.
496 
497 // ----------------------------------------------------------------------------
498 // Function : MaterialSupport::calcCarrierMobOld
499 // Purpose : This function returns the mobility of electrons and
500 // holes for various materials.
501 // Special Notes :
502 //
503 // J. M. Dorkel and Ph. Leturcq, “Carrier Mobilities in Silicon Semi-
504 // Empirically Related to Temperature, Doping, and Injection Level,”
505 // Solid-State Electronics, 24, pp. 821-825, 1981.
506 //
507 // Scope : public
508 // Creator : Eric Keiter, SNL
509 // Creation Date : 10/25/12
510 // ----------------------------------------------------------------------------
511 template <typename ScalarT>
513 {
514  ExtendedString mater = min.materialName;
515  mater.toLower();
516  ScalarT mobil=0.0;
517 
518  double Al, Bl, Ai, Bi;
519  ScalarT mul, mui;
520  ScalarT muc, X;
521 
522  if(mater=="si") // silicon
523  {
524  if(min.holeFlag)
525  {
526  Al = 495.0;
527  Bl = -2.2;
528  Ai = 1.00e17;
529  Bi = 6.25e14;
530  }
531  else
532  {
533  Al = 1430.0;
534  Bl = -2.2;
535  Ai = 4.61e17;
536  Bi = 1.52e15;
537  }
538 
539  }
540  else if(mater=="gaas") // gallium arsenide
541  {
542  if(min.holeFlag)
543  {
544  Al = 4.0e2;
545  Bl = 0.0;
546  Ai = 1.00e17;
547  Bi = 6.25e14;
548  }
549  else
550  {
551  Al = 8.50e3;
552  Bl = 0.0;
553  Ai = 4.61e17;
554  Bi = 1.52e15;
555  }
556  }
557  else
558  {
559  Report::UserFatal0() << "Carrier-carrier mobility model not supported for " << mater;
560  }
561 
562  // lattice scattering term:
563  mul = Al*pow((min.T/min.refTemp),Bl);
564 
565  // impurity scattering term:
566  mui = (Ai*pow(min.T,1.5)/min.N)*(log(1.0+Bi*min.T*min.T/min.N)-
567  Bi*min.T*min.T/(min.N+Bi*min.T*min.T));
568 
569  // carrier-carrier scattering term:
570  // first, make sure n and p are kosher.
571  ScalarT N = std::fabs(min.n); if(N == 0.0) N = 1.0;
572  ScalarT P = std::fabs(min.p); if(P == 0.0) P = 1.0;
573 
574  muc = (2.0e17*pow(min.T,1.5)/std::sqrt(P*N))*
575  1.0/(log(1.0+8.28e8*min.T*min.T*pow(P*N,-1.0/3.0)));
576 
577  X = sqrt(6.0*mul*(mui+muc)/(mui*muc));
578  mobil = mul*(1.025/(1.0+pow(X/1.68,1.43))-0.025);
579 
580  if (DEBUG_DEVICE && mobil != 0.0 && !(mobil > 0.0) && !(mobil < 0.0))
581  {
582  Xyce::dout() << "mobil is nan" << std::endl;
583  Xyce::dout() << "mul = " << mul << std::endl;
584  Xyce::dout() << "mui = " << mui << std::endl;
585  Xyce::dout() << "muc = " << muc << std::endl;
586  Xyce::dout() << "X = " << X << std::endl;
587  Xyce::dout() << "T = " << min.T << std::endl;
588  Xyce::dout() << "n = " << min.n << std::endl;
589  Xyce::dout() << "p = " << min.p << std::endl;
590  }
591  return mobil;
592 }
593 
594 // new version
595 
596 // ----------------------------------------------------------------------------
597 // Function : MaterialSupport::calcCarrierMobNew
598 // Purpose : This function returns the mobility of electrons and
599 // holes for various materials.
600 //
601 // Special Notes : This function is intended to replace the old one,
602 // calcCarrierMobOld. This one matches what is in Charon and
603 // Taurus. This one also has params for more materials.
604 //
605 // J. M. Dorkel and Ph. Leturcq, “Carrier Mobilities in Silicon Semi-
606 // Empirically Related to Temperature, Doping, and Injection Level,”
607 // Solid-State Electronics, 24, pp. 821-825, 1981.
608 //
609 // Scope : public
610 // Creator : Eric Keiter, SNL
611 // Creation Date : 10/25/12
612 // ----------------------------------------------------------------------------
613 template <typename ScalarT>
615 {
616  ExtendedString mater = min.materialName;
617  mater.toLower();
618  ScalarT mobil=0.0;
619 
620  double a_ccs, b_ccs, a_lic, b_lic, c_lic;
621  double ex_lic, mun0_lat, exn_lat;
622  double an_iis, bn_iis, mup0_lat, exp_lat;
623  double ap_iis, bp_iis;
624 
625  if(mater=="si") // silicon
626  {
627  a_ccs = 1.04e21;
628  b_ccs = 7.45e13;
629  a_lic = 1.0;
630  b_lic = 2.126;
631  c_lic = 0.0;
632  ex_lic = 0.715;
633  mun0_lat = 1430.0;
634  exn_lat = 2.3;
635  an_iis = 2.4e21;
636  bn_iis = 1.37e20;
637  mup0_lat = 495.0;
638  exp_lat = 2.2;
639  ap_iis = 5.2e20;
640  bp_iis = 5.63e19;
641  }
642  else if(mater=="gaas") // gallium arsenide
643  {
644  a_ccs = 1.04e21;
645  b_ccs = 7.45e13;
646  a_lic = 1.0;
647  b_lic = 0.0;
648  c_lic = 0.0;
649  ex_lic = 0.0;
650  mun0_lat = 8.50e3;
651  exn_lat = 0.0;
652  an_iis = 2.4e21;
653  bn_iis = 1.37e20;
654  mup0_lat = 400.0;
655  exp_lat = 0.0;
656  ap_iis = 5.2e20;
657  bp_iis = 5.63e19;
658  }
659  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
660  {
661  a_ccs = 1.0e22;
662  b_ccs = 1.0e22;
663  a_lic = 1.0;
664  b_lic = 0.0;
665  c_lic = 0.0;
666  ex_lic = 0.0;
667  mun0_lat = 2.414e4;
668  exn_lat = 0.0;
669  an_iis = 1.0e22;
670  bn_iis = 1.0e22;
671  mup0_lat = 480.0;
672  exp_lat = 0.0;
673  ap_iis = 1.0e22;
674  bp_iis = 1.0e22;
675  }
676  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
677  {
678  a_ccs = 1.0e22;
679  b_ccs = 1.0e22;
680  a_lic = 1.0;
681  b_lic = 0.0;
682  c_lic = 0.0;
683  ex_lic = 0.0;
684  mun0_lat = 2.73e4;
685  exn_lat = 0.0;
686  an_iis = 1.0e22;
687  bn_iis = 1.0e22;
688  mup0_lat = 480.0;
689  exp_lat = 0.0;
690  ap_iis = 1.0e22;
691  bp_iis = 1.0e22;
692  }
693  else if (mater=="inp")
694  {
695  a_ccs = 1.0e22;
696  b_ccs = 1.0e22;
697  a_lic = 1.0;
698  b_lic = 0.0;
699  c_lic = 0.0;
700  ex_lic = 0.0;
701  mun0_lat = 2.414e4;
702  exn_lat = 0.0;
703  an_iis = 1.0e22;
704  bn_iis = 1.0e22;
705  mup0_lat = 480.0;
706  exp_lat = 0.0;
707  ap_iis = 1.0e22;
708  bp_iis = 1.0e22;
709  }
710  else if (mater=="ingap")
711  {
712  a_ccs = 1.0e22;
713  b_ccs = 1.0e22;
714  a_lic = 1.0;
715  b_lic = 0.0;
716  c_lic = 0.0;
717  ex_lic = 0.0;
718  mun0_lat = 200.0;
719  exn_lat = 0.0;
720  an_iis = 1.0e22;
721  bn_iis = 1.0e22;
722  mup0_lat = 150.0;
723  exp_lat = 0.0;
724  ap_iis = 1.0e22;
725  bp_iis = 1.0e22;
726  }
727  else
728  {
729  Report::UserFatal0() << "Carrier-carrier mobility model not supported for " << mater;
730  }
731 
732  ScalarT n_impurity = std::fabs(min.N);
733 
734  // make sure n and p are kosher.
735  ScalarT N = std::fabs(min.n); if(N == 0.0) N = 1.0;
736  ScalarT P = std::fabs(min.p); if(P == 0.0) P = 1.0;
737 
738  // Carrier-carrier scattering term
739  ScalarT muc = a_ccs*pow((min.T/min.refTemp),1.5)/std::sqrt(P*N)*
740  1.0/(log(1.0+b_ccs*pow((min.T/min.refTemp),2.0)*pow(P*N,-1.0/3.0)));
741 
742  // electron or hole
743  if(min.holeFlag)
744  {
745  // hole mobility
746  // lattice scattering term:
747  ScalarT mul_h = mup0_lat*pow((min.T/min.refTemp), -exp_lat);
748 
749  // impurity scattering term:
750  ScalarT gB_hole = bp_iis*pow((min.T/min.refTemp), 2.0)/(N+P);
751 
752  ScalarT mui_h = (ap_iis*pow((min.T/min.refTemp),1.5)/n_impurity)/
753  (log(1.0 + gB_hole) - gB_hole/(1.0 + gB_hole));
754 
755  ScalarT muic_h = 1.0/(1.0/muc + 1.0/mui_h);
756 
757  if (std::fabs(b_lic) < std::numeric_limits<double>::epsilon())
758  {
759  mobil = mul_h*(a_lic - c_lic);
760  }
761  else
762  {
763  mobil = mul_h*(a_lic/(1.0+pow(b_lic*(mul_h/muic_h),ex_lic))-c_lic);
764  }
765  }
766  else
767  {
768  // electron mobility
769  // lattice scattering term:
770  ScalarT mul_e = mun0_lat*pow((min.T/min.refTemp), -exn_lat);
771 
772  // impurity scattering term:
773  ScalarT gB_elec = bn_iis*pow((min.T/min.refTemp), 2.0)/(N+P);
774 
775  ScalarT mui_e = (an_iis*pow((min.T/min.refTemp),1.5)/n_impurity)/
776  (log(1.0 + gB_elec) - gB_elec/(1.0 + gB_elec));
777 
778  ScalarT muic_e = 1.0/(1.0/muc + 1.0/mui_e);
779 
780  if (std::fabs(b_lic) < std::numeric_limits<double>::epsilon())
781  {
782  mobil = mul_e*(a_lic - c_lic);
783  }
784  else
785  {
786  mobil = mul_e*(a_lic/(1.0+pow(b_lic*(mul_e/muic_e),ex_lic))-c_lic);
787  }
788  }
789 
790  return mobil;
791 }
792 
793 // ----------------------------------------------------------------------------
794 // Function : MaterialSupport::calcLombardiMob
795 // Purpose : This function returns the mobility of electrons and
796 // holes for various materials.
797 // Special Notes :
798 //
799 // Lombardi Surface Mobility Model --
800 // combines mobility of the semiconductor-insulator
801 // interface with bulk mobility.
802 // Reference: Lombardi, Manzini, Saporito, and Vanzi,
803 // "A physically based mobility model for numerical
804 // simulation of nonplanar devices", IEEE Trans. on
805 // Computer-Aided Design of Integrated Circuits and
806 // Systems, Nov. 1988, vol. 7, no. 11, p.1164-71./
807 //
808 // Scope : public
809 // Creator : Eric Keiter, SNL
810 // Creation Date : 10/25/12
811 // ----------------------------------------------------------------------------
812 template <typename ScalarT>
814 {
815  ExtendedString mater = min.materialName;
816  mater.toLower();
817  ScalarT mobil=0.0;
818 
819  ScalarT muac, musr;
820  ScalarT mub, mumax;
821  ScalarT mun0_lsm, mun1_lsm, mun2_lsm, crn_lsm, csn_lsm;
822  double bn_lsm, cn_lsm, dn_lsm, exn1_lsm, exn2_lsm, exn3_lsm;
823  double exn4_lsm, exn8_lsm;
824  double mup0_lsm, mup1_lsm, mup2_lsm, crp_lsm, csp_lsm;
825  double bp_lsm, cp_lsm, dp_lsm, exp1_lsm, exp2_lsm, exp3_lsm;
826  double exp4_lsm, exp8_lsm, pc_lsm;
827 
828  if(mater=="si")
829  {
830  mun0_lsm = 52.2; mup0_lsm = 44.9;
831  mun1_lsm = 43.4; mup1_lsm = 29.0;
832  mun2_lsm = 1417.0; mup2_lsm = 470.5;
833  crn_lsm = 9.68e16; crp_lsm = 2.23e17;
834  csn_lsm = 3.43e20; csp_lsm = 6.1e20;
835  bn_lsm = 4.75e7; bp_lsm = 9.93e6;
836  cn_lsm = 1.74e5; cp_lsm = 8.84e5;
837  dn_lsm = 5.82e14; dp_lsm = 2.05e14;
838  exn1_lsm = 0.680; exp1_lsm = 0.719;
839  exn2_lsm = 2.0; exp2_lsm = 2.0;
840  exn3_lsm = 2.5; exp3_lsm = 2.2;
841  exn4_lsm = 0.125; exp4_lsm = 0.0317;
842  exn8_lsm = 2.0; exp8_lsm = 2.0;
843  pc_lsm = 9.23e16;
844  }
845  else if(mater=="gaas")
846  {
847  mun0_lsm = 0.0; mup0_lsm = 0.0;
848  mun1_lsm = 0.0; mup1_lsm = 0.0;
849  mun2_lsm = 1e6; mup2_lsm = 1.0;
850  crn_lsm = 9.68e16; crp_lsm = 2.23e17;
851  csn_lsm = 0.0; csp_lsm = 0.0;
852  bn_lsm = 1e10; bp_lsm = 1e10;
853  cn_lsm = 0.0; cp_lsm = 0.0;
854  dn_lsm = 1e6; dp_lsm = 1e6;
855  exn1_lsm = 0.0; exp1_lsm = 0.0;
856  exn2_lsm = 0.0; exp2_lsm = 0.0;
857  exn3_lsm = 0.0; exp3_lsm = 0.0;
858  exn4_lsm = 0.0; exp4_lsm = 0.0;
859  exn8_lsm = 0.0; exp8_lsm = 0.0;
860  pc_lsm = 0.0;
861  }
862  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
863  {
864  mun0_lsm = 0.0; mup0_lsm = 0.0;
865  mun1_lsm = 0.0; mup1_lsm = 0.0;
866  mun2_lsm = 1.0e6; mup2_lsm = 1.0e6;
867  crn_lsm = 1.0e20; crp_lsm = 1.0e20;
868  csn_lsm = 0.0; csp_lsm = 0.0;
869  bn_lsm = 1.0e10; bp_lsm = 1.0e10;
870  cn_lsm = 0.0; cp_lsm = 0.0;
871  dn_lsm = 1.0e6; dp_lsm = 1.0e6;
872  exn1_lsm = 0.0; exp1_lsm = 0.0;
873  exn2_lsm = 0.0; exp2_lsm = 0.0;
874  exn3_lsm = 0.0; exp3_lsm = 0.0;
875  exn4_lsm = 0.0; exp4_lsm = 0.0;
876  exn8_lsm = 0.0; exp8_lsm = 0.0;
877  pc_lsm = 0.0;
878  }
879  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
880  {
881  mun0_lsm = 0.0; mup0_lsm = 0.0;
882  mun1_lsm = 0.0; mup1_lsm = 0.0;
883  mun2_lsm = 1.0e6; mup2_lsm = 1.0e6;
884  crn_lsm = 1.0e20; crp_lsm = 1.0e20;
885  csn_lsm = 0.0; csp_lsm = 0.0;
886  bn_lsm = 1.0e10; bp_lsm = 1.0e10;
887  cn_lsm = 0.0; cp_lsm = 0.0;
888  dn_lsm = 1.0e6; dp_lsm = 1.0e6;
889  exn1_lsm = 0.0; exp1_lsm = 0.0;
890  exn2_lsm = 0.0; exp2_lsm = 0.0;
891  exn3_lsm = 0.0; exp3_lsm = 0.0;
892  exn4_lsm = 0.0; exp4_lsm = 0.0;
893  exn8_lsm = 0.0; exp8_lsm = 0.0;
894  pc_lsm = 0.0;
895  }
896  else if (mater=="inp")
897  {
898  mun0_lsm = 0.0; mup0_lsm = 0.0;
899  mun1_lsm = 0.0; mup1_lsm = 0.0;
900  mun2_lsm = 1.0e6; mup2_lsm = 1.0e6;
901  crn_lsm = 1.0e20; crp_lsm = 1.0e20;
902  csn_lsm = 0.0; csp_lsm = 0.0;
903  bn_lsm = 1.0e10; bp_lsm = 1.0e10;
904  cn_lsm = 0.0; cp_lsm = 0.0;
905  dn_lsm = 1.0e6; dp_lsm = 1.0e6;
906  exn1_lsm = 0.0; exp1_lsm = 0.0;
907  exn2_lsm = 0.0; exp2_lsm = 0.0;
908  exn3_lsm = 0.0; exp3_lsm = 0.0;
909  exn4_lsm = 0.0; exp4_lsm = 0.0;
910  exn8_lsm = 0.0; exp8_lsm = 0.0;
911  pc_lsm = 0.0;
912  }
913  else if (mater=="ingap")
914  {
915  mun0_lsm = 0.0; mup0_lsm = 0.0;
916  mun1_lsm = 0.0; mup1_lsm = 0.0;
917  mun2_lsm = 1.0e6; mup2_lsm = 1.0e6;
918  crn_lsm = 1.0e20; crp_lsm = 1.0e20;
919  csn_lsm = 0.0; csp_lsm = 0.0;
920  bn_lsm = 1.0e10; bp_lsm = 1.0e10;
921  cn_lsm = 0.0; cp_lsm = 0.0;
922  dn_lsm = 1.0e6; dp_lsm = 1.0e6;
923  exn1_lsm = 0.0; exp1_lsm = 0.0;
924  exn2_lsm = 0.0; exp2_lsm = 0.0;
925  exn3_lsm = 0.0; exp3_lsm = 0.0;
926  exn4_lsm = 0.0; exp4_lsm = 0.0;
927  exn8_lsm = 0.0; exp8_lsm = 0.0;
928  pc_lsm = 0.0;
929  }
930  else
931  {
932  Report::UserFatal0() << "Lobardi surface mobility model not supported for " << mater;
933  }
934 
935  if(min.holeFlag)
936  {
937  muac = bp_lsm/min.eperp + cp_lsm*pow(min.N,exp4_lsm)/(min.T*pow(min.eperp,1.0/3.0));
938  mumax = mup2_lsm*pow((min.T/min.refTemp),-exp3_lsm);
939  mub = mup0_lsm*exp(-pc_lsm/min.N) + mumax/(1.0 + pow(min.N/crp_lsm, exp1_lsm))-
940  mup1_lsm/(1.0 + pow(csp_lsm/min.N, exp2_lsm));
941  musr = dp_lsm/pow(min.eperp, exp8_lsm);
942  }
943  else
944  {
945  muac = bn_lsm/min.eperp + cn_lsm*pow(min.N,exn4_lsm)/(min.T*pow(min.eperp,1.0/3.0));
946  mumax = mun2_lsm*pow((min.T/min.refTemp),-exn3_lsm);
947  mub = mun0_lsm + (mumax - mun0_lsm)/(1.0 + pow(min.N/crn_lsm, exn1_lsm))-
948  mun1_lsm/(1.0 + pow(csn_lsm/min.N, exn2_lsm));
949  musr = dn_lsm/pow(min.eperp, exn8_lsm);
950  }
951 
952  mobil = 1.0/(1.0/muac + 1.0/mub + 1.0/musr);
953 
954  return mobil;
955 }
956 
957 // ----------------------------------------------------------------------------
958 // Function : MaterialSupport::calcPhilipsMob
959 // Purpose : This function returns the mobility of electrons and
960 // holes for various materials.
961 // Special Notes :
962 //
963 // Philips Unified Mobility model -- references by Klaassen
964 // "A Unified Mobility Model for Device Simulation - I",
965 // Solid State Electronics, Vol. 35, pp.953-959, 1992.
966 // "A Unified Mobility Model for Device Simulation - II",
967 // Solid State Electronics, Vol. 35, pp.961-967, 1992.
968 //
969 // Scope : public
970 // Creator : Eric Keiter, SNL
971 // Creation Date : 10/25/12
972 // ----------------------------------------------------------------------------
973 template <typename ScalarT>
975 {
976  ExtendedString mater = min.materialName;
977  mater.toLower();
978  ScalarT mobil=0.0;
979 
980  double mmnn_um, mmxn_um, nrfn_um, alpn_um, tetn_um, nrfd_um, crfd_um;
981  double mmnp_um, mmxp_um, nrfp_um, alpp_um, tetp_um, nrfa_um, crfa_um;
982 
983  if(mater=="si")
984  {
985  mmnn_um = 52.2; mmnp_um = 44.9;
986  mmxn_um = 1.417e3; mmxp_um = 470.5;
987  nrfn_um = 9.68e16; nrfp_um = 2.23e17;
988  alpn_um = 0.68; alpp_um = 0.719;
989  tetn_um = 2.285; tetp_um = 2.247;
990  nrfd_um = 4.0e20; nrfa_um = 7.2e20;
991  crfd_um = 0.21; crfa_um = 0.5;
992  }
993  else if(mater=="gaas")
994  {
995  mmnn_um = 0.0; mmnp_um = 0.0;
996  mmxn_um = 8.5e3; mmxp_um = 400.0;
997  nrfn_um = 1.0e30; nrfp_um = 1.0e30;
998  alpn_um = 1.0; alpp_um = 1.0;
999  tetn_um = 0.0; tetp_um = 0.0;
1000  nrfd_um = 1.0e30; nrfa_um = 1.0e30;
1001  crfd_um = 1.0e30; crfa_um = 1.0e30;
1002  }
1003  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
1004  {
1005  mmnn_um = 0.0; mmnp_um = 0.0;
1006  mmxn_um = 2.414e4; mmxp_um = 480.0;
1007  nrfn_um = 1.0e30; nrfp_um = 1.0e30;
1008  alpn_um = 1.0; alpp_um = 1.0;
1009  tetn_um = 0.0; tetp_um = 0.0;
1010  nrfd_um = 1.0e30; nrfa_um = 1.0e30;
1011  crfd_um = 1.0e30; crfa_um = 1.0e30;
1012  }
1013  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
1014  {
1015  mmnn_um = 0.0; mmnp_um = 0.0;
1016  mmxn_um = 2.725e4; mmxp_um = 400.0;
1017  nrfn_um = 1.0e30; nrfp_um = 1.0e30;
1018  alpn_um = 1.0; alpp_um = 1.0;
1019  tetn_um = 0.0; tetp_um = 0.0;
1020  nrfd_um = 1.0e30; nrfa_um = 1.0e30;
1021  crfd_um = 1.0e30; crfa_um = 1.0e30;
1022  }
1023  else if (mater=="inp")
1024  {
1025  mmnn_um = 0.0; mmnp_um = 0.0;
1026  mmxn_um = 2.414e4; mmxp_um = 480.0;
1027  nrfn_um = 1.0e30; nrfp_um = 1.0e30;
1028  alpn_um = 1.0; alpp_um = 1.0;
1029  tetn_um = 0.0; tetp_um = 0.0;
1030  nrfd_um = 1.0e30; nrfa_um = 1.0e30;
1031  crfd_um = 1.0e30; crfa_um = 1.0e30;
1032  }
1033  else if (mater=="ingap")
1034  {
1035  mmnn_um = 0.0; mmnp_um = 0.0;
1036  mmxn_um = 200.0; mmxp_um = 150.0;
1037  nrfn_um = 1.0e30; nrfp_um = 1.0e30;
1038  alpn_um = 1.0; alpp_um = 1.0;
1039  tetn_um = 0.0; tetp_um = 0.0;
1040  nrfd_um = 1.0e30; nrfa_um = 1.0e30;
1041  crfd_um = 1.0e30; crfa_um = 1.0e30;
1042  }
1043  else
1044  {
1045  Report::UserFatal0() << "Philips mobility model not supported for " << mater;
1046  }
1047 
1048  double me_mo = 1.0;
1049  double mh_mo = 1.258;
1050  ScalarT Nd_doping = min.Nd;
1051  ScalarT Na_doping = min.Na;
1052  ScalarT n_dens = min.n;
1053  ScalarT p_dens = min.p;
1054 
1055  if (Nd_doping <= 1.0 ) Nd_doping = 1.0;
1056  if (Na_doping <= 1.0 ) Na_doping = 1.0;
1057  if (n_dens <= 1.0 ) n_dens = 1.0;
1058  if (p_dens <= 1.0 ) p_dens = 1.0;
1059 
1060  ScalarT Ndeff = Nd_doping * ( 1.0 + 1.0/(crfd_um + pow(nrfd_um/Nd_doping,2.0)));
1061  ScalarT Naeff = Na_doping * ( 1.0 + 1.0/(crfa_um + pow(nrfa_um/Na_doping,2.0)));
1062 
1063  double vsat = 2.4e7/(1.0+0.8*exp(min.T/600.0));
1064  if(min.holeFlag)
1065  {
1066  //hole mobility
1067  double Tps = min.T/min.refTemp;
1068  ScalarT Nscp = Ndeff + Naeff + n_dens;
1069  ScalarT Pp = Tps*Tps * (1.0/( 2.459/(3.97e13*pow(Nscp,-2.0/3.0))
1070  + 3.828/(1.36e20/(n_dens+p_dens)*mh_mo) ));
1071 
1072  // Initial values Pnmin is the Pmin value for 300 K.
1073  // Initial values of FPnmin and dFPnmin are chosen to start the loop.
1074  ScalarT Ppmin = 0.2891;
1075  ScalarT FPpmin = 1.0;
1076  ScalarT dFPpmin = 1.0;
1077  // minimizing GPp here
1078  while( (FPpmin > 0.00001) || (FPpmin < -0.00001) )
1079  {
1080  FPpmin = 1.0 - (0.89233/pow(0.41372+Ppmin*pow(1.0/mh_mo*Tps,0.28227),0.19778))
1081  + (0.005978/pow(Ppmin*pow(mh_mo/Tps,0.72169),1.80618));
1082 
1083  dFPpmin = -0.89233*(-0.19778)*
1084  pow(0.41372+Ppmin*pow(1.0/mh_mo*Tps,0.28227),-1.19778)*
1085  pow(1.0/mh_mo*Tps,0.28227) +
1086  0.005978*(-1.80618)*
1087  pow(Ppmin*pow(mh_mo/Tps,0.72169),-2.80618)*
1088  pow(mh_mo/Tps,0.72169);
1089 
1090  Ppmin = Ppmin - FPpmin/dFPpmin;
1091  }
1092 
1093  ScalarT FPp = (0.7643*pow(Pp,0.6478) + 2.2999 + 6.5502*mh_mo/me_mo)
1094  /(pow(Pp,0.6478) + 2.3670 - 0.8552*mh_mo/me_mo);
1095 
1096  ScalarT GPp = 1.0 - (0.89233/pow(0.41372+Pp*pow(1.0/mh_mo*Tps,0.28227),0.19778))
1097  + (0.005978/pow(Pp*pow(mh_mo/Tps,0.72169),1.80618));
1098 
1099  if (Pp < Ppmin)
1100  {
1101  GPp = 1.0 - (0.89233/pow(0.41372+Ppmin*pow(1.0/mh_mo*Tps,0.28227),0.19778))
1102  + (0.005978/pow(Ppmin*pow(mh_mo/Tps,0.72169),1.80618));
1103  }
1104 
1105  ScalarT Nsceffp = Ndeff*GPp + Naeff + n_dens/FPp;
1106  ScalarT mulattp = mmxp_um * pow(Tps,-tetp_um);
1107 
1108  ScalarT mu1p = mmxp_um*mmxp_um/(mmxp_um-mmnp_um)*pow(Tps,3.0*alpp_um-1.5);
1109  ScalarT mu2p = mmxp_um*mmnp_um/(mmxp_um-mmnp_um)*pow(Tps,-0.5);
1110 
1111  ScalarT muDAn = mu1p*(Nscp/Nsceffp)*pow(nrfp_um/Nscp,alpp_um)
1112  + mu2p*(n_dens+p_dens)/Nsceffp;
1113 
1114  mobil = 1.0/(1.0/mulattp+1.0/muDAn);
1115  }
1116  else
1117  {
1118  //electron mobility
1119  double Tns = min.T/min.refTemp;
1120  ScalarT Nscn = Ndeff + Naeff + p_dens;
1121  ScalarT Pn = Tns*Tns * (1.0/(2.459/(3.97e13*pow(Nscn,-2.0/3.0))
1122  + 3.828/(1.36e20/(n_dens+p_dens)*me_mo)));
1123 
1124  // Initial values Pnmin is the Pmin value for 300 K.
1125  // Initial values of FPnmin and dFPnmin are chosen to start the loop.
1126  ScalarT Pnmin = 0.3246;
1127  ScalarT FPnmin = 1.0;
1128  ScalarT dFPnmin = 1.0;
1129  // minimizing GPn here
1130  while( (FPnmin > 0.00001) || (FPnmin < -0.00001) )
1131  {
1132  FPnmin = 1.0 - (0.89233/pow(0.41372+Pnmin*pow(1.0/me_mo*Tns,0.28227),0.19778))
1133  + (0.005978/pow(Pnmin*pow(me_mo/Tns,0.72169),1.80618));
1134 
1135  dFPnmin = -0.89233*(-0.19778)*
1136  pow(0.41372+Pnmin*pow(1.0/me_mo*Tns,0.28227),-1.19778)*
1137  pow(1.0/me_mo*Tns,0.28227) +
1138  0.005978*(-1.80618)*
1139  pow(Pnmin*pow(me_mo/Tns,0.72169),-2.80618)*
1140  pow(me_mo/Tns,0.72169);
1141 
1142  Pnmin = Pnmin - FPnmin/dFPnmin;
1143  }
1144 
1145  ScalarT FPn = (0.7643*pow(Pn,0.6478) + 2.2999 + 6.5502*me_mo/mh_mo)
1146  /(pow(Pn,0.6478) + 2.3670 - 0.8552*me_mo/mh_mo);
1147 
1148  ScalarT GPn = 1.0 - (0.89233/pow(0.41372+Pn*pow(1.0/me_mo*Tns,0.28227),0.19778))
1149  + (0.005978/pow(Pn*pow(me_mo/Tns,0.72169),1.80618));
1150 
1151  if (Pn < Pnmin)
1152  {
1153  GPn = 1.0 - (0.89233/pow(0.41372+Pnmin*pow(1.0/me_mo*Tns,0.28227),0.19778))
1154  + (0.005978/pow(Pnmin*pow(me_mo/Tns,0.72169),1.80618));
1155  }
1156 
1157  ScalarT Nsceffn = Ndeff + Naeff*GPn + p_dens/FPn;
1158  ScalarT mulattn = mmxn_um * pow(Tns,-tetn_um);
1159  ScalarT mu1n = mmxn_um*mmxn_um/(mmxn_um-mmnn_um)*pow(Tns,3.0*alpn_um-1.5);
1160  ScalarT mu2n = mmxn_um*mmnn_um/(mmxn_um-mmnn_um)*pow(Tns,-0.5);
1161 
1162  ScalarT muDAp = mu1n*(Nscn/Nsceffn)*pow(nrfn_um/Nscn,alpn_um)
1163  + mu2n*(n_dens+p_dens)/Nsceffn;
1164 
1165  mobil = 1.0/(1.0/mulattn+1.0/muDAp);
1166  }
1167 
1168  return mobil;
1169 }
1170 
1171 // ----------------------------------------------------------------------------
1172 // Function : MaterialSupport::calcIIIVMob
1173 // Purpose : This function returns the mobility of electrons and
1174 // holes for III-V materials.
1175 // Special Notes :
1176 // This mobility model comes from Wampler, Myers SAND report
1177 // for GaaS clusters. I'm not sure of the reference, so
1178 // calling it IIIV for now.
1179 //
1180 //
1181 // Scope : public
1182 // Creator : Lawrence C Musson, SNL
1183 // Creation Date : 06/27/2014
1184 // ----------------------------------------------------------------------------
1185 template <typename ScalarT>
1187 {
1188  ExtendedString mater = min.materialName;
1189  mater.toLower();
1190  ScalarT mobil=0.0;
1191 
1192  double hole0FieldMob,electron0FieldMob;
1193  double fieldSat,electronVSat,holeVSat;
1194 
1195  if(mater=="si")
1196  {
1197  //need data
1198  }
1199  else if(mater=="gaas")
1200  {
1201  hole0FieldMob = 30.0;
1202  electron0FieldMob = 2240.0;
1203  fieldSat = 4000.0;
1204  electronVSat = 7.7e6;
1205  holeVSat = 7.7e6;
1206  }
1207  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
1208  {
1209  //need data
1210  }
1211  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
1212  {
1213  //need data
1214  }
1215  else if (mater=="inp")
1216  {
1217  //need data
1218  }
1219  else if (mater=="ingap")
1220  {
1221  //need data
1222  }
1223  else
1224  {
1225  Report::UserFatal0() << "III-V mobility model not supported for " << mater;
1226  }
1227 
1228  if(min.holeFlag)
1229  {
1230  //hole mobility
1231 
1232  ScalarT ratio = hole0FieldMob*abs(min.epar)/holeVSat;
1233 
1234  mobil = hole0FieldMob/(1.0+ratio);
1235  }
1236  else
1237  {
1238  //electron mobility
1239 
1240  ScalarT fieldRatio = pow(pow(abs(min.epar),0.75)/fieldSat,4.0);
1241 
1242  ScalarT vfRatio = electronVSat;
1243 
1244  ScalarT eMobNumerator = electron0FieldMob + vfRatio*fieldRatio;
1245 
1246  ScalarT eMobDenominator = 1.0 + abs(min.epar)*fieldRatio;
1247 
1248  mobil = eMobNumerator/eMobDenominator;
1249  }
1250 
1251  return mobil;
1252 }
1253 
1254 // ----------------------------------------------------------------------------
1255 // Function : MaterialSupport::applyHighFieldMobilityModel
1256 // Purpose : modifies a computed mobility to include high field effects.
1257 //
1258 // Special Notes : There are two possible approximations applied.
1259 //
1260 // (1) Caughy-Thomas approximation.
1261 // D.M. Caughey and R.E. Thomas
1262 // "Carrier Mobilities in Silicon Empirically Related to
1263 // Doping and Field", Proc. IEEE, Vol 55, pp. 2192-2193, 1967.
1264 //
1265 // mu = mu0/(1.0 + mu0*E/vsat)
1266 //
1267 // (2) Barnes approximation. This one is ONLY applied to III-V
1268 // materials, and ONLY to electrons, not holes. For electrons in
1269 // GaAs and other III-V materials, the velocity-field characteristic
1270 // has a peak and then falls off. That gives rise to the negative
1271 // differential resistance. The Barnes expression encapsulates that behavior.
1272 //
1273 // Barnes, J J and Lomax, R J and Haddad, G I
1274 // "Finite-element simulation of GaAs MESFET's with lateral
1275 // doping profiles and submicron gates"
1276 // IEEE Transactions on Electron Devices, vol. 23, number 9,
1277 // pp. 1042-1048, Sept., 1976
1278 //
1279 // mu = (mu0+(vsat/E)*(E/E0)^4)/(1.0 + (E/E0)^4)
1280 //
1281 // Scope : public
1282 // Creator : Eric Keiter, SNL
1283 // Creation Date : 10/26/12
1284 // ----------------------------------------------------------------------------
1285 template <typename ScalarT>
1287 (MobInfo<ScalarT> & min, ScalarT & mobil)
1288 {
1289  ScalarT mob0 = mobil;
1290 
1291  ExtendedString mater = min.materialName;
1292  mater.toLower();
1293 
1294  double vsatn, betan, eon, vsatp, betan_ha, betap, eop, betap_ha, vsn_x1, vsn_x2;
1295  double en_x1, en_x2;
1296 
1297  if(mater=="si")
1298  {
1299  vsatn = 1.035e7; betan = 2.0; eon = 4000.0;
1300  vsatp = 1.035e7; betan_ha = 2.0; betap = 1.0;
1301  eop = 4000.0; betap_ha = 2.0; vsn_x1 = 0.0;
1302  vsn_x2 = 0.0; en_x1 = 0.0; en_x2 = 0.0;
1303 
1304  // Caughy-Thomas for both carriers
1305  if(min.holeFlag)
1306  {
1307  mobil = mob0/ (1.0 + mob0*min.epar/vsatp);
1308  }
1309  else
1310  {
1311  mobil = mob0/ (1.0 + mob0*min.epar/vsatn);
1312  }
1313  }
1314  else if(mater=="ge") // germanium
1315  {
1316  vsatn = 1.035e7; betan = 2.0; eon = 4000.0;
1317  vsatp = 1.035e7; betan_ha = 2.0; betap = 1.0;
1318  eop = 4000.0; betap_ha = 2.0; vsn_x1 = 0.0;
1319  vsn_x2 = 0.0; en_x1 = 0.0; en_x2 = 0.0;
1320 
1321  // Caughy-Thomas for both carriers
1322  if(min.holeFlag)
1323  {
1324  mobil = mob0/ (1.0 + mob0*min.epar/vsatp);
1325  }
1326  else
1327  {
1328  mobil = mob0/ (1.0 + mob0*min.epar/vsatn);
1329  }
1330  }
1331  else if(mater=="gaas") // gallium arsenide
1332  {
1333  vsatn = 7.7e6; betan = 1.0; eon = 4000.0;
1334  vsatp = 7.7e6; betan_ha = 2.0; betap = 1.0;
1335  eop = 4000.0; betap_ha = 2.0; vsn_x1 = 0.0;
1336  vsn_x2 = 0.0; en_x1 = 0.0; en_x2 = 0.0;
1337 
1338  if(min.holeFlag) // Caughy-Thomas
1339  {
1340  mobil = mob0/ (1.0 + mob0*min.epar/vsatp);
1341  }
1342  else // Barnes for e-
1343  {
1344  mobil = (mob0 + (vsatn/min.epar)*pow((min.epar/eon),4.0))/
1345  (1.0 + pow((min.epar/eon),4.0));
1346  }
1347  }
1348  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
1349  {
1350  vsatn = 4.70e+06; betan = 1.0; eon = 8.40e+03;
1351  vsatp = 3.00e+6; betan_ha = 2.0; betap = 1.0;
1352  eop = 8.40e+03; betap_ha = 2.0; vsn_x1 = -0.7493;
1353  vsn_x2 = 0.0; en_x1 = 4.169; en_x2 = 0.0;
1354 
1355  if(min.holeFlag) // Caughy-Thomas
1356  {
1357  mobil = mob0/ (1.0 + mob0*min.epar/vsatp);
1358  }
1359  else // Barnes for e-
1360  {
1361  mobil = (mob0 + (vsatn/min.epar)*pow((min.epar/eon),4.0))/
1362  (1.0 + pow((min.epar/eon),4.0));
1363  }
1364  }
1365  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
1366  {
1367  vsatn = 8.40e+06; betan = 1.0; eon = 5.07e+03;
1368  vsatp = 4.80e+06; betan_ha = 2.0; betap = 1.0;
1369  eop = 5.07e+03; betap_ha = 2.0; vsn_x1 = -1.019;
1370  vsn_x2 = 0.709; en_x1 = -0.7956; en_x2 = 0.63;
1371 
1372  if(min.holeFlag) // Caughy-Thomas
1373  {
1374  mobil = mob0/ (1.0 + mob0*min.epar/vsatp);
1375  }
1376  else // Barnes for e-
1377  {
1378  mobil = (mob0 + (vsatn/min.epar)*pow((min.epar/eon),4.0))/
1379  (1.0 + pow((min.epar/eon),4.0));
1380  }
1381  }
1382  else if (mater=="inp")
1383  {
1384  vsatn = 1.3e+07; betan = 1.0; eon = 1.06e+04;
1385  vsatp = 6.6e6; betan_ha = 2.0; betap = 1.0;
1386  eop = 1.06e+04; betap_ha = 2.0; vsn_x1 = -0.332;
1387  vsn_x2 = 0.0; en_x1 = 5.883; en_x2 = 0.0;
1388 
1389  if(min.holeFlag) // Caughy-Thomas
1390  {
1391  mobil = mob0/ (1.0 + mob0*min.epar/vsatp);
1392  }
1393  else // Barnes for e-
1394  {
1395  mobil = (mob0 + (vsatn/min.epar)*pow((min.epar/eon),4.0))/
1396  (1.0 + pow((min.epar/eon),4.0));
1397  }
1398  }
1399  else if (mater=="ingap")
1400  {
1401  vsatn = 7.7e6; betan = 1.0; eon = 4000.0;
1402  vsatp = 7.7e6; betan_ha = 2.0; betap = 1.0;
1403  eop = 4000.0; betap_ha = 2.0; vsn_x1 = -0.0341;
1404  vsn_x2 = 0.0; en_x1 = 1.533; en_x2 = 0.0;
1405 
1406  if(min.holeFlag) // Caughy-Thomas
1407  {
1408  mobil = mob0/ (1.0 + mob0*min.epar/vsatp);
1409  }
1410  else // Barnes for e-
1411  {
1412  mobil = (mob0 + (vsatn/min.epar)*pow((min.epar/eon),4.0))/
1413  (1.0 + pow((min.epar/eon),4.0));
1414  }
1415  }
1416  else
1417  {
1418  mobil = mob0; // just ignore in this case. Code can still run.
1419  }
1420 }
1421 
1422 } // namespace MaterialSupport
1423 } // namespace Device
1424 } // namespace Xyce
1425 
1426 #endif
ScalarT calcAroraMob(MobInfo< ScalarT > &min)
double getNi_old(const std::string &material, double temp)
double get_DOS_EffectiveMassP(const std::string &material)
#define CONSTREFTEMP
Definition: N_DEV_Const.h:56
ScalarT calcCarrierMobNew(MobInfo< ScalarT > &min)
Pure virtual class to augment a linear system.
ScalarT calcCarrierMobOld(MobInfo< ScalarT > &min)
double getEffectiveMassP(const std::string &material)
double pdRaugN(const std::string &material, double ni, double n, double p)
void applyHighFieldMobilityModel(MobInfo< ScalarT > &min, ScalarT &mobil)
double getCarrierThermalVelocity(const std::string &material, const std::string &carrier)
double getNc(const std::string &material, double temp)
double calcRaug(const std::string &material, double ni, double n, double p)
double getRelPerm(const std::string &material)
double workfunc(std::string &metal)
double bandgap(const std::string &material, double temp)
double bennetWilsonEbgn(const std::string &material, double dope, bool ntype)
double Ebgn(const std::string &material, const std::string &bgnModel, double dope, bool ntype)
ScalarT calcAnalyticMob(MobInfo< ScalarT > &min)
ScalarT calcIIIVMob(MobInfo< ScalarT > &min)
double getEffectiveMassN(const std::string &material)
double calcRsrh(const std::string &material, double ni, double n, double p, double tn, double tp)
double slotboomEbgn(const std::string &material, double dope, bool ntype)
double calcLt(bool holeFlag, double conc, std::string material="si")
ScalarT calcLombardiMob(MobInfo< ScalarT > &min)
double pdRsrhN(const std::string &material, double ni, double n, double p, double tn, double tp)
double pdRaugP(const std::string &material, double ni, double n, double p)
double jain3Ebgn(const std::string &material, double dope, bool ntype)
double jain2Ebgn(const std::string &material, double dope, bool ntype)
double jainEbgn(const std::string &material, double dope, bool ntype)
double affin(const std::string &material)
ScalarT calcPhilipsMob(MobInfo< ScalarT > &min)
ScalarT calcMob(MobInfo< ScalarT > &min)
double getNv(const std::string &material, double temp)
double getNi(const std::string &material, double temp)
double pdRsrhP(const std::string &material, double ni, double n, double p, double tn, double tp)
double get_DOS_EffectiveMassN(const std::string &material)