from solcore import material, si
from solcore.absorption_calculator import search_db, download_db
import os
from solcore.structure import Layer
from solcore.light_source import LightSource
from rayflare.transfer_matrix_method import tmm_structure
from rayflare.options import default_options
from rayflare.structure import Interface, BulkLayer, Structure
from rayflare.matrix_formalism import process_structure, calculate_RAT
from solcore.constants import q
import numpy as np
import matplotlib.pyplot as plt
Section 9a: Planar III-V on planar Si, with rear grating
In this example, we will build two structures similar to those described in this paper. These are both triple-junction, two-terminal GaInP/GaAs/Si cells; one cell is planar, while the other has a diffraction grating deposited on the rear of the bottom Si cell to boost its current.
Setting up
As before, we load some materials from the refractiveindex.info database. The MgF\(_2\) and Ta\(_2\)O\(_5\) are the same as the ARC example; the SU8 is a negative photoresist which was used in the reference paper The optical constants for silver are also loaded from a reliable literature source. Note that the exact compositions of some semiconductor alloy layers (InGaP, AlInP and AlGaAs) are not given in the paper and are thus reasonable guesses.
# only needs to be run once download_db()
= search_db(os.path.join("MgF2", "Rodriguez-de Marcos"))[0][0];
MgF2_pageid = search_db(os.path.join("Ta2O5", "Rodriguez-de Marcos"))[0][0];
Ta2O5_pageid = search_db("SU8")[0][0];
SU8_pageid = search_db(os.path.join("Ag", "Jiang"))[0][0];
Ag_pageid
= material(str(MgF2_pageid), nk_db=True)();
MgF2 = material(str(Ta2O5_pageid), nk_db=True)();
Ta2O5 = material(str(SU8_pageid), nk_db=True)();
SU8 = material(str(Ag_pageid), nk_db=True)();
Ag
= material("AlInP")(Al=0.52)
window = material("GaInP")(In=0.5)
GaInP = material("AlGaAs")(Al=0.8)
AlGaAs = material("GaAs")()
GaAs = material("Si")
Si
= material("Air")()
Air = material("Al2O3P")()
Al2O3 = material("Al")() Al
Defining the cell layers
Now we define the layers for the III-V top junctions, and the Si wafer, grouping them together in a logical way. In this example, we will only do optical simulations, so we will not set e.g. diffusion lengths or doping levels.
= [
ARC 110e-9, MgF2),
Layer(65e-9, Ta2O5),
Layer(
]
= [
GaInP_junction 17e-9, window),
Layer(400e-9, GaInP),
Layer(100e-9, AlGaAs)
Layer(
]
= [
tunnel_1 80e-9, AlGaAs),
Layer(20e-9, GaInP),
Layer(
]
= [
GaAs_junction 17e-9, GaInP),
Layer(1050e-9, GaAs),
Layer(70e-9, AlGaAs)]
Layer(
= [
tunnel_2 50e-9, AlGaAs),
Layer(125e-9, GaAs),
Layer(
]
= [
Si_junction 280e-6, Si(Nd=si("2e18cm-3"), hole_diffusion_length=2e-6), role="emitter"),
Layer(
]
= len(ARC) + len(GaInP_junction) + len(tunnel_1) + len(GaAs_junction) + \
coh_layers len(tunnel_2)
As for Example 7, to get physically reasonable results we must treat the very thick layers in the structure incoherently. The coh_layers
variable sums up how many thin layers (which must be treated coherently) must be included in the coherency_list
options.
Planar cell
Now we define the planar cell, and options for the solver:
= tmm_structure(
cell_planar + GaInP_junction + tunnel_1 + GaAs_junction + tunnel_2 + Si_junction,
ARC =Air,
incidence=Ag,
transmission
)
= cell_planar.layer_stack.num_layers
n_layers
= ["c"]*coh_layers + ["i"]*(n_layers-coh_layers)
coherency_list
= default_options()
options
= np.arange(300, 1201, 10) * 1e-9
wl = LightSource(source_type="standard", version="AM1.5g", x=wl,
AM15G ="photon_flux_per_m")
output_units
= wl
options.wavelengths = coherency_list
options.coherency_list = False options.coherent
Run the TMM calculation for the planar cell, and then extract the relevant layer absorptions. These are used to calculate limiting currents (100% internal quantum efficiency), which are displayed on the plot with the absorption in each layer.
= cell_planar.calculate(options=options)
tmm_result
= tmm_result['A_per_layer'][:,3]
GaInP_A = tmm_result['A_per_layer'][:,8]
GaAs_A = tmm_result['A_per_layer'][:,coh_layers]
Si_A
= q*np.trapz(GaInP_A*AM15G.spectrum()[1], x=wl)/10
Jmax_GaInP = q*np.trapz(GaAs_A*AM15G.spectrum()[1], x=wl)/10
Jmax_GaAs = q*np.trapz(Si_A*AM15G.spectrum()[1], x=wl)/10
Jmax_Si
= tmm_result['R']
R_spacer_ARC
=(6,4))
plt.figure(figsize* 1e9, GaInP_A, "-k", label="GaInP")
plt.plot(wl * 1e9, GaAs_A, "-b", label="GaAs")
plt.plot(wl * 1e9, Si_A, "-r", label="Si")
plt.plot(wl * 1e9, 1 - R_spacer_ARC, '-y', label="1 - R")
plt.plot(wl
450, 0.55, r"{:.1f} mA/cm$^2$".format(Jmax_GaInP))
plt.text(670, 0.55, r"{:.1f} mA/cm$^2$".format(Jmax_GaAs))
plt.text(860, 0.55, r"{:.1f} mA/cm$^2$".format(Jmax_Si))
plt.text("Wavelength (nm)")
plt.xlabel("Absorptance")
plt.ylabel(
plt.tight_layout()='upper right')
plt.legend(loc=(1.05, 1), loc=2, borderaxespad=0.)
plt.legend(bbox_to_anchor plt.show()
Database file found at /Users/phoebe/.solcore/nk/nk.db
Material main/Ag/Jiang.yml loaded.
Database file found at /Users/phoebe/.solcore/nk/nk.db
Material main/Ag/Jiang.yml loaded.
Database file found at /Users/phoebe/.solcore/nk/nk.db
Material main/MgF2/Rodriguez-de Marcos.yml loaded.
Database file found at /Users/phoebe/.solcore/nk/nk.db
Material main/MgF2/Rodriguez-de Marcos.yml loaded.
Database file found at /Users/phoebe/.solcore/nk/nk.db
Material main/Ta2O5/Rodriguez-de Marcos.yml loaded.
Database file found at /Users/phoebe/.solcore/nk/nk.db
Material main/Ta2O5/Rodriguez-de Marcos.yml loaded.
Cell with rear grating
Now, for the cell with a grating on the rear, we have a multi-scale problem where we must combine the calculation of absorption in a very thick (compared to the wavelengths of light) layer of Si with the effect of a wavelength-scale (1000 nm pitch) diffraction grating. For this, we will use the Angular Redistribution Matrix Method (ARMM) which was also used in Example 8.
The front surface of the cell (i.e. all the layers on top of Si) are planar, and can be treated using TMM. The rear surface of the cell, which has a crossed grating consisting of silver and SU8, must be treated with RCWA to account for diffraction. The thick Si layer will be the bulk coupling layer between these two interfaces.
First, we set up the rear grating surface; we must define its lattice vectors, and place the Ag rectangle in the unit cell of the grating. More details on how unit cells of different shapes can be defined for the RCWA solver can be found here.
= 1000
x
= ((x, 0), (0, x))
d_vectors = 0.4
area_fill_factor = np.sqrt(area_fill_factor) * 500
hw
= [Layer(width=si("250nm"),
back_materials =SU8,
material=[{"type": "rectangle", "mat": Ag, "center": (x / 2, x / 2),
geometry"halfwidths": (hw, hw), "angle": 0}],
)]
Now, we define the Si bulk layer, and the III-V layers which go in the front interface. Finally, we put everything together into the ARMM Structure
, also giving the incidence and transmission materials.
= BulkLayer(280e-6, Si(), name="Si_bulk")
bulk_Si
= ARC + GaInP_junction + tunnel_1 + GaAs_junction + tunnel_2
III_V_layers
= Interface("TMM", layers=III_V_layers, name="III_V_front",
front_surf_planar =True)
coherent
= Interface(
back_surf_grating "RCWA",
=back_materials,
layers="crossed_grating_back",
name=d_vectors,
d_vectors=60,
rcwa_orders
)
= Structure(
cell_grating
[front_surf_planar, bulk_Si, back_surf_grating],=Air,
incidence=Ag,
transmission )
Because RCWA calculations are very slow compared to TMM, it makes sense to only carry out the RCWA calculation at wavelengths where the grating has any effect. Depending on the wavelength, all the incident light may be absorbed in the III-V layers or in its first pass through the Si, so it never reaches the grating. We check this by seeing which wavelengths have even a small amount of transmission into the silver back mirror, and only doing the new calculation at these wavelengths. At shorter wavelengths, the results previously calculated using TMM can be used.
= wl[tmm_result['T'] > 1e-4] # check where transmission fraction is bigger
wl_rcwa # than 1E-4
= wl_rcwa
options.wavelengths = "III_V_Si_cell"
options.project_name = 30
options.n_theta_bins = 0.25
options.c_azimuth
='current')
process_structure(cell_grating, options, save_location= calculate_RAT(cell_grating, options, save_location='current')
results_armm = results_armm[0] RAT
Comparison of planar and grating cell
We extract the relevant absorption per layer, and use it to calculate the new limiting current for the Si junction. The plot compares the absorption in the Si with and without the grating.
= np.zeros(len(wl))
Si_A_total 'T'] > 1e-4] = RAT['A_bulk'][0]
Si_A_total[tmm_result['T'] <= 1e-4] = Si_A[tmm_result['T'] <= 1e-4]
Si_A_total[tmm_result[
= q*np.trapz(Si_A_total*AM15G.spectrum()[1], x=wl)/10
Jmax_Si_grating
=(6,3))
plt.figure(figsize* 1e9, GaInP_A, "-k", label="GaInP")
plt.plot(wl * 1e9, GaAs_A, "-b", label="GaAs")
plt.plot(wl * 1e9, Si_A, "--r", label="Si (planar)")
plt.plot(wl * 1e9, Si_A_total, '-r', label="Si (with grating)")
plt.plot(wl 420, 0.55, r"{:.1f} mA/cm$^2$".format(Jmax_GaInP))
plt.text(670, 0.50, r"{:.1f} mA/cm$^2$".format(Jmax_GaAs))
plt.text(860, 0.45, r"{:.1f} mA/cm$^2$".format(Jmax_Si_grating))
plt.text(=(1.05, 1), loc=2, borderaxespad=0.)
plt.legend(bbox_to_anchor"Wavelength (nm)")
plt.xlabel("Absorptance")
plt.ylabel(
plt.tight_layout() plt.show()
Questions
- Why does the grating only affect the absorption in Si at long wavelengths?
- What is the reason for using the angular redistribution matrix method, rather than defining an RCWA-only structure (
rcwa_structure
)?