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