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