Ejemplo n.º 1
0
options = default_options
options.nm_spacing = 0.5
options.wavelengths = wavelengths
options.project_name = 'test_matrix2'
options.n_rays = 1e4
options.n_theta_bins = 100
options.phi_symmetry = np.pi / 4
options.I_thresh = 1e-10
options.lookuptable_angles = 200
options.parallel = True
options.c_azimuth = 0.05
options.theta_in = 80 * np.pi / 180
options.phi_in = 0

Si = material('Si')()
GaAs = material('GaAs')()
GaInP = material('GaInP')(In=0.5)
Ag = material('Ag')()
SiN = material('Si3N4')()
Air = material('Air')()

# stack based on doi:10.1038/s41563-018-0115-4
front_materials = [Layer(60e-9, SiN), Layer(50E-9, GaInP), Layer(50e-9, GaAs)]
back_materials = [Layer(100E-9, GaInP), Layer(70e-9, GaAs)]

# whether pyramids are upright or inverted is relative to front incidence.
# so if the same etch is applied to both sides of a slab of silicon, one surface
# will have 'upright' pyramids and the other side will have 'not upright' (inverted)
# pyramids in the model
Ejemplo n.º 2
0
def i_gaas():
    return material(i_gaas_material_name)(T=t)
Ejemplo n.º 3
0
import numpy as np
import os
import tempfile

import solcore.poisson_drift_diffusion as PDD
from solcore.solar_cell import SolarCell, default_GaAs
from solcore.structure import Layer, Junction
from solcore import si
from solcore import material
from solcore.light_source import LightSource
from solcore.solar_cell_solver import solar_cell_solver

T = 298

substrate = material('GaAs')(T=T)


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")
    ],
Ejemplo n.º 4
0
    if calculate_absorption:
        result_band_edge["alpha"] = calc_alpha(result_band_edge,
                                               **alpha_params)
        result_band_edge["alphaE"] = interp1d(x=result_band_edge["alpha"][0],
                                              y=result_band_edge["alpha"][1])

    return result_band_edge, bands


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

    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
Ejemplo n.º 5
0
def qw_mat():
    return material(qw_mat_material_name)(T=t, In=qw_mat_in)
Ejemplo n.º 6
0
    def test_43_TMM_absorption_profile(self):
        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)

        for i in range(len(out['absorption'][0])):
            self.assertAlmostEqual(data[i], out['absorption'][0][i])
Ejemplo n.º 7
0
    'phi_in': 1e-6,
    'I_thresh': 0.001,
    #'coherent': True,
    #'coherency_list': None,
    #'lookuptable_angles': 200,
    #'prof_layers': [1,2],
    #'n_rays': 100000,
    #'random_angles': False,
    #'nx': 5, 'ny': 5,
    'parallel': True,
    'n_jobs': -1,
    'phi_symmetry': np.pi / 2,
    'only_incidence_angle': True
}

Si = material('Si_OPTOS')()
Air = material('Air')()

# materials with constant n, zero k
x = 1000

d_vectors = ((x, 0), (0, x))
area_fill_factor = 0.36
hw = np.sqrt(area_fill_factor) * 500

front_materials = []
back_materials = [
    Layer(si('120nm'),
          Si,
          geometry=[{
              'type': 'rectangle',
Ejemplo n.º 8
0
import numpy as np
import matplotlib.pyplot as plt

from solcore import material, si

from solcore.solar_cell import SolarCell, Layer, Junction
from solcore.solar_cell_solver import solar_cell_solver, prepare_solar_cell
from solcore.state import State

GaInP = material("GaInP")(In=0.5)
GaAs = material("GaAs")()
Ge = material("Ge")()

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

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

options = State()
options.wavelength = wl
options.optics_method = "TMM"
options.no_back_reflection = False
search_db('Ag', exact=True)
# This prints out, line by line, matching entries. This shows us entries with
# "pageid"s 0 to 14 correspond to silver.

# Let's compare the optical behaviour of some of those sources:
# pageid = 0, Johnson
# pageid = 2, McPeak
# pageid = 8, Hagemann
# pageid = 12, Rakic (BB)

# create instances of materials with the optical constants from the database.
# The name (when using Solcore's built-in materials, this would just be the
# name of the material or alloy, like 'GaAs') is the pageid, AS A STRING, while
# the flag nk_db must be set to True to tell Solcore to look in the previously
# downloaded database from refractiveindex.info
Ag_Joh = material(name='0', nk_db=True)()

Ag_McP = material(name='2', nk_db=True)()
Ag_Hag = material(name='8', nk_db=True)()
Ag_Rak = material(name='12', nk_db=True)()

Ag_Sol = material(name='Ag')()  # Solcore built-in (from SOPRA)

# plot the n and k data. Note that not all the data covers the full wavelength range,
# so the n/k value stays flat.

names = ['Johnson', 'McPeak', 'Hagemann', 'Rakic', 'Solcore built-in']

plt.figure()
plt.plot(wl * 1e9, Ag_Joh.n(wl), wl * 1e9, Ag_McP.n(wl), wl * 1e9,
         Ag_Hag.n(wl), wl * 1e9, Ag_Rak.n(wl), wl * 1e9, Ag_Sol.n(wl))
Ejemplo n.º 10
0
# matrix multiplication
wavelengths = np.linspace(300, 1200, 200)*1e-9

options = default_options
options.nm_spacing = 0.5
options.wavelengths = wavelengths
options.project_name = 'Perovskite_Si_1e6_150wl'
options.n_rays = 100000
options.n_theta_bins = 100
options.phi_symmetry = np.pi/4
options.I_thresh = 1e-4
options.lookuptable_angles = 200
options.parallel = True
options.only_incidence_angle = True

Si = material('Si')()
Air = material('Air')()
MgF2 = material('MgF2_RdeM')()
ITO_back = material('ITO_lowdoping')()
Perovskite = material('Perovskite_CsBr')()
Ag = material('Ag_Jiang')()
aSi_i = material('aSi_i')()
aSi_p = material('aSi_p')()
aSi_n = material('aSi_n')()
LiF = material('LiF')()
IZO = material('IZO')()
C60 = material('C60')()

# materials with constant n, zero k
Spiro = [12e-9, np.array([0,1]), np.array([1.65, 1.65]), np.array([0,0])]
SnO2 = [10e-9, np.array([0,1]), np.array([2, 2]), np.array([0,0])]
pal = sns.cubehelix_palette(15)

cols = cycler('color', pal)

params = {
    'legend.fontsize': 'small',
    'axes.labelsize': 'small',
    'axes.titlesize': 'small',
    'xtick.labelsize': 'small',
    'ytick.labelsize': 'small',
    'axes.prop_cycle': cols
}

plt.rcParams.update(params)

Air = material('Air')()
Si = material('566', nk_db=True)()

size = 5
#for size in [4]:
n_passes = []
nxy = [5, 10, 20, 35, 50]
reps = [1, 2, 4, 10]

calc = True

options = {
    'wavelengths': np.arange(300, 1201, 20) * 1e-9,
    'theta': 0 * np.pi / 180,
    'phi': 0,
    'I_thresh': 1e-2,
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
       (6.15, 1.69), (5.39, 2.14), (5.89, 1.41), (5.40, 2.49), (5.44, 1.21),
       (5.67, 0.73)]

zz = np.linspace(0, 1, 100)
lat = np.zeros_like(zz)
eg = np.zeros_like(zz)

colors = plt.cm.jet(np.linspace(0, 1, len(mat)))

fig = plt.figure(figsize=(6, 4.5))
ax = fig.add_subplot(111)

for j, (m, x) in enumerate(zip(mat, xx)):
    for i, z in enumerate(zz):
        param = {x: z}
        new_mat = material(m)(T=300, **param)

        lat[i] = new_mat.lattice_constant * 1e10
        eg[i] = asUnit(new_mat.band_gap, 'eV')

    ax.plot(lat, eg, label=m, color=colors[j])

lat2 = []
eg2 = []
for (m, p) in zip(mat2, pos):
    new_mat = material(m)(T=300)

    lat2.append(new_mat.lattice_constant * 1e10)
    eg2.append(asUnit(new_mat.band_gap, 'eV'))

    ax.annotate(m, xy=p)
Ejemplo n.º 14
0
import numpy as np
import matplotlib.pyplot as plt

from solcore import material, si

from solcore.solar_cell import SolarCell, Layer, Junction
from solcore.solar_cell_solver import solar_cell_solver, prepare_solar_cell
from solcore.state import State

GaInP = material('GaInP')(In=0.5)
GaAs = material('GaAs')()
Ge = material('Ge')()

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

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

options = State()
options.wavelength = wl
options.optics_method = 'TMM'
options.no_back_reflexion = False
options.BL_correction = True
options.recalculate_absorption = True

options.theta = 0

Ejemplo n.º 15
0
from solcore import material
from solcore.structure import Layer, Junction, TunnelJunction
from solcore.solar_cell import SolarCell
from solcore.solar_cell_solver import solar_cell_solver
from solcore.light_source import LightSource
import solcore.poisson_drift_diffusion as PDD

import numpy as np
import matplotlib.pyplot as plt

T = 298
wl = np.linspace(350, 1050, 601) * 1e-9

# First, we create the materials of the QW
QWmat = material('InGaAs')(T=T, In=0.2, strained=True)
Bmat = material('GaAsP')(T=T, P=0.1, strained=True)
i_GaAs = material('GaAs')(T=T)

# The QW is 7 nm wide, with GaAs interlayers 2 nm thick at each side and GaAsP barriers 10 nm thick.
# The final device will have 30 of these QWs.
QW = PDD.CreateDeviceStructure('QW',
                               T=T,
                               repeat=30,
                               substrate=i_GaAs,
                               layers=[
                                   Layer(width=10e-9,
                                         material=Bmat,
                                         role="barrier"),
                                   Layer(width=2e-9,
                                         material=i_GaAs,
                                         role="interlayer"),
Ejemplo n.º 16
0
from solcore import si, material
from solcore.structure import Layer, Structure
import matplotlib.pyplot as plt
import numpy as np
import solcore.quantum_mechanics as QM
from solcore.constants import vacuum_permittivity, q

# 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=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

# We define some parameters need to calculate the shape of the excitonic absorption
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"
Ejemplo n.º 17
0
    return 2 * np.pi * (A_back + A_front)


if __name__ == '__main__':
    import numpy as np
    import matplotlib.pyplot as plt

    from solcore.state import State
    from solcore import material

    junction = State()
    options = State()

    wl = np.linspace(300, 900, 300) * 1e-9
    GaAs = material('GaAs')(T=300)

    n = GaAs.n(wl)
    cos_tc = np.sqrt(1 - 1 / n**2)
    Rn = ((n - 1) / (n + 1))**2
    wlg = 800 * 1e-9
    A = 1

    V = 0
    T = 300

    options.wavelength = wl
    junction.reflected = interp1d(wl, Rn)
    junction.absorptance = lambda x: A * (x < wlg)

    #
Ejemplo n.º 18
0
from solcore import material
from solcore.quantum_mechanics import kp_bands
import numpy as np

# Material parameters
GaAs = material("GaAs")(T=300)
InGaAs = material("InGaAs")

comp = np.linspace(0.01, 0.25, 5)
for i in comp:
    InGaAs2 = InGaAs(In=i, T=300)

    result = kp_bands(GaAs,
                      InGaAs2,
                      graph=True,
                      fit_effective_mass=True,
                      effective_mass_direction="L")
Ejemplo n.º 19
0
import matplotlib.pyplot as plt
import numpy as np
from solcore.absorption_calculator import calculate_absorption_profile
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
my_structure = Structure([
    Layer(si(30, 'nm'), material=AlGaAs),
    Layer(si(3000, 'nm'), material=GaAs),
    Layer(si(300, 'um'), material=GaAs),
])

# We want to calculate the absorption profile of this structure as a function of the position and wavelength
x = np.linspace(400, 1000, 200)
out = calculate_absorption_profile(my_structure, x, steps_size=1, z_limit=3000)

# Finally, we plot the absorption profile. Note that absorption at short wavelengths take place near the surface of the
# structure, in the AlGaAs layer and top of the GaAs layer, while longer wavelengths penetrate more. Wavelengths beyond
# the GaAs band edge are not absorbed.
plt.figure(1)
ax = plt.contourf(out['position'], x, out['absorption'], 200)
plt.xlabel('Position (nm)')
plt.ylabel('Wavelength (nm)')
cbar = plt.colorbar()
cbar.set_label('Absorption (1/nm)')
Ejemplo n.º 20
0
from solcore import material

import numpy as np
import matplotlib.pyplot as plt
import os

# Initiate some variables...
wl = np.linspace(300, 1800, 1000)
Al_fraction = np.linspace(10, 100, 10)

f, (ax1, ax2) = plt.subplots(1, 2, figsize=(11.25, 4))
ax1b = ax1.twinx()

# Load GaAs n and k data from the Sopra database...
GaAs = material("GaAs", sopra=True)(T=300)
GaAs_n = GaAs.n(wl * 1e-9)
GaAs_k = GaAs.k(wl * 1e-9)

# Load Ge n and k data from Sopra database...
Ge = material("Ge", sopra=True)(T=300)
Ge_n = Ge.n(wl * 1e-9)
Ge_k = Ge.k(wl * 1e-9)

# Load AlGaAs k data for a range of compositions...
AlGaAs = material("AlGaAs", sopra=True)

AlGaAs_k = [GaAs_k]

for comp in Al_fraction:
    AlGaAs_k.append(AlGaAs(T=300, Al=comp / 100).k(wl * 1e-9))
Ejemplo n.º 21
0
                np.imag(stack.get_indices(wavelength)) / wavelength)
            data_p = tmm.inc_position_resolved(
                layer, d_in_layer, out2, coherency_list, 4 * np.pi *
                np.imag(stack.get_indices(wavelength)) / wavelength)

            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_reflexion=False)
    # #
    # plt.plot(wavelength, out['R'], 'b', label='Reflexion')
Ejemplo n.º 22
0
    def test_61_kp_bulk_solvers(self):
        GaAs = solcore.material("GaAs")(T=300)
        GaAsP = solcore.material("GaAsP")(P=0.3, T=300)
        InGaAs = solcore.material("InGaAs")(In=0.2, T=300)

        # Testing QM.kp_bands
        bands_GaAsP = QM.kp_bands(GaAsP, GaAs, graph=False, fit_effective_mass=True, effective_mass_direction="X",
                                  return_so=True)
        bands_InGaAs = QM.kp_bands(InGaAs, GaAs, graph=False, fit_effective_mass=True, effective_mass_direction="X",
                                   return_so=True)

        expected_bands_GaAsP = (1.2168382480631407e-19, -1.5452519153253004e-19, -1.4042149045828435e-19,
                                -1.9192138182935611e-19, 8.0093555784846597e-32, 1.2472835955929216e-31,
                                2.6423749777877535e-31, 1.2393634061184521e-31)
        expected_bands_InGaAs = (8.6764014773233634e-20, -1.0573103504669798e-19, -1.1984351916698905e-19,
                                 -1.6993543036257329e-19, 6.6193386922591731e-32, 1.3576713980579555e-31,
                                 8.0904387208083259e-32, 1.2268187169919973e-31)

        for i in range(len(bands_GaAsP)):
            self.assertAlmostEqual(bands_GaAsP[i], expected_bands_GaAsP[i])
            self.assertAlmostEqual(bands_InGaAs[i], expected_bands_InGaAs[i])

        # Testing QM.KPbands and QM.fit_effective_masses
        edges_GaAsP = QM.KPbands(GaAsP, GaAs, fraction=0.2, return_edges_only=True)
        bands_GaAsP = QM.KPbands(GaAsP, GaAs, fraction=0.2)
        masses_GaAsP = QM.fit_effective_masses(bands_GaAsP, GaAsP, GaAs, plot_result=False)

        edges_InGaAs = QM.KPbands(InGaAs, GaAs, fraction=0.2, return_edges_only=True)
        bands_InGaAs = QM.KPbands(InGaAs, GaAs, fraction=0.2)
        masses_InGaAs = QM.fit_effective_masses(bands_InGaAs, InGaAs, GaAs, plot_result=False)

        expected_edges_GaAsP = (1.2168382480631407e-19, -1.5452519153253004e-19, -1.4042149045828435e-19,
                                -1.9192138182935611e-19)

        expected_edges_InGaAs = (8.6764014773233634e-20, -1.0573103504669798e-19, -1.1984351916698905e-19,
                                 -1.6993543036257329e-19)

        expected_masses_GaAsP = (8.049577422084102e-32, 1.2627430248682043e-31, 2.6577242586172804e-31,
                                 1.2305748108835472e-31)

        expected_masses_InGaAs = (6.6895885457875e-32, 1.3994390560400583e-31, 8.142667105522975e-32,
                                  1.2060355194525871e-31)

        for i in range(len(edges_GaAsP)):
            self.assertAlmostEqual(edges_GaAsP[i], expected_edges_GaAsP[i])
            self.assertAlmostEqual(edges_InGaAs[i], expected_edges_InGaAs[i])
            self.assertAlmostEqual(masses_GaAsP[i], expected_masses_GaAsP[i])
            self.assertAlmostEqual(masses_InGaAs[i], expected_masses_InGaAs[i])

        # Testing QM.kp8x8_bulk
        bands_GaAsP = QM.kp8x8_bulk(GaAsP, GaAs)
        bands_InGaAs = QM.kp8x8_bulk(InGaAs, GaAs)

        expected_bands_GaAsP = (1.2168382480631407e-19, -1.5452519153253004e-19, -1.4042149045828435e-19,
                                -1.9192138182935611e-19, 8.138445281947437e-32, 1.3543674202428507e-31,
                                2.848952594319033e-31, 1.145125159048442e-31)

        expected_bands_InGaAs = (8.6764014773233634e-20, -1.0573103504669798e-19, -1.1984351916698905e-19,
                                 -1.6993543036257329e-19, 6.77957483053393e-32, 1.6988821114765817e-31,
                                 7.820551493038613e-32, 1.1461138067300424e-31)

        for i in range(len(bands_GaAsP)):
            self.assertAlmostEqual(bands_GaAsP[i], expected_bands_GaAsP[i])
            self.assertAlmostEqual(bands_InGaAs[i], expected_bands_InGaAs[i])
Ejemplo n.º 23
0
# user options
T = 298
wl = si(np.linspace(400, 900, 80), 'nm')
light_source = LightSource(source_type='standard',
                           version='AM1.5g',
                           x=wl,
                           output_units='photon_flux_per_m',
                           concentration=1)
opts = default_options
opts.wavelength, opts.no_back_reflexion, opts.size, opts.light_source, opts.T_ambient = \
    wl, False, [400, 400], light_source, T
# The size of the unit cell for the RCWA structure is 400 x 400 nm

# Defining all the materials we need
Air = material('Air')(T=T)
p_GaAs = material('GaAs')(T=T, Na=si('4e18cm-3'))  # for the GaAs cell emitter
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([
Ejemplo n.º 24
0
options = default_options
options.nm_spacing = 0.5
options.wavelengths = wavelengths
options.project_name = 'test_matrix2'
options.n_rays = 50000
options.n_theta_bins = 30
options.phi_symmetry = np.pi/4
options.I_thresh = 1e-5
options.lookuptable_angles = 200
options.parallel = True
options.c_azimuth = 0.001
options.theta_in = 0*np.pi/180
options.phi_in = 'all'
options.only_incidence_angle = False

Ge = material('Ge')()
GaAs = material('GaAs')()
GaInP = material('GaInP')(In=0.5)
Ag = material('Ag')()
SiN = material('Si3N4')()
Air = material('Air')()
Ta2O5 = material('410', nk_db=True)()
MgF2 = material('203', nk_db=True)()
SiGeSn = material('SiGeSn')()

# stack based on doi:10.1038/s41563-018-0115-4
front_materials = [Layer(120e-9, MgF2), Layer(74e-9, Ta2O5), Layer(464e-9, GaInP), Layer(1682e-9, GaAs), Layer(1289e-9, SiGeSn)]
back_materials = [Layer(100E-9, SiN)]

# whether pyramids are upright or inverted is relative to front incidence.
# so if the same etch is applied to both sides of a slab of silicon, one surface
Ejemplo n.º 25
0
def b_mat():
    return material(b_mat_material_name)(T=t, P=b_mat_p)
Ejemplo n.º 26
0
options['n_theta_bins'] = 100
options['wavelengths'] = wavelengths
options['c_azimuth'] = 0.1
options['phi_symmetry'] = np.pi / 2
options['parallel'] = True
options['pol'] = 'u'

options.project_name = 'testing'

theta_intv, phi_intv, angle_vector = make_angle_vector(options['n_theta_bins'],
                                                       options['phi_symmetry'],
                                                       options['c_azimuth'])

surf = regular_pyramids(elevation_angle=0, upright=True)  # [texture, reverse]

GaAs = material('GaAs')()
Ge = material('Ge')()
Si = material('Si')()

Air = material('Air')()

layers = [Layer(500e-9, GaAs), Layer(200e-9, Ge)]
# optist = OptiStack(layers, False, Si, Air)
# lookup table:
size = ((500, 0), (0, 500))

results_front = RCWA(layers,
                     size,
                     orders,
                     options,
                     Air,
Ejemplo n.º 27
0
        """

        try:
            num = self.junction_indices[junction]
            self[num].__dict__.update(kwargs)
        except IndexError:
            print(
                'ERROR updating junction: The junction index must be {} or less.'
                .format(len(self.junction_indices)))

    def __call__(self, i):
        return self[self.junction_indices[i]]


if __name__ == '__main__':
    window = material('AlGaAs')(T=298, Na=1e24, Al=0.8)
    stack = [Layer(width=si("50nm"), material=window), default_GaAs(298)]

    # stack = [default_GaAs(298)]

    my_cell = SolarCell(layers=stack)
    #
    # my_cell.append_multiple([default_GaAs(298), default_GaAs(298), default_GaAs(298)])
    # print(my_cell)

    from solcore.poisson_drift_diffusion.DriftDiffusionUtilities import solve_pdd, default_photon_flux, \
        default_wavelengths
    import matplotlib.pyplot as plt

    solve_pdd(my_cell, 'QE', vfin=1.2, vstep=0.05, light=True)
    QE = my_cell(0).qe
Ejemplo n.º 28
0
# We need to build the solar cell layer by layer.
# We start from the AR coating. In this case, we load it from an an external file
refl_nm = np.loadtxt(this_dir_file("MgF-ZnS_AR.csv"),
                     unpack=True,
                     delimiter=",")
ref = interp1d(x=siUnits(refl_nm[0], "nm"),
               y=refl_nm[1],
               bounds_error=False,
               fill_value=0)

# TOP CELL - GaInP
# Now we build the top cell, which requires the n and p sides of GaInP and a window layer.
# We also load the absorption coefficient from an external file. We also add some extra parameters needed for the
# calculation such as the minority carriers diffusion lengths
AlInP = material("AlInP")
InGaP = material("GaInP")
window_material = AlInP(Al=0.52)
top_cell_n_material = InGaP(In=0.49,
                            Nd=siUnits(2e18, "cm-3"),
                            hole_diffusion_length=si("200nm"))
top_cell_p_material = InGaP(In=0.49,
                            Na=siUnits(1e17, "cm-3"),
                            electron_diffusion_length=si("1um"))

all_materials.append(window_material)
all_materials.append(top_cell_n_material)
all_materials.append(top_cell_p_material)

# MID CELL  - InGaAs
# We add manually the absorption coefficient of InGaAs since the one contained in the database doesn't cover
Ejemplo n.º 29
0
import tkinter as tk
from tkinter import ttk

from solcore import material
from solcore.material_data import calculate_mobility
from solcore.constants import q

from solcore.solar_cell_solver import rcwa_options, pdd_options, asc_options

# The default material is a GaAs at 298 K and provides a set of minimum properties that are used if they are not
# available for the material of interest and not alternative is given
# Default values MUST BE in SI units
DefaultMaterial = material("GaAs")(T=298)
default_layer_properties = {
    'band_gap': DefaultMaterial.band_gap,  # J
    'electron_affinity': DefaultMaterial.electron_affinity,  # J
    'eff_mass_electron': DefaultMaterial.eff_mass_electron,  # relative to m0
    'eff_mass_hh_z': DefaultMaterial.eff_mass_hh_z,  # relative to m0
    'eff_mass_lh_z': DefaultMaterial.eff_mass_lh_z,  # relative to m0
    'electron_mobility': calculate_mobility("GaAs", 0, 1),  # m2 V-1 s-1
    'hole_mobility': calculate_mobility("GaAs", 1, 1),  # m2 V-1 s-1
    'ni': DefaultMaterial.ni,  # m-3
    'Nc': DefaultMaterial.Nc,  # m-3
    'Nv': DefaultMaterial.Nv,  # m-3
    'electron_minority_lifetime': 3e-6,  # s
    'hole_minority_lifetime': 2.5e-7,  # s
    'relative_permittivity':
    DefaultMaterial.relative_permittivity,  # relative to epsilon0
    'electron_auger_recombination': 1e-42,  # m6 s-1,
    'hole_auger_recombination': 1e-42,  # m6 s-1
    'radiative_recombination':
Ejemplo n.º 30
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"])