def test_BL_correction():

    wl = np.linspace(800, 950, 4) * 1e-9

    GaAs = material("GaAs")()

    thick_cell = SolarCell([Layer(material=GaAs, width=si("20um"))])

    opts = State()
    opts.position = None
    prepare_solar_cell(thick_cell, opts)
    position = np.arange(0, thick_cell.width, 1e-9)
    opts.position = position
    opts.recalculate_absorption = True
    opts.no_back_reflexion = False

    opts.BL_correction = False
    opts.wavelength = wl
    solve_tmm(thick_cell, opts)

    no_corr = thick_cell.absorbed

    opts.BL_correction = True

    solve_tmm(thick_cell, opts)

    with_corr = thick_cell.absorbed

    assert with_corr == approx(
        np.array([6.71457872e-01, 6.75496354e-01, 2.09738887e-01, 0]))
    assert no_corr == approx(
        np.array([6.71457872e-01, 6.75496071e-01, 2.82306407e-01, 0]))
Exemplo n.º 2
0
def test_tmm_rcwa_structure_comparison(pol, angle):
    import numpy as np
    from solcore import si, material
    from solcore.structure import Layer
    from solcore.solar_cell import SolarCell
    from solcore.optics.tmm import calculate_rat, OptiStack
    from solcore.optics.rcwa import calculate_rat_rcwa

    InGaP = material('GaInP')(In=0.5)
    GaAs = material('GaAs')()
    Ge = material('Ge')()
    Ag = material('Ag')()
    Air = material('Air')()

    Al2O3 = material('Al2O3')()

    wavelengths = np.linspace(250, 1900, 500)

    size = ((100, 0), (0, 100))

    ARC = [Layer(si('80nm'), Al2O3)]

    solar_cell = SolarCell(ARC + [
        Layer(material=InGaP, width=si('400nm')),
        Layer(material=GaAs, width=si('4000nm')),
        Layer(material=Ge, width=si('3000nm'))
    ],
                           substrate=Ag)

    solar_cell_OS = OptiStack(solar_cell,
                              no_back_reflection=False,
                              substrate=solar_cell.substrate)

    rcwa_result = calculate_rat_rcwa(solar_cell,
                                     size,
                                     2,
                                     wavelengths,
                                     Air,
                                     Ag,
                                     theta=angle,
                                     phi=angle,
                                     pol=pol,
                                     parallel=True)
    tmm_result = calculate_rat(solar_cell_OS,
                               wavelengths,
                               angle,
                               pol,
                               no_back_reflection=False)

    assert tmm_result['A_per_layer'][1:-1] == approx(
        rcwa_result['A_per_layer'].T)
    assert tmm_result['R'] == approx(rcwa_result['R'])
    assert tmm_result['T'] == approx(rcwa_result['T'])

    assert np.sum(tmm_result['A_per_layer'][1:-1].T,
                  1) + tmm_result['R'] + tmm_result['T'] == approx(1)
    assert np.sum(rcwa_result['A_per_layer'],
                  1) + rcwa_result['R'] + rcwa_result['T'] == approx(1)
def plot_R(obj, x, icol):

    cols = sns.cubehelix_palette(len(use_orders),
                                 start=.5,
                                 rot=-.9,
                                 reverse=True)
    GaAs = material('GaAs_WVASE')()
    Air = material('Air')()

    InAlP = material('InAlP_WVASE')()
    InGaP = material('InGaP_WVASE')()

    Ag = material('Ag_Jiang')()

    # MgF2 = material('MgF2')()
    # Ta2O5 = material('410', nk_db=True)()
    SiN = material('SiN_SE')()

    R_data = np.loadtxt('Talbot_precursor_R.csv', delimiter=',')

    grating1 = [Layer(si(x[2] * x[1], 'nm'), SiN)]

    grating2 = [
        Layer(si((1 - x[1]) * x[2], 'nm'),
              SiN,
              geometry=[{
                  'type': 'circle',
                  'mat': Ag,
                  'center': (0, 0),
                  'radius': x[3],
                  'angle': 0
              }])
    ]

    solar_cell = SolarCell([
        Layer(material=GaAs, width=si('25nm')),
        Layer(material=InGaP, width=si('19nm')),
        Layer(material=GaAs, width=si(x[0], 'nm')),
        Layer(material=InAlP, width=si('18nm'))
    ] + grating1 + grating2,
                           substrate=Ag)

    S4_setup = rcwa_structure(solar_cell, obj.size, obj.orders, obj.options,
                              Air, Ag)

    RAT = S4_setup.calculate()

    total_A = np.sum(RAT['A_layer'], axis=1)

    # plt.figure()

    plt.plot(S4_setup.wavelengths * 1e9,
             RAT['R'],
             label=str(obj.orders),
             color=cols[icol])

    return S4_setup.wavelengths * 1e9, interp1d(R_data[:, 0], R_data[:, 1])(
        S4_setup.wavelengths * 1e9)
def test_substrate_presence_profile():
    wavelength = np.linspace(300, 800, 3) * 1e-9

    GaAs = material("GaAs")(T=300)

    my_structure = SolarCell([Layer(si(700, "nm"), material=GaAs)],
                             substrate=GaAs)

    solar_cell_solver(
        my_structure,
        "optics",
        user_options={
            "wavelength": wavelength,
            "optics_method": "TMM",
            "no_back_reflection": False,
        },
    )

    z_pos = np.linspace(0, my_structure.width, 10)

    profile_subs = my_structure[0].absorbed(z_pos)

    my_structure = SolarCell([Layer(si(700, "nm"), material=GaAs)])

    solar_cell_solver(
        my_structure,
        "optics",
        user_options={
            "wavelength": wavelength,
            "optics_method": "TMM",
            "no_back_reflection": False,
        },
    )

    profile_nosubs = my_structure[0].absorbed(z_pos)
    profile = np.vstack((profile_subs, profile_nosubs))

    data_path = Path(
        __file__).parent / "data" / "substrate_presence_profile.csv"
    expected = np.loadtxt(data_path, delimiter=",")

    assert profile.shape == expected.shape
    assert profile == approx(expected)
Exemplo n.º 5
0
def junction(nd_top, na_top, nd_bottom, na_bottom):
    from solcore.structure import Junction, Layer
    from solcore import si, material
    from solcore.solar_cell import SolarCell
    from solcore.constants import vacuum_permittivity
    from solcore.solar_cell_solver import prepare_solar_cell
    from solcore.optics import solve_beer_lambert

    Lp = np.power(10, np.random.uniform(-8, -6))
    Ln = np.power(10, np.random.uniform(-8, -6))

    AlInP = material("AlInP")
    InGaP = material("GaInP")
    window_material = AlInP(Al=0.52)
    top_cell_n_material = InGaP(
        In=0.48,
        Nd=nd_top,
        Na=na_top,
        hole_diffusion_length=Lp,
        electron_diffusion_length=Ln,
    )
    top_cell_p_material = InGaP(
        In=0.48,
        Nd=nd_bottom,
        Na=na_bottom,
        hole_diffusion_length=Lp,
        electron_diffusion_length=Ln,
    )

    rel_perm = np.random.uniform(1, 20)
    for mat in [top_cell_n_material, top_cell_p_material]:
        mat.permittivity = rel_perm * vacuum_permittivity

    n_width = np.random.uniform(500, 1000) * 1e-9
    p_width = np.random.uniform(3000, 5000) * 1e-9

    test_junc = SolarCell([
        Junction(
            [
                Layer(si("25nm"), material=window_material, role="window"),
                Layer(n_width, material=top_cell_n_material, role="emitter"),
                Layer(p_width, material=top_cell_p_material, role="base"),
            ],
            sn=1,
            sp=1,
            kind="DA",
        )
    ])

    options = da_options()
    options.light_source = da_light_source()
    prepare_solar_cell(test_junc, options)
    solve_beer_lambert(test_junc, options)

    return test_junc, options
def test_substrate_presence_A():
    wavelength = np.linspace(300, 800, 3) * 1e-9

    GaAs = material("GaAs")(T=300)

    my_structure = SolarCell([Layer(si(700, "nm"), material=GaAs)],
                             substrate=GaAs)

    solar_cell_solver(
        my_structure,
        "optics",
        user_options={
            "wavelength": wavelength,
            "optics_method": "TMM",
            "no_back_reflexion": False,
        },
    )

    z_pos = np.linspace(0, my_structure.width, 10)

    A_subs = my_structure[0].layer_absorption

    my_structure = SolarCell([Layer(si(700, "nm"), material=GaAs)])

    solar_cell_solver(
        my_structure,
        "optics",
        user_options={
            "wavelength": wavelength,
            "optics_method": "TMM",
            "no_back_reflexion": False,
        },
    )

    A_nosubs = my_structure[0].layer_absorption

    A = np.vstack((A_subs, A_nosubs))

    A_data = np.array([[0.56610281, 0.62692985, 0.41923175],
                       [0.56610281, 0.62711355, 0.37837737]])

    assert all([d == approx(o) for d, o in zip(A, A_data)])
Exemplo n.º 7
0
def test_light_iv(AlGaAs, light_source):
    import numpy as np
    from solcore.solar_cell import SolarCell, default_GaAs
    from solcore import material
    from solcore.solar_cell_solver import solar_cell_solver

    expected = np.array([
        142.68025180227374,
        2.519346556870366,
        0.9169672186977382,
        329.61395441947565,
        2.347826086956522,
        140.3911287342211,
        0.3294918264376029,
    ])

    T = AlGaAs.T
    Vin = np.linspace(-2, 2.61, 201)
    V = np.linspace(0, 2.6, 300)

    substrate = material("GaAs")(T=T)

    my_solar_cell = SolarCell([AlGaAs, default_GaAs(T)],
                              T=T,
                              R_series=0,
                              substrate=substrate)
    solar_cell_solver(
        my_solar_cell,
        "iv",
        user_options={
            "T_ambient": T,
            "db_mode": "boltzmann",
            "voltages": V,
            "light_iv": True,
            "wavelength": light_source.x,
            "optics_method": "BL",
            "mpp": True,
            "internal_voltages": Vin,
            "light_source": light_source,
        },
    )

    output = [
        my_solar_cell.iv.Isc,
        my_solar_cell.iv.Voc,
        my_solar_cell.iv.FF,
        my_solar_cell.iv.Pmpp,
        my_solar_cell.iv.Vmpp,
        my_solar_cell.iv.Impp,
        my_solar_cell.iv.Eta,
    ]

    assert np.array(output) == approx(expected, rel=1e-2)
Exemplo n.º 8
0
def solve_MJ(EgBot, EgMid, EgTop):
    db_junction0 = Junction(kind='DB', T=T, Eg=EgBot, A=1, R_shunt=np.inf, n=3.5)
    db_junction1 = Junction(kind='DB', T=T, Eg=EgMid, A=1, R_shunt=np.inf, n=3.5)
    db_junction2 = Junction(kind='DB', T=T, Eg=EgTop, A=1, R_shunt=np.inf, n=3.5)

    my_solar_cell = SolarCell([db_junction2, db_junction1, db_junction0], T=T, R_series=0)

    solar_cell_solver(my_solar_cell, 'iv',
                      user_options={'T_ambient': T, 'db_mode': 'top_hat', 'voltages': V, 'light_iv': True,
                                    'internal_voltages': np.linspace(-6, 5, 1100), 'wavelength': wl,
                                    'mpp': True, 'light_source': light})

    return my_solar_cell
Exemplo n.º 9
0
def test_light_iv():
    answer = [
        142.68025180227374,
        2.519346556870366,
        0.9169672186977382,
        329.61395441947565,
        2.347826086956522,
        140.3911287342211,
        0.3294918264376029,
    ]
    with tempfile.TemporaryDirectory(prefix="tmp",
                                     suffix="_sc3TESTS") as working_directory:
        filename = os.path.join(working_directory, "solcore_log.txt")
        PDD.log(filename)

        my_solar_cell = SolarCell([AlGaAs(T), default_GaAs(T)],
                                  T=T,
                                  R_series=0,
                                  substrate=substrate)
        solar_cell_solver(
            my_solar_cell,
            "iv",
            user_options={
                "T_ambient": T,
                "db_mode": "boltzmann",
                "voltages": V,
                "light_iv": True,
                "wavelength": wl,
                "optics_method": "BL",
                "mpp": True,
                "internal_voltages": Vin,
                "light_source": light_source,
            },
        )

        output = [
            my_solar_cell.iv.Isc,
            my_solar_cell.iv.Voc,
            my_solar_cell.iv.FF,
            my_solar_cell.iv.Pmpp,
            my_solar_cell.iv.Vmpp,
            my_solar_cell.iv.Impp,
            my_solar_cell.iv.Eta,
        ]

    for i in range(len(output)):
        assert output[i] == approx(answer[i])
Exemplo n.º 10
0
def test_quantum_efficiency(AlGaAs, light_source):
    import numpy as np
    from solcore.solar_cell import SolarCell, default_GaAs
    from solcore import material
    from solcore.solar_cell_solver import solar_cell_solver

    expected = np.array([
        0.9866334968497021,
        2.1512408472022467e-14,
        0.9779769012349702,
        0.03506561338387434,
    ])
    T = AlGaAs.T
    Vin = np.linspace(-2, 2.61, 201)
    V = np.linspace(0, 2.6, 300)

    substrate = material("GaAs")(T=T)

    my_solar_cell = SolarCell([AlGaAs, default_GaAs(T)],
                              T=T,
                              R_series=0,
                              substrate=substrate)

    solar_cell_solver(
        my_solar_cell,
        "qe",
        user_options={
            "T_ambient": T,
            "db_mode": "boltzmann",
            "voltages": V,
            "light_iv": True,
            "wavelength": light_source.x,
            "optics_method": "BL",
            "mpp": True,
            "internal_voltages": Vin,
            "light_source": light_source,
        },
    )

    output = [
        my_solar_cell[0].eqe(500e-9),
        my_solar_cell[0].eqe(800e-9),
        my_solar_cell[1].eqe(700e-9),
        my_solar_cell[1].eqe(900e-9),
    ]
    assert np.array(output) == approx(expected, abs=1e-3)
    def evaluate(self, x):
        GaAs = material('GaAs_WVASE')()
        Air = material('Air')()

        InAlP = material('InAlP_WVASE')()
        InGaP = material('InGaP_WVASE')()

        Ag = material('Ag_Jiang')()

        # MgF2 = material('MgF2')()
        # Ta2O5 = material('410', nk_db=True)()
        SiN = material('SiN_SE')()
        # print('SiN thickness', x[2]*x[1], 'Ag th', (1-x[1])*x[2])

        grating1 = [Layer(si(x[2] * x[1], 'nm'), SiN)]

        grating2 = [
            Layer(si((1 - x[1]) * x[2], 'nm'),
                  SiN,
                  geometry=[{
                      'type': 'circle',
                      'mat': Ag,
                      'center': (0, 0),
                      'radius': x[3],
                      'angle': 0
                  }])
        ]

        solar_cell = SolarCell([
            Layer(material=InGaP, width=si('19nm')),
            Layer(material=GaAs, width=si(x[0], 'nm')),
            Layer(material=InAlP, width=si('18nm'))
        ] + grating1 + grating2,
                               substrate=Ag)

        S4_setup = rcwa_structure(solar_cell, self.size, self.orders,
                                  self.options, Air, Ag)

        RAT = S4_setup.calculate()
        EQE_sim = 0.9 * 100 * (RAT['A_layer'][:, 0] + RAT['A_layer'][:, 1])

        # least squares?
        residual = np.sum((EQE_sim - self.EQE_meas)**2)

        return residual
Exemplo n.º 12
0
def test_quantum_efficiency():
    answer = [
        0.9866334968497021,
        2.1512408472022467e-14,
        0.9779769012349702,
        0.03506561338387434,
    ]
    with tempfile.TemporaryDirectory(prefix="tmp",
                                     suffix="_sc3TESTS") as working_directory:
        filename = os.path.join(working_directory, "solcore_log.txt")
        PDD.log(filename)

        my_solar_cell = SolarCell([AlGaAs(T), default_GaAs(T)],
                                  T=T,
                                  R_series=0,
                                  substrate=substrate)

        solar_cell_solver(
            my_solar_cell,
            "qe",
            user_options={
                "T_ambient": T,
                "db_mode": "boltzmann",
                "voltages": V,
                "light_iv": True,
                "wavelength": wl,
                "optics_method": "BL",
                "mpp": True,
                "internal_voltages": Vin,
                "light_source": light_source,
            },
        )

        output = [
            my_solar_cell[0].eqe(500e-9),
            my_solar_cell[0].eqe(800e-9),
            my_solar_cell[1].eqe(700e-9),
            my_solar_cell[1].eqe(900e-9),
        ]

    for i in range(len(output)):
        assert output[i] == approx(answer[i])
Exemplo n.º 13
0
def test_inc_coh_tmm():
    GaInP = material("GaInP")(In=0.5)
    GaAs = material("GaAs")()
    Ge = material("Ge")()

    optical_struct = SolarCell([
        Layer(material=GaInP, width=si("5000nm")),
        Layer(material=GaAs, width=si("200nm")),
        Layer(material=GaAs, width=si("5um")),
        Layer(material=Ge, width=si("50um")),
    ])

    wl = np.linspace(400, 1200, 5) * 1e-9

    options = State()
    options.wavelength = wl
    options.optics_method = "TMM"
    options.no_back_reflection = False
    options.BL_correction = True
    options.recalculate_absorption = True

    c_list = [
        ["c", "c", "c", "c"],
        ["c", "c", "c", "i"],
        ["c", "i", "i", "c"],
        ["i", "i", "i", "i"],
    ]

    results = []
    for i1, cl in enumerate(c_list):
        options.coherency_list = cl
        solar_cell_solver(optical_struct, "optics", options)
        results.append(optical_struct.absorbed)

    A_calc = np.stack(results)
    A_data = np.array(
        [[0.5742503, 0.67956899, 0.73481184, 0.725372, 0.76792856],
         [0.5742503, 0.67956899, 0.73481184, 0.725372, 0.76792856],
         [0.5742503, 0.67956899, 0.73474943, 0.70493469, 0.70361194],
         [0.5742503, 0.67956899, 0.70927724, 0.71509221, 0.71592772]])
    assert A_calc == approx(A_data)
Exemplo n.º 14
0
def solve_MJ(EgBot, EgMid, EgTop):
    db_junction0 = Junction(kind="DB",
                            T=T,
                            Eg=EgBot,
                            A=1,
                            R_shunt=np.inf,
                            n=3.5)
    db_junction1 = Junction(kind="DB",
                            T=T,
                            Eg=EgMid,
                            A=1,
                            R_shunt=np.inf,
                            n=3.5)
    db_junction2 = Junction(kind="DB",
                            T=T,
                            Eg=EgTop,
                            A=1,
                            R_shunt=np.inf,
                            n=3.5)

    my_solar_cell = SolarCell([db_junction2, db_junction1, db_junction0],
                              T=T,
                              R_series=0)

    solar_cell_solver(
        my_solar_cell,
        "iv",
        user_options={
            "T_ambient": T,
            "db_mode": "top_hat",
            "voltages": V,
            "light_iv": True,
            "internal_voltages": np.linspace(-6, 5, 1100),
            "wavelength": wl,
            "mpp": True,
            "light_source": light,
        },
    )

    return my_solar_cell
Exemplo n.º 15
0
def prepare_test_cell():

    from solcore import material, si
    from solcore.structure import Junction, Layer, TunnelJunction
    from solcore.solar_cell import SolarCell

    GaAs = material("GaAs")()
    MgF2 = material("MgF2")()
    TiO2 = material("TiO2")()
    Ge = material("Ge")()

    widths = np.random.rand(9) * 200

    solar_cell = SolarCell([
        Layer(si(widths[0], "nm"), material=MgF2),
        Layer(si(widths[1], "nm"), material=TiO2),
        Junction(
            [
                Layer(si(widths[2], "nm"), material=GaAs, role="window"),
                Layer(si(widths[3], "nm"), material=GaAs, role="emitter"),
                Layer(si(widths[4], "nm"), material=GaAs, role="base"),
            ],
            kind="DA",
        ),
        TunnelJunction([
            Layer(si(widths[5], "nm"), material=GaAs),
            Layer(si(widths[6], "nm"), material=GaAs),
        ]),
        Junction(
            [
                Layer(si(widths[7], "nm"), material=Ge, role="emitter"),
                Layer(si(widths[8], "nm"), material=Ge, role="base"),
            ],
            kind="PDD",
        ),
    ])

    return solar_cell, widths
Exemplo n.º 16
0
    def test_92_light_iv(self):
        answer = [
            142.68025180227374, 2.519346556870366, 0.9169672186977382,
            329.61395441947565, 2.347826086956522, 140.3911287342211,
            0.3294918264376029
        ]
        with tempfile.TemporaryDirectory(
                prefix="tmp", suffix="_sc3TESTS") as working_directory:
            filename = os.path.join(working_directory, 'solcore_log.txt')
            PDD.log(filename)

            my_solar_cell = SolarCell([AlGaAs(T), default_GaAs(T)],
                                      T=T,
                                      R_series=0,
                                      substrate=substrate)
            solar_cell_solver(my_solar_cell,
                              'iv',
                              user_options={
                                  'T_ambient': T,
                                  'db_mode': 'boltzmann',
                                  'voltages': V,
                                  'light_iv': True,
                                  'wavelength': wl,
                                  'optics_method': 'BL',
                                  'mpp': True,
                                  'internal_voltages': Vin,
                                  'light_source': light_source
                              })

            output = [
                my_solar_cell.iv.Isc, my_solar_cell.iv.Voc,
                my_solar_cell.iv.FF, my_solar_cell.iv.Pmpp,
                my_solar_cell.iv.Vmpp, my_solar_cell.iv.Impp,
                my_solar_cell.iv.Eta
            ]

        for i in range(len(output)):
            self.assertAlmostEqual(output[i], answer[i])
Exemplo n.º 17
0
    def test_92_light_iv(self):
        answer = [
            141.434980729, 2.46952886616, 0.91434377329, 319.359951949,
            2.29565217391, 139.115130584, 0.319241623262
        ]
        with tempfile.TemporaryDirectory(
                prefix="tmp", suffix="_sc3TESTS") as working_directory:
            filename = os.path.join(working_directory, 'solcore_log.txt')
            PDD.log(filename)

            my_solar_cell = SolarCell([AlGaAs(T), default_GaAs(T)],
                                      T=T,
                                      R_series=0,
                                      substrate=substrate)
            solar_cell_solver(my_solar_cell,
                              'iv',
                              user_options={
                                  'T_ambient': T,
                                  'db_mode': 'boltzmann',
                                  'voltages': V,
                                  'light_iv': True,
                                  'wavelength': wl,
                                  'optics_method': 'BL',
                                  'mpp': True,
                                  'internal_voltages': Vin,
                                  'light_source': light_source
                              })

            output = [
                my_solar_cell.iv.Isc, my_solar_cell.iv.Voc,
                my_solar_cell.iv.FF, my_solar_cell.iv.Pmpp,
                my_solar_cell.iv.Vmpp, my_solar_cell.iv.Impp,
                my_solar_cell.iv.Eta
            ]

        for i in range(len(output)):
            self.assertAlmostEqual(output[i], answer[i])
Exemplo n.º 18
0
    def test_93_qe(self):
        answer = [
            0.9831923128532823, 1.315965183418519e-13, 0.9672990699170962,
            0.032767290395462376
        ]
        with tempfile.TemporaryDirectory(
                prefix="tmp", suffix="_sc3TESTS") as working_directory:
            filename = os.path.join(working_directory, 'solcore_log.txt')
            PDD.log(filename)

            my_solar_cell = SolarCell([AlGaAs(T), default_GaAs(T)],
                                      T=T,
                                      R_series=0,
                                      substrate=substrate)

            solar_cell_solver(my_solar_cell,
                              'qe',
                              user_options={
                                  'T_ambient': T,
                                  'db_mode': 'boltzmann',
                                  'voltages': V,
                                  'light_iv': True,
                                  'wavelength': wl,
                                  'optics_method': 'BL',
                                  'mpp': True,
                                  'internal_voltages': Vin,
                                  'light_source': light_source
                              })

            output = [
                my_solar_cell[0].eqe(500e-9), my_solar_cell[0].eqe(800e-9),
                my_solar_cell[1].eqe(700e-9), my_solar_cell[1].eqe(900e-9)
            ]

        for i in range(len(output)):
            self.assertAlmostEqual(output[i], answer[i])
Exemplo n.º 19
0
    def test_93_qe(self):
        answer = [
            0.9866334968497021, 2.1512408472022467e-14, 0.9779769012349702,
            0.03506561338387434
        ]
        with tempfile.TemporaryDirectory(
                prefix="tmp", suffix="_sc3TESTS") as working_directory:
            filename = os.path.join(working_directory, 'solcore_log.txt')
            PDD.log(filename)

            my_solar_cell = SolarCell([AlGaAs(T), default_GaAs(T)],
                                      T=T,
                                      R_series=0,
                                      substrate=substrate)

            solar_cell_solver(my_solar_cell,
                              'qe',
                              user_options={
                                  'T_ambient': T,
                                  'db_mode': 'boltzmann',
                                  'voltages': V,
                                  'light_iv': True,
                                  'wavelength': wl,
                                  'optics_method': 'BL',
                                  'mpp': True,
                                  'internal_voltages': Vin,
                                  'light_source': light_source
                              })

            output = [
                my_solar_cell[0].eqe(500e-9), my_solar_cell[0].eqe(800e-9),
                my_solar_cell[1].eqe(700e-9), my_solar_cell[1].eqe(900e-9)
            ]

        for i in range(len(output)):
            self.assertAlmostEqual(output[i], answer[i])
Exemplo n.º 20
0
# the 4* here makes the two layers given repeat 4 times (so 8 layers total)
bottom_junction = [
    Junction([
        Layer(si("405.048nm"), material=bot_buffer_material, role='window'),
        Layer(si("14.369nm"), material=bot_nucleation_material, role='window'),
        Layer(si("200nm"), material=bot_cell_n_material, role='emitter'),
        Layer(si("29800nm"), material=bot_cell_p_material, role='base')
    ],
             sn=1,
             sp=1,
             kind='DA')
]
# And, finally, we put everything together, adding also the surface recombination velocities sn and sp.
# setting kind = 'DA' in the Junction definition tells the electrical solver later to use the depletion approximation
optical_struct = SolarCell(ARC + top_junction + middle_junction + DBRa + DBRb +
                           DBRc + bottom_junction,
                           shading=0.05)

wl = np.linspace(250, 1700, 400) * 1e-9

options = State()
options.wavelength = wl
options.optics_method = 'TMM'
options.no_back_reflection = False
options.pol = 'p'
options.BL_correction = True
options.coherency_list = 111 * ['c']
options.theta = 30
solar_cell_solver(optical_struct, 'qe', options)

plt.figure()
Exemplo n.º 21
0
                relative_permittivity=11.68)
p_material = Si(T=T,
                Na=si(1e16, "cm-3"),
                electron_diffusion_length=si("150um"),
                hole_mobility=400e-4,
                relative_permittivity=11.68)

ARC_width = si("100nm")
n_material_width = si("500nm")
p_material_width = si("50um")

solar_cell = SolarCell([
    Layer(width=ARC_width, material=SiO2),
    Junction([
        Layer(width=n_material_width, material=n_material, role='emitter'),
        Layer(width=p_material_width, material=p_material, role='base'),
    ],
             sn=1,
             sp=1,
             kind='DA'),
])

total_width = ARC_width + n_material_width + p_material_width

options = default_options
options.optics_method = "TMM"
options.wavelength = wavelengths_optics
# options.position = np.linspace(0, total_width, 100000)
options.light_iv = True
V = np.linspace(0, 1.2, 200)

solar_cell_solver(solar_cell, 'iv', options)
light_source = LightSource(source_type='standard', version='AM1.5g', x=wl, output_units='photon_flux_per_m',
                           concentration=1)

color = ['b', 'g', 'r']
label = ['Top', 'Mid', 'Bot']

fig, ax = plt.subplots(1, 2, sharey='all', figsize=(7, 4.5))

for k, rad in enumerate([False, True]):

    # Input data for the 2D kind of junction
    db_junction = Junction(kind='2D', T=T, reff=0.3, jref=300, Eg=0.66, A=1, R_shunt=np.inf, n=3.5)
    db_junction2 = Junction(kind='2D', T=T, reff=1, jref=300, Eg=1.4, A=1, R_shunt=np.inf, n=3.5)
    db_junction3 = Junction(kind='2D', T=T, reff=1, jref=300, Eg=1.8, A=1, R_shunt=np.inf, n=3.5)

    my_solar_cell = SolarCell([db_junction3, db_junction2, db_junction], T=T, R_series=0)

    solar_cell_solver(my_solar_cell, 'iv',
                      user_options={'T_ambient': T, 'voltages': V, 'light_iv': True, 'wavelength': wl,
                                    'light_source': light_source, 'radiative_coupling': rad, 'mpp': True,
                                    'internal_voltages': Vin})

    # This is the total junction IV
    ax[k].plot(my_solar_cell.iv['IV'][0], my_solar_cell.iv['IV'][1], marker='o', color=colours("Black"), ls='-',
               markerfacecolor='none', markeredgecolor=colours("Black"))

    # This is the junciton IV when it is in the MJ device, including coupling if it is enabled. 
    for i, data in enumerate(my_solar_cell.iv['junction IV']):
        ax[k].plot(data[0], data[1], color[i] + '--', linewidth=2)

    # This is the junction IV as if it were an isolated device and therefore not affected by coupling or current limiting. 
Exemplo n.º 23
0
# The layer with nanoparticles
NP_layer = [
    Layer(si('50nm'),
          Air,
          geometry=[{
              'type': 'circle',
              'mat': TiO2,
              'center': (200, 200),
              'radius': 50
          }])
]

substrate = [Layer(width=si('50um'), material=GaAs)]
spacer = [Layer(width=si('25nm'), material=SiO2)]

solar_cell = SolarCell(spacer + GaAs_junction +
                       substrate)  # solar cell with SiO2 coating
opts.optics_method = 'TMM'
solar_cell_solver(solar_cell, 'qe', opts)
TMM_EQE = solar_cell[1].eqe(opts.wavelength)
opts.optics_method = 'BL'
solar_cell_solver(solar_cell, 'qe', opts)
BL_EQE = solar_cell[1].eqe(opts.wavelength)

solar_cell = SolarCell(spacer + GaAs_junction + DBR +
                       substrate)  # as above, with a DBR on the back
opts.optics_method = 'TMM'
solar_cell_solver(solar_cell, 'qe', opts)
TMM_EQE_DBR = solar_cell[1].eqe(opts.wavelength)

solar_cell = SolarCell(NP_layer + spacer + GaAs_junction + DBR + substrate)
# cell with TiO2 nanocylinder array on the front
Exemplo n.º 24
0
for mat in all_materials:
    mat.hole_mobility = 5e-2
    mat.electron_mobility = 3.4e-3
    mat.hole_mobility = 3.4e-3
    mat.electron_mobility = 5e-2
    mat.relative_permittivity = 9

# And, finally, we put everything together, adding also the surface recombination velocities. We also add some shading
# due to the metallisation of the cell = 8%, and indicate it has an area of 0.7x0.7 mm2 (converted to m2)
solar_cell = SolarCell(
    [
        Junction([Layer(si("25nm"), material=window_material, role='window'),
                  Layer(si("100nm"), material=top_cell_n_material, role='emitter'),
                  Layer(si("600nm"), material=top_cell_p_material, role='base'),
                  ], sn=1, sp=1, kind='DA'),
        Junction([Layer(si("200nm"), material=mid_cell_n_material, role='emitter'),
                  Layer(si("3000nm"), material=mid_cell_p_material, role='base'),
                  ], sn=1, sp=1, kind='DA'),
        Junction([Layer(si("400nm"), material=bot_cell_n_material, role='emitter'),
                  Layer(si("100um"), material=bot_cell_p_material, role='base'),
                  ], sn=1, sp=1, kind='DA'),
    ], reflectivity=ref, shading=0.08, cell_area=0.7 * 0.7 / 1e4)

wl = np.linspace(300, 1800, 700) * 1e-9
solar_cell_solver(solar_cell, 'qe', user_options={'wavelength': wl})

plt.figure(1)
plt.plot(wl * 1e9, solar_cell[0].eqe(wl) * 100, 'b', label='GaInP')
plt.plot(wl * 1e9, solar_cell[1].eqe(wl) * 100, 'g', label='InGaAs')
plt.plot(wl * 1e9, solar_cell[2].eqe(wl) * 100, 'r', label='Ge')
    output = Junction([
        Layer(width=si('30nm'), material=window, role="Window"),
        Layer(width=si('150nm'), material=p_AlGaAs, role="Emitter"),
        Layer(width=si('1000nm'), material=n_AlGaAs, role="Base"),
        Layer(width=si('200nm'), material=bsf, role="BSF")
    ],
                      sn=1e6,
                      sp=1e6,
                      T=T,
                      kind='PDD')

    return output


my_solar_cell = SolarCell([AlGaAs(T), default_GaAs(T)],
                          T=T,
                          R_series=0,
                          substrate=substrate)

Vin = np.linspace(-2, 2.61, 201)
V = np.linspace(0, 2.6, 300)
wl = np.linspace(350, 1000, 301) * 1e-9
light_source = LightSource(source_type='standard',
                           version='AM1.5g',
                           x=wl,
                           output_units='photon_flux_per_m',
                           concentration=1)

# We calculate the IV curve under illumination
solar_cell_solver(my_solar_cell,
                  'iv',
                  user_options={
Exemplo n.º 26
0
def run_solar_cell_model(task, model):
    """

    :param model:
    :return: a Solar cell object
    """

    # First, we take care of the options
    # ----------------------------------
    options = copy.copy(model['Global'])
    options.update(model['Electrical'])
    options.update(model['Optical'])
    T = float(options['T'])

    # We have to validate the options and check they have the correct format and type
    array_based_options = ['voltages', 'internal_voltages', 'position', 'wavelength']
    float_options = ['T', 'T_ambient']
    bool_options = ['mpp', 'light_iv', 'radiative_coupling']

    try:
        for p in options:
            # For the options that should be arrays, we create the arrays. The wavelength need ot be converted to meters
            if p in array_based_options:
                c = options[p].split(', ')
                ini = float(c[0])
                end = float(c[1])
                num = int(c[2])
                options[p] = np.linspace(ini, end, num) * 1e-9 ** (p == 'wavelength')

            # For the options that need to be floats
            elif p in float_options:
                options[p] = float(options[p])

            elif p in bool_options:
                options[p] = options[p].lower() in ['true', 'yes', 't', 1]

    except Exception as err:
        print('ERROR parsing the solver options: Option format not recognised')
        print(err)
        raise

    # Now we create the layers and junctions to the solar cell object
    # ---------------------------------------------------------------
    sc_data = model['Solar cell']
    all_layers = []
    all_materials = []

    for i in sc_data['structure']:
        current_element = sc_data[i[0]]

        # First the individual layers
        if 'Layer' in current_element['type']:
            layer_properties = {}
            width = current_element['width'] * 1e-9

            # Set the composition and get the properties, converting them to the correct units
            for key in current_element['options']:
                if key in ['element', 'x']:
                    layer_properties[current_element['options']['element']] = current_element['options']['x']
                else:
                    layer_properties[key] = current_element['options'][key] * conversion[key]

            all_materials.append(material(current_element['material'])(T=T, **layer_properties))

            all_layers.append(Layer(width, all_materials[-1], role=current_element['name']))
            continue

        # Unless it is an individual layer, we have junctions
        properties = {}
        for p in properties_junctions[current_element['type']]:
            properties[p] = default_junction_properties[p]

        properties.update(**current_element['options'])
        kind = current_element['type'].split('-')[-1]
        if 'TJ' in current_element['type']:
            new_junction = TunnelJunction(name=current_element['name'], kind=kind, T=T, **properties)
        else:
            new_junction = Junction(name=current_element['name'], kind=kind, T=T, **properties)

        # Now we add the layers, if any
        for l in i[1:]:
            current_child = sc_data[l]

            width = current_child['width'] * 1e-9
            layer_properties = {}

            # Set the composition and get the properties, converting them to the correct units
            for key in current_child['options']:
                if key in ['element', 'x']:
                    layer_properties[current_child['options']['element']] = current_child['options']['x']
                else:
                    layer_properties[key] = current_child['options'][key] * conversion[key]

            all_materials.append(material(current_child['material'])(T=T, **layer_properties))
            new_junction.append(Layer(width, all_materials[-1], role=current_child['name']))

        all_layers.append(new_junction)

    # Now we have to create the solar cell
    # ------------------------------------
    reflectivity = create_reflectivity(sc_data['reflectivity']) if sc_data['reflectivity'] != '' else None

    try:
        substrate = material(sc_data['substrate'])(T=T, **{sc_data['element']: sc_data['composition']})
    except KeyError:
        substrate = material(sc_data['substrate'])(T=T)

    sc = SolarCell(layers=all_layers, name=sc_data['name'], substrate=substrate, T=T, cell_area=sc_data['size'],
                   shading=sc_data['shading'], R_series=sc_data['r_series'], reflectivity=reflectivity)

    # With all said and done, we can run the solver
    # ---------------------------------------------
    solar_cell_solver(sc, task, user_options=options)
    print('Done!')

    return sc
Exemplo n.º 27
0
plt.xlabel("Wavelength (nm)")
plt.ylabel("k")
plt.show()

# Compare performance as a back mirror on a GaAs 'cell'

# Solid line: absorption in GaAs
# Dashed line: absorption in Ag

GaAs = material('GaAs')()

colors = ['b', 'r', 'k', 'm', 'y']

plt.figure()
for c, Ag_mat in enumerate([Ag_Joh, Ag_McP, Ag_Hag, Ag_Rak, Ag_Sol]):
    my_solar_cell = SolarCell([Layer(width=si('50nm'), material=GaAs)] +
                              [Layer(width=si('100nm'), material=Ag_mat)])
    solar_cell_solver(my_solar_cell, 'optics', opts)
    GaAs_positions = np.linspace(
        my_solar_cell[0].offset,
        my_solar_cell[0].offset + my_solar_cell[0].width, 1000)
    Ag_positions = np.linspace(
        my_solar_cell[1].offset,
        my_solar_cell[1].offset + my_solar_cell[1].width, 1000)
    GaAs_abs = np.trapz(my_solar_cell[0].diff_absorption(GaAs_positions),
                        GaAs_positions)
    Ag_abs = np.trapz(my_solar_cell[1].diff_absorption(Ag_positions),
                      Ag_positions)
    plt.plot(wl * 1e9,
             GaAs_abs,
             color=colors[c],
             linestyle='-',
Exemplo n.º 28
0
for mat in all_materials:
    mat.hole_mobility = 5e-2
    mat.electron_mobility = 3.4e-3
    mat.hole_mobility = 3.4e-3
    mat.electron_mobility = 5e-2
    mat.relative_permittivity = 9

# And, finally, we put everything together, adding also the surface recombination velocities. We also add some shading
# due to the metallisation of the cell = 8%, and indicate it has an area of 0.7x0.7 mm2 (converted to m2)
solar_cell = SolarCell(
    [
        Junction([Layer(si("25nm"), material=window_material, role='window'),
                  Layer(si("100nm"), material=top_cell_n_material, role='emitter'),
                  Layer(si("600nm"), material=top_cell_p_material, role='base'),
                  ], sn=1, sp=1, kind='DA'),
        Junction([Layer(si("200nm"), material=mid_cell_n_material, role='emitter'),
                  Layer(si("3000nm"), material=mid_cell_p_material, role='base'),
                  ], sn=1, sp=1, kind='DA'),
        # Uncomment the following to add the Ge junction. The calculation will be MUCH longer.
        # Junction([Layer(si("400nm"), material=bot_cell_n_material, role='emitter'),
        #           Layer(si("100um"), material=bot_cell_p_material, role='base'),
        #           ], sn=1, sp=1, kind='DA'),
    ], reflectivity=ref, shading=0.08, cell_area=0.7 * 0.7 / 1e4)

wl = np.linspace(300, 1800, 700) * 1e-9
solar_cell_solver(solar_cell, 'qe', user_options={'wavelength': wl})

plt.figure(1)
plt.plot(wl * 1e9, solar_cell[0].eqe(wl) * 100, 'b', label='GaInP')
plt.plot(wl * 1e9, solar_cell[1].eqe(wl) * 100, 'g', label='InGaAs')
# Uncomment to plot the Ge junction
# plt.plot(wl * 1e9, solar_cell[2].eqe(wl) * 100, 'r', label='Ge')
Exemplo n.º 29
0
    def __init__(self):
        GaAs = material('GaAs_WVASE')()
        Air = material('Air')()

        InAlP = material('InAlP_WVASE')()
        InGaP = material('InGaP_WVASE')()

        Ag = material('Ag_Jiang')()

        SiN = material('SiN_SE')()

        x = 600

        # anti-reflection coating
        ARC1 = [Layer(si('60nm'), SiN)]
        size = ((x, 0), (x / 2, np.sin(np.pi / 3) * x))

        wavelengths = np.linspace(250, 930, 200) * 1e-9

        RCWA_wl = wavelengths

        options = {
            'nm_spacing': 0.5,
            'n_theta_bins': 100,
            'c_azimuth': 1e-7,
            'pol': 's',
            'wavelengths': RCWA_wl,
            'theta_in': 0,
            'phi_in': 0,
            'parallel': True,
            'n_jobs': -1,
            'phi_symmetry': np.pi / 2,
            'project_name': 'ultrathin'
        }

        ropt = dict(LatticeTruncation='Circular',
                    DiscretizedEpsilon=True,
                    DiscretizationResolution=4,
                    PolarizationDecomposition=False,
                    PolarizationBasis='Default',
                    LanczosSmoothing=True,
                    SubpixelSmoothing=True,
                    ConserveMemory=False,
                    WeismannFormulation=True)

        options['rcwa_options'] = ropt

        grating = [
            Layer(si(100, 'nm'),
                  SiN,
                  geometry=[{
                      'type': 'circle',
                      'mat': Ag,
                      'center': (0, 0),
                      'radius': 100,
                      'angle': 0
                  }])
        ]
        solar_cell = SolarCell(ARC1 + [
            Layer(material=InGaP, width=si('19nm')),
            Layer(material=GaAs, width=si('86nm')),
            Layer(material=InAlP, width=si('18nm'))
        ] + grating)
        self.S4_setup = rcwa_structure(solar_cell, size, 37, options, Air, Ag)
        spect = np.loadtxt('AM0.csv', delimiter=',')

        self.AM0 = interp1d(spect[:, 0], spect[:, 1])(wavelengths * 1e9)
    def plot(self, x, icol=0):

        if icol == 'with_ARC' or icol == 'ideal_with_ARC' or icol == 'ideal' or icol == 'best':
            cols = sns.color_palette("husl", 4)
        else:
            cols = sns.cubehelix_palette(len(use_orders),
                                         start=.5,
                                         rot=-.9,
                                         reverse=True)

        GaAs = material('GaAs_WVASE')()
        Air = material('Air')()

        InAlP = material('InAlP_WVASE')()
        InGaP = material('InGaP_WVASE')()

        Ag = material('Ag_Jiang')()

        # MgF2 = material('MgF2')()
        # Ta2O5 = material('410', nk_db=True)()
        SiN = material('SiN_SE')()

        grating1 = [Layer(si(x[2] * x[1], 'nm'), SiN)]

        grating2 = [
            Layer(si((1 - x[1]) * x[2], 'nm'),
                  SiN,
                  geometry=[{
                      'type': 'circle',
                      'mat': Ag,
                      'center': (0, 0),
                      'radius': x[3],
                      'angle': 0
                  }])
        ]
        if icol == 'with_ARC' or icol == 'ideal_with_ARC':
            Al2O3 = material('354', nk_db=True)()
            solar_cell = SolarCell([
                Layer(material=Al2O3, width=si('70nm')),
                Layer(material=InGaP, width=si('19nm')),
                Layer(material=GaAs, width=si(x[0], 'nm')),
                Layer(material=InAlP, width=si('18nm'))
            ] + grating1 + grating2,
                                   substrate=Ag)

            S4_setup = rcwa_structure(solar_cell, self.size, self.orders,
                                      self.options, Air, Ag)

            RAT = S4_setup.calculate()
            EQE_sim = 0.9 * 100 * (RAT['A_layer'][:, 1] + RAT['A_layer'][:, 2])
            Acomb = RAT['A_layer'][:, 2] + RAT['A_layer'][:, 1]
            Jsc = np.round(
                0.1 * (q / (h * c)) *
                np.trapz(S4_setup.wavelengths * 1e9 * Acomb * self.AM0,
                         S4_setup.wavelengths * 1e9) / 1e9, 1)
            print('Jsc with ARC ', Jsc)

        else:
            solar_cell = SolarCell([
                Layer(material=InGaP, width=si('19nm')),
                Layer(material=GaAs, width=si(x[0], 'nm')),
                Layer(material=InAlP, width=si('18nm'))
            ] + grating1 + grating2,
                                   substrate=Ag)

            S4_setup = rcwa_structure(solar_cell, self.size, self.orders,
                                      self.options, Air, Ag)

            RAT = S4_setup.calculate()
            EQE_sim = 0.9 * 100 * (RAT['A_layer'][:, 0] + RAT['A_layer'][:, 1])
            Acomb = RAT['A_layer'][:, 0] + RAT['A_layer'][:, 1]
            Jsc = np.round(
                0.1 * (q / (h * c)) *
                np.trapz(S4_setup.wavelengths * 1e9 * Acomb * self.AM0,
                         S4_setup.wavelengths * 1e9) / 1e9, 1)
            print('Jsc without ARC ', Jsc)

        # plt.figure()
        if icol == 'ideal':
            plt.plot(S4_setup.wavelengths * 1e9,
                     EQE_sim,
                     color=cols[0],
                     label='Fully etched (' + str(Jsc) + ')')

        elif icol == 'with_ARC':

            plt.plot(S4_setup.wavelengths * 1e9,
                     EQE_sim,
                     '--',
                     color=cols[1],
                     label='Partly etched ith ARC (' + str(Jsc) + ')')

        elif icol == 'ideal_with_ARC':
            plt.plot(S4_setup.wavelengths * 1e9,
                     EQE_sim,
                     '--',
                     color=cols[2],
                     label='Fully etched with ARC (' + str(Jsc) + ')')

        elif icol == 'best':
            plt.plot(S4_setup.wavelengths * 1e9,
                     EQE_sim,
                     color=cols[3],
                     label='Best fit (' + str(Jsc) + ')')

        else:
            plt.plot(S4_setup.wavelengths * 1e9,
                     EQE_sim,
                     label='n = ' + str(self.orders),
                     color=cols[icol])

        # plt.show()
        return S4_setup.wavelengths * 1e9, self.EQE_meas