Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor fixes: n/k database, updating examples, bugs in Cauchy model and material parameters #218

Merged
merged 5 commits into from
Jun 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
127 changes: 64 additions & 63 deletions docs/source/Examples/refractiveindex_info_db_example.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Searching the refractiveindex.info database and comparing materials
opts = default_options
opts.optics_method = 'TMM'
opts.wavelength = wl

# Download the database from refractiveindex.info. This only needs to be done once.
# Can specify the source URL and number of interpolation points.
# download_db()
Expand All @@ -37,67 +38,67 @@ Searching the refractiveindex.info database and comparing materials
# 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))
plt.legend(labels=names)
plt.xlabel("Wavelength (nm)")
plt.ylabel("n")
plt.show()

plt.figure()
plt.plot(wl * 1e9, Ag_Joh.k(wl), wl * 1e9, Ag_McP.k(wl),
wl * 1e9, Ag_Hag.k(wl), wl * 1e9, Ag_Rak.k(wl), wl * 1e9, Ag_Sol.k(wl))
plt.legend(labels=names)
plt.xlabel("Wavelength (nm)")
plt.ylabel("k")
plt.show()

# Compare performance as a back mirror on a GaAs 'cell'
# Solid line: absorption in GaAs
# Dashed line: absorption in Ag

GaAs = material('GaAs')()

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

plt.figure()
for c, Ag_mat in enumerate([Ag_Joh, Ag_McP, Ag_Hag, Ag_Rak, Ag_Sol]):
my_solar_cell = SolarCell([Layer(width=si('50nm'), material = GaAs)] +
[Layer(width = si('100nm'), material = Ag_mat)])
solar_cell_solver(my_solar_cell, 'optics', opts)
GaAs_positions = np.linspace(my_solar_cell[0].offset, my_solar_cell[0].offset + my_solar_cell[0].width, 1000)
Ag_positions = np.linspace(my_solar_cell[1].offset, my_solar_cell[1].offset + my_solar_cell[1].width, 1000)
GaAs_abs = np.trapz(my_solar_cell[0].diff_absorption(GaAs_positions), GaAs_positions)
Ag_abs = np.trapz(my_solar_cell[1].diff_absorption(Ag_positions), Ag_positions)
plt.plot(wl*1e9, GaAs_abs, color=colors[c], linestyle='-', label=names[c])
plt.plot(wl*1e9, Ag_abs, color=colors[c], linestyle='--')

plt.legend()
plt.xlabel("Wavelength (nm)")
plt.ylabel("Absorbed")
plt.show()
# Let's compare the optical behaviour of some of those sources:
# (The pageid values listed are for the 2021-07-18 version of the refractiveindex.info database)
# pageid = 0, Johnson
# pageid = 2, Jiang
# pageid = 4, McPeak
# pageid = 10, Hagemann
# pageid = 14, 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_Jia = material(name='2', nk_db=True)()
Ag_McP = material(name='4', nk_db=True)()
Ag_Hag = material(name='10', nk_db=True)()
Ag_Rak = material(name='14', nk_db=True)()
Ag_Sol = material(name='Ag')() # Solcore built-in (from SOPRA)

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

plt.figure(figsize=(8,4))
plt.subplot(121)
plt.plot(wl*1e9, np.array([Ag_Joh.n(wl), Ag_Jia.n(wl), Ag_McP.n(wl),
Ag_Hag.n(wl), Ag_Rak.n(wl), Ag_Sol.n(wl)]).T)
plt.legend(labels=names)
plt.xlabel("Wavelength (nm)")
plt.title("(2) $n$ and $\kappa$ values for Ag from different literature sources")
plt.ylabel("n")

plt.subplot(122)
plt.plot(wl*1e9, np.array([Ag_Joh.k(wl), Ag_Jia.k(wl), Ag_McP.k(wl),
Ag_Hag.k(wl), Ag_Rak.k(wl), Ag_Sol.k(wl)]).T)
plt.legend(labels=names)
plt.xlabel("Wavelength (nm)")
plt.ylabel("k")
plt.show()

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

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

GaAs = material('GaAs')()

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

plt.figure()
for c, Ag_mat in enumerate([Ag_Joh, Ag_Jia, Ag_McP, Ag_Hag, Ag_Rak, Ag_Sol]):
my_solar_cell = OptiStack([Layer(width=si('50nm'), material = GaAs)], substrate=Ag_mat)
RAT = calculate_rat(my_solar_cell, wl*1e9, no_back_reflection=False)
GaAs_abs = RAT["A_per_layer"][1]
Ag_abs = RAT["T"]
plt.plot(wl*1e9, GaAs_abs, color=colors[c], linestyle='-', label=names[c])
plt.plot(wl*1e9, Ag_abs, color=colors[c], linestyle='--')

plt.legend()
plt.xlabel("Wavelength (nm)")
plt.ylabel("Absorbed")
plt.title("(3) Absorption in GaAs depending on silver optical constants")
plt.show()


1 change: 0 additions & 1 deletion examples/MJ_solar_cell_using_DA.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ def this_dir_file(f):
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)
Expand Down
125 changes: 66 additions & 59 deletions examples/advanced_examples/differential_evolution_4Jcell.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
"from solcore.structure import Junction, Layer\n",
"from solcore.solar_cell_solver import solar_cell_solver\n",
"from solcore.constants import q, kb\n",
"from solcore.material_system import create_new_material"
"from solcore.material_system import create_new_material\n",
"from solcore.absorption_calculator import search_db"
]
},
{
Expand Down Expand Up @@ -114,7 +115,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"add SiGeSn optical constants to the database"
"add SiGeSn optical constants to the database, and search the refractiveindex.info for the Ta2O5 data we want to use and save the pageid to use later:"
]
},
{
Expand All @@ -124,7 +125,9 @@
"outputs": [],
"source": [
"create_new_material('SiGeSn', 'SiGeSn_n.txt', 'SiGeSn_k.txt', 'SiGeSn_params.txt') # Note: comment out this line after the material\n",
"# has been added to avoid being asked if you want to overwrite it."
"# has been added to avoid being asked if you want to overwrite it.\n",
"\n",
"Ta2O5_pageid = str(search_db(\"Ta2O5/Rodriguez-de Marcos\")[0][0])"
]
},
{
Expand All @@ -134,46 +137,6 @@
"define class for the optimization:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class calc_min_Jsc():\n",
" def __init__(self):\n",
" # initialize an instance of the class; set some information which will be used in each iteration of the calculation:\n",
" # materials, wavelengths, the light source\n",
" T = 298\n",
" wl = np.linspace(300, 1900, 800)\n",
"\n",
" # materials\n",
" SiGeSn = material('SiGeSn')(T=T)\n",
" GaAs = material('GaAs')(T=T)\n",
" InGaP = material('GaInP')(In=0.5, T=T)\n",
" Ge = material('Ge')(T=T)\n",
"\n",
" # make these attributes of 'self' so they can be accessed by the class object\n",
" # here I am also creating lists of wavelengths and corresponding n and k data from\n",
" # the Solcore materials - the reason for this is that there is currently an issue with using the Solcore\n",
" # material class in parallel computations. Thus the information for the n and k data is saved here as a list\n",
" # rather than a material object (see the documentation of OptiStack for the different acceptable formats\n",
" # to pass optical constants for an OptiStack\n",
" self.wl = wl\n",
" self.SiGeSn = [self.wl, SiGeSn.n(self.wl*1e-9), SiGeSn.k(self.wl*1e-9)]\n",
" self.Ge = [self.wl, Ge.n(self.wl*1e-9), Ge.k(self.wl*1e-9)]\n",
" self.InGaP = [self.wl, InGaP.n(self.wl*1e-9), InGaP.k(self.wl*1e-9)]\n",
" self.GaAs = [self.wl, GaAs.n(self.wl*1e-9), GaAs.k(self.wl*1e-9)]\n",
" self.MgF2 = [self.wl, material('MgF2')().n(self.wl*1e-9), material('MgF2')().k(self.wl*1e-9)]\n",
" self.Ta2O5 = [self.wl, material('410',\n",
" nk_db=True)().n(self.wl*1e-9), material('410',\n",
" nk_db=True)().k(self.wl*1e-9)]\n",
"\n",
" # assuming an AM1.5G spectrum\n",
" self.spectr = LightSource(source_type='standard', version='AM1.5g', x=self.wl,\n",
" output_units='photon_flux_per_nm', concentration=1).spectrum(self.wl)[1]"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -269,7 +232,7 @@
" InGaP = material('GaInP')\n",
" Ge = material('Ge')\n",
" MgF2 = material('MgF2')()\n",
" Ta2O5 = material('410', nk_db=True)()\n",
" Ta2O5 = material(Ta2O5_pageid, nk_db=True)()\n",
" AlInP = material(\"AlInP\")\n",
" window_material = AlInP(Al=0.52)\n",
" GaInP_mobility_h = 0.03 #\n",
Expand All @@ -280,10 +243,8 @@
" GaInP_lifetime_e = 1e-8\n",
" GaInP_D_e = GaInP_mobility_e * kb * 300 / e_charge\n",
" GaInP_L_e = np.sqrt(GaInP_D_e * GaInP_lifetime_e)\n",
" top_cell_n_material = InGaP(In=0.5, Nd=si(\"2e18cm-3\"), hole_diffusion_length=GaInP_L_h,\n",
" relative_permittivity=11.75, hole_mobility=GaInP_mobility_h)\n",
" top_cell_p_material = InGaP(In=0.5, Na=si(\"2e17cm-3\"), electron_diffusion_length=GaInP_L_e,\n",
" relative_permittivity=11.75, electron_mobility=GaInP_mobility_e)\n",
" top_cell_n_material = InGaP(In=0.5, Nd=si(\"2e18cm-3\"), hole_diffusion_length=GaInP_L_h, hole_mobility=GaInP_mobility_h)\n",
" top_cell_p_material = InGaP(In=0.5, Na=si(\"2e17cm-3\"), electron_diffusion_length=GaInP_L_e, electron_mobility=GaInP_mobility_e)\n",
"\n",
" # MID CELL - GaAs\n",
" GaAs_mobility_h = 0.85 #\n",
Expand All @@ -294,10 +255,8 @@
" GaAs_lifetime_e = 1e-8\n",
" GaAs_D_e = GaAs_mobility_e * kb * 300 / e_charge\n",
" GaAs_L_e = np.sqrt(GaAs_D_e * GaAs_lifetime_e)\n",
" mid_cell_n_material = GaAs(Nd=si(\"1e18cm-3\"), hole_diffusion_length=GaAs_L_h,\n",
" relative_permittivity=13.1, hole_mobility=GaAs_mobility_h)\n",
" mid_cell_p_material = GaAs(Na=si(\"1e17cm-3\"), electron_diffusion_length=GaAs_L_e,\n",
" relative_permittivity=13.1, electron_mobility=GaAs_mobility_e)"
" mid_cell_n_material = GaAs(Nd=si(\"1e18cm-3\"), hole_diffusion_length=GaAs_L_h, hole_mobility=GaAs_mobility_h)\n",
" mid_cell_p_material = GaAs(Na=si(\"1e17cm-3\"), electron_diffusion_length=GaAs_L_e, electron_mobility=GaAs_mobility_e)"
]
},
{
Expand Down Expand Up @@ -333,14 +292,62 @@
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" bot_cell_n_material = Ge(Nd=si(\"2e18cm-3\"), hole_diffusion_length=Ge_L_h,\n",
" relative_permittivity=16, hole_mobility=Ge_mobility_h)\n",
" bot_cell_p_material = Ge(Na=si(\"1e17cm-3\"), electron_diffusion_length=Ge_L_e,\n",
" relative_permittivity=16, electron_mobility=Ge_mobility_e)"
]
"class calc_min_Jsc():\n",
" def __init__(self):\n",
" # initialize an instance of the class; set some information which will be used in each iteration of the calculation:\n",
" # materials, wavelengths, the light source\n",
" T = 298\n",
" wl = np.linspace(300, 1900, 800)\n",
"\n",
" # materials\n",
" SiGeSn = material('SiGeSn')(T=T)\n",
" GaAs = material('GaAs')(T=T)\n",
" InGaP = material('GaInP')(In=0.5, T=T)\n",
" Ge = material('Ge')(T=T)\n",
"\n",
" # make these attributes of 'self' so they can be accessed by the class object\n",
" # here I am also creating lists of wavelengths and corresponding n and k data from\n",
" # the Solcore materials - the reason for this is that there is currently an issue with using the Solcore\n",
" # material class in parallel computations. Thus the information for the n and k data is saved here as a list\n",
" # rather than a material object (see the documentation of OptiStack for the different acceptable formats\n",
" # to pass optical constants for an OptiStack\n",
" self.wl = wl\n",
" self.SiGeSn = [self.wl, SiGeSn.n(self.wl*1e-9), SiGeSn.k(self.wl*1e-9)]\n",
" self.Ge = [self.wl, Ge.n(self.wl*1e-9), Ge.k(self.wl*1e-9)]\n",
" self.InGaP = [self.wl, InGaP.n(self.wl*1e-9), InGaP.k(self.wl*1e-9)]\n",
" self.GaAs = [self.wl, GaAs.n(self.wl*1e-9), GaAs.k(self.wl*1e-9)]\n",
" self.MgF2 = [self.wl, material('MgF2')().n(self.wl*1e-9), material('MgF2')().k(self.wl*1e-9)]\n",
" self.Ta2O5 = [self.wl, material(Ta2O5_pageid,\n",
" nk_db=True)().n(self.wl*1e-9), material(Ta2O5_pageid,\n",
" nk_db=True)().k(self.wl*1e-9)]\n",
"\n",
" # assuming an AM1.5G spectrum\n",
" self.spectr = LightSource(source_type='standard', version='AM1.5g', x=self.wl,\n",
" output_units='photon_flux_per_nm', concentration=1).spectrum(self.wl)[1]"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [
" bot_cell_n_material = Ge(Nd=si(\"2e18cm-3\"), hole_diffusion_length=Ge_L_h, hole_mobility=Ge_mobility_h)\n",
" bot_cell_p_material = Ge(Na=si(\"1e17cm-3\"), electron_diffusion_length=Ge_L_e, electron_mobility=Ge_mobility_e)"
],
"metadata": {
"collapsed": false,
"pycharm": {
"name": "#%%\n"
}
}
},
{
"cell_type": "code",
Expand Down Expand Up @@ -611,4 +618,4 @@
},
"nbformat": 4,
"nbformat_minor": 2
}
}