Ejemplo n.º 1
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
Ejemplo n.º 2
0
def test_layer_and_junction(qw_mat, b_mat, i_gaas, layer1, layer2, layer3):
    assert layer1.width == width1
    assert layer1.role == role1
    assert layer1.material == qw_mat
    assert layer1.geometry == wkt_box
    assert layer1.__dict__['new_property'] == 'new_property'

    assert layer2.width == width2
    assert layer2.role == role2
    assert layer2.material == b_mat
    assert layer2.geometry == wkt_box

    assert layer3.width == width3
    assert layer3.role == role3
    assert layer3.material == i_gaas
    assert layer3.geometry == wkt_box

    sn = random.uniform(1e6, 1e7)
    sp = random.uniform(1e6, 1e7)
    junction1 = Junction([layer1, layer2, layer3],
                         sn=sn,
                         sp=sp,
                         T=t,
                         kind='PDD')

    assert junction1.__len__() == 3
    assert junction1.__dict__ == {'sn': sn, 'sp': sp, 'T': t, 'kind': 'PDD'}
    assert junction1[0] == layer1
    assert junction1[1] == layer2
    assert junction1[2] == layer3

    tunnel1 = TunnelJunction([layer1, layer2, layer3],
                             sn=sn,
                             sp=sp,
                             T=t,
                             kind='PDD')

    assert tunnel1.__len__() == 3
    assert tunnel1.__dict__ == {
        'sn': sn,
        'sp': sp,
        'T': t,
        'kind': 'PDD',
        'R': 1e-16,
        'pn': True
    }
    assert tunnel1[0] == layer1
    assert tunnel1[1] == layer2
    assert tunnel1[2] == layer3
def test_get_depletion_widths():
    from solcore.analytic_solar_cells.depletion_approximation import get_depletion_widths
    from solcore.structure import Junction

    xi = np.power(10, np.random.uniform(-10, -6))

    Vbi = np.random.uniform(0, 3)
    es = np.random.uniform(1, 20) * vacuum_permittivity
    Na = np.power(10, np.random.uniform(22, 25))
    Nd = np.power(10, np.random.uniform(22, 25))

    V = np.linspace(-6, 4, 20)
    V = np.where(V < Vbi - 0.001, V, Vbi - 0.001)

    test_junc = Junction()

    wn_e = (-xi + np.sqrt(xi**2 + 2. * es * (Vbi - V) / q *
                          (1 / Na + 1 / Nd))) / (1 + Nd / Na)
    wp_e = (-xi + np.sqrt(xi**2 + 2. * es * (Vbi - V) / q *
                          (1 / Na + 1 / Nd))) / (1 + Na / Nd)

    wn_r, wp_r = get_depletion_widths(test_junc, es, Vbi, V, Na, Nd, xi)

    assert wn_r == approx(wn_e)
    assert wp_r == approx(wp_e)
def test_process_junction_pn():
    from solcore.analytic_solar_cells.depletion_approximation import identify_layers, identify_parameters
    from solcore import material
    from solcore.structure import Layer, Junction
    from solcore.state import State

    Na = np.power(10, np.random.uniform(22, 25))
    Nd = np.power(10, np.random.uniform(23, 26))

    options = State()
    options.T = np.random.uniform(250, 350)

    Lp = np.power(10, np.random.uniform(-9, -6))  # Diffusion length
    Ln = np.power(10, np.random.uniform(-9, -6))  # Diffusion length

    GaAs_n = material("GaAs")(Nd=Nd, hole_diffusion_length=Ln)
    GaAs_p = material("GaAs")(Na=Na, electron_diffusion_length=Lp)

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

    test_junc = Junction([Layer(p_width, GaAs_p, role="emitter"), Layer(n_width, GaAs_n, role="base")])

    id_top, id_bottom, pRegion, nRegion, iRegion, pn_or_np = identify_layers(test_junc)
    xn, xp, xi, sn, sp, ln, lp, dn, dp, Nd_c, Na_c, ni, es = identify_parameters(test_junc, options.T, pRegion, nRegion, iRegion)

    ni_expect = GaAs_n.ni

    assert [id_top, id_bottom] == approx([0, 1])
    assert pn_or_np == 'pn'
    assert [xn, xp, xi, sn, sp, ln, lp, dn, dp, Nd_c, Na_c, ni, es] == approx([n_width, p_width, 0, 0, 0, Lp, Ln, GaAs_n.hole_mobility * kb * options.T / q,
                                    GaAs_p.electron_mobility * kb * options.T / q, Nd, Na, ni_expect, GaAs_n.permittivity])
def test_process_junction_set_in_junction():
    from solcore.analytic_solar_cells.depletion_approximation import identify_layers, identify_parameters
    from solcore import material
    from solcore.structure import Layer, Junction
    from solcore.state import State

    options = State()
    options.T = np.random.uniform(250, 350)

    Lp = np.power(10, np.random.uniform(-9, -6))  # Diffusion length
    Ln = np.power(10, np.random.uniform(-9, -6))  # Diffusion length

    sn = np.power(10, np.random.uniform(0, 3))
    sp = np.power(10, np.random.uniform(0, 3))

    se = np.random.uniform(1, 20) * vacuum_permittivity

    GaAs_n = material("GaAs")()
    GaAs_p = material("GaAs")()
    GaAs_i = material("GaAs")()

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

    mun = np.power(10, np.random.uniform(-5, 0))
    mup = np.power(10, np.random.uniform(-5, 0))

    Vbi = np.random.uniform(0, 3)

    test_junc = Junction([
        Layer(p_width, GaAs_p, role="emitter"),
        Layer(i_width, GaAs_i, role="intrinsic"),
        Layer(n_width, GaAs_n, role="base")
    ],
                         sn=sn,
                         sp=sp,
                         permittivity=se,
                         ln=Ln,
                         lp=Lp,
                         mup=mup,
                         mun=mun,
                         Vbi=Vbi)

    id_top, id_bottom, pRegion, nRegion, iRegion, pn_or_np = identify_layers(
        test_junc)
    xn, xp, xi, sn_c, sp_c, ln, lp, dn, dp, Nd_c, Na_c, ni, es = identify_parameters(
        test_junc, options.T, pRegion, nRegion, iRegion)

    ni_expect = GaAs_n.ni

    assert [id_top, id_bottom] == approx([0, 2])
    assert pn_or_np == 'pn'
    assert [xn, xp, xi, sn_c, sp_c, ln, lp, dn, dp, Nd_c, Na_c, ni,
            es] == approx([
                n_width, p_width, i_width, sn, sp, Ln, Lp,
                mun * kb * options.T / q, mup * kb * options.T / q, 1, 1,
                ni_expect, se
            ])
def test_identify_layers_exceptions():
    from solcore.analytic_solar_cells.depletion_approximation import identify_layers
    from solcore import material
    from solcore.structure import Layer, Junction

    Na = np.power(10, np.random.uniform(22, 25))
    Nd = np.power(10, np.random.uniform(22, 25))

    Lp = np.power(10, np.random.uniform(-9, -6))  # Diffusion length
    Ln = np.power(10, np.random.uniform(-9, -6))  # Diffusion length

    GaAs_n = material("GaAs")(Nd=Nd, hole_diffusion_length=Ln)
    GaAs_p = material("GaAs")(Na=Na, electron_diffusion_length=Lp)
    GaAs_i = material("GaAs")()
    Ge_n = material("Ge")(Nd=Nd, hole_diffusion_length=Ln)

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

    test_junc = Junction([
        Layer(n_width, GaAs_n, role="emitter"),
        Layer(p_width, GaAs_p, role="neither")
    ])

    with raises(RuntimeError):
        identify_layers(test_junc)

    test_junc = Junction([
        Layer(n_width, GaAs_n, role="emitter"),
        Layer(i_width, GaAs_i, role="intrinsic"),
        Layer(p_width, GaAs_p, role="nothing")
    ])

    with raises(RuntimeError):
        identify_layers(test_junc)

    test_junc = Junction([
        Layer(n_width, Ge_n, role="emitter"),
        Layer(p_width, GaAs_p, role="base")
    ])

    with raises(AssertionError):
        identify_layers(test_junc)
Ejemplo n.º 7
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_get_depletion_widths_set_in_junction():
    from solcore.analytic_solar_cells.depletion_approximation import get_depletion_widths
    from solcore.structure import Junction

    wn = np.random.uniform(1, 100)
    wp = np.random.uniform(1, 100)
    test_junc = Junction(wn=wn, wp=wp)

    wn_r, wp_r = get_depletion_widths(test_junc, 0, 0, 0, 0, 0, 0)

    assert wn_r == approx(wn)
    assert wp_r == approx(wp)
Ejemplo n.º 9
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
Ejemplo n.º 10
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
Ejemplo n.º 11
0
def default_GaAs(T):
    # We create the other materials we need for the device
    window = material('AlGaAs')(T=T, Na=5e24, Al=0.8)
    p_GaAs = material('GaAs')(T=T, Na=1e24)
    n_GaAs = material('GaAs')(T=T, Nd=8e22)
    bsf = material('GaAs')(T=T, Nd=2e24)

    output = Junction([
        Layer(width=si('30nm'), material=window, role="Window"),
        Layer(width=si('150nm'), material=p_GaAs, role="Emitter"),
        Layer(width=si('3000nm'), material=n_GaAs, role="Base"),
        Layer(width=si('200nm'), material=bsf, role="BSF")
    ],
                      sn=1e6,
                      sp=1e6,
                      T=T,
                      kind='PDD')

    return output
Ejemplo n.º 12
0
def AlGaAs(T):
    # We create the other materials we need for the device
    window = material("AlGaAs")(T=T, Na=5e24, Al=0.8)
    p_AlGaAs = material("AlGaAs")(T=T, Na=1e24, Al=0.4)
    n_AlGaAs = material("AlGaAs")(T=T, Nd=8e22, Al=0.4)
    bsf = material("AlGaAs")(T=T, Nd=2e24, Al=0.6)

    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
def test_get_depletion_widths_onesided():
    from solcore.analytic_solar_cells.depletion_approximation import get_depletion_widths
    from solcore.structure import Junction

    xi = np.power(10, np.random.uniform(-10, -6))

    Vbi = np.random.uniform(0, 3)
    es = np.random.uniform(1, 20) * vacuum_permittivity
    Na = np.power(10, np.random.uniform(22, 25))
    Nd = np.power(10, np.random.uniform(22, 25))

    V = np.linspace(-6, 4, 20)
    V = np.where(V < Vbi - 0.001, V, Vbi - 0.001)

    test_junc = Junction(depletion_approximation="one-sided abrupt")

    wn_e = np.sqrt(2 * es * (Vbi - V) / (q * Nd))
    wp_e = np.sqrt(2 * es * (Vbi - V) / (q * Na))

    wn_r, wp_r = get_depletion_widths(test_junc, es, Vbi, V, Na, Nd, xi)

    assert wn_r == approx(wn_e)
    assert wp_r == approx(wp_e)
Ejemplo n.º 14
0
def AlGaAs():
    from solcore import material
    from solcore.structure import Layer, Junction
    from solcore import si

    T = 298
    # We create the other materials we need for the device
    window = material("AlGaAs")(T=T, Na=5e24, Al=0.8)
    p_AlGaAs = material("AlGaAs")(T=T, Na=1e24, Al=0.4)
    n_AlGaAs = material("AlGaAs")(T=T, Nd=8e22, Al=0.4)
    bsf = material("AlGaAs")(T=T, Nd=2e24, Al=0.6)

    return 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",
    )
    Layer(si(79, 'nm'),
          SiN,
          geometry=[{
              'type': 'circle',
              'mat': Ag,
              'center': (0, 0),
              'radius': 110,
              'angle': 0
          }])
]

solar_cell = SolarCell([
    Junction([
        Layer(material=window_material, width=si('19nm'), role='window'),
        Layer(material=top_cell_p_material, width=si('43.5nm'),
              kind='emitter'),
        Layer(material=top_cell_n_material, width=si('43.5nm'), kind='base'),
        Layer(material=bsf_material, width=si('18nm'))
    ],
             kind='PDD')
] + grating1 + grating2,
                       substrate=Ag)

solar_cell_solver(solar_cell, 'qe', user_options=options)

#solar_cell_solver(solar_cell, 'iv', user_options=options)

EQE_data = np.loadtxt('data/V2A_9_EQE.dat', skiprows=129)

solar_cell_optical = SolarCell([
    Layer(material=InGaP_nk, width=si('19nm')),
    Layer(material=GaAs_nk, width=si('43.5nm')),
Ejemplo n.º 16
0
# We add some other properties to the materials, assumed the same in all cases, for simplicity.
# If different, we should have added them above in the definition of the materials.

for mat in all_materials:

    mat.hole_mobility = 3.4e-3
    mat.electron_mobility = 5e-2

ARC = [Layer(si('80nm'), material=ARC1), Layer(si('33nm'), material=ARC2)]

top_junction = [
    Junction([
        Layer(si("18nm"), material=top_window_material, role='window'),
        Layer(si("100nm"), material=top_cell_n_material, role='emitter'),
        Layer(si("891.248nm"), material=top_cell_p_material, role='base'),
        Layer(si("111.445nm"), material=top_cell_TJ_material, role='TJ')
    ],
             sn=1,
             sp=1,
             kind='DA')
]
middle_junction = [
    Junction([
        Layer(si("18nm"), material=mid_window_material, role='window'),
        Layer(si("100nm"), material=mid_cell_n_material, role='emitter'),
        Layer(si("1632.091nm"), material=mid_cell_p_material, role='base'),
        Layer(si("10nm"), material=mid_BSF_material, role='BSF'),
        Layer(si("91.084nm"), material=mid_cell_TJ_material, role='TJ')
    ],
             sn=1,
             sp=1,
Ejemplo n.º 17
0
# Height of the metal fingers (m)
h = 2.2e-6

# Contact resistance (Ohm m2)
Rcontact = 3e-10

# Resistivity metal fingers (Ohm m)
Rline = 2e-8

# Bias (V)
vini = 0
vfin = 1.3
step = 0.01

T = 298
db_junction = Junction(kind='2D', T=T, reff=1, jref=300, Eg=0.66, A=1, R_sheet_top=100, R_sheet_bot=1e-16,
                       R_shunt=1e16, n=3.5)
db_junction2 = Junction(kind='2D', T=T, reff=1, jref=300, Eg=1.4, A=1, R_sheet_top=100, R_sheet_bot=1e-16,
                        R_shunt=1e16, n=3.5)
db_junction3 = Junction(kind='2D', T=T, reff=0.5, jref=300, Eg=1.8, A=1, R_sheet_top=100, R_sheet_bot=100,
                        R_shunt=1e16, n=3.5)

# For a single junction, this will have >28800 nodes and for the full 3J it will be >86400, so it is worth to
# exploit symmetries whenever possible. A smaller number of nodes also makes the solver more robust.
my_solar_cell = SolarCell([db_junction2], T=T)

wl = np.linspace(350, 2000, 301) * 1e-9
light_source = LightSource(source_type='standard', version='AM1.5g', x=wl, output_units='photon_flux_per_m',
                           concentration=100)

options = {'light_iv': True, 'wavelength': wl, 'light_source': light_source, 'optics_method': 'BL'}
Ejemplo n.º 18
0
# We add some other properties to the materials, assumed the same in all cases, for simplicity.
# If different, we should have added them above in the definition of the materials.
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')
Ejemplo n.º 19
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
Ejemplo n.º 20
0
    def make_cell(self, x):

        #x[0]: total InGaP thickness
        #x[1]: total InGaAs thickness
        #x[2]: total SiGeSn thickness
        #x[3]: total Ge thickness

        #x[4]: InGaP n thickness
        #x[5]: InGaAs n thickness
        #x[6]: SiGeSn n thickness
        #x[7]: Ge n thickness

        e_charge = si('1eV')

        # materials
        SiGeSn = material('SiGeSn')

        GaAs = material('GaAs')
        InGaP = material('GaInP')
        Ge = material('Ge')
        MgF2 = material('MgF2')()
        Ta2O5 = material('410', nk_db=True)()
        AlInP = material("AlInP")

        window_material = AlInP(Al=0.52)

        GaInP_mobility_h = 0.03  #
        GaInP_lifetime_h = 1e-8
        GaInP_D_h = GaInP_mobility_h * kb * 300 / e_charge
        GaInP_L_h = np.sqrt(GaInP_D_h * GaInP_lifetime_h)
        GaInP_mobility_e = 0.015
        GaInP_lifetime_e = 1e-8
        GaInP_D_e = GaInP_mobility_e * kb * 300 / e_charge
        GaInP_L_e = np.sqrt(GaInP_D_e * GaInP_lifetime_e)

        top_cell_n_material = InGaP(In=0.5,
                                    Nd=si("2e18cm-3"),
                                    hole_diffusion_length=GaInP_L_h,
                                    relative_permittivity=11.75,
                                    hole_mobility=GaInP_mobility_h)
        top_cell_p_material = InGaP(In=0.5,
                                    Na=si("2e17cm-3"),
                                    electron_diffusion_length=GaInP_L_e,
                                    relative_permittivity=11.75,
                                    electron_mobility=GaInP_mobility_e)

        # MID CELL  - GaAs

        GaAs_mobility_h = 0.85  #
        GaAs_lifetime_h = 1e-8
        GaAs_D_h = GaAs_mobility_h * kb * 300 / e_charge
        GaAs_L_h = np.sqrt(GaAs_D_h * GaAs_lifetime_h)
        GaAs_mobility_e = 0.08
        GaAs_lifetime_e = 1e-8
        GaAs_D_e = GaAs_mobility_e * kb * 300 / e_charge
        GaAs_L_e = np.sqrt(GaAs_D_e * GaAs_lifetime_e)

        mid_cell_n_material = GaAs(Nd=si("1e18cm-3"),
                                   hole_diffusion_length=GaAs_L_h,
                                   relative_permittivity=13.1,
                                   hole_mobility=GaAs_mobility_h)
        mid_cell_p_material = GaAs(Na=si("1e17cm-3"),
                                   electron_diffusion_length=GaAs_L_e,
                                   relative_permittivity=13.1,
                                   electron_mobility=GaAs_mobility_e)

        SiGeSn.band_gap = si('0.77eV')  # from PL measurement
        SiGeSn_L_h = si('0.35um')
        SiGeSn_L_e = si('5um')
        SiGeSn_lifetime_e = 1e-6
        SiGeSn_lifetime_h = 1e-6
        SiGeSn_mobility_h = SiGeSn_L_h**2 * e_charge / (SiGeSn_lifetime_h *
                                                        kb * 300)
        SiGeSn_mobility_e = SiGeSn_L_e**2 * e_charge / (SiGeSn_lifetime_e *
                                                        kb * 300)

        pen_cell_n_material = SiGeSn(Nd=si("1e18cm-3"),
                                     hole_diffusion_length=SiGeSn_L_h,
                                     relative_permittivity=16,
                                     hole_mobility=SiGeSn_mobility_h)
        pen_cell_p_material = SiGeSn(Na=si("1e17cm-3"),
                                     electron_diffusion_length=SiGeSn_L_e,
                                     relative_permittivity=16,
                                     electron_mobility=SiGeSn_mobility_e)

        # Ge_mobility_h = 0.38 #
        Ge_lifetime_h = 1e-6
        # Ge_D_h = Ge_mobility_h*kb*300/e_charge
        # Ge_L_h = np.sqrt(Ge_D_h*Ge_lifetime_h)
        Ge_L_h = si('500nm')
        Ge_mobility_h = Ge_L_h**2 * e_charge / (Ge_lifetime_h * kb * 300)
        Ge_mobility_e = 0.18
        Ge_lifetime_e = 1e-6
        Ge_D_e = Ge_mobility_e * kb * 300 / e_charge
        Ge_L_e = np.sqrt(Ge_D_e * Ge_lifetime_e)

        bot_cell_n_material = Ge(Nd=si("2e18cm-3"),
                                 hole_diffusion_length=Ge_L_h,
                                 relative_permittivity=16,
                                 hole_mobility=Ge_mobility_h)
        bot_cell_p_material = Ge(Na=si("1e17cm-3"),
                                 electron_diffusion_length=Ge_L_e,
                                 relative_permittivity=16,
                                 electron_mobility=Ge_mobility_e)

        # 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(
            [
                # Layer(si('110nm'), material = MgF2), Layer(si('55nm'), material = ZnS),
                Layer(si(self.ARC[0], 'nm'), material=MgF2),
                Layer(si(self.ARC[1], 'nm'), material=Ta2O5),
                Junction([
                    Layer(
                        si(25, 'nm'), material=window_material, role='window'),
                    Layer(si(x[4], 'nm'),
                          material=top_cell_n_material,
                          role='emitter'),
                    Layer(si(x[0] - x[4], 'nm'),
                          material=top_cell_p_material,
                          role='base'),
                ],
                         sn=1,
                         sp=1,
                         kind='DA'),
                Junction([
                    Layer(si(x[5], 'nm'),
                          material=mid_cell_n_material,
                          role='emitter'),
                    Layer(si(x[1] - x[5], 'nm'),
                          material=mid_cell_p_material,
                          role='base'),
                ],
                         sn=1,
                         sp=1,
                         kind='DA'),
                Junction([
                    Layer(si(x[6], 'nm'),
                          material=pen_cell_n_material,
                          role='emitter'),
                    Layer(si(x[2] - x[6], 'nm'),
                          material=pen_cell_p_material,
                          role='base'),
                ],
                         sn=1,
                         sp=1,
                         kind='DA'),
                Junction([
                    Layer(si(x[7], 'nm'),
                          material=bot_cell_n_material,
                          role='emitter'),
                    Layer(si(x[3] - x[7], 'nm'),
                          material=bot_cell_p_material,
                          role='base'),
                ],
                         sn=1,
                         sp=1,
                         kind='DA'),
            ],
            shading=0.0,
            substrate=bot_cell_n_material)

        return solar_cell
Ejemplo n.º 21
0
n_GaAs = material('GaAs')(T=T, Nd=si('2e17cm-3'))  # for the GaAs cell base
AlAs, GaAs = material('AlAs')(T=T), material('GaAs')(T=T)  # for the DBR
SiO2 = material('SiO2', sopra=True)(T=T)  # for the spacer layer
TiO2 = material('TiO2', sopra=True)(T=T)  # for the nanoparticles

# some parameters for the QE solver
for mat in [n_GaAs, p_GaAs]:
    mat.hole_mobility, mat.electron_mobility, mat.permittivity = 3.4e-3, 5e-2, 9
    n_GaAs.hole_diffusion_length, p_GaAs.electron_diffusion_length = si(
        "500nm"), si("5um")

# Define the different parts of the structure we will use. For the GaAs junction, we use the depletion approximation
GaAs_junction = [
    Junction([
        Layer(width=si('100nm'), material=p_GaAs, role="emitter"),
        Layer(width=si('400nm'), material=n_GaAs, role="base")
    ],
             T=T,
             kind='DA')
]

# this creates 10 repetitions of the AlAs and GaAs layers, to make the DBR structure
DBR = 10 * [
    Layer(width=si("73nm"), material=AlAs),
    Layer(width=si("60nm"), material=GaAs)
]

# The layer with nanoparticles
NP_layer = [
    Layer(si('50nm'),
          Air,
          geometry=[{
Vin = np.linspace(-6, 2, 600)
V = np.linspace(-1.5, 4, 500)
wl = np.linspace(350, 2000, 301) * 1e-9
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. 
Ejemplo n.º 23
0
import numpy as np
from solcore.solar_cell import SolarCell
from solcore.light_source import LightSource
from solcore.spice.pv_module_solver import solve_pv_module
import matplotlib.pyplot as plt

from solcore.structure import Junction

T = 298

# First we define the properties of the MJ solar cell that the solar module is made of. We use junctions of kind 2-diode
db_junction = Junction(kind='2D', T=T, reff=1, jref=300, Eg=0.66, A=1, R_series=0.00236, R_shunt=1e14, n=3.5)
db_junction2 = Junction(kind='2D', T=T, reff=1, jref=300, Eg=1.4, A=1, R_series=0.00012, R_shunt=1e14, n=3.5)
db_junction3 = Junction(kind='2D', T=T, reff=1, jref=300, Eg=1.9, A=1, R_series=8.0e-5, R_shunt=1e14, n=3.5)

my_solar_cell = SolarCell([db_junction3, db_junction2, db_junction], T=T, R_series=0.0, area=0.1)

wl = np.linspace(350, 2000, 301) * 1e-9
light_source = LightSource(source_type='standard', version='AM1.5g', x=wl,
                           output_units='photon_flux_per_m', concentration=1)

options = {'light_iv': True, 'wavelength': wl, 'light_source': light_source}

# After defining the individual solar cell, we solve the module IV characteristics adding some dispersion in the values of the short circuit currents.
voltage, current, all_Isc_values, raw_data = solve_pv_module(my_solar_cell, options, jscSigma=0.02)

plt.figure(1)

plt.subplot(311)
plt.title('Histogram of sub-cell photocurrents')
plt.ylabel('InGaP')
Ejemplo n.º 24
0
# We solve the quantum properties of the QW, leaving the default values of all parameters
QW_list = PDD.SolveQWproperties(QW, wavelengths=wl)

# Materials for the BOTTOM junction
window_bottom = material('GaInP')(T=T, Nd=5e24, In=0.49)
n_GaAs = material('GaAs')(T=T, Nd=1e24)
p_GaAs = material('GaAs')(T=T, Na=8e22)
bsf_bottom = material('GaInP')(T=T, Na=5e24, In=0.49)

# If you want to test the code without QWs, to make ti a bit faster, comment the line with QW_list
GaAs_junction = Junction([
    Layer(width=10e-9, material=window_bottom, role="Window"),
    Layer(width=150e-9, material=n_GaAs, role="Emitter")
] + QW_list + [
    Layer(width=2000e-9, material=p_GaAs, role="Base"),
    Layer(width=200e-9, material=bsf_bottom, role="BSF")
],
                         sn=1e6,
                         sp=1e6,
                         T=T,
                         kind='PDD')

# Materials for the TOP junction
window_top = material('AlInP')(T=T,
                               Nd=5e23,
                               Al=0.53,
                               electron_mobility=0.01,
                               hole_mobility=7e-4)
n_GaInP = material('GaInP')(T=T, Nd=5e23, In=0.49)
p_GaInP = material('GaInP')(T=T, Na=8e22, In=0.49)
bsf_top = material('AlInP')(T=T,
Ejemplo n.º 25
0
# Materials for the BOTTOM junction
window_bottom = material("GaInP")(T=T, Nd=5e24, In=0.49)
n_GaAs = material("GaAs")(T=T, Nd=1e24)
p_GaAs = material("GaAs")(T=T, Na=8e22)
bsf_bottom = material("GaInP")(T=T, Na=5e24, In=0.49)

# If you want to test the code without QWs, to make ti a bit faster, comment the line
# with QW_list
GaAs_junction = Junction(
    [
        Layer(width=10e-9, material=window_bottom, role="Window"),
        Layer(width=150e-9, material=n_GaAs, role="Emitter"),
    ]
    # Comment the following line to remove the QWs
    + QW_list + [
        Layer(width=2000e-9, material=p_GaAs, role="Base"),
        Layer(width=200e-9, material=bsf_bottom, role="BSF"),
    ],
    sn=1e6,
    sp=1e6,
    T=T,
    kind="PDD",
)

# Materials for the TOP junction
window_top = material("AlInP")(T=T,
                               Nd=5e23,
                               Al=0.53,
                               electron_mobility=0.01,
                               hole_mobility=7e-4)
n_GaInP = material("GaInP")(T=T, Nd=5e23, In=0.49)