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
def i_gaas(): return material(i_gaas_material_name)(T=t)
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") ],
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
def qw_mat(): return material(qw_mat_material_name)(T=t, In=qw_mat_in)
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])
'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',
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))
# 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,
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)
(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)
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
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"),
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"
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) #
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")
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)')
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))
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')
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])
# 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([
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
def b_mat(): return material(b_mat_material_name)(T=t, P=b_mat_p)
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,
""" 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
# 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
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':
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"])