Skip to content

Commit

Permalink
something broken about RT, despite no (intentional?) changes?
Browse files Browse the repository at this point in the history
  • Loading branch information
phoebe-p committed Nov 14, 2023
1 parent 60559cb commit 77cc5c1
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 196 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- name: Install python dependencies
run: |
python -m pip install --upgrade setuptools wheel pip twine numba
pip install -e .[dev]
pip install .
- name: Install S4 in Linux
if: matrix.os == 'ubuntu-latest'
Expand All @@ -64,20 +64,19 @@ 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
- name: Codecov
if: matrix.os == 'ubuntu-latest'
env:
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
10 changes: 4 additions & 6 deletions examples/grating_pyramids_OPTOS.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
options = default_options()
options.wavelengths = wavelengths
options.theta_in = angle_degrees_in * np.pi / 180
options.n_theta_bins = 100
options.n_theta_bins = 50
options.c_azimuth = 0.25
options.n_rays = 25 * 25 * 1300
options.project_name = "OPTOS_comparison"
Expand All @@ -43,8 +43,7 @@
options.nx = 25
options.ny = 25
options.parallel = True
options.orders = 60
options.RCWA_method = "Inkstone"
options.RCWA_method = "S4"

# materials with constant n, zero k
x = 1000
Expand Down Expand Up @@ -88,7 +87,7 @@
layers=back_materials,
name="crossed_grating_back",
d_vectors=d_vectors,
rcwa_orders=15,
rcwa_orders=30,
)
back_surf_planar = Interface("TMM", layers=[], name="planar_back")

Expand Down Expand Up @@ -118,7 +117,7 @@
#
# process_structure(SC_fig8, options)

process_structure(planar, options)
process_structure(planar, options, overwrite=True)

results_fig6 = calculate_RAT(SC_fig6, options)

Expand Down Expand Up @@ -207,7 +206,6 @@
options["n_theta_bins"], options["phi_symmetry"], options["c_azimuth"]
)


path = get_savepath("default", options.project_name)
sprs = load_npz(os.path.join(path, SC_fig6[2].name + "frontRT.npz"))

Expand Down
156 changes: 156 additions & 0 deletions examples/thin_Si.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
from rayflare.rigorous_coupled_wave_analysis.rcwa import rcwa_structure
from rayflare.transfer_matrix_method import tmm_structure
from solcore import material, si
from solcore.solar_cell import Layer
from rayflare.options import default_options
import numpy as np
import matplotlib.pyplot as plt
from time import time

x = 1000
size = ((x, 0), (0, x))
hw = x/4

Air = material("Air")()
Si = material("Si")()
SiO2 = material("SiO2")()
Ag = material("Ag")()

geom_1 = [{ "type": "circle", "mat": SiO2, "radius": hw, "center": (0, 0)}]
geom_2 = [{ "type": "circle", "mat": Air, "radius": hw, "center": (0, 0)}]

stack = [
Layer(si("100nm"), SiO2),
Layer(si("200nm"), Si, geometry=geom_1),
Layer(si("3000nm"), Si),
Layer(si("200nm"), Si, geometry=geom_1)
]

options = default_options()
options.wavelengths = np.linspace(300, 1250, 120)*1e-9
options.orders = 50
options.parallel = True
options.theta_in = 0*np.pi/180
options.pol = 'u'

strt = rcwa_structure(stack, size, options, Air, Ag)
# IS = rcwa_structure_inkstone(stack, size, options, Air, Ag)

tmm_strt = tmm_structure(stack, Air, Ag)

RAT_planar = tmm_strt.calculate(options)

# options.RCWA_method = 'S4'
# strt.get_fields(3, 500, options, depth=100)
# options.RCWA_method = 'Inkstone'
# strt.get_fields(3, 500, options, depth=100)

start = time()
options.RCWA_method = 'S4'
S4_res = strt.calculate(options)
S4_res = strt.calculate_profile(options)
print(time() - start)
#
# start = time()
# options.RCWA_method = 'Inkstone'
# IS_res = strt.calculate(options)
# IS_res = strt.calculate_profile(options)
# print(time() - start)

plt.figure()
plt.plot(options.wavelengths*1e9, S4_res["R"], '-r')
# plt.plot(options.wavelengths*1e9, IS_res["R"], '--r')

plt.plot(options.wavelengths*1e9, S4_res["T"], '-b')
# plt.plot(options.wavelengths*1e9, IS_res["T"], '--b')

# plt.plot(options.wavelengths*1e9, S4_res["A_per_layer"], '-g')
# plt.plot(options.wavelengths*1e9, IS_res["A_per_layer"], '--g')

plt.plot(options.wavelengths*1e9, np.sum(S4_res["A_per_layer"], 1), '-y')
# plt.plot(options.wavelengths*1e9, np.sum(IS_res["A_per_layer"], 1), '--y')

plt.plot(options.wavelengths*1e9, np.sum(RAT_planar["A_per_layer"], 1))
plt.show()


plt.figure()
plt.plot(S4_res["profile"][15])
# plt.plot(IS_res["profile"][15], '--')
plt.show()
#
# stack = [
# Layer(si("50nm"), SiO2),
# Layer(si("500nm"), Si),
# Layer(si("1000nm"), GaAs,
# )
# ]
#
# options = default_options()
# options.wavelengths = np.linspace(300, 1250, 80)*1e-9
# options.orders = 60
# options.parallel = True
# options.theta_in = 45*np.pi/180
# options.pol = 's'
#
# strt = rcwa_structure(stack, size, options, Air, Ag)
# # IS = rcwa_structure_inkstone(stack, size, options, Air, Ag)
#
# start = time()
# options.RCWA_method = 'S4'
# S4_res = strt.calculate(options)
# S4_res = strt.calculate_profile(options)
# print(time() - start)
#
# start = time()
# options.RCWA_method = 'Inkstone'
# IS_res = strt.calculate(options)
# IS_res = strt.calculate_profile(options)
# print(time() - start)
#
# plt.figure()
# plt.plot(options.wavelengths*1e9, S4_res["R"], '-r')
# plt.plot(options.wavelengths*1e9, IS_res["R"], '--r')
#
# plt.plot(options.wavelengths*1e9, S4_res["T"], '-b')
# plt.plot(options.wavelengths*1e9, IS_res["T"], '--b')
#
# plt.plot(options.wavelengths*1e9, S4_res["A_per_layer"], '-g')
# plt.plot(options.wavelengths*1e9, IS_res["A_per_layer"], '--g')
#
# plt.plot(options.wavelengths*1e9, np.sum(S4_res["A_per_layer"], 1), '-y')
# plt.plot(options.wavelengths*1e9, np.sum(IS_res["A_per_layer"], 1), '--y')
# plt.show()
#
# plt.figure()
# plt.plot(S4_res["profile"][5])
# plt.plot(IS_res["profile"][5], '--')
# plt.show()
#

#
# options.pol = 'u'
#
# S4 = rcwa_structure(stack, size, options, Air, Ag)
# IS = rcwa_structure_inkstone(stack, size, options, Air, Ag)
#
# start = time()
# S4_res = S4.calculate(options)
# print(time() - start)
# IS_res = IS.calculate(options)
#
# plt.figure()
# plt.plot(options.wavelengths*1e9, S4_res["R"], '-r')
# plt.plot(options.wavelengths*1e9, IS_res["R"], '--r')
#
# plt.plot(options.wavelengths*1e9, S4_res["T"], '-b')
# plt.plot(options.wavelengths*1e9, IS_res["T"], '--b')
#
# plt.plot(options.wavelengths*1e9, S4_res["A_per_layer"], '-g')
# plt.plot(options.wavelengths*1e9, IS_res["A_per_layer"], '--g')
#
# plt.plot(options.wavelengths*1e9, np.sum(S4_res["A_per_layer"], 1), '-y')
# plt.plot(options.wavelengths*1e9, np.sum(IS_res["A_per_layer"], 1), '--y')
# plt.show()
#
# S4.get_fields(1, 200, options)
20 changes: 12 additions & 8 deletions rayflare/matrix_formalism/multiply_matrices.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@
from rayflare.structure import Interface, BulkLayer
from rayflare.utilities import get_savepath

from solcore.state import State

def calculate_RAT(SC, options, save_location="default"):
"""
After the list of Interface and BulkLayers has been processed by process_structure,
this function calculates the R, A and T by calling matrix_multiplication.
:param SC: list of Interface and BulkLayer objects. Order is [Interface, BulkLayer, Interface]
:param options: options for the matrix calculations
:param options: options for the matrix calculations (State object or dictionary)
:param save_location: location from which to load the redistribution matrices. Current options:
- 'default', which stores the results in folder in your home directory called 'RayFlare_results'
Expand All @@ -47,6 +48,9 @@ def calculate_RAT(SC, options, save_location="default"):
"""

if isinstance(options, dict):
options = State(options)

bulk_mats = []
bulk_widths = []
layer_widths = []
Expand Down Expand Up @@ -292,7 +296,7 @@ def matrix_multiplication(
:param bulk_mats: list of bulk materials
:param bulk_thick: list of bulk thicknesses (in m)
:param options: user options (dictionary or State object)
:param options: user options (State object)
:param layer_names: list of names of the Interface layers, to load the redistribution matrices
:param calc_prof_list: list of lists - for each interface, which layers should be included in profile calculations
(can be empty)
Expand All @@ -301,19 +305,19 @@ def matrix_multiplication(
:rtype:
"""

results_path = get_savepath(save_location, options["project_name"])
results_path = get_savepath(save_location, options.project_name)

n_bulks = len(bulk_mats)
n_interfaces = n_bulks + 1

theta_spacing = (
options["theta_spacing"] if hasattr(options, "theta_spacing") else "sin"
options.theta_spacing if "theta_spacing" in options else "sin"
)

theta_intv, phi_intv, angle_vector = make_angle_vector(
options["n_theta_bins"],
options["phi_symmetry"],
options["c_azimuth"],
options.n_theta_bins,
options.phi_symmetry,
options.c_azimuth,
theta_spacing,
)
n_a_in = int(len(angle_vector) / 2)
Expand All @@ -324,7 +328,7 @@ def matrix_multiplication(

thetas = angle_vector[:n_a_in, 1]

if options["phi_in"] != "all" and options["phi_in"] > options["phi_symmetry"]:
if options.phi_in != "all" and options.phi_in > options.phi_symmetry:
# fold phi_in back into phi_symmetry
print("fold")
phi_in = fold_phi(options["phi_in"], options["phi_symmetry"])
Expand Down
17 changes: 7 additions & 10 deletions rayflare/matrix_formalism/process_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from rayflare.matrix_formalism.ideal_cases import lambertian_matrix, mirror_matrix
from rayflare.utilities import get_savepath

from solcore.state import State


def process_structure(SC, options, save_location="default", overwrite=False):
"""
Expand All @@ -36,6 +38,9 @@ def process_structure(SC, options, save_location="default", overwrite=False):
any existing results (based on the project name, save_location and names of the surfaces) if they are available.
"""

if isinstance(options, dict):
options = State(options)

def determine_only_incidence(sd, j1, oia):
if sd == "front" and j1 == 0 and oia:
only_inc = True
Expand Down Expand Up @@ -117,11 +122,7 @@ def determine_coherency(strt):
which_sides = ["front", "rear"]

if struct.method == "Mirror":
theta_spacing = (
options["theta_spacing"]
if hasattr(options, "theta_spacing")
else "sin"
)
theta_spacing = options.theta_spacing if "theta_spacing" in options else "sin"

theta_intv, phi_intv, angle_vector = make_angle_vector(
options["n_theta_bins"],
Expand All @@ -142,11 +143,7 @@ def determine_coherency(strt):
)

if struct.method == "Lambertian":
theta_spacing = (
options["theta_spacing"]
if hasattr(options, "theta_spacing")
else "sin"
)
theta_spacing = options.theta_spacing if "theta_spacing" in options else "sin"

theta_intv, _, angle_vector = make_angle_vector(
options["n_theta_bins"],
Expand Down
Loading

0 comments on commit 77cc5c1

Please sign in to comment.