def test_calculate_absorption_profile_rcwa():
    import numpy as np

    from solcore import material, si
    from solcore.structure import Layer, Structure
    from solcore.absorption_calculator.rigorous_coupled_wave import calculate_rat_rcwa, calculate_absorption_profile_rcwa

    T = 300
    Air = material("Air")(T=T)
    TiO2 = material("TiO2", sopra=True)(T=T)  # for the nanoparticles
    GaAs = material("GaAs")(T=T)
    th = 50
    NP_layer = Layer(
        si(th, "nm"),
        Air,
        geometry=[{
            "type": "ellipse",
            "mat": TiO2,
            "center": (200, 200),
            "halfwidths": [70, 100],
            "angle": 30
        }],
    )
    np_struct = Structure([NP_layer])
    wl = np.linspace(300, 1000, 10)

    rat_np = calculate_rat_rcwa(np_struct,
                                size=((400, 0), (0, 400)),
                                orders=10,
                                wavelength=wl,
                                substrate=GaAs,
                                incidence=Air)

    A_output = rat_np['A_pol']
    step_size = 2
    dist = np.arange(0, th, step_size)
    result = calculate_absorption_profile_rcwa(np_struct,
                                               size=((400, 0), (0, 400)),
                                               orders=10,
                                               wavelength=wl,
                                               rat_output_A=A_output,
                                               steps_size=step_size)

    parallel_result = calculate_absorption_profile_rcwa(np_struct,
                                                        size=((400, 0), (0,
                                                                         400)),
                                                        orders=10,
                                                        wavelength=wl,
                                                        rat_output_A=A_output,
                                                        parallel=True,
                                                        steps_size=step_size)

    assert sorted(list(result.keys())) == ["absorption", "position"]
    assert sorted(list(parallel_result.keys())) == ["absorption", "position"]

    assert len(result["position"]) == len(dist)
    assert len(parallel_result["position"]) == len(dist)

    assert result["absorption"] == approx(parallel_result["absorption"],
                                          abs=1e-5)
Example #2
0
def test_TMM_ellipsometry():
    GaAs = material("GaAs")(T=300)

    my_structure = Structure(
        [Layer(si(3000, "nm"), material=GaAs), Layer(si(300, "um"), material=GaAs)]
    )

    wavelength = np.linspace(450, 1100, 300)
    idx = np.argmin(abs(wavelength - 800))

    angles = [60, 65, 70]
    out = calculate_ellipsometry(my_structure, wavelength, angle=angles)

    data = (
        22.2849089096,
        181.488417672,
        16.4604621886,
        182.277656469,
        9.10132195668,
        184.509752582,
    )

    for i in range(len(angles)):
        assert data[2 * i] == approx(out["psi"][idx, i])
        assert data[2 * i + 1] == approx(out["Delta"][idx, i])
Example #3
0
    def test_64_quantum_mechanics_schrodinger(self):
        bulk = material("GaAs")(T=293)
        barrier = material("GaAsP")(T=293, P=0.1)

        bulk.strained = False
        barrier.strained = True

        top_layer = Layer(width=si("30nm"), material=bulk)
        inter = Layer(width=si("3nm"), material=bulk)
        barrier_layer = Layer(width=si("15nm"), material=barrier)
        bottom_layer = top_layer

        E = np.linspace(1.15, 1.5, 300) * q
        alfas = np.zeros((len(E), 6))

        alfas[:, 0] = E / q

        alpha_params = {
            "well_width": si("7.2nm"),
            "theta": 0,
            "eps": 12.9 * vacuum_permittivity,
            "espace": E,
            "hwhm": si("6meV"),
            "dimensionality": 0.16,
            "line_shape": "Gauss"
        }

        QW = material("InGaAs")(T=293, In=0.2)
        QW.strained = True
        well_layer = Layer(width=si("7.2nm"), material=QW)

        my_structure = Structure(
            [top_layer, barrier_layer, inter] +
            1 * [well_layer, inter, barrier_layer, inter] + [bottom_layer],
            substrate=bulk)

        band_edge, bands = QM.schrodinger(my_structure,
                                          quasiconfined=0,
                                          num_eigenvalues=20,
                                          alpha_params=alpha_params,
                                          calculate_absorption=True)

        for key in band_edge['E']:
            for i in range(len(band_edge['E'][key])):
                band_edge['E'][key][i] = solcore.asUnit(
                    band_edge['E'][key][i], 'eV') * 1000
                band_edge['E'][key][i] = round(band_edge['E'][key][i])

        Ehh = np.all(np.equal(band_edge['E']['Ehh'], my_energies['Ehh']))
        Elh = np.all(np.equal(band_edge['E']['Elh'], my_energies['Elh']))
        Ee = np.all(np.equal(band_edge['E']['Ee'], my_energies['Ee']))

        idx = 100
        out = [band_edge['alpha'][0][idx] / q, band_edge['alpha'][1][idx]]

        # Test over the energies
        self.assertTrue(Ehh and Elh and Ee)
        # Test over the absorption coefficent at a given energy
        for i, data in enumerate(out):
            self.assertAlmostEqual(out[i], my_absorption[i])
Example #4
0
def test_TMM_rat():
    GaAs = material("GaAs")(T=300)

    my_structure = Structure([Layer(si(3000, "nm"), material=GaAs)])

    wavelength = np.linspace(450, 1100, 300)
    idx = np.argmin(abs(wavelength - 800))

    out = calculate_rat(
        my_structure, wavelength, coherent=True, no_back_reflexion=False
    )
    out = (out["R"][idx], out["A"][idx], out["T"][idx])

    data = (0.33328918841743332, 0.65996607786373396, 0.0067447337188326914)

    assert all([d == approx(o) for d, o in zip(data, out)])
def test_TMM_absorption_profile():
    GaAs = material("GaAs")(T=300)

    my_structure = Structure([
        Layer(si(3000, "nm"), material=GaAs),
        Layer(si(300, "um"), material=GaAs)
    ])

    out = calculate_absorption_profile(my_structure,
                                       np.array([800]),
                                       z_limit=3000,
                                       steps_size=20)

    data_path = Path(__file__).parent / "data" / "absorption_profile.txt"
    data = tuple(np.loadtxt(data_path))

    assert all([d == approx(o) for d, o in zip(data, out["absorption"][0])])
Example #6
0
    def test_44_TMM_ellipsometry(self):
        GaAs = material('GaAs')(T=300)

        my_structure = Structure([
            Layer(si(3000, 'nm'), material=GaAs),
            Layer(si(300, 'um'), material=GaAs),
        ])

        wavelength = np.linspace(450, 1100, 300)
        idx = np.argmin(abs(wavelength - 800))

        angles = [60, 65, 70]
        out = calculate_ellipsometry(my_structure, wavelength, angle=angles)

        data = (22.2849089096, 181.488417672, 16.4604621886, 182.277656469,
                9.10132195668, 184.509752582)

        for i in range(len(angles)):
            self.assertAlmostEqual(data[2 * i], out['psi'][idx, i])
            self.assertAlmostEqual(data[2 * i + 1], out['Delta'][idx, i])
Example #7
0
    def test_42_TMM_rat(self):
        GaAs = material('GaAs')(T=300)

        my_structure = Structure([
            Layer(si(3000, 'nm'), material=GaAs),
        ])

        wavelength = np.linspace(450, 1100, 300)
        idx = np.argmin(abs(wavelength - 800))

        out = calculate_rat(my_structure,
                            wavelength,
                            coherent=True,
                            no_back_reflexion=False)
        out = (out['R'][idx], out['A'][idx], out['T'][idx])

        data = (0.33328918841743332, 0.65996607786373396,
                0.0067447337188326914)

        for i in range(3):
            self.assertAlmostEqual(data[i], out[i])
Example #8
0
def test_calculate_rat_rcwa():
    import numpy as np

    from solcore import material, si
    from solcore.structure import Layer, Structure
    from solcore.absorption_calculator.rigorous_coupled_wave import calculate_rat_rcwa

    T = 300
    Air = material("Air")(T=T)
    TiO2 = material("TiO2", sopra=True)(T=T)  # for the nanoparticles
    GaAs = material("GaAs")(T=T)

    NP_layer = Layer(
        si("50nm"),
        Air,
        geometry=[{
            "type": "circle",
            "mat": TiO2,
            "center": (200, 200),
            "radius": 50
        }],
    )
    np_struct = Structure([NP_layer])
    wl = np.linspace(300, 1000, 150)

    rat_np = calculate_rat_rcwa(np_struct,
                                size=((400, 0), (0, 400)),
                                orders=10,
                                wavelength=wl,
                                substrate=GaAs,
                                incidence=Air)

    assert sorted(list(
        rat_np.keys())) == ["A", "A_per_layer", "A_pol", "R", "T"]
    for v in rat_np.values():
        assert v.shape[0] == len(wl)
Example #9
0
}

# We are going to calculate the absorption coefficient of InGaAs QWs of fixed thickness but different compositions
comp = [0.05, 0.1, 0.15, 0.2, 0.25]
colors = plt.cm.jet(np.linspace(0, 1, len(comp)))

plt.figure(figsize=(4, 4.5))
for j, i in enumerate(comp):
    # We create the QW material at the given composition
    QW = material("InGaAs")(T=293, In=i, strained=True)

    # And the layer
    well_layer = Layer(width=si("7.2nm"), material=QW)

    # The following lines create the QW structure, with different number of QWs and interlayers
    test_structure = Structure(
        [barrier_layer, inter, well_layer, inter, barrier_layer])

    test_structure.substrate = bulk

    # Finally, the quantum properties are claculated here
    output = QM.schrodinger(test_structure,
                            quasiconfined=0,
                            num_eigenvalues=20,
                            alpha_params=alpha_params,
                            calculate_absorption=True)

    alfa = output[0]['alphaE'](E)
    plt.plot(1240 / (E / q), alfa / 100, label='{}%'.format(int(i * 100)))
    alfas[:, j + 1] = alfa / 100

plt.xlim(826, 1100)
Example #10
0
import solcore.quantum_mechanics as QM

# First we create the materials we need
bulk = material("GaAs")(T=293, strained=False)
barrier = material("GaAsP")(T=293, P=0.1, strained=True)

# As well as some of the layers
top_layer = Layer(width=si("30nm"), material=barrier)
inter = Layer(width=si("3nm"), material=bulk)
barrier_layer = Layer(width=si("5nm"), material=barrier)
bottom_layer = top_layer

# We create the QW material at the given composition
QW = material("InGaAs")(T=293, In=0.15, strained=True)

# And the layer
well_layer = Layer(width=si("7.2nm"), material=QW)

# The following lines create the QW structure, with different number of QWs and interlayers. Indicating the substrate
# material with the keyword "substrate" is essential in order to calculate correctly the strain.

# A single QW with interlayers
test_structure_1 = Structure([top_layer, inter, well_layer, inter, bottom_layer], substrate=bulk)
output_1 = QM.schrodinger(test_structure_1, quasiconfined=0, graphtype='potentials', num_eigenvalues=20, show=True)

# 10 QWs without interlayers
test_structure_2 = Structure([top_layer, barrier_layer] + 10 * [well_layer, barrier_layer] + [bottom_layer],
                             substrate=bulk)
output_2 = QM.schrodinger(test_structure_2, quasiconfined=0.05, graphtype='potentialsLDOS', num_eigenvalues=200,
                          show=True)
Example #11
0
def test_arbitrary_pol_rcwa():
    import numpy as np

    from solcore import material, si
    from solcore.structure import Layer, Structure
    from solcore.absorption_calculator.rigorous_coupled_wave import calculate_rat_rcwa, \
        calculate_absorption_profile_rcwa

    T = 300
    Air = material("Air")(T=T)
    TiO2 = material("TiO2", sopra=True)(T=T)  # for the nanoparticles
    GaAs = material("GaAs")(T=T)
    th = 50
    NP_layer = Layer(
        si(th, "nm"),
        Air,
        geometry=[{
            "type": "ellipse",
            "mat": TiO2,
            "center": (200, 200),
            "halfwidths": [100, 70],
            "angle": 40
        }],
    )
    np_struct = Structure([NP_layer])
    wl = np.linspace(300, 1000, 10)

    step_size = 2

    rat_np = calculate_rat_rcwa(np_struct,
                                size=((400, 0), (0, 400)),
                                orders=10,
                                wavelength=wl,
                                substrate=GaAs,
                                incidence=Air,
                                pol=[1, 0])

    A_output = rat_np['A_pol']
    result = calculate_absorption_profile_rcwa(np_struct,
                                               size=((400, 0), (0, 400)),
                                               orders=10,
                                               wavelength=wl,
                                               rat_output_A=A_output,
                                               parallel=True,
                                               steps_size=step_size,
                                               pol=[1, 0])

    rat_np_s = calculate_rat_rcwa(np_struct,
                                  size=((400, 0), (0, 400)),
                                  orders=10,
                                  wavelength=wl,
                                  substrate=GaAs,
                                  incidence=Air,
                                  pol='s')

    A_output_s = rat_np_s['A_pol']
    result_s = calculate_absorption_profile_rcwa(np_struct,
                                                 size=((400, 0), (0, 400)),
                                                 orders=10,
                                                 wavelength=wl,
                                                 rat_output_A=A_output_s,
                                                 parallel=True,
                                                 steps_size=step_size,
                                                 pol='s')

    assert approx(A_output == A_output_s)

    assert approx(result["absorption"] == result_s["absorption"])
Example #12
0
    return (energy, n_interp, k_interp)


# Load nk data using nk_convert function...
alinp_nk = nk_convert("AlInP_nk.csv", energy=E_eV)
gainp_nk = nk_convert("GaInP_nk.csv", energy=E_eV)
mgf_nk = nk_convert("MgF_nk.csv", energy=E_eV)
sic_nk = nk_convert("SiCx_nk.csv", energy=E_eV)
zns_nk = nk_convert("ZnS_nk.csv", energy=E_eV)

# Build the optical stack...
OptiStack = Structure([
    [117, 1240/E_eV, mgf_nk[1], mgf_nk[2]],
    [80, 1240/E_eV, sic_nk[1], sic_nk[2]],
    [61, 1240/E_eV, zns_nk[1], zns_nk[2]],
    [25, 1240/E_eV, alinp_nk[1], alinp_nk[2]],
    [350000, 1240/E_eV, gainp_nk[1], gainp_nk[2]]
])

angles = np.linspace(0, 80, 10)

RAT_angles = []

print("Calculate RAT ::")
for theta in angles:

    rat_data = []
    print("Calculating at angle :: %4.1f deg" % theta)
    # Calculate RAT data...
    rat_data = calculate_rat(OptiStack, angle=theta, wavelength=1240 / E_eV)
Example #13
0
def test_structure(b_mat, layer1, layer2, layer3):
    structure1 = Structure([layer1, layer2], substrate=b_mat, T=t)

    assert structure1.__len__() == 2
    assert structure1.__dict__ == {
        'substrate': b_mat,
        'T': t,
        'labels': [None, None]
    }
    assert structure1.width() == approx(width1 + width2)
    assert structure1[0] == layer1
    assert structure1[1] == layer2

    structure2 = Structure([], substrate=b_mat, T=t)
    structure2.append(layer1, layer_label='layer1')

    assert structure2.__len__() == 1
    assert structure2.__dict__ == {
        'substrate': b_mat,
        'T': t,
        'labels': ['layer1']
    }
    assert structure2[0] == layer1

    structure2.append_multiple([layer2, layer3],
                               layer_labels=['layer2', 'layer3'])

    assert structure2.__len__() == 3
    assert structure2.__dict__ == {
        'substrate': b_mat,
        'T': t,
        'labels': ['layer1', 'layer2', 'layer3']
    }
    assert structure2[0] == layer1
    assert structure2[1] == layer2
    assert structure2[2] == layer3
    assert structure2.width() == approx(width1 + width2 + width3)
    assert structure2.relative_widths()['layer1'] == approx(width1 /
                                                            structure2.width())
    assert structure2.relative_widths()['layer2'] == approx(width2 /
                                                            structure2.width())
    assert structure2.relative_widths()['layer3'] == approx(width3 /
                                                            structure2.width())

    structure3 = Structure([])
    structure3.append(layer1, layer_label='layer1', repeats=2)

    assert structure3.__len__() == 2
    assert structure3.__dict__ == {'labels': ['layer1', 'layer1']}
    assert structure3[0] == layer1
    assert structure3[1] == layer1
    assert structure3.width() == approx(width1 * 2)
    # Below currently fails due to a bug when specifying labels and repeating more than once
    # assert structure3.relative_widths()['layer1'] == width1 / structure3.width()

    structure4 = Structure([])
    structure4.append_multiple([layer1, layer2],
                               layer_labels=['layer1', 'layer2'],
                               repeats=2)

    assert structure4.__len__() == 4
    assert structure4.__dict__ == {
        'labels': ['layer1', 'layer2', 'layer1', 'layer2']
    }
    assert structure4[0] == layer1
    assert structure4[1] == layer2
    assert structure4[2] == layer1
    assert structure4[3] == layer2
    assert structure4.width() == approx(width1 * 2 + width2 * 2)
Example #14
0
Air = material("Air")(T=T)
TiO2 = material("TiO2", sopra=True)(T=T)  # for the nanoparticles
GaAs = material("GaAs")(T=T)

# define a flat layer and another with circular discs with the same thickness
Flat = Layer(si('50nm'), TiO2)
NP_layer = Layer(si('50nm'),
                 Air,
                 geometry=[{
                     'type': 'circle',
                     'mat': TiO2,
                     'center': (200, 200),
                     'radius': 50
                 }])

flat_struct = Structure([Flat])
np_struct = Structure([NP_layer])

# And the wavelength in which the solve the problem
wl = np.linspace(300, 1000, 150)

rat_flat = calculate_rat_rcwa(flat_struct,
                              size=((400, 0), (0, 400)),
                              orders=10,
                              wavelength=wl,
                              substrate=GaAs,
                              incidence=Air)
rat_np = calculate_rat_rcwa(np_struct,
                            size=((400, 0), (0, 400)),
                            orders=10,
                            wavelength=wl,
Example #15
0
def test_TMM_absorption_profile():
    GaAs = material("GaAs")(T=300)

    my_structure = Structure(
        [Layer(si(3000, "nm"), material=GaAs), Layer(si(300, "um"), material=GaAs)]
    )

    out = calculate_absorption_profile(
        my_structure, np.array([800]), z_limit=3000, steps_size=20
    )

    data = (
        0.00093920198054733134,
        0.00091329190431268755,
        0.00088809661793623094,
        0.00086359640227330484,
        0.00083977208217782804,
        0.00081660501149482764,
        0.0007940770584669893,
        0.00077217059154379222,
        0.00075086846558214263,
        0.00073015400842769127,
        0.00071001100786633451,
        0.00069042369893569059,
        0.00067137675158661923,
        0.00065285525868512457,
        0.00063484472434525627,
        0.00061733105258387328,
        0.00060030053628839001,
        0.00058373984648887986,
        0.00056763602192612503,
        0.00055197645890746013,
        0.00053674890144246557,
        0.0005219414316507909,
        0.00050754246043459913,
        0.00049354071840833585,
        0.00047992524707871981,
        0.00046668539026805409,
        0.0004538107857741483,
        0.00044129135726031623,
        0.00042911730636911071,
        0.00041727910505361793,
        0.00040576748812031177,
        0.00039457344597762961,
        0.00038368821758459675,
        0.00037310328359397839,
        0.00036281035968459497,
        0.00035280139007758007,
        0.00034306854123150837,
        0.00033360419571145685,
        0.00032440094622720458,
        0.00031545158983589954,
        0.00030674912230466134,
        0.00029828673262870248,
        0.00029005779770068137,
        0.00028205587712711315,
        0.00027427470818778237,
        0.00026670820093421067,
        0.00025935043342334711,
        0.00025219564708274435,
        0.00024523824220360293,
        0.00023847277355814448,
        0.00023189394613789383,
        0.00022549661100952902,
        0.0002192757612850577,
        0.00021322652820316562,
        0.00020734417731867015,
        0.00020162410479709653,
        0.00019606183381147725,
        0.00019065301103855347,
        0.0001853934032516379,
        0.00018027889400747007,
        0.00017530548042447405,
        0.00017046927004989423,
        0.00016576647781335848,
        0.00016119342306448588,
        0.00015674652669221659,
        0.00015242230832361372,
        0.00014821738359994165,
        0.00014412846152789071,
        0.00014015234190387394,
        0.00013628591280938143,
        0.00013252614817542982,
        0.0001288701054142039,
        0.00012531492311603331,
        0.00012185781880990432,
        0.00011849608678575335,
        0.00011522709597683633,
        0.00011204828790051968,
        0.00010895717465587773,
        0.00010595133697653208,
        0.00010302842233720751,
        0.00010018614311252307,
        9.7422274786577231e-05,
        9.4734654211925496e-05,
        9.2121177916588886e-05,
        8.9579800457766819e-05,
        8.7108532820967001e-05,
        8.470544086329888e-05,
        8.2368643799712795e-05,
        8.009631273099949e-05,
        7.7886669212397987e-05,
        7.573798386169243e-05,
        7.3648575005706959e-05,
        7.1616807364140996e-05,
        6.9641090769713272e-05,
        6.7719878923614451e-05,
        6.5851668185292527e-05,
        6.4034996395625842e-05,
        6.2268441732560816e-05,
        6.0550621598319883e-05,
        5.8880191537308663e-05,
        5.7255844183874585e-05,
        5.5676308239094561e-05,
        5.41403474757902e-05,
        5.2646759770991723e-05,
        5.1194376165094236e-05,
        4.9782059946968693e-05,
        4.8408705764312587e-05,
        4.7073238758543685e-05,
        4.5774613723559514e-05,
        4.4511814287704784e-05,
        4.3283852118305772e-05,
        4.2089766148149713e-05,
        4.0928621823303459e-05,
        3.9799510371682887e-05,
        3.8701548091800482e-05,
        3.7633875661134488e-05,
        3.6595657463578247e-05,
        3.5586080935443529e-05,
        3.4604355929505788e-05,
        3.3649714096593824e-05,
        3.2721408284239568e-05,
        3.1818711951917646e-05,
        3.0940918602416916e-05,
        3.0087341228898868e-05,
        2.9257311777210295e-05,
        2.8450180623029266e-05,
        2.7665316063435288e-05,
        2.6902103822505617e-05,
        2.6159946570550893e-05,
        2.5438263456613905e-05,
        2.4736489653865175e-05,
        2.4054075917540213e-05,
        2.3390488155071715e-05,
        2.2745207008081107e-05,
        2.211772744590139e-05,
        2.1507558370314028e-05,
        2.0914222231189692e-05,
        2.0337254652732693e-05,
        1.9776204070036316e-05,
        1.9230631375664536e-05,
        1.8700109575983667e-05,
        1.8184223456974879e-05,
        1.7682569259266036e-05,
        1.7194754362128619e-05,
        1.6720396976192213e-05,
        1.6259125844636267e-05,
        1.5810579952625165e-05,
        1.5374408244759177e-05,
        1.4950269350320186e-05,
        1.4537831316097222e-05,
    )

    assert all([d == approx(o) for d, o in zip(data, out["absorption"][0])])
Example #16
0
def test_rcwa_polygon():
    import numpy as np

    from solcore import material, si
    from solcore.structure import Layer, Structure
    from solcore.absorption_calculator.rigorous_coupled_wave import calculate_rat_rcwa, \
        calculate_absorption_profile_rcwa

    T = 300
    Air = material("Air")(T=T)
    TiO2 = material("TiO2", sopra=True)(T=T)  # for the nanoparticles
    GaAs = material("GaAs")(T=T)
    th = 50

    NP_layer_square = Layer(
        si(th, "nm"),
        Air,
        geometry=[{
            "type": "rectangle",
            "mat": TiO2,
            "center": (200, 200),
            "halfwidths": [50, 50],
            "angle": 0
        }],
    )
    np_struct_square = Structure([NP_layer_square])

    NP_layer_polygon = Layer(
        si(th, "nm"),
        Air,
        geometry=[{
            "type": "polygon",
            "mat": TiO2,
            "center": (200, 200),
            "vertices": ((150, 150), (250, 150), (250, 250), (150, 250)),
            "angle": 0
        }],
    )
    np_struct_polygon = Structure([NP_layer_polygon])

    wl = np.linspace(300, 1000, 10)

    step_size = 2

    rat_np_sq = calculate_rat_rcwa(np_struct_square,
                                   size=((400, 0), (0, 400)),
                                   orders=10,
                                   wavelength=wl,
                                   substrate=GaAs,
                                   incidence=Air,
                                   pol=[1, 0])

    A_output_sq = rat_np_sq['A_pol']
    result_square = calculate_absorption_profile_rcwa(np_struct_square,
                                                      size=((400, 0), (0,
                                                                       400)),
                                                      orders=10,
                                                      wavelength=wl,
                                                      rat_output_A=A_output_sq,
                                                      parallel=True,
                                                      steps_size=step_size,
                                                      pol=[1, 0])

    rat_np_pol = calculate_rat_rcwa(np_struct_polygon,
                                    size=((400, 0), (0, 400)),
                                    orders=10,
                                    wavelength=wl,
                                    substrate=GaAs,
                                    incidence=Air,
                                    pol=[1, 0])

    A_output_pol = rat_np_pol['A_pol']
    result_polygon = calculate_absorption_profile_rcwa(
        np_struct_polygon,
        size=((400, 0), (0, 400)),
        orders=10,
        wavelength=wl,
        rat_output_A=A_output_pol,
        parallel=True,
        steps_size=step_size,
        pol=[1, 0])

    assert approx(A_output_sq == A_output_pol)

    assert approx(result_polygon["absorption"] == result_square["absorption"])
import matplotlib.pyplot as plt
import numpy as np
from solcore.absorption_calculator import calculate_ellipsometry
from solcore import material, si
from solcore.structure import Structure, Layer

# First we defined a couple of materials, for example, GaAs and AlGAs
GaAs = material('GaAs')(T=300)
AlGaAs = material('AlGaAs')(T=300, Al=0.3)

# Now, let's build the structure. We don't add a substrate and assume that there is an infinitely thick absorbing
# material in the back.
my_structure = Structure([
    Layer(si(40, 'nm'), material=AlGaAs),
    Layer(si(3000, 'nm'), material=GaAs),
])

# We want to calculate the ellipsometry of this structure as a function of the wavelength for a few angles
wavelength = np.linspace(400, 1000, 200)
angles = [65, 70, 75]

out = calculate_ellipsometry(my_structure, wavelength, angle=angles)

# This results must be taken with care. As the ellipsometry routine can only deal with coherent light, there might be
# strange oscillations related with intereference in thick layers, something that should not happen.
# Setting no_back_reflection=True (the default) should take care of most of this effects, but might add other unexpected
# ones.
fig, ax1 = plt.subplots(1, 1)
ax2 = ax1.twinx()

ax1.plot(wavelength, out['psi'][:, 0], 'b', label=r'$\Psi$')
Example #18
0
n_spline = InterpolatedUnivariateSpline(x=Ge_nk_Exp[::5, 0],
                                        y=Ge_nk_Exp[::5, 1],
                                        k=3)(E_eV)
k_spline = InterpolatedUnivariateSpline(x=Ge_nk_Exp[::5, 2],
                                        y=Ge_nk_Exp[::5, 3],
                                        k=3)(E_eV)

## Step 1 :: n and k modelling...
# First model the Ge02 layer with the Sellmeier model

# Define Oscillator Structure
GeO2 = Structure([
    Oscillator(oscillator_type="Sellmeier",
               material_parameters=None,
               A1=0.80686642,
               L1=0.68972606E-1,
               A2=0.71815848,
               L2=0.15396605,
               A3=0.85416831,
               L3=0.11841931E2)
])

GeO2_nk = cppb().nk_calc(oscillator_structure=GeO2, energy_array=E_eV)

# Step 2 :: use this modelled n and k to calculate the ellipsometry data...
# Define a structure for the optical stack...
stack = Structure([
    [4.4, 1240 / E_eV, GeO2_nk["n"],
     GeO2_nk["k"]],  # Layer 1 :: GeO2 native oxide layer
    [350000, 1240 / E_eV, n_spline, k_spline]  # Layer 2/ Substrate :: Bulk Ge
])
Example #19
0
def test_quantum_mechanics_schrodinger():
    """ Testing schrodinger equation solver
    """
    bulk = material("GaAs")(T=293)
    barrier = material("GaAsP")(T=293, P=0.1)

    bulk.strained = False
    barrier.strained = True

    top_layer = Layer(width=si("30nm"), material=bulk)
    inter = Layer(width=si("3nm"), material=bulk)
    barrier_layer = Layer(width=si("15nm"), material=barrier)
    bottom_layer = top_layer

    E = np.linspace(1.15, 1.5, 300) * q
    alfas = np.zeros((len(E), 6))

    alfas[:, 0] = E / q

    alpha_params = {
        "well_width": si("7.2nm"),
        "theta": 0,
        "eps": 12.9 * vacuum_permittivity,
        "espace": E,
        "hwhm": si("6meV"),
        "dimensionality": 0.16,
        "line_shape": "Gauss",
    }

    QW = material("InGaAs")(T=293, In=0.2)
    QW.strained = True
    well_layer = Layer(width=si("7.2nm"), material=QW)

    my_structure = Structure(
        [
            top_layer,
            barrier_layer,
            inter,
            well_layer,
            inter,
            barrier_layer,
            inter,
            bottom_layer,
        ],
        substrate=bulk,
    )

    band_edge, bands = QM.schrodinger(
        my_structure,
        quasiconfined=0,
        num_eigenvalues=20,
        alpha_params=alpha_params,
        calculate_absorption=True,
    )

    for key in band_edge["E"]:
        for i in range(len(band_edge["E"][key])):
            band_edge["E"][key][i] = solcore.asUnit(band_edge["E"][key][i],
                                                    "eV") * 1000
            band_edge["E"][key][i] = round(band_edge["E"][key][i])

    Ehh = np.all(np.equal(band_edge["E"]["Ehh"], my_energies["Ehh"]))
    Elh = np.all(np.equal(band_edge["E"]["Elh"], my_energies["Elh"]))
    Ee = np.all(np.equal(band_edge["E"]["Ee"], my_energies["Ee"]))

    idx = 100
    out = [band_edge["alpha"][0][idx] / q, band_edge["alpha"][1][idx]]

    # Test over the energies
    assert Ehh and Elh and Ee

    # Test over the absorption coefficent at a given energy
    for i, data in enumerate(out):
        assert out[i] == approx(my_absorption[i], rel=1e-4)
Example #20
0
            output['absorption'] = 0.5 * (data_s + data_p)

    return output


if __name__ == '__main__':
    import matplotlib.pyplot as plt
    from solcore import material, si
    from solcore.structure import Layer, Structure

    GaAs = material('GaAs')(T=300)
    InGaAs = material('InGaAs')(T=300, In=0.1)

    my_structure = Structure([
        Layer(si(3000, 'nm'), material=InGaAs),
        Layer(si(30, 'um'), material=GaAs),
    ])

    wavelength = np.linspace(450, 1100, 300)

    out = calculate_rat(my_structure,
                        wavelength,
                        coherent=True,
                        no_back_reflection=False)
    # #
    # plt.plot(wavelength, out['R'], 'b', label='Reflexion')
    # plt.plot(wavelength, out['A'], 'r', label='Absorption')
    # plt.plot(wavelength, out['T'], 'g', label='Transmission')
    # plt.legend()
    # plt.show()
Example #21
0
MatParams["B1s"] = 1.0
MatParams["Gamma_Eg_ID"] = 0.3
MatParams["Alpha_Eg_ID"] = 0.0
MatParams["E1"] = 2.8
MatParams["E1_d1"] = 2.9
MatParams["Gamma_E1"] = 0.1
MatParams["E2"] = 4.72
MatParams["C"] = 3.0
MatParams["Alpha_E2"] = 0.04
MatParams["Gamma_E2"] = 0.19

# Must define a structure object containing the required oscillator functions. The oscillator type and material
# parameters are both passed to individual 'Oscillators' in the structure...
Adachi_GaAs = Structure([
    Oscillator(oscillator_type="E0andE0_d0", material_parameters=MatParams),
    Oscillator(oscillator_type="E1andE1_d1", material_parameters=MatParams),
    Oscillator(oscillator_type="E_ID", material_parameters=MatParams),
    Oscillator(oscillator_type="E2", material_parameters=MatParams)
])

Output = CPPB_Model.eps_calc(Adachi_GaAs, E)

# PLOT OUTPUT...
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(7, 4.5))

# Subplot I :: Real part of the dielectric function.
ax1.set_yscale("linear")
ax1.set_xlim(0, 5.3)
ax1.set_ylim(-14, 27)

ax1.plot(Palik_Eps1[:, 0], Palik_Eps1[:, 1], label="Exp. Data (Palik)",
         marker='o', ls='none', markerfacecolor='none', markeredgecolor=colours("Red"))
Example #22
0
    "dimensionality": 0.16,
    "line_shape": "Gauss"
}

# We create the QW material at the given composition
QW = material("InGaAs")(T=293, In=0.15)
QW.strained = True

# And the layer
well_layer = Layer(width=si("7.2nm"), material=QW)

# The following lines create the QW structure, with different number of QWs and interlayers
# test_structure = Structure([top_layer, barrier_layer, inter] + 10 * [well_layer, inter, barrier_layer, inter] +
#                            [bottom_layer])

# test_structure = Structure([barrier_layer, inter] + 1 * [well_layer, inter] +
#                            [barrier_layer])

test_structure = Structure([top_layer, barrier_layer] +
                           10 * [well_layer, barrier_layer] + [bottom_layer])

test_structure.substrate = bulk

# Finally, the quantum properties are claculated here
output = QM.schrodinger(test_structure,
                        quasiconfined=0,
                        graphtype='potentials',
                        num_eigenvalues=50,
                        alpha_params=alpha_params,
                        calculate_absorption=True)
        "line_shape": "Gauss"
    }

    comp = [0.05, 0.1, 0.15, 0.2, 0.25]
    colors = plt.cm.jet(np.linspace(0, 1, len(comp)))

    plt.figure(figsize=(6, 4.5))
    for j, i in enumerate(comp):
        QW = material("InGaAs")(T=293, In=i)
        QW.strained = True
        well_layer = Layer(width=si("7.2nm"), material=QW)

        # test_structure = Structure([top_layer, barrier_layer, inter] + 1 * [well_layer, inter, barrier_layer, inter] +
        #                            [bottom_layer])

        test_structure = Structure([barrier_layer, inter] +
                                   1 * [well_layer, inter] + [barrier_layer])

        # test_structure = Structure([top_layer, barrier_layer] + 10 * [well_layer, barrier_layer] +
        #                            [bottom_layer])

        test_structure.substrate = bulk

        output = schrodinger(test_structure,
                             quasiconfined=0,
                             num_eigenvalues=20,
                             alpha_params=alpha_params,
                             calculate_absorption=True)

        alfa = output[0]['alphaE'](E)
        plt.plot(1240 / (E / q), alfa / 100, label='{}%'.format(int(i * 100)))
        alfas[:, j + 1] = alfa / 100
Example #24
0
                        fill_value=(k[0], k[-1]))(energy)

    return (energy, n_interp, k_interp)


# Load nk data using nk_convert function...
alinp_nk = nk_convert("data/AlInP_nk.csv", energy=E_eV)
gainp_nk = nk_convert("data/GaInP_nk.csv", energy=E_eV)
mgf_nk = nk_convert("data/MgF_nk.csv", energy=E_eV)
sic_nk = nk_convert("data/SiCx_nk.csv", energy=E_eV)
zns_nk = nk_convert("data/ZnS_nk.csv", energy=E_eV)

# Build the optical stack...
stack = Structure([[117, 1240 / E_eV, mgf_nk[1], mgf_nk[2]],
                   [80, 1240 / E_eV, sic_nk[1], sic_nk[2]],
                   [61, 1240 / E_eV, zns_nk[1], zns_nk[2]],
                   [25, 1240 / E_eV, alinp_nk[1], alinp_nk[2]],
                   [350000, 1240 / E_eV, gainp_nk[1], gainp_nk[2]]])

angles = np.linspace(0, 80, 10)
RAT_angles = []

print("Calculate RAT ::")
for theta in angles:
    print("Calculating at angle :: %4.1f deg" % theta)
    # Calculate RAT data...
    rat_data = calculate_rat(stack, angle=theta, wavelength=1240 / E_eV)

    RAT_angles.append((theta, rat_data["R"], rat_data["A"]))

colors = plt.cm.jet(np.linspace(1, 0, len(RAT_angles)))
    "hwhm": si("6meV"),
    "dimensionality": 0.16,
    "line_shape": "Gauss"
}

# plt.figure(figsize=(4, 4.5))
for j, i in enumerate(comp):
    # We create the QW material at the given composition
    QW = material("InGaAs")(T=293, In=i, strained=True)

    # And the layer
    well_layer = Layer(width=si("7.2nm"), material=QW)

    # The following lines create the QW structure, with different number of QWs and interlayers
    test_structure = Structure(
        [barrier_layer, inter, well_layer, inter, barrier_layer],
        substrate=bulk)

    # Finally, the quantum properties are claculated here
    output = QM.schrodinger(test_structure,
                            quasiconfined=0,
                            num_eigenvalues=20,
                            alpha_params=alpha_params,
                            calculate_absorption=True)

    alfa = output[0]['alphaE'](E)
    plt.plot(1240 / (E / q), alfa / 100, label='{}%'.format(int(i * 100)))

plt.xlim(826, 1100)
plt.ylim(0, 23000)
plt.xlabel('Wavelength (nm)')