Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_MaterialSupport.C
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 //
8 // Xyce(TM) Parallel Electrical Simulator
9 // Copyright (C) 2002-2014 Sandia Corporation
10 //
11 // This program is free software: you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation, either version 3 of the License, or
14 // (at your option) any later version.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //-----------------------------------------------------------------------------
24 
25 //-------------------------------------------------------------------------
26 // Filename : $RCSfile: N_DEV_MaterialSupport.C,v $
27 //
28 // Purpose :
29 //
30 // Special Notes :
31 //
32 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
33 //
34 // Creation Date : 07/19/03
35 //
36 // Revision Information:
37 // ---------------------
38 //
39 // Revision Number: $Revision: 1.29 $
40 //
41 // Revision Date : $Date: 2014/02/24 23:49:18 $
42 //
43 // Current Owner : $Author: tvrusso $
44 //-------------------------------------------------------------------------
45 
46 #include <Xyce_config.h>
47 
48 
49 // ---------- Standard Includes ----------
50 #ifdef HAVE_CMATH
51 #include <cmath>
52 #else
53 #include <math.h>
54 #endif
55 
56 #ifdef Xyce_DEBUG_DEVICE
57 #include <iostream>
58 #endif
59 
60 // ---------- Xyce Includes ----------
61 #include <N_DEV_MaterialSupport.h>
62 
63 namespace Xyce {
64 namespace Device {
65 
66 //-----------------------------------------------------------------------------
67 // Function : MaterialSupport::MaterialSupport
68 // Purpose : constructor.
69 // Special Notes :
70 // Scope : public
71 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
72 // Creation Date : 07/19/03
73 //-----------------------------------------------------------------------------
75 {
76 
77 }
78 
79 //-----------------------------------------------------------------------------
80 // Function : MaterialSupport::~MaterialSupport
81 // Purpose : constructor.
82 // Special Notes :
83 // Scope : public
84 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
85 // Creation Date : 07/19/03
86 //-----------------------------------------------------------------------------
88 {
89 
90 }
91 
92 //-----------------------------------------------------------------------------
93 // Function : MaterialSupport::MaterialSupport
94 // Purpose : copy constructor.
95 // Special Notes :
96 // Scope : public
97 // Creator : Eric Keiter, SNL, Parallel Computational Sciences
98 // Creation Date : 04/01/03
99 //-----------------------------------------------------------------------------
101  (const MaterialSupport & right)
102 {
103 
104 }
105 
106 // ----------------------------------------------------------------------------
107 // Function : MaterialSupport::getEffectiveMassN
108 // Purpose : returns effective mass for electrons.
109 // Special Notes : Relative to free space mass.
110 //
111 // These are from Appendix 3 of Streetman.
112 //
113 // Scope : public
114 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
115 // Creation Date : 7/19/03
116 // ----------------------------------------------------------------------------
117 double MaterialSupport::getEffectiveMassN (const std::string & material)
118 {
119  ExtendedString mater = material;
120  mater.toLower();
121 
122  double mass=0.0;
123 
124  if (mater == "si")
125  {
126  mass = pow((0.98*0.19*0.19),1.0/3.0); // longitudinal mass = 0.98
127  // transverse mass = 0.19
128  }
129  else if (mater == "ge" )
130  {
131  mass = pow((1.64*0.082*0.082),1.0/3.0); // long. mass = 1.64
132  // trans. mass = 0.082
133  }
134  else if (mater == "gaas")
135  {
136  mass = 0.067;
137  }
138  // don't have these yet, but what is really needed is the DOS mass, which
139  // I do have (see the DOS functions, below)
140  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
141  {
142  }
143  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
144  {
145  }
146  else if (mater == "inp")
147  {
148  }
149  else
150  {
151  Report::UserFatal0() << material << " material not recognized.";
152  }
153 
154  return mass;
155 }
156 
157 // ----------------------------------------------------------------------------
158 // Function : MaterialSupport::getEffectiveMassP
159 // Purpose : returns effective mass for holes.
160 // Special Notes : Relative to free space mass.
161 //
162 // These are from Appendix 3 of Streetman.
163 //
164 // Scope : public
165 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
166 // Creation Date : 7/19/03
167 // ----------------------------------------------------------------------------
168 double MaterialSupport::getEffectiveMassP (const std::string & material)
169 {
170  ExtendedString mater = material;
171  mater.toLower();
172  double mass=0.0;
173 
174  if (mater == "si")
175  {
176  double mlh = 0.16; // light hole mass
177  double mhh = 0.49; // heavy hole mass
178  mass = pow((pow(mlh,1.5) + pow(mhh,1.5)),2.0/3.0);
179  }
180  else if (mater == "ge" )
181  {
182  double mlh = 0.04; // light hole mass
183  double mhh = 0.28; // heavy hole mass
184  mass = pow((pow(mlh, 1.5) + pow(mhh, 1.5)),2.0/3.0);
185  }
186  else if (mater == "gaas")
187  {
188  double mlh = 0.074; // light hole mass
189  double mhh = 0.5; // heavy hole mass
190  mass = pow((pow(mlh,1.5) + pow(mhh, 1.5)), 2.0/3.0);
191  }
192  // don't have these yet, but what is really needed is the DOS mass, which
193  // I do have (see the DOS functions, below)
194  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
195  {
196  double mlh = 0.08; // light hole mass
197  double mhh = 0.6; // heavy hole mass
198  mass = pow((pow(mlh,1.5) + pow(mhh, 1.5)), 2.0/3.0);
199  }
200  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
201  {
202  double mlh = 0.05; // light hole mass
203  double mhh = 0.54; // heavy hole mass
204  mass = pow((pow(mlh,1.5) + pow(mhh, 1.5)), 2.0/3.0);
205  }
206  else if (mater == "inp")
207  {
208  double mlh = 0.074; // light hole mass
209  double mhh = 0.5; // heavy hole mass
210  mass = pow((pow(mlh,1.5) + pow(mhh, 1.5)), 2.0/3.0);
211  }
212  else
213  {
214  Report::UserFatal0() << material << " material not recognized.";
215  }
216 
217  return mass;
218 }
219 
220 // ----------------------------------------------------------------------------
221 // Function : MaterialSupport::getDOSEffectiveMassN
222 // Purpose : returns effective mass for electrons for density of states
223 // Special Notes :
224 //
225 // Scope : public
226 // Creator : Eric R. Keiter, SNL
227 // Creation Date :
228 // ----------------------------------------------------------------------------
229 double MaterialSupport::getDOSEffectiveMassN (const std::string & material)
230 {
231  ExtendedString mater = material;
232  mater.toLower();
233  double mass = getEffectiveMassN (mater);
234  double Mc = 1.0;
235 
236  if (mater == "si")
237  {
238  Mc = pow(6.0,2.0/3.0);
239  }
240  else if (mater == "gaas")
241  {
242  Mc = 1.0;
243  }
244  else if (mater == "ge")
245  {
246  Mc = 2.0;
247  }
248  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
249  {
250  mass = 0.074;
251  Mc = 1.0;
252  }
253  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
254  {
255  mass = 0.041;
256  Mc = 1.0;
257  }
258  else if (mater == "inp")
259  {
260  mass = 0.079;
261  Mc = 1.0;
262  }
263  else
264  {
265  Report::UserFatal0() << material << " material not recognized.";
266  }
267 
268  mass *= Mc;
269  return mass;
270 }
271 
272 // ----------------------------------------------------------------------------
273 // Function : MaterialSupport::getDOSEffectiveMassP
274 // Purpose : returns effective mass for holes for density of states
275 // Special Notes :
276 //
277 // Scope : public
278 // Creator : Eric R. Keiter, SNL
279 // Creation Date :
280 // ----------------------------------------------------------------------------
281 double MaterialSupport::getDOSEffectiveMassP (const std::string & material)
282 {
283  ExtendedString mater = material;
284  mater.toLower();
285  double mass = getEffectiveMassP (mater);
286 
287  // Mc is not applied to holes.
288 #if 0
289  double Mc = 1.0;
290  if (mater == "si")
291  {
292  Mc = pow(6.0,(2.0/3.0));
293  }
294  else if (mater == "gaas")
295  {
296  Mc = 1.0;
297  }
298  else if (mater == "ge")
299  {
300  Mc = pow(2.0,(4.0/3.0));
301  }
302  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
303  {
304  mass = 0.62;
305  Mc = 1.0;
306  }
307  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
308  {
309  mass = 0.55;
310  Mc = 1.0;
311  }
312  else if (mater == "inp")
313  {
314  mass = 0.72;
315  Mc = 1.0;
316  }
317  else
318  {
319  Report::UserFatal0() << material << " material not recognized.";
320  }
321 
322  mass *= Mc;
323 #endif
324 
325  return mass;
326 }
327 
328 // ----------------------------------------------------------------------------
329 // Function : MaterialSupport::getNi
330 // Purpose : returns intrinsic electron concentration.
331 // Special Notes :
332 // Scope : public
333 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
334 // Creation Date : 10/24/12
335 // ----------------------------------------------------------------------------
336 double MaterialSupport::getNi (const std::string & material, double temp)
337 {
338  ExtendedString mater = material;
339  mater.toLower();
340  double ni=0.0;
341 
342  double charge(1.602176565e-19);
343  double h_planck(6.62606957e-34); // Planck's constant (in J-s)
344  double e_mass (9.10938291e-31); // e- mass in kg.
345  double kb (1.3806488e-23); // boltzmann's constant (J/K)
346  double kbq = 8.6173324e-5; // boltzmann's constant (eV/K)
347  double dnbnd0 = 2.0*M_PI*e_mass*kb*temp/(h_planck*h_planck);
348  dnbnd0 = 2.0*pow(dnbnd0,1.5)/1.0e6;
349 
350  double bg = bandgap(mater,temp);
351 
352  double mnDOS = getDOSEffectiveMassN(mater);
353  double mpDOS = getDOSEffectiveMassP(mater);
354  double Nc = dnbnd0 * pow(mnDOS,1.50);
355  double Nv = dnbnd0 * pow(mpDOS,1.50);
356  ni = sqrt (Nc * Nv) * exp(-bg/(2.0 * kbq * temp));
357 
358 #ifdef Xyce_DEBUG_DEVICE
359  Xyce::dout() << "mnDOS = " <<mnDOS <<std::endl;
360  Xyce::dout() << "mpDOS = " <<mpDOS <<std::endl;
361  Xyce::dout() << "dnbnd0 = " << dnbnd0 <<std::endl;
362  Xyce::dout() << "Nc = " << Nc <<std::endl;
363  Xyce::dout() << "Nv = " << Nv <<std::endl;
364  Xyce::dout() << "Ni = " << ni <<std::endl;
365 #endif
366  return ni;
367 }
368 
369 // ----------------------------------------------------------------------------
370 // Function : MaterialSupport::getNi_old
371 // Purpose : returns intrinsic electron concentration.
372 // Special Notes :
373 // Scope : public
374 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
375 // Creation Date : 7/19/03
376 // ----------------------------------------------------------------------------
377 double MaterialSupport::getNi_old (const std::string & material, double temp)
378 {
379  ExtendedString mater = material;
380  mater.toLower();
381  double ni=0.0;
382 
383  if (mater == "si")
384  {
385  ni = 4.9e15
386  * pow(getEffectiveMassN(mater)*getEffectiveMassP(mater),0.75)
387  * pow(6.0,0.5) * pow(temp, 1.5) * exp(-bandgap(mater,temp)/
388  (2.0 * 8.6174e-5 * temp));
389  // ni = 1.25e10;
390  }
391  else if (mater == "gaas")
392  {
393  ni = 4.9e15
394  * pow(getEffectiveMassN(mater)*getEffectiveMassP(mater),0.75)
395  * pow(temp, 1.5) * exp(-bandgap(mater,temp)/
396  (2.0 * 8.6174e-5 * temp));
397  //ni = 2.0e6;
398  }
399  else if (mater == "ge")
400  {
401  ni = 4.9e15
402  * pow(getEffectiveMassN(mater)*getEffectiveMassP(mater),0.75)
403  * 2.0 * pow(temp, 1.5) * exp(-bandgap(mater,temp)/
404  (2.0 * 8.6174e-5 * temp));
405  // ni = 2.5e13;
406  }
407  // for the next several, as they are all III-V materials, I copied the
408  // gaas functions. I *think* this is correct, as I *think* that Mc is
409  // going to be 1.0 for all of these.
410  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
411  {
412  ni = 4.9e15
413  * pow(getEffectiveMassN(mater)*getEffectiveMassP(mater),0.75)
414  * pow(temp, 1.5) * exp(-bandgap(mater,temp)/
415  (2.0 * 8.6174e-5 * temp));
416  }
417  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
418  {
419  ni = 4.9e15
420  * pow(getEffectiveMassN(mater)*getEffectiveMassP(mater),0.75)
421  * pow(temp, 1.5) * exp(-bandgap(mater,temp)/
422  (2.0 * 8.6174e-5 * temp));
423  }
424  else if (mater == "inp")
425  {
426  ni = 4.9e15
427  * pow(getEffectiveMassN(mater)*getEffectiveMassP(mater),0.75)
428  * pow(temp, 1.5) * exp(-bandgap(mater,temp)/
429  (2.0 * 8.6174e-5 * temp));
430  }
431  else
432  {
433  std::string msg = "MaterialSupport::getNi: ";
434  msg += material;
435  msg += " material not recognized.\n";
436  N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL_0,msg);
437  }
438 
439  return ni;
440 }
441 
442 // ----------------------------------------------------------------------------
443 // Function : MaterialSupport::getRelPerm
444 // Purpose : returns relative permitivity
445 // Special Notes :
446 // Scope : public
447 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
448 // Creation Date : 7/19/03
449 // ----------------------------------------------------------------------------
450 double MaterialSupport::getRelPerm (const std::string & material)
451 {
452  ExtendedString mater = material;
453  mater.toLower();
454 
455  double perm;
456  if (mater == "si")
457  {
458  perm = 11.8;
459  }
460  else if (mater == "sio2")
461  {
462  perm = 3.9;
463  }
464  else if (mater == "ge" )
465  {
466  perm = 16.0;
467  }
468  else if (mater == "gaas")
469  {
470  perm = 13.2;
471  }
472  else if (mater=="inalas" || mater=="alinas") // indium aluminum arsenide
473  {
474  perm = 12.5;
475  }
476  else if (mater=="ingaas" || mater=="gainas") // indium galium arsenide
477  {
478  perm = 14.0;
479  }
480  else if (mater == "inp")
481  {
482  perm = 12.6;
483  }
484  else
485  {
486  Report::UserFatal0() << material << " material not recognized.";
487  }
488 
489  return perm;
490 }
491 
492 // ----------------------------------------------------------------------------
493 // Function : MaterialSupport::calcRsrh
494 // Purpose : Calculates schockley-read-hall recombination.
495 //
496 // Special Notes : For this function, it shouldn't matter if the variables
497 // are scaled or not.
498 //
499 // The material dependence here comes indirectly, from the
500 // lifetimes, the carrier densities, and Ni, the intrinsic
501 // concentration.
502 //
503 // Scope : public
504 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
505 // Creation Date : 6/27/03
506 // ----------------------------------------------------------------------------
508  (const std::string & material, double ni, double n, double p, double tn, double tp)
509 {
510  double Ni = ni;
511  double pn = Ni*Ni;
512 
513  double A = (n*p-pn);
514  double B = (tp*(n+Ni)+tn*(p+Ni));
515 
516  double arg = CONSTMAX_EXP_ARG;
517  if (B >= exp(arg)) B = exp(arg);
518 
519  return (A/B);
520 }
521 
522 // ----------------------------------------------------------------------------
523 // Function : MaterialSupport::pdRsrhN
524 // Purpose : Calculates partial derivatives for schockley-read-hall
525 // recombination, with respect to electron density.
526 //
527 // Special Notes : For this function, it shouldn't matter if the variables
528 // are scaled or not.
529 //
530 // The material dependence here comes indirectly, from the
531 // lifetimes, the carrier densities, and Ni, the intrinsic
532 // concentration.
533 //
534 // Scope : public
535 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
536 // Creation Date : 7/19/03
537 // ----------------------------------------------------------------------------
539  (const std::string & material, double ni, double n, double p, double tn, double tp)
540 {
541  double Ni = ni;
542  double pdRsrhN;
543  double A1, B1, C1;
544  double dAdn;
545  double dBdn;
546 
547  double pn = Ni*Ni;
548 
549  double arg = CONSTMAX_EXP_ARG;
550 
551  A1 = (n*p-pn);
552  if (A1 >= exp(arg)) A1 = exp(arg);
553 
554  dAdn = (p);
555 
556  C1 = (tp*(n+Ni)+tn*(p+Ni));
557  if (C1 >= exp(arg)) C1 = exp(arg);
558 
559  B1 = 1.0/C1;
560  dBdn = -1.0/(C1*C1) * tp;
561 
562  pdRsrhN = dAdn * B1 + dBdn * A1;
563 
564  return pdRsrhN;
565 }
566 
567 // ----------------------------------------------------------------------------
568 // Function : MaterialSupport::pdRsrhP
569 // Purpose : Calculates partial derivatives for schockley-read-hall
570 // recombination, with respect to hole density.
571 //
572 // Special Notes : For this function, it shouldn't matter if the variables
573 // are scaled or not.
574 //
575 // The material dependence here comes indirectly, from the
576 // lifetimes, the carrier densities, and Ni, the intrinsic
577 // concentration.
578 //
579 // Scope : public
580 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
581 // Creation Date : 7/19/03
582 // ----------------------------------------------------------------------------
584  (const std::string & material, double ni, double n, double p, double tn, double tp)
585 {
586  double Ni = ni;
587  double pdRsrhP;
588  double A1, B1, C1;
589  double dAdp;
590  double dBdp;
591 
592  double pn = Ni*Ni;
593 
594  double arg = CONSTMAX_EXP_ARG;
595 
596  A1 = (n*p-pn);
597  if (A1 >= exp(arg)) A1 = exp(arg);
598 
599  dAdp = (n);
600 
601  C1 = (tp*(n+Ni)+tn*(p+Ni));
602  if (C1 >= exp(arg)) C1 = exp(arg);
603 
604  B1 = 1.0/C1;
605  dBdp = -1.0/(C1*C1) * tn;
606 
607  pdRsrhP = dAdp * B1 + dBdp * A1;
608 
609  return pdRsrhP;
610 }
611 
612 
613 // ----------------------------------------------------------------------------
614 // Function : MaterialSupport::calcRaug
615 // Purpose : Calculates Auger recombination.
616 //
617 // Special Notes : For this function, it shouldn't matter if the variables
618 // are scaled or not.
619 //
620 // I believe (but am not sure) that the constants Cn and Cp
621 // are material dependent. That is part of why the
622 // material name is passed in as an argument. The values
623 // here are for Si.
624 //
625 // Scope : public
626 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
627 // Creation Date : 6/27/03
628 // ----------------------------------------------------------------------------
630  (const std::string & material, double ni, double n, double p)
631 {
632  double Ni = ni;
633  double Cn = 2.8e-31;
634  double Cp = 1.2e-31;
635  double pn = Ni*Ni;
636 
637  double A = (n*p-pn);
638  double C = (Cn*n+Cp*p);
639 
640  double arg = CONSTMAX_EXP_ARG;
641  if (C >= exp(arg)) C = exp(arg);
642 
643  return (A*C);
644 }
645 
646 // ----------------------------------------------------------------------------
647 // Function : MaterialSupport::pdRaugN
648 // Purpose : Calculates partial derivative w.r.t. electron density
649 // for Auger recombination.
650 //
651 // Special Notes : For this function, it shouldn't matter if the variables
652 // are scaled or not.
653 //
654 // I believe (but am not sure) that the constants Cn and Cp
655 // are material dependent. That is part of why the
656 // material name is passed in as an argument. The values
657 // here are for Si.
658 //
659 // Scope : public
660 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
661 // Creation Date : 7/19/03
662 // ----------------------------------------------------------------------------
664  (const std::string & material, double ni, double n, double p)
665 {
666  double Ni = ni;
667  double pdRaugN;
668  double A1, B1;
669  double dAdn;
670  double dBdn;
671 
672  double Cn = 2.8e-31;
673  double Cp = 1.2e-31;
674  double pn = Ni*Ni;
675  double arg = CONSTMAX_EXP_ARG;
676 
677  A1 = (n*p-pn);
678  if (A1 >= exp(arg)) A1 = exp(arg);
679 
680  dAdn = (p);
681 
682  B1 = (Cn*n+Cp*p);
683  if (B1 >= exp(arg)) B1 = exp(arg);
684 
685  dBdn = Cn;
686 
687  pdRaugN = dAdn*B1 + A1*dBdn;
688 
689  return pdRaugN;
690 }
691 
692 // ----------------------------------------------------------------------------
693 // Function : MaterialSupport::pdRaugP
694 // Purpose : Calculates partial derivative w.r.t. hole density
695 // for Auger recombination.
696 //
697 // Special Notes : For this function, it shouldn't matter if the variables
698 // are scaled or not.
699 //
700 // I believe (but am not sure) that the constants Cn and Cp
701 // are material dependent. That is part of why the
702 // material name is passed in as an argument. The values
703 // here are for Si.
704 //
705 // Scope : public
706 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
707 // Creation Date : 7/19/03
708 // ----------------------------------------------------------------------------
710  (const std::string & material, double ni, double n, double p)
711 {
712  double Ni = ni;
713  double pdRaugP;
714  double A1, B1;
715  double dAdp;
716  double dBdp;
717 
718  double Cn = 2.8e-31;
719  double Cp = 1.2e-31;
720  double pn = Ni*Ni;
721  double arg = CONSTMAX_EXP_ARG;
722 
723  A1 = (n*p-pn);
724  if (A1 >= exp(arg)) A1 = exp(arg);
725 
726  dAdp = (n);
727 
728  B1 = (Cn*n+Cp*p);
729  if (B1 >= exp(arg)) B1 = exp(arg);
730 
731  dBdp = Cp;
732 
733  pdRaugP = dAdp*B1 + A1*dBdp;
734 
735  return pdRaugP;
736 }
737 
738 //----------------------------------------------------------------------------
739 // Function : MaterialSupport::workfunc
740 // Purpose : This function returns the workfunction
741 // of various metals
742 //
743 // Special Notes :
744 //
745 // Scope : public
746 // Creator : Deborah Fixel, SNL, Parallel Computational Sciences
747 // Creation Date : 7/15/03
748 //----------------------------------------------------------------------------
749 double MaterialSupport::workfunc(std::string & metal)
750 {
751  double wkfunc=0.0;
752 
753  ExtendedString metalName = metal;
754  metalName.toLower ();
755 
756  if (metalName=="al")
757  {
758  wkfunc = 4.10; //aluminum
759  }
760  else if (metalName=="ppoly")
761  {
762  wkfunc = 5.25; // p+-polysilicon
763  }
764  else if (metalName=="npoly")
765  {
766  wkfunc = 4.17; // n+-polysilicon
767  }
768  else if (metalName=="mo")
769  {
770  wkfunc = 4.53; // molybdenum
771  }
772  else if (metalName=="w")
773  {
774  wkfunc = 4.63; // tungsten
775  }
776  else if (metalName=="modi")
777  {
778  wkfunc = 4.80; // molybdenum disilicide
779  }
780  else if (metalName=="wdi")
781  {
782  wkfunc = 4.80; // tungsten disilicide
783  }
784  else if (metalName=="cu")
785  {
786  wkfunc = 4.25; // copper
787  }
788  else if (metalName=="pt")
789  {
790  wkfunc = 5.30; // platinum
791  }
792  else if (metalName=="au")
793  {
794  wkfunc = 4.80; // gold
795  }
796  else if (metalName=="neutral")
797  {
798  wkfunc = 0.0;
799  }
800  else
801  {
802  Report::UserFatal0() << metalName << " material not recognized.";
803  }
804 
805  return wkfunc;
806 }
807 //----------------------------------------------------------------------------
808 // Function : MaterialSupport::affin
809 // Purpose : This function returns the electron affinity
810 // of various semiconductor materials
811 //
812 // Special Notes :
813 //
814 // Scope : public
815 // Creator : Deborah Fixel, SNL, Parallel Computational Sciences
816 // Creation Date : 7/15/03
817 //---------------------------------------------------------------------------
818 double MaterialSupport::affin(const std::string & material)
819 {
820 
821  double afty=0.0;
822 
823  ExtendedString materialName = material;
824  materialName.toLower();
825 
826  if (materialName=="si")
827  {
828  afty = 4.17; // silicon
829  }
830  else if (materialName=="ge")
831  {
832  afty = 4.00; // germanium
833  }
834  else if (materialName=="gaas")
835  {
836  afty = 4.07; // gallium arsenide
837  }
838  else if (materialName=="sio2")
839  {
840  afty = 0.97; // silicon dioxide
841  }
842  else if (materialName=="nitride")
843  {
844  afty = 0.97; // silicon nitride
845  }
846  else if (materialName=="sapphire")
847  {
848  afty = 0.97; // sapphire (also known as aluminum oxide)
849  }
850  else
851  {
852  Report::UserError0() << materialName << " material not recognized.";
853  }
854 
855  return afty;
856 }
857 //----------------------------------------------------------------------------
858 // Function : MaterialSupport::bandgap
859 // Purpose : This function returns the electronic bandgap
860 // of various semiconductor materials.
861 //
862 // Special Notes : Reference for temperature-dependent semiconductor
863 // materials is "The Standard Thermodynamic Function
864 // of the Formation of Electrons and Holes in Ge, Si,
865 // GaAs, and GaP," by C. D. Thurmond, J. Electrochem. Soc.,
866 // vol. 122, p. 1133, 1975.
867 //
868 // Scope : public
869 // Creator : Deborah Fixel, SNL, Parallel Computational Sciences
870 // Creation Date : 7/18/03
871 //---------------------------------------------------------------------------
872 double MaterialSupport::bandgap(const std::string & material, double temp)
873 {
874  double gap = 0.0;
875  ExtendedString materialName = material;
876  materialName.toLower();
877 
878  if (materialName=="si") // silicon
879  {
880  gap = 1.17 - 4.73e-4*pow(temp,2.0)/(temp + 636.0);
881  }
882  else if (materialName=="ge") // germanium
883  {
884  gap = 0.7437 - 4.774e-4*pow(temp,2.0)/(temp + 235);
885  }
886  else if (materialName=="gaas") // gallium arsenide
887  {
888  gap = 1.519 - 5.405e-4*pow(temp,2.0)/(temp + 204);
889  }
890  else if (materialName=="sio2") // silicon dioxide
891  {
892  gap = 9.00;
893  }
894  else if (materialName=="nitride") // silicon nitride
895  {
896  gap = 4.7;
897  }
898  else if (materialName=="sapphire") // sapphire
899  {
900  gap = 4.7;
901  }
902  else if (materialName=="inalas" || materialName=="alinas") // indium aluminum arsenide
903  {
904  double con = 1.46;
905  double val = 0.0;
906  gap = con-val;
907  }
908  else if (materialName=="ingaas" || materialName=="gainas") // indium galium arsenide
909  {
910  double con = 0.96;
911  double val = 0.21;
912  gap = con-val;
913  }
914  else if (materialName=="inp") // indium phosphide
915  {
916  double con = 1.21;
917  double val = -0.14;
918  gap = con-val;
919  }
920  else
921  {
922  Report::UserError0() << materialName << " material not recognized.";
923  }
924 
925  return gap;
926 }
927 // ----------------------------------------------------------------------------
928 // Function : MaterialSupport::calcLt
929 // Purpose : This function calculates carrier lifetimes.
930 //
931 // Special Notes : holeFlag parameter indicates electrons or holes:
932 // holeFlag = true -> holes
933 // holeFlag = false -> electrons
934 //
935 // This function assumes that conc is an absolute value.
936 //
937 // This function comes from this paper:
938 //
939 // "Analysis of High-Efficiency Silicon Solar Cells",
940 // IEEE Transactions on Electron Devices, by Harry T.
941 // Weaver and R. D. Nasby, vol. ED-28, no. 5, May 1981.
942 //
943 // This is a function that probably should have some material dependence,
944 // but at the moment it doesn't. I think all the values in this function
945 // are for Si.
946 //
947 // Scope : public
948 // Creator : Eric R. Keiter, SNL, Parallel Computational Sciences
949 // Creation Date : 6/20/03
950 // ----------------------------------------------------------------------------
951 double MaterialSupport::calcLt (bool holeFlag, double conc)
952 {
953  double lt = 0.0;
954  double LT0, Nref;
955 
956  conc = fabs(conc);
957 
958  if (holeFlag)
959  {
960  LT0 = 3.52e-5;
961  Nref = 7.1e15;
962  lt = LT0 / (1.0 + conc / Nref);
963  }
964  else
965  {
966  LT0 = 3.95e-4;
967  Nref = 7.1e15;
968  lt = LT0 / (1.0 + conc / Nref);
969  }
970  return lt;
971 }
972 
973 } // namespace Device
974 } // namespace Xyce