def test_degenerate_fermi_level(self): mat = DopedSemiconductor(Si, 1e21, 0.045 * eV, 0, Si.Eg) self.assertAlmostEqual(mat.fermi_level() / eV, -0.04, delta=0.001) # Note the negative value mat = DopedSemiconductor(Si, 10, 0, 1e20, Si.Eg - 0.045 * eV) self.assertAlmostEqual(mat.fermi_level() / eV, 1.142, delta=0.001)
class TestDopedSemiconductor(unittest.TestCase): def setUp(self): self.mat_a = DopedSemiconductor(Si, 1e18, 0.045 * eV, 0, 0) self.mat_d = DopedSemiconductor(Si, 0, 0, 1e18, Si.Eg - 0.045 * eV) def test_n_acceptor(self): self.assertAlmostEqual(self.mat_a.n_acceptor_concentration(0.04 * eV), 4.5e17, delta=1e16) self.assertAlmostEqual(self.mat_a.n_acceptor_concentration(0.04 * eV, T=200), 4.2e17, delta=1e16) def test_p_donor(self): self.assertAlmostEqual(self.mat_d.p_donor_concentration(Si.Eg - 0.04 * eV), 4.5e17, delta=1e17) self.assertAlmostEqual(self.mat_d.p_donor_concentration(Si.Eg - 0.04 * eV, T=200), 4.2e17, delta=1e17) def test_fermi_level(self): self.assertAlmostEqual(self.mat_a.fermi_level(T=200), 0.047 * eV, delta=0.001 * eV) self.assertAlmostEqual(self.mat_d.fermi_level(T=200), Si.Eg - 0.035 * eV, delta=0.001 * eV) def test_conductivity_type(self): with self.assertRaises(ValueError): self.mat_a.conductivity_type(T=300, Ef=1 * eV) self.assertEqual(self.mat_a.conductivity_type(), 'p') self.assertEqual(self.mat_d.conductivity_type(), 'n') def test_from_materials(self): # КДБ-100 res = DopedSemiconductor.from_materials( Si, from_unit(500, 'cm^2 / V s'), # Mobility for holes 'B', from_unit(100, 'Ohm cm')) self.assertEqual(res.Nd, 0) self.assertAlmostEqual(res.Na, 1.2e14, delta=0.1e14) # КЭМ-100 res = DopedSemiconductor.from_materials( Si, from_unit(1500, 'cm^2 / V s'), # Mobility for electrons 'As', from_unit(100, 'Ohm cm')) self.assertEqual(res.Na, 0) self.assertAlmostEqual(res.Nd, 4.1e13, delta=0.1e13) with self.assertRaises(KeyError): DopedSemiconductor.from_materials(Si, 1, 'UNKNOWN', 1)
def test_issue_11(self): # Should not raise OverflowError m = DopedSemiconductor(Si, 1e12, 0, 0, Si.Eg) m.fermi_level(T=11) self.assertEqual(functions.fermi(Si.Eg, 0, 11), 0)
from fompy.materials import Si from fompy.models import DopedSemiconductor if __name__ == '__main__': # Хотя материалы 1 и 2 имеют разные концентрации и донорные уровни, # разницы между концентрациями доноров и акцепторов одинаковы. # Поэтому кривые дисбаланса, а следовательно и уровни ферми, почти совпадают. # При совпадении донорных уровней уровни ферми становятся еще ближе. # Для вырожденного полупроводника это приближение уже не работает. # Это связанно с тем что интеграл Ферми-Дирака не обладает # основным функциональным свойством экспоненты exp(a+b) = exp(a)*exp(b). # А в выровжденном мы как раз больше не можем приближать интеграл Ферми-Дирака экспонентой. mat1 = DopedSemiconductor(Si, 2e17, 0.045 * eV, 1e17, Si.Eg - 0.045 * eV) mat2 = DopedSemiconductor(Si, 1e17, 0, 0, Si.Eg) mat3 = DopedSemiconductor(Si, 2e17, 0.045 * eV, 0, Si.Eg - 0.045 * eV) print('E_f_1 =', mat1.fermi_level() / eV, 'eV') print('E_f_2 =', mat2.fermi_level() / eV, 'eV') min_e = 0.1 * Si.Eg max_e = 0.9 * Si.Eg xs = np.linspace(min_e, max_e, 1000) func = np.vectorize(DopedSemiconductor._charge_imbalance) ys1 = func(mat1, xs, T=300) ys2 = func(mat2, xs, T=300) ys3 = func(mat3, xs, T=300) plt.plot(xs / eV, ys1, 'r', label='1') plt.plot(xs / eV, ys2, 'g', label='2') plt.plot(xs / eV, ys3, 'b', label='3') plt.title('Charge carrier imbalance') plt.xlabel('$E_f, eV$')