Skip to content

Commit

Permalink
Merge pull request #62 from qpv-research-group/inkstone_integration
Browse files Browse the repository at this point in the history
Inkstone integration
  • Loading branch information
phoebe-p authored Nov 19, 2023
2 parents 549f2ac + d961a8c commit abea738
Show file tree
Hide file tree
Showing 60 changed files with 2,691 additions and 3,107 deletions.
19 changes: 9 additions & 10 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.9', '3.10']
exclude:
- os: windows-latest
python-version: '3.9'
python-version: ['3.9', '3.10', '3.11']
# exclude:
# - os: windows-latest
# python-version: '3.9'

steps:
- uses: actions/checkout@v1
Expand All @@ -41,8 +41,8 @@ jobs:
- name: Install python dependencies
run: |
python -m pip install --upgrade setuptools wheel pip twine numba
pip install -e .[dev]
python -m pip install --upgrade setuptools wheel pip
pip install .
- name: Install S4 in Linux
if: matrix.os == 'ubuntu-latest'
Expand All @@ -64,19 +64,18 @@ jobs:
- name: Install on Linux and MacOS
if: matrix.os != 'windows-latest'
run: pip install -e .
run: pip install .

- name: Install on Windows
if: matrix.os == 'windows-latest'
run: |
pip install -e .
pip install .
shell: powershell

- name: Test with pytest
run: |
pip install pytest-cov pytest-rerunfailures
pytest --cov-report= --cov=rayflare tests/ --reruns 3
pytest --cov-report= --cov=rayflare tests/ --reruns 5
- name: Codecov
if: matrix.os == 'ubuntu-latest'
Expand Down
2 changes: 1 addition & 1 deletion docs/Installation/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ To do a normal installation from PyPI (using :literal:`pip`):
pip install setuptools wheel numba
pip install rayflare
This will install install the most recent version uploaded to PyPI (currently 1.2.0), which is not necessarily the most
This will install install the most recent version uploaded to PyPI (currently 1.2.1), which is not necessarily the most
up to date version.

To install RayFlare from source (GitHub):
Expand Down
7 changes: 5 additions & 2 deletions docs/Options/user_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ rule, values with units of distance (wavelength, depth spacing) are in m while a
General options/options for matrix framework
---------------------------------------------

- **wavelengths**: wavelengths at which to carry out calculations (in m)
- **wavelength**: wavelengths at which to carry out calculations (in m)
- **theta_in**: polar angle of incident light (in radians)
- **phi_in**: azimuthal angle of incident light (in radians). If you are using the angular redistribution matrix framework,
you can also set this to 'all' to spread the incident light evenly over all the azimuthal bins
Expand All @@ -34,9 +34,12 @@ Options used only by RCWA (S4)
---------------------------------------------

- **A_per_order**: whether or not to calculate absorption per diffraction order (Boolean)
- **S4_options**: options which are passed to S4. See S4 documentation for details
- **S4_options**: options which are passed to S4. See S4 documentation for details. Note that these are
not used by Inkstone.
- **orders**: the number of Fourier orders to retain. The actual number of orders used may be different, depending on
the lattice truncation rule used.
- **RCWA_method**: 'Inkstone' or 'S4'. If 'Inkstone', the Inkstone RCWA implementation is used. If 'S4', the S4 RCWA implementation is used.
The default is S4. Note that this is not case-sensitive.


Options used only by the ray-tracer
Expand Down
12 changes: 12 additions & 0 deletions docs/news.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ To update to the latest version of RayFlare, run the following command in your t
pip install rayflare --upgrade
Version 1.2.1 released (2023-11-19)
------------------------------------
**Highlights:**

- New RCWA method ([Inkstone](https://github.com/alexysong/inkstone) now intergrated with RayFlare.
This is an all-Python program which is therefore easy to install (unlike S4). This means all core u
functionality of RayFlare is now available without the need to compile anything on your computer.
Users can toggle between S4 and Inkstone by setting the ``RCWA_method`` option.
- Calculations with unpolarized light using RCWA should be faster now.
- The ``wavelengths`` user options is now called ``wavelength``, for compatibility with Solcore.
``wavelengths`` still works, but will be deprecated in future.

Version 1.2.0 released (2023-03-21)
------------------------------------

Expand Down
3 changes: 2 additions & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ joblib==1.1.0
matplotlib==3.5.1
scipy==1.7.3
solcore==5.7.5
nbsphinx==0.8.8
nbsphinx==0.8.8
inkstone==0.3.12
67 changes: 17 additions & 50 deletions examples/GaAs_GaAs_Si_spacer_tmm_rt.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,12 @@
options.n_rays = 2000
options.randomize_surface = True
options.project_name = "GaAs_GaAs_Si_spacer_tmm_rt"
options.wavelengths = wavelengths
options.wavelength = wavelengths

# Set up materials
# from solcore.absorption_calculator import download_db
# download_db() # uncomment to download the database if you haven't already
epoxy_result = search_db("NOA-61")[
0
] # Norland optical adhesive 61. n = 1.5, typical for materials used in this way
epoxy_result = search_db("NOA-61")[0] # Norland optical adhesive 61. n = 1.5, typical for materials used in this way

MgF2_pageid = str(search_db(os.path.join("MgF2", "Rodriguez-de Marcos"))[0][0])
Ta2O5_pageid = str(search_db(os.path.join("Ta2O5", "Rodriguez-de Marcos"))[0][0])
Expand Down Expand Up @@ -94,10 +92,10 @@
aSi_n = material("aSi_n")()

plt.figure()
plt.plot(wavelengths*1e9, GaAs.n(wavelengths), label='GaAs')
plt.plot(wavelengths*1e9, GaInP.n(wavelengths), label='GaInP')
plt.plot(wavelengths*1e9, NOA.n(wavelengths), label='epoxy')
plt.plot(wavelengths*1e9, Si.n(wavelengths), label='Si')
plt.plot(wavelengths * 1e9, GaAs.n(wavelengths), label="GaAs")
plt.plot(wavelengths * 1e9, GaInP.n(wavelengths), label="GaInP")
plt.plot(wavelengths * 1e9, NOA.n(wavelengths), label="epoxy")
plt.plot(wavelengths * 1e9, Si.n(wavelengths), label="Si")
plt.show()

# x = np.linspace(0, 1, 6)
Expand Down Expand Up @@ -140,9 +138,7 @@

Si_back_labels = ["a-Si i", "a-Si n", "ITO (back)"]

front_surface = planar_surface(
interface_layers=front_layers, prof_layers=cell_layer_ind
)
front_surface = planar_surface(interface_layers=front_layers, prof_layers=cell_layer_ind)
Si_surface = regular_pyramids(upright=True, interface_layers=Si_front_layers)
back_surface = regular_pyramids(upright=False, interface_layers=Si_back_layers)

Expand Down Expand Up @@ -183,29 +179,19 @@
Si_back_plot_labels.append(Si_back_labels[j1])

plt.figure(figsize=(8, 4))
plt.plot(options.wavelengths * 1e9, result["T"], label="T (Al)")
plt.plot(options.wavelengths * 1e9, result["R"], '--', label="R")
plt.plot(options.wavelength * 1e9, result["T"], label="T (Al)")
plt.plot(options.wavelength * 1e9, result["R"], "--", label="R")

if len(front_plot_res) > 0:
plt.plot(
options.wavelengths * 1e9, np.array(front_plot_res).T, label=front_plot_labels
)
plt.plot(options.wavelength * 1e9, np.array(front_plot_res).T, label=front_plot_labels)

if len(Si_front_plot_res) > 0:
plt.plot(
options.wavelengths * 1e9,
np.array(Si_front_plot_res).T,
label=Si_front_plot_labels,
)
plt.plot(options.wavelength * 1e9, np.array(Si_front_plot_res).T, label=Si_front_plot_labels)

plt.plot(options.wavelengths * 1e9, result["A_per_layer"][:, 1], label="Si")
plt.plot(options.wavelength * 1e9, result["A_per_layer"][:, 1], label="Si")

if len(Si_back_plot_res) > 0:
plt.plot(
options.wavelengths * 1e9,
np.array(Si_back_plot_res).T,
label=Si_back_plot_labels,
)
plt.plot(options.wavelength * 1e9, np.array(Si_back_plot_res).T, label=Si_back_plot_labels)

plt.legend(bbox_to_anchor=(1.05, 1))
plt.xlabel("Wavelength (nm)")
Expand All @@ -215,31 +201,12 @@

# limiting currents:

light_source = LightSource(
source_type="standard",
version="AM1.5g",
x=wavelengths,
output_units="photon_flux_per_m",
)
light_source = LightSource(source_type="standard", version="AM1.5g", x=wavelengths, output_units="photon_flux_per_m")

photon_flux = light_source.spectrum(wavelengths)[1]

J_GaAs_1 = (
q
* np.trapz(
result["A_per_interface"][0][:, cell_layer_ind[0] - 1] * photon_flux,
wavelengths,
)
/ 10
)
J_GaAs_2 = (
q
* np.trapz(
result["A_per_interface"][0][:, cell_layer_ind[1] - 1] * photon_flux,
wavelengths,
)
/ 10
)
J_GaAs_1 = q * np.trapz(result["A_per_interface"][0][:, cell_layer_ind[0] - 1] * photon_flux, wavelengths) / 10
J_GaAs_2 = q * np.trapz(result["A_per_interface"][0][:, cell_layer_ind[1] - 1] * photon_flux, wavelengths) / 10
J_Si = q * np.trapz(result["A_per_layer"][:, 1] * photon_flux, wavelengths) / 10

print(J_GaAs_1, J_GaAs_2, J_Si)
print(J_GaAs_1, J_GaAs_2, J_Si)
2 changes: 1 addition & 1 deletion examples/HIT_emissivity.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"wavelengths = np.round(np.floor(np.exp(wavelengths)) * 1e-9, 12)\n",
"\n",
"options = default_options()\n",
"options.wavelengths = wavelengths\n",
"options.wavelength = wavelengths\n",
"options.project_name = \"HIT_notebook\"\n",
"options.n_rays = 5000\n",
"options.n_theta_bins = 20\n",
Expand Down
28 changes: 9 additions & 19 deletions examples/HIT_emissivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,13 @@
wavelengths = np.round(np.floor(np.exp(wavelengths)) * 1e-9, 12)

options = default_options()
options.wavelengths = wavelengths
options.wavelength = wavelengths
options.project_name = "HIT_notebook"
options.n_rays = 5000
options.n_theta_bins = 20
options.nx = 5
options.ny = 5
_, _, angle_vector = make_angle_vector(
options["n_theta_bins"], options["phi_symmetry"], options["c_azimuth"]
)
_, _, angle_vector = make_angle_vector(options["n_theta_bins"], options["phi_symmetry"], options["c_azimuth"])
options.bulk_profile = True
options.phi_symmetry = np.pi / 2

Expand All @@ -70,12 +68,8 @@
surf = regular_pyramids(elevation_angle=55, upright=True)
surf_back = regular_pyramids(elevation_angle=55, upright=False)

front_surf = Interface(
"RT_TMM", texture=surf, layers=front_materials, name="HIT_front", coherent=True
)
back_surf = Interface(
"RT_TMM", texture=surf_back, layers=back_materials, name="HIT_back", coherent=True
)
front_surf = Interface("RT_TMM", texture=surf, layers=front_materials, name="HIT_front", coherent=True)
back_surf = Interface("RT_TMM", texture=surf_back, layers=back_materials, name="HIT_back", coherent=True)


bulk_Si = BulkLayer(170e-6, Si, name="Si_bulk") # bulk thickness in m
Expand Down Expand Up @@ -117,11 +111,7 @@
# calculated photogenerated current (Jsc with 100% EQE)

spectr_flux = LightSource(
source_type="standard",
version="AM1.5g",
x=wavelengths,
output_units="photon_flux_per_m",
concentration=1,
source_type="standard", version="AM1.5g", x=wavelengths, output_units="photon_flux_per_m", concentration=1
).spectrum(wavelengths)[1]

Jph_Si = q * np.trapz(RAT["A_bulk"][0] * spectr_flux, wavelengths) / 10 # mA/cm2
Expand Down Expand Up @@ -155,16 +145,16 @@
# plot total R, A, T
fig = plt.figure(figsize=(5, 4))
ax = plt.subplot(111)
ax.semilogx(options["wavelengths"] * 1e6, R_escape + R_0, "--k", label=r"$R_{total}$")
ax.semilogx(options["wavelengths"] * 1e6, R_0, "-.k", label=r"$R_0$")
ax.semilogx(options["wavelength"] * 1e6, R_escape + R_0, "--k", label=r"$R_{total}$")
ax.semilogx(options["wavelength"] * 1e6, R_0, "-.k", label=r"$R_0$")
ax.stackplot(
options["wavelengths"] * 1e6,
options["wavelength"] * 1e6,
allres,
labels=["Ag", "Back ITO", "a-Si (back)", "Bulk Si", "a-Si (front)", "Front ITO"],
)
ax.semilogx(emissivity[:, 0], emissivity[:, 1], "-k")
ax.set_xlabel(r"Wavelength ($\mu$m)")
ax.set_ylabel("Absorption/Emissivity")
ax.set_xlim(min(options["wavelengths"] * 1e6), max(options["wavelengths"] * 1e6))
ax.set_xlim(min(options["wavelength"] * 1e6), max(options["wavelength"] * 1e6))
ax.set_ylim(0, 1)
plt.show()
Loading

0 comments on commit abea738

Please sign in to comment.