Esempio n. 1
0
def resistivity(mat, Na, Ea, Nd, Ed, T):
    """Вычисляет сопротивление по концентрациям в функции irwin написано тоже самое но *немного* оптимальнее"""
    A = mat.mobility_const_a
    B = mat.mobility_const_b
    sem = DopedSemiconductor(mat.semiconductor, Na, Ea, Nd, Ed)
    return 1 / conductivity(0, 0, sem.p_concentration(T=T),
                            mobility(sem, T, A, B))
Esempio n. 2
0
def conductivity(mat, type, Na, Ea, Nd, Ed, T):
    """Вычисляет проводимость по концентрациям в функции"""
    a = mat.mobility_const_a
    b = mat.mobility_const_b
    sem = DopedSemiconductor(mat.semiconductor, Na, Ea, Nd, Ed)
    n = sem.p_concentration(T=T) if type == 'p' else sem.n_concentration(T=T)
    mob = mobility(sem, T, a, b)
    return models.conductivity(n, mob)
Esempio n. 3
0
 def test_intrinsic_concentrations(self):
     mat = DopedSemiconductor(Si, 1e15, 0, 1e17, Si.Eg)  # random parameters
     self.assertAlmostEqual(Si.n_concentration(),
                            Si.p_concentration(),
                            delta=1e7)
     self.assertAlmostEqual(Si.n_concentration(),
                            Si.i_concentration(),
                            delta=1e7)
     self.assertAlmostEqual(mat.i_concentration(),
                            Si.i_concentration(),
                            delta=1e7)
Esempio n. 4
0
def irwin(mat, Ea, Nd, Ed, T, Nas):
    """
    То же что и выше но бес постоянного создания объектов (хотя это совсем не критично)
    Мне даже больше нравится первый вариант
    """
    A = mat.mobility_const_a
    B = mat.mobility_const_b
    sem = DopedSemiconductor(mat.semiconductor, -1, Ea, Nd, Ed)
    res = []
    for na in Nas:
        sem.Na = na
        cond = conductivity(0, 0, sem.p_concentration(T=T),
                            mobility(sem, T, A, B))
        res.append(1 / cond)
    return np.array(res)
Esempio n. 5
0
 def test_full_depletion_width(self):
     # The parameters are selected to comply with the condition delta_phi = 0.5 volt
     c = MSJunction(Metal(4.65 * eV),
                    DopedSemiconductor(Si, 0, 0, 1e17, Si.Eg))
     self.assertAlmostEqual(c.delta_phi() / volt, 0.5, delta=0.001)
     self.assertAlmostEqual(c.full_depletion_width() / unit('nm'),
                            81,
                            delta=1)
Esempio n. 6
0
 def test_contact_type(self):
     with self.assertRaises(NotImplementedError):
         c = MSJunction(Metal(4.1 * eV), Si)
         c.contact_type()
     # Al -- p-Si
     c = MSJunction(Metal(4.1 * eV),
                    DopedSemiconductor(Si, 1e17, 0.045 * eV, 0, Si.Eg))
     self.assertEqual(c.contact_type(), ContactType.INVERSION)
     # Pt -- n-Si
     c = MSJunction(Metal(5.2 * eV),
                    DopedSemiconductor(Si, 0, 0, 1e18, Si.Eg))
     self.assertEqual(c.contact_type(), ContactType.INVERSION)
     # Cs -- n-Si
     c = MSJunction(Metal(2.14 * eV),
                    DopedSemiconductor(Si, 0, 0, 1e18, Si.Eg))
     self.assertEqual(c.contact_type(), ContactType.AUGMENTATION)
     # Imaginary -- p-Si
     c = MSJunction(Metal(4.8 * eV),
                    DopedSemiconductor(Si, 1e17, 0.045 * eV, 0, Si.Eg))
     self.assertEqual(c.contact_type(), ContactType.DEPLETION)
Esempio n. 7
0
    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)
Esempio n. 8
0
 def test_schottky_barrier(self):
     c = MSJunction(Metal(4.1 * eV),
                    DopedSemiconductor(Si, 1e18, 0.045 * eV, 0, Si.Eg))
     self.assertAlmostEqual(c.schottky_barrier() / volt, 0.05, delta=0.001)
Esempio n. 9
0
import matplotlib.pyplot as plt
import numpy as np

from fompy.constants import eV
from fompy.materials import Si
from fompy.models import DopedSemiconductor

if __name__ == '__main__':
    mat1 = DopedSemiconductor(Si, 1e18, 0.045 * eV, 1e20, Si.Eg - 0.045 * eV)
    mat2 = DopedSemiconductor(Si, 0, 0.045 * eV, 1e15, Si.Eg - 0.045 * eV)
    mat3 = DopedSemiconductor(Si, 1e20, 0.4 * eV, 1e20, Si.Eg - 0.4 * eV)
    mat4 = DopedSemiconductor(Si, 2e20, 0.045 * eV, 0, Si.Eg)
    min_e = -0.1 * Si.Eg
    max_e = 1.1 * 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)
    ys4 = func(mat4, 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.plot(xs / eV, ys4, 'y', label='4')

    plt.title('Charge carrier imbalance')
    plt.xlabel('$E_f, eV$')
    plt.ylabel(r'$\Delta N$')
    plt.axvline(x=0)
    plt.axvline(x=Si.Eg / eV)
Esempio n. 10
0
 def test_intrinsic_fermi_level(self):
     mat = DopedSemiconductor(Si, 1e15, 0, 1e17, Si.Eg)  # random parameters
     self.assertAlmostEqual(mat.intrinsic_fermi_level(),
                            0.57 * eV,
                            delta=0.01 * eV)
     self.assertEqual(mat.intrinsic_fermi_level(), Si.fermi_level())
Esempio n. 11
0
 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)
Esempio n. 12
0
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)
Esempio n. 13
0
    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)
Esempio n. 14
0
 def test_debye_length(self):
     c = MSJunction(Metal(4.1 * eV),
                    DopedSemiconductor(Si, 0, 0, 1e18, Si.Eg))
     self.assertAlmostEqual(c.debye_length() / unit('nm'), 4.4, delta=0.1)
Esempio n. 15
0
        plt.plot(line.xs, line.ys, line.description.style)


def complete_plot():
    plt.legend()
    plt.xscale('log')
    plt.yscale('log')
    plt.show()


descriptions = {
    'Si_n':
    FileDescription(
        'Si electrons (Si_n)', ['3', '4'], {
            '1':
            LineDescription(DopedSemiconductor(Si, 0, 0, 1e12, Si.Eg), 'k',
                            '1'),
            '2':
            LineDescription(DopedSemiconductor(Si, 0, 0, 1e13, Si.Eg), 'r',
                            '2'),
            '3':
            LineDescription(DopedSemiconductor(Si, 1.48e15, 0, 1.75e16, Si.Eg),
                            'g', '3'),
            '4':
            LineDescription(DopedSemiconductor(Si, 2.2e15, 0, 1.3e17, Si.Eg),
                            'b', '4'),
        }),
    'Si_p':
    FileDescription(
        'Si holes (Si_p)', ['3', '4'], {
            '1':
Esempio n. 16
0
 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)
Esempio n. 17
0
 def test_delta_phi(self):
     c = MSJunction(Metal(4.1 * eV),
                    DopedSemiconductor(Si, 1e18, 0.045 * eV, 0, Si.Eg))
     self.assertAlmostEqual(c.delta_phi(300),
                            -0.98 * volt,
                            delta=0.1 * volt)
Esempio n. 18
0

def handle_two(l1, l2, title):
    start_plot(lines, title)
    mean_ps = fit_two_curves(l1, l2)
    print_params(mean_ps, title)

    handle_line(l1, mean_ps)
    handle_line(l2, mean_ps)
    complete_plot()


if __name__ == '__main__':
    print('=== electrons ===')
    desc = [
        ('1', DopedSemiconductor(Si, 0, 0, 1e12, Si.Eg), 'k', '1'),
        ('2', DopedSemiconductor(Si, 0, 0, 1e13, Si.Eg), 'r', '2'),
        ('3', DopedSemiconductor(Si, 1.48e15, 0, 1.75e16, Si.Eg), 'g', '3'),
        ('4', DopedSemiconductor(Si, 2.2e15, 0, 1.3e17, Si.Eg), 'b', '4'),
    ]

    lines = get_lines('../data/Si_n/mobility.csv', desc)
    handle_independent(lines, 'Константы вчсиляются для каждой кривой')
    print('==========')
    handle_two(lines[2], lines[3], 'Константы усреднены для кривых 3 и 4')

    print('=== holes ===')
    desc = [
        ('1', DopedSemiconductor(Si, 1e12, 0, 0, Si.Eg), 'k', '1'),
        ('2', DopedSemiconductor(Si, 1e14, 0, 0, Si.Eg), 'r', '2'),
        ('3', DopedSemiconductor(Si, 2.4e16, 0, 2.3e15, Si.Eg), 'g', '3'),
Esempio n. 19
0
import numpy as np

from fompy.constants import eV
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')