From 63798bf9bdbe5befdab2de908ff5d0c68c4dd451 Mon Sep 17 00:00:00 2001 From: Phoebe Pearce Date: Mon, 20 Nov 2023 15:55:05 +1100 Subject: [PATCH] update install instructions --- docs/search.json | 12 +- .../solcore-workshop-2/macos_installation.txt | 6 +- .../notebooks/6b-arc_optimization.html | 190 ++++++----- .../figure-html/cell-11-output-1.png | Bin 20589 -> 0 bytes .../figure-html/cell-7-output-3.png | Bin 29916 -> 0 bytes .../notebooks/8-grating_pyramids_OPTOS.html | 296 ++++++++++++------ .../windows_installation.txt | 6 +- 7 files changed, 301 insertions(+), 209 deletions(-) delete mode 100644 docs/solcore-workshop-2/notebooks/6b-arc_optimization_files/figure-html/cell-11-output-1.png delete mode 100644 docs/solcore-workshop-2/notebooks/6b-arc_optimization_files/figure-html/cell-7-output-3.png diff --git a/docs/search.json b/docs/search.json index e27c661..fa17301 100644 --- a/docs/search.json +++ b/docs/search.json @@ -256,7 +256,7 @@ "href": "solcore-workshop-2/notebooks/6b-arc_optimization.html", "title": "Section 6b: Optimizing an ARC", "section": "", - "text": "In the previous example, we introduced a simple one-layer anti-reflection coating (ARC); ARCs are a standard feature of all high-efficiency solar cells. But how do you find out the right thickness for the anti-reflection coating layer(s) (or the right dimensions for a light-trapping grating, or some other structure in your cell)? This is where optimization comes in. Here, we will look at a very simple ‘brute-force’ optimization for a single or double-layer ARC.\nimport numpy as np\nimport os\nimport matplotlib.pyplot as plt\n\nfrom solcore import material, si\nfrom solcore.solar_cell import Layer, SolarCell\nfrom solcore.solar_cell_solver import solar_cell_solver\nfrom solcore.light_source import LightSource\nfrom solcore.absorption_calculator import search_db, download_db\nfrom solcore.absorption_calculator import calculate_rat\nfrom solcore.state import State\n\nfrom rayflare.transfer_matrix_method import tmm_structure\nfrom rayflare.options import default_options\nimport seaborn as sns" + "text": "In the previous example, we introduced a simple one-layer anti-reflection coating (ARC); ARCs are a standard feature of all high-efficiency solar cells. But how do you find out the right thickness for the anti-reflection coating layer(s) (or the right dimensions for a light-trapping grating, or some other structure in your cell)? This is where optimization comes in. Here, we will look at a very simple ‘brute-force’ optimization for a single or double-layer ARC.\nimport numpy as np\nimport os\nimport matplotlib.pyplot as plt\n\nfrom solcore import material, si\nfrom solcore.solar_cell import Layer, SolarCell\nfrom solcore.solar_cell_solver import solar_cell_solver\nfrom solcore.light_source import LightSource\nfrom solcore.absorption_calculator import search_db, download_db\nfrom solcore.absorption_calculator import calculate_rat\nfrom solcore.state import State\n\nfrom rayflare.transfer_matrix_method import tmm_structure\nfrom rayflare.options import default_options\nimport seaborn as sns\n\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The Poisson - Drift-Diffusion solver will not be available because the ddModel fortran library could not be imported.\nname 'dd' is not defined\n\n\n/Users/z3533914/.pyenv/versions/3.11.5/lib/python3.11/site-packages/solcore/registries.py:73: UserWarning: Optics solver 'RCWA' will not be available. An installation of S4 has not been found.\n warn(" }, { "objectID": "solcore-workshop-2/notebooks/6b-arc_optimization.html#setting-up", @@ -270,14 +270,14 @@ "href": "solcore-workshop-2/notebooks/6b-arc_optimization.html#single-layer-arc", "title": "Section 6b: Optimizing an ARC", "section": "Single-layer ARC", - "text": "Single-layer ARC\nHere, we will calculate the behaviour of a single-layer SiN anti-reflection coating on Si while changing the ARC thickness between 0 and 200 nm. We will consider two values to optimize: the mean reflectance mean_R, and the reflectance weighted by the photon flux in an AM1.5G spectrum (weighted_R). The reason for considering the second value is that it is more useful to suppress reflection at wavelengths where there are more photons which could be absorbed by the cell (up to the cell’s bandgap).\nWe will loop through the different ARC thicknesses in d_range, build the structure for each case, and then calculate the reflectance. We then save the mean reflected and weighted mean reflectance in the corresponding arrays. We also plot the reflectance for each 15th loop (this is just so the plot does not get too crowded).\n\nd_range = np.linspace(0, 200, 200)\n\nmean_R = np.empty_like(d_range)\nweighted_R = np.empty_like(d_range)\n\ncols = sns.cubehelix_palette(np.ceil(len(d_range)/15))\n\nplt.figure()\njcol = 0\n\nfor i1, d in enumerate(d_range):\n\n struct = SolarCell([Layer(si(d, 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)\n solar_cell_solver(struct, task='optics', user_options=opts)\n\n if i1 % 15 == 0:\n plt.plot(wavelengths*1e9, struct.reflected, label=str(np.round(d, 0)), color=cols[jcol])\n jcol += 1\n\n mean_R[i1] = np.mean(struct.reflected)\n weighted_R[i1] = np.mean(struct.reflected*normalised_spectrum)\n\nplt.legend()\nplt.show()\n\nWe now find at which index mean_R and weighted_R are minimised using np.argmin, and use this to print the ARC thickness at which this occurs (rounded to 1 decimal place).\n\nprint('Minimum mean reflection occurs at d = ' + str(np.round(d_range[np.argmin(mean_R)], 1)) + ' nm')\nprint('Minimum weighted reflection occurs at d = ' + str(np.round(d_range[np.argmin(weighted_R)], 1)) + ' nm')\n\nMinimum mean reflection occurs at d = 67.3 nm\nMinimum weighted reflection occurs at d = 74.4 nm\n\n\nWe see that the values of \\(d\\) for the two different ways of optimizing are very similar, but not exactly the same, as we would expect. The minimum in both cases occurs around 70 nm. We can also plot the variation of the mean and weighted \\(R\\) with ARC thickness \\(d\\):\n\nplt.figure()\nplt.plot(d_range, mean_R, label='Mean reflection')\nplt.plot(d_range[np.argmin(mean_R)], np.min(mean_R), 'ok')\nplt.plot(d_range, weighted_R, label='Weighted mean reflection')\nplt.plot(d_range[np.argmin(weighted_R)], np.min(weighted_R), 'ok')\nplt.xlabel('d$_{SiN}$')\nplt.ylabel('(Weighted) mean reflection 300-1200 nm')\nplt.legend()\nplt.show()\n\n\n\n\nNow, to see what the reflectance looks like for the optimized structure, we make new tmm_structures with the optimal values and calculate and plot the reflectance:\n\nstruct_1 = SolarCell([Layer(si(d_range[np.argmin(mean_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)\nsolar_cell_solver(struct_1, task='optics', user_options=opts)\nR_1 = struct_1.reflected\n\nstruct_2 = SolarCell([Layer(si(d_range[np.argmin(weighted_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)\nsolar_cell_solver(struct_2, task='optics', user_options=opts)\nR_2 = struct_2.reflected\n\nplt.figure()\nplt.plot(wavelengths*1e9, R_1, label='Mean R minimum')\nplt.plot(wavelengths*1e9, R_2, label='Weighted R minimum')\nplt.legend()\nplt.xlabel(\"Wavelength (nm)\")\nplt.ylabel(\"R\")\nplt.show()\n\nINFO: Solving optics of the solar cell...\nINFO: Solving optics of the solar cell...\n\n\nTreating layer(s) 1 incoherently\nCalculating RAT...\nCalculating absorption profile...\nTreating layer(s) 1 incoherently\nCalculating RAT...\nCalculating absorption profile...\n\n\n\n\n\nWe see that the two reflectance curves are very similar, as expected because the layer thicknesses are very similar." + "text": "Single-layer ARC\nHere, we will calculate the behaviour of a single-layer SiN anti-reflection coating on Si while changing the ARC thickness between 0 and 200 nm. We will consider two values to optimize: the mean reflectance mean_R, and the reflectance weighted by the photon flux in an AM1.5G spectrum (weighted_R). The reason for considering the second value is that it is more useful to suppress reflection at wavelengths where there are more photons which could be absorbed by the cell (up to the cell’s bandgap).\nWe will loop through the different ARC thicknesses in d_range, build the structure for each case, and then calculate the reflectance. We then save the mean reflected and weighted mean reflectance in the corresponding arrays. We also plot the reflectance for each 15th loop (this is just so the plot does not get too crowded).\n\nd_range = np.linspace(0, 200, 200)\n\nmean_R = np.empty_like(d_range)\nweighted_R = np.empty_like(d_range)\n\ncols = sns.cubehelix_palette(np.ceil(len(d_range)/15))\n\nplt.figure()\njcol = 0\n\nfor i1, d in enumerate(d_range):\n\n struct = SolarCell([Layer(si(d, 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)\n solar_cell_solver(struct, task='optics', user_options=opts)\n\n if i1 % 15 == 0:\n plt.plot(wavelengths*1e9, struct.reflected, label=str(np.round(d, 0)), color=cols[jcol])\n jcol += 1\n\n mean_R[i1] = np.mean(struct.reflected)\n weighted_R[i1] = np.mean(struct.reflected*normalised_spectrum)\n\nplt.legend()\nplt.show()\n\nWe now find at which index mean_R and weighted_R are minimised using np.argmin, and use this to print the ARC thickness at which this occurs (rounded to 1 decimal place).\n\nprint('Minimum mean reflection occurs at d = ' + str(np.round(d_range[np.argmin(mean_R)], 1)) + ' nm')\nprint('Minimum weighted reflection occurs at d = ' + str(np.round(d_range[np.argmin(weighted_R)], 1)) + ' nm')\n\nMinimum mean reflection occurs at d = 67.3 nm\nMinimum weighted reflection occurs at d = 74.4 nm\n\n\nWe see that the values of \\(d\\) for the two different ways of optimizing are very similar, but not exactly the same, as we would expect. The minimum in both cases occurs around 70 nm. We can also plot the variation of the mean and weighted \\(R\\) with ARC thickness \\(d\\):\n\nplt.figure()\nplt.plot(d_range, mean_R, label='Mean reflection')\nplt.plot(d_range[np.argmin(mean_R)], np.min(mean_R), 'ok')\nplt.plot(d_range, weighted_R, label='Weighted mean reflection')\nplt.plot(d_range[np.argmin(weighted_R)], np.min(weighted_R), 'ok')\nplt.xlabel('d$_{SiN}$')\nplt.ylabel('(Weighted) mean reflection 300-1200 nm')\nplt.legend()\nplt.show()\n\n\n\n\nNow, to see what the reflectance looks like for the optimized structure, we make new tmm_structures with the optimal values and calculate and plot the reflectance:\n\nstruct_1 = SolarCell([Layer(si(d_range[np.argmin(mean_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)\nsolar_cell_solver(struct_1, task='optics', user_options=opts)\nR_1 = struct_1.reflected\n\nstruct_2 = SolarCell([Layer(si(d_range[np.argmin(weighted_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)\nsolar_cell_solver(struct_2, task='optics', user_options=opts)\nR_2 = struct_2.reflected\n\nplt.figure()\nplt.plot(wavelengths*1e9, R_1, label='Mean R minimum')\nplt.plot(wavelengths*1e9, R_2, label='Weighted R minimum')\nplt.legend()\nplt.xlabel(\"Wavelength (nm)\")\nplt.ylabel(\"R\")\nplt.show()\n\nTreating layer(s) 1 incoherently\nCalculating RAT...\nCalculating absorption profile...\nTreating layer(s) 1 incoherently\nCalculating RAT...\nCalculating absorption profile...\n\n\n\n\n\nWe see that the two reflectance curves are very similar, as expected because the layer thicknesses are very similar." }, { "objectID": "solcore-workshop-2/notebooks/6b-arc_optimization.html#double-layer-arc", "href": "solcore-workshop-2/notebooks/6b-arc_optimization.html#double-layer-arc", "title": "Section 6b: Optimizing an ARC", "section": "Double-layer ARC", - "text": "Double-layer ARC\nWe will now consider a similar situation, but for a double-layer MgF\\(_2\\)/Ta\\(_2\\)O\\(_5\\) ARC on GaAs.\nSolcore can directly interface with the database from www.refractiveindex.info, which contains around 3000 sets of data for a large number of different materials. Before the first use, it is necessary to download the database. This only needs to be done once, so you can comment this line out after it’s done:\n\ndownload_db(confirm=True) # only needs to be done once\n\nDatabase file found at /Users/z3533914/.solcore/nk/nk.db\nMaking request to https://refractiveindex.info/download/database/rii-database-2021-07-18.zip\nDownloaded and extracting...\nWrote /var/folders/wh/w5k56r_927j4yp3mh91bggfc0000gq/T/tmpfnrk4_hu/database from https://refractiveindex.info/download/database/rii-database-2021-07-18.zip\nLOG: 2746,other,PtAl2,Chen : Bad Material YAML File.\n***Wrote SQLite DB on /Users/z3533914/.solcore/nk/nk.db\n\n\n/Users/z3533914/.pyenv/versions/3.11.5/lib/python3.11/site-packages/solcore/material_data/refractiveindex_info_DB/dbmaterial.py:278: RuntimeWarning: invalid value encountered in sqrt\n n = numpy.sqrt(nsq)\n/Users/z3533914/.pyenv/versions/3.11.5/lib/python3.11/site-packages/solcore/material_data/refractiveindex_info_DB/dbmaterial.py:299: RuntimeWarning: invalid value encountered in sqrt\n n = numpy.sqrt(n)\n\n\nWe search for materials in the refractiveindex.info database, and use only the part of the solar spectrum relevant for absorption in GaAs (in this case, there is no benefit to reducing absorption above the GaAs bandgap around 900 nm). We will only consider the weighted mean \\(R\\) in this case. Since all the layers in the structure are relatively thin compared to the wavelengths of light, we do a coherent calculation.\n\npageid_MgF2 = search_db(os.path.join(\"MgF2\", \"Rodriguez-de Marcos\"))[0][0]\npageid_Ta2O5 = search_db(os.path.join(\"Ta2O5\", \"Rodriguez-de Marcos\"))[0][0]\n\nGaAs = material(\"GaAs\")()\nMgF2 = material(str(pageid_MgF2), nk_db=True)()\nTa2O5 = material(str(pageid_Ta2O5), nk_db=True)()\n\nMgF2_thickness = np.linspace(50, 100, 20)\nTa2O5_thickness = np.linspace(30, 80, 20)\n\nweighted_R_matrix = np.zeros((len(MgF2_thickness), len(Ta2O5_thickness)))\n\nwavelengths_GaAs = wavelengths[wavelengths < 900e-9]\nnormalised_spectrum_GaAs = normalised_spectrum[wavelengths < 900e-9]\n\nopts.coherency_list = None\nopts.wavelength = wavelengths_GaAs\nopts.position = 20e-6\n\nWe now have two thicknesses to loop through; otherwise, the procedure is similar to the single-layer ARC example.\n\nfor i1, d_MgF2 in enumerate(MgF2_thickness):\n for j1, d_Ta2O5 in enumerate(Ta2O5_thickness):\n struct = SolarCell([Layer(si(d_MgF2, 'nm'), MgF2), Layer(si(d_Ta2O5, 'nm'), Ta2O5),\n Layer(si('20um'), GaAs)],\n substrate=Ag)\n solar_cell_solver(struct, 'optics', opts)\n R = struct.reflected\n\n weighted_R_matrix[i1, j1] = np.mean(R * normalised_spectrum_GaAs)\n\n# find the row and column indices of the minimum weighted R value\nri, ci = np.unravel_index(weighted_R_matrix.argmin(), weighted_R_matrix.shape)\n\nWe plot the total absorption (\\(1-R\\)) in the structure with the optimized ARC, and print the thicknesses of MgF\\(_2\\) and Ta\\(_2\\)O\\(_5\\) at which this occurs:\n\nplt.figure()\nplt.imshow(1-weighted_R_matrix, extent=[min(Ta2O5_thickness), max(Ta2O5_thickness),\n min(MgF2_thickness), max(MgF2_thickness)],\n origin='lower', aspect='equal')\nplt.plot(Ta2O5_thickness[ci], MgF2_thickness[ri], 'xk')\nplt.colorbar()\nplt.xlabel(\"Ta$_2$O$_5$ thickness (nm)\")\nplt.ylabel(\"MgF$_2$ thickness (nm)\")\nplt.show()\n\nprint(\"Minimum reflection occurs at MgF2 / Ta2O5 thicknesses of %.1f / %.1f nm \"\n % (MgF2_thickness[ri], Ta2O5_thickness[ci]))\n\n\n\n\nMinimum reflection occurs at MgF2 / Ta2O5 thicknesses of 73.7 / 53.7 nm \n\n\nFor these two examples, where we are only trying to optimize one and two parameters respectively across a relatively small range, using a method (TMM) which executes quickly, brute force searching is possible. However, as we introduce more parameters, a wider parameter space, and slower simulation methods, it may no longer be computationally tractable; in that case, using for example differential evolution or other types of numerical optimization may be more appropriate (see this example)." + "text": "Double-layer ARC\nWe will now consider a similar situation, but for a double-layer MgF\\(_2\\)/Ta\\(_2\\)O\\(_5\\) ARC on GaAs.\nSolcore can directly interface with the database from www.refractiveindex.info, which contains around 3000 sets of data for a large number of different materials. Before the first use, it is necessary to download the database. This only needs to be done once, so you can comment this line out after it’s done:\n\ndownload_db(confirm=True) # only needs to be done once\n\nDatabase file found at /Users/z3533914/.solcore/nk/nk.db\nMaking request to https://refractiveindex.info/download/database/rii-database-2021-07-18.zip\nDownloaded and extracting...\n\n\nWe search for materials in the refractiveindex.info database, and use only the part of the solar spectrum relevant for absorption in GaAs (in this case, there is no benefit to reducing absorption above the GaAs bandgap around 900 nm). We will only consider the weighted mean \\(R\\) in this case. Since all the layers in the structure are relatively thin compared to the wavelengths of light, we do a coherent calculation.\n\npageid_MgF2 = search_db(os.path.join(\"MgF2\", \"Rodriguez-de Marcos\"))[0][0]\npageid_Ta2O5 = search_db(os.path.join(\"Ta2O5\", \"Rodriguez-de Marcos\"))[0][0]\n\nGaAs = material(\"GaAs\")()\nMgF2 = material(str(pageid_MgF2), nk_db=True)()\nTa2O5 = material(str(pageid_Ta2O5), nk_db=True)()\n\nMgF2_thickness = np.linspace(50, 100, 20)\nTa2O5_thickness = np.linspace(30, 80, 20)\n\nweighted_R_matrix = np.zeros((len(MgF2_thickness), len(Ta2O5_thickness)))\n\nwavelengths_GaAs = wavelengths[wavelengths < 900e-9]\nnormalised_spectrum_GaAs = normalised_spectrum[wavelengths < 900e-9]\n\nopts.coherency_list = None\nopts.wavelength = wavelengths_GaAs\nopts.position = 20e-6\n\nWe now have two thicknesses to loop through; otherwise, the procedure is similar to the single-layer ARC example.\n\nfor i1, d_MgF2 in enumerate(MgF2_thickness):\n for j1, d_Ta2O5 in enumerate(Ta2O5_thickness):\n struct = SolarCell([Layer(si(d_MgF2, 'nm'), MgF2), Layer(si(d_Ta2O5, 'nm'), Ta2O5),\n Layer(si('20um'), GaAs)],\n substrate=Ag)\n solar_cell_solver(struct, 'optics', opts)\n R = struct.reflected\n\n weighted_R_matrix[i1, j1] = np.mean(R * normalised_spectrum_GaAs)\n\n# find the row and column indices of the minimum weighted R value\nri, ci = np.unravel_index(weighted_R_matrix.argmin(), weighted_R_matrix.shape)\n\nWe plot the total absorption (\\(1-R\\)) in the structure with the optimized ARC, and print the thicknesses of MgF\\(_2\\) and Ta\\(_2\\)O\\(_5\\) at which this occurs:\n\nplt.figure()\nplt.imshow(1-weighted_R_matrix, extent=[min(Ta2O5_thickness), max(Ta2O5_thickness),\n min(MgF2_thickness), max(MgF2_thickness)],\n origin='lower', aspect='equal')\nplt.plot(Ta2O5_thickness[ci], MgF2_thickness[ri], 'xk')\nplt.colorbar()\nplt.xlabel(\"Ta$_2$O$_5$ thickness (nm)\")\nplt.ylabel(\"MgF$_2$ thickness (nm)\")\nplt.show()\n\nprint(\"Minimum reflection occurs at MgF2 / Ta2O5 thicknesses of %.1f / %.1f nm \"\n % (MgF2_thickness[ri], Ta2O5_thickness[ci]))\n\nFor these two examples, where we are only trying to optimize one and two parameters respectively across a relatively small range, using a method (TMM) which executes quickly, brute force searching is possible. However, as we introduce more parameters, a wider parameter space, and slower simulation methods, it may no longer be computationally tractable; in that case, using for example differential evolution or other types of numerical optimization may be more appropriate (see this example)." }, { "objectID": "solcore-workshop-2/notebooks/6b-arc_optimization.html#questions", @@ -1117,14 +1117,14 @@ "href": "solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html#setting-up", "title": "Section 8: Textured Si", "section": "Setting up", - "text": "Setting up\nFirst, importing relevant packages:\n\nimport numpy as np\nimport os\n\n# solcore imports\nfrom solcore.structure import Layer\nfrom solcore import material\nfrom solcore import si\n\nfrom rayflare.structure import Interface, BulkLayer, Structure\nfrom rayflare.matrix_formalism import process_structure, calculate_RAT\nfrom rayflare.utilities import get_savepath\nfrom rayflare.transfer_matrix_method import tmm_structure\nfrom rayflare.angles import theta_summary, make_angle_vector\nfrom rayflare.textures import regular_pyramids\nfrom rayflare.options import default_options\n\nimport matplotlib.pyplot as plt\nimport matplotlib as mpl\nimport seaborn as sns\nfrom sparse import load_npz\n\nSetting options (taking the default options for everything not specified explicitly):\n\nangle_degrees_in = 8 # same as in Fraunhofer paper\n\nwavelengths = np.linspace(900, 1200, 20) * 1e-9\n\nSi = material(\"Si\")()\nAir = material(\"Air\")()\n\noptions = default_options()\noptions.wavelength = wavelengths\noptions.theta_in = angle_degrees_in * np.pi / 180 # incidence angle (polar angle)\noptions.n_theta_bins = 30\noptions.c_azimuth = 0.25\noptions.n_rays = 1e5 # number of rays per wavelength in ray-tracing\noptions.project_name = \"OPTOS_comparison\"\noptions.orders = 60 # number of RCWA orders to use (more = better convergence, but slower)\noptions.pol = \"u\" # unpolarized light\noptions.only_incidence_angle = False\noptions.RCWA_method = \"Inkstone\"" + "text": "Setting up\nFirst, importing relevant packages:\n\nimport numpy as np\nimport os\n\n# solcore imports\nfrom solcore.structure import Layer\nfrom solcore import material\nfrom solcore import si\n\nfrom rayflare.structure import Interface, BulkLayer, Structure\nfrom rayflare.matrix_formalism import process_structure, calculate_RAT\nfrom rayflare.utilities import get_savepath\nfrom rayflare.transfer_matrix_method import tmm_structure\nfrom rayflare.angles import theta_summary, make_angle_vector\nfrom rayflare.textures import regular_pyramids\nfrom rayflare.options import default_options\n\nimport matplotlib.pyplot as plt\nimport matplotlib as mpl\nimport seaborn as sns\nfrom sparse import load_npz\n\nSetting options (taking the default options for everything not specified explicitly):\n\nangle_degrees_in = 8 # same as in Fraunhofer paper\n\nwavelengths = np.linspace(900, 1200, 20) * 1e-9\n\nSi = material(\"Si\")()\nAir = material(\"Air\")()\n\noptions = default_options()\noptions.wavelength = wavelengths\noptions.theta_in = angle_degrees_in * np.pi / 180 # incidence angle (polar angle)\noptions.n_theta_bins = 30\noptions.c_azimuth = 0.25\noptions.n_rays = 5e4 # number of rays per wavelength in ray-tracing\noptions.project_name = \"OPTOS_comparison\"\noptions.orders = 60 # number of RCWA orders to use (more = better convergence, but slower)\noptions.pol = \"u\" # unpolarized light\noptions.only_incidence_angle = True\noptions.RCWA_method = \"Inkstone\"" }, { "objectID": "solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html#defining-the-structures", "href": "solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html#defining-the-structures", "title": "Section 8: Textured Si", "section": "Defining the structures", - "text": "Defining the structures\nNow, set up the grating basis vectors for the RCWA calculations and define the grating structure. These are squares, rotated by 45 degrees. The halfwidth is calculated based on the area fill factor of the etched pillars given in the paper.\n\nx = 1000\n\nd_vectors = ((x, 0), (0, x))\narea_fill_factor = 0.36\nhw = np.sqrt(area_fill_factor) * 500\n\nback_materials = [\n Layer(width=si(\"120nm\"), material=Si,\n geometry=[{\"type\": \"rectangle\", \"mat\": Air, \"center\": (x / 2, x / 2),\n \"halfwidths\": (hw, hw), \"angle\": 45}],\n )]\n\nNow we define the pyramid texture for the front surface in case (2) and (3) and make the four possible different surfaces: planar front and rear, front with pyramids, rear with grating. We specify the method to use to calculate the redistribution matrices in each case and create the bulk layer.\n\nsurf = regular_pyramids(elevation_angle=55, upright=False)\n\nfront_surf_pyramids = Interface(\n \"RT_Fresnel\",\n texture=surf,\n layers=[],\n name=\"inv_pyramids_front_\" + str(options[\"n_rays\"]),\n)\n\nfront_surf_planar = Interface(\"TMM\", layers=[], name=\"planar_front\")\n\nback_surf_grating = Interface(\n \"RCWA\",\n layers=back_materials,\n name=\"crossed_grating_back\",\n d_vectors=d_vectors,\n rcwa_orders=20,\n)\n\nback_surf_planar = Interface(\"TMM\", layers=[], name=\"planar_back\")\n\nbulk_Si = BulkLayer(200e-6, Si, name=\"Si_bulk\")\n\nNow we create the different structures and ‘process’ them (this will calculate the relevant matrices if necessary, or do nothing if it finds the matrices have previously been calculated and the files already exist). We don’t need to process the final structure because it will use matrices calculated for SC_fig6 and SC_fig7.\n\nSC_fig6 = Structure(\n [front_surf_planar, bulk_Si, back_surf_grating], incidence=Air, transmission=Air\n)\nSC_fig7 = Structure(\n [front_surf_pyramids, bulk_Si, back_surf_planar], incidence=Air, transmission=Air\n)\nSC_fig8 = Structure(\n [front_surf_pyramids, bulk_Si, back_surf_grating], incidence=Air, transmission=Air\n)\n\nprocess_structure(SC_fig6, options, save_location='current')\nprocess_structure(SC_fig7, options, save_location='current')" + "text": "Defining the structures\nNow, set up the grating basis vectors for the RCWA calculations and define the grating structure. These are squares, rotated by 45 degrees. The halfwidth is calculated based on the area fill factor of the etched pillars given in the paper.\n\nx = 1000\n\nd_vectors = ((x, 0), (0, x))\narea_fill_factor = 0.36\nhw = np.sqrt(area_fill_factor) * 500\n\nback_materials = [\n Layer(width=si(\"120nm\"), material=Si,\n geometry=[{\"type\": \"rectangle\", \"mat\": Air, \"center\": (x / 2, x / 2),\n \"halfwidths\": (hw, hw), \"angle\": 45}],\n )]\n\nNow we define the pyramid texture for the front surface in case (2) and (3) and make the four possible different surfaces: planar front and rear, front with pyramids, rear with grating. We specify the method to use to calculate the redistribution matrices in each case and create the bulk layer.\n\nsurf = regular_pyramids(elevation_angle=55, upright=False)\n\nfront_surf_pyramids = Interface(\n \"RT_Fresnel\",\n texture=surf,\n layers=[],\n name=\"inv_pyramids_front_\" + str(options[\"n_rays\"]),\n)\n\nfront_surf_planar = Interface(\"TMM\", layers=[], name=\"planar_front\")\n\nback_surf_grating = Interface(\n \"RCWA\",\n layers=back_materials,\n name=\"crossed_grating_back\",\n d_vectors=d_vectors,\n rcwa_orders=20,\n)\n\nback_surf_planar = Interface(\"TMM\", layers=[], name=\"planar_back\")\n\nbulk_Si = BulkLayer(200e-6, Si, name=\"Si_bulk\")\n\nNow we create the different structures and ‘process’ them (this will calculate the relevant matrices if necessary, or do nothing if it finds the matrices have previously been calculated and the files already exist). We don’t need to process the final structure because it will use matrices calculated for SC_fig6 and SC_fig7.\n\nSC_fig6 = Structure(\n [front_surf_planar, bulk_Si, back_surf_grating], incidence=Air, transmission=Air\n)\nSC_fig7 = Structure(\n [front_surf_pyramids, bulk_Si, back_surf_planar], incidence=Air, transmission=Air\n)\nSC_fig8 = Structure(\n [front_surf_pyramids, bulk_Si, back_surf_grating], incidence=Air, transmission=Air\n)\n\nprocess_structure(SC_fig6, options, save_location='current') # if you want to overwrite previous results, add overwrite=Trues\nprocess_structure(SC_fig7, options, save_location='current')\n\nINFO: Making matrix for planar surface using TMM for element 0 in structure\nINFO: RCWA calculation for element 2 in structure\nINFO: RCWA calculation for wavelength = 947.3684210526316 nm\nINFO: RCWA calculation for wavelength = 915.7894736842105 nm\nINFO: RCWA calculation for wavelength = 978.9473684210526 nm\nINFO: RCWA calculation for wavelength = 1010.5263157894736 nm\nINFO: RCWA calculation for wavelength = 994.7368421052631 nm\nINFO: RCWA calculation for wavelength = 931.578947368421 nm\nINFO: RCWA calculation for wavelength = 1026.3157894736842 nm\nINFO: RCWA calculation for wavelength = 900.0000000000001 nm\nINFO: RCWA calculation for wavelength = 1042.1052631578948 nm\nINFO: RCWA calculation for wavelength = 963.1578947368421 nm\nINFO: RCWA calculation for wavelength = 1057.8947368421054 nm\nINFO: RCWA calculation for wavelength = 1073.6842105263158 nm\nINFO: RCWA calculation for wavelength = 1089.4736842105265 nm\nINFO: RCWA calculation for wavelength = 1105.2631578947369 nm\nINFO: RCWA calculation for wavelength = 1121.0526315789475 nm\nINFO: RCWA calculation for wavelength = 1136.842105263158 nm\nINFO: RCWA calculation for wavelength = 1152.6315789473683 nm\nINFO: RCWA calculation for wavelength = 1168.421052631579 nm\nINFO: RCWA calculation for wavelength = 1184.2105263157896 nm\nINFO: RCWA calculation for wavelength = 1200.0000000000002 nm\nINFO: Ray tracing with Fresnel equations for element 0 in structure\nINFO: Calculating matrix only for incidence theta/phi\nINFO: RT calculation for wavelength = 931.578947368421 nm\nINFO: RT calculation for wavelength = 900.0000000000001 nm\nINFO: RT calculation for wavelength = 915.7894736842105 nm\nINFO: RT calculation for wavelength = 947.3684210526316 nm\nINFO: RT calculation for wavelength = 963.1578947368421 nm\nINFO: RT calculation for wavelength = 978.9473684210526 nm\nINFO: RT calculation for wavelength = 994.7368421052631 nm\nINFO: RT calculation for wavelength = 1010.5263157894736 nm\nINFO: RT calculation for wavelength = 1042.1052631578948 nm\nINFO: RT calculation for wavelength = 1026.3157894736842 nm\nINFO: RT calculation for wavelength = 1057.8947368421054 nm\nINFO: RT calculation for wavelength = 1073.6842105263158 nm\nINFO: RT calculation for wavelength = 1089.4736842105265 nm\nINFO: RT calculation for wavelength = 1105.2631578947369 nm\nINFO: RT calculation for wavelength = 1136.842105263158 nm\nINFO: RT calculation for wavelength = 1152.6315789473683 nm\nINFO: RT calculation for wavelength = 1121.0526315789475 nm\nINFO: RT calculation for wavelength = 1168.421052631579 nm\nINFO: RT calculation for wavelength = 1184.2105263157896 nm\nINFO: RT calculation for wavelength = 1200.0000000000002 nm\nINFO: RT calculation for wavelength = 900.0000000000001 nm\nINFO: RT calculation for wavelength = 915.7894736842105 nm\nINFO: RT calculation for wavelength = 931.578947368421 nm\nINFO: RT calculation for wavelength = 947.3684210526316 nm\nINFO: RT calculation for wavelength = 963.1578947368421 nm\nINFO: RT calculation for wavelength = 978.9473684210526 nm\nINFO: RT calculation for wavelength = 994.7368421052631 nm\nINFO: RT calculation for wavelength = 1010.5263157894736 nm\nINFO: RT calculation for wavelength = 1026.3157894736842 nm\nINFO: RT calculation for wavelength = 1042.1052631578948 nm\nINFO: RT calculation for wavelength = 1057.8947368421054 nm\nINFO: RT calculation for wavelength = 1073.6842105263158 nm\nINFO: RT calculation for wavelength = 1089.4736842105265 nm\nINFO: RT calculation for wavelength = 1105.2631578947369 nm\nINFO: RT calculation for wavelength = 1121.0526315789475 nm\nINFO: RT calculation for wavelength = 1136.842105263158 nm\nINFO: RT calculation for wavelength = 1152.6315789473683 nm\nINFO: RT calculation for wavelength = 1168.421052631579 nm\nINFO: RT calculation for wavelength = 1184.2105263157896 nm\nINFO: RT calculation for wavelength = 1200.0000000000002 nm\nINFO: Making matrix for planar surface using TMM for element 2 in structure\n\n\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.WARNING: The RCWA solver will not be available because an S4 installation has not been found.\n\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found.\nWARNING: The RCWA solver will not be available because an S4 installation has not been found." }, { "objectID": "solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html#calculating-rat", @@ -1138,7 +1138,7 @@ "href": "solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html#plotting", "title": "Section 8: Textured Si", "section": "Plotting", - "text": "Plotting\nPlot everything together, including data from the reference paper for comparison:\n\npalhf = sns.color_palette(\"hls\", 4)\n\nfig = plt.figure()\nplt.plot(sim_fig6[:, 0], sim_fig6[:, 1],\n \"--\", color=palhf[0], label=\"OPTOS - rear grating (1)\")\nplt.plot(wavelengths * 1e9, RAT_fig6[\"A_bulk\"][0],\n \"-o\", color=palhf[0], label=\"RayFlare - rear grating (1)\", fillstyle=\"none\")\nplt.plot(sim_fig7[:, 0], sim_fig7[:, 1],\n \"--\", color=palhf[1], label=\"OPTOS - front pyramids (2)\",)\nplt.plot(wavelengths * 1e9, RAT_fig7[\"A_bulk\"][0],\n \"-o\", color=palhf[1], label=\"RayFlare - front pyramids (2)\", fillstyle=\"none\")\nplt.plot(sim_fig8[:, 0], sim_fig8[:, 1],\n \"--\", color=palhf[2], label=\"OPTOS - grating + pyramids (3)\")\nplt.plot(wavelengths * 1e9, RAT_fig8[\"A_bulk\"][0],\n \"-o\", color=palhf[2],label=\"RayFlare - grating + pyramids (3)\", fillstyle=\"none\",)\nplt.plot(wavelengths * 1e9, RAT[\"A_per_layer\"][:, 0], \"-k\", label=\"Planar\")\nplt.legend(loc=\"lower left\")\nplt.xlabel(\"Wavelength (nm)\")\nplt.ylabel(\"Absorption in Si\")\nplt.xlim([900, 1200])\nplt.ylim([0, 1])\nplt.show()\n\nWe can see good agreement between the reference values and our calculated values. The structure with rear grating also behaves identically to the planar TMM reference case at the short wavelengths where front surface reflection dominates the result, as expected. Clearly, the pyramids perform much better overall, giving a large boost in the absorption at long wavelengths and also reducing the reflection significantly at shorter wavelengths. Plotting reflection and transmission emphasises this:\n\nfig = plt.figure()\nplt.plot(wavelengths * 1e9,RAT_fig6[\"R\"][0],\n \"-o\", color=palhf[0], label=\"RayFlare - rear grating (1)\", fillstyle=\"none\")\nplt.plot(wavelengths * 1e9, RAT_fig7[\"R\"][0],\n \"-o\", color=palhf[1], label=\"RayFlare - front pyramids (2)\", fillstyle=\"none\")\nplt.plot(wavelengths * 1e9, RAT_fig8[\"R\"][0],\n \"-o\", color=palhf[2], label=\"RayFlare - grating + pyramids (3)\", fillstyle=\"none\")\n\nplt.plot(wavelengths * 1e9, RAT_fig6[\"T\"][0], \"--o\", color=palhf[0])\nplt.plot(wavelengths * 1e9, RAT_fig7[\"T\"][0], \"--o\", color=palhf[1])\nplt.plot(wavelengths * 1e9, RAT_fig8[\"T\"][0], \"--o\", color=palhf[2])\n\n# these are just to create the legend:\nplt.plot(-1, 0, \"k-o\", label=\"R\", fillstyle=\"none\")\nplt.plot(-1, 0, \"k--o\", label=\"T\")\n\nplt.legend()\nplt.xlabel(\"Wavelength (nm)\")\nplt.ylabel(\"Reflected/transmitted fraction\")\nplt.xlim([900, 1200])\nplt.ylim([0, 0.6])\nplt.show()" + "text": "Plotting\nPlot everything together, including data from the reference paper for comparison:\n\npalhf = sns.color_palette(\"hls\", 4)\n\nfig = plt.figure()\nplt.plot(sim_fig6[:, 0], sim_fig6[:, 1],\n \"--\", color=palhf[0], label=\"OPTOS - rear grating (1)\")\nplt.plot(wavelengths * 1e9, RAT_fig6[\"A_bulk\"][0],\n \"-o\", color=palhf[0], label=\"RayFlare - rear grating (1)\", fillstyle=\"none\")\nplt.plot(sim_fig7[:, 0], sim_fig7[:, 1],\n \"--\", color=palhf[1], label=\"OPTOS - front pyramids (2)\",)\nplt.plot(wavelengths * 1e9, RAT_fig7[\"A_bulk\"][0],\n \"-o\", color=palhf[1], label=\"RayFlare - front pyramids (2)\", fillstyle=\"none\")\nplt.plot(sim_fig8[:, 0], sim_fig8[:, 1],\n \"--\", color=palhf[2], label=\"OPTOS - grating + pyramids (3)\")\nplt.plot(wavelengths * 1e9, RAT_fig8[\"A_bulk\"][0],\n \"-o\", color=palhf[2],label=\"RayFlare - grating + pyramids (3)\", fillstyle=\"none\",)\nplt.plot(wavelengths * 1e9, RAT[\"A_per_layer\"][:, 0], \"-k\", label=\"Planar\")\nplt.legend(loc=\"lower left\")\nplt.xlabel(\"Wavelength (nm)\")\nplt.ylabel(\"Absorption in Si\")\nplt.xlim([900, 1200])\nplt.ylim([0, 1])\nplt.show()\n\n\n\n\nWe can see good agreement between the reference values and our calculated values. The structure with rear grating also behaves identically to the planar TMM reference case at the short wavelengths where front surface reflection dominates the result, as expected. Clearly, the pyramids perform much better overall, giving a large boost in the absorption at long wavelengths and also reducing the reflection significantly at shorter wavelengths. Plotting reflection and transmission emphasises this:\n\nfig = plt.figure()\nplt.plot(wavelengths * 1e9,RAT_fig6[\"R\"][0],\n \"-o\", color=palhf[0], label=\"RayFlare - rear grating (1)\", fillstyle=\"none\")\nplt.plot(wavelengths * 1e9, RAT_fig7[\"R\"][0],\n \"-o\", color=palhf[1], label=\"RayFlare - front pyramids (2)\", fillstyle=\"none\")\nplt.plot(wavelengths * 1e9, RAT_fig8[\"R\"][0],\n \"-o\", color=palhf[2], label=\"RayFlare - grating + pyramids (3)\", fillstyle=\"none\")\n\nplt.plot(wavelengths * 1e9, RAT_fig6[\"T\"][0], \"--o\", color=palhf[0])\nplt.plot(wavelengths * 1e9, RAT_fig7[\"T\"][0], \"--o\", color=palhf[1])\nplt.plot(wavelengths * 1e9, RAT_fig8[\"T\"][0], \"--o\", color=palhf[2])\n\n# these are just to create the legend:\nplt.plot(-1, 0, \"k-o\", label=\"R\", fillstyle=\"none\")\nplt.plot(-1, 0, \"k--o\", label=\"T\")\n\nplt.legend()\nplt.xlabel(\"Wavelength (nm)\")\nplt.ylabel(\"Reflected/transmitted fraction\")\nplt.xlim([900, 1200])\nplt.ylim([0, 0.6])\nplt.show()" }, { "objectID": "solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html#redistribution-matrices", diff --git a/docs/solcore-workshop-2/macos_installation.txt b/docs/solcore-workshop-2/macos_installation.txt index 09a5ed5..de35c71 100644 --- a/docs/solcore-workshop-2/macos_installation.txt +++ b/docs/solcore-workshop-2/macos_installation.txt @@ -32,8 +32,10 @@ from rayflare.transfer_matrix_method import tmm_structure print("Success!") - If this prints the "Success!" to your terminal, things are installed. Do - not worry about any warnings which appear. + If this prints the "Success!" to your terminal, things are installed. Note: you + will get a warning message which says "WARNING: The RCWA solver will not be + available because an S4 installation has not been found." - this is fine, do + not worry about it. 7. We will also be using Jupyter notebooks during the workshop (these are files which let you combine Python code blocks, normal text, images etc.). First, diff --git a/docs/solcore-workshop-2/notebooks/6b-arc_optimization.html b/docs/solcore-workshop-2/notebooks/6b-arc_optimization.html index c9bc746..36f0f61 100644 --- a/docs/solcore-workshop-2/notebooks/6b-arc_optimization.html +++ b/docs/solcore-workshop-2/notebooks/6b-arc_optimization.html @@ -177,7 +177,7 @@

Section 6b: Optimizing an ARC

In the previous example, we introduced a simple one-layer anti-reflection coating (ARC); ARCs are a standard feature of all high-efficiency solar cells. But how do you find out the right thickness for the anti-reflection coating layer(s) (or the right dimensions for a light-trapping grating, or some other structure in your cell)? This is where optimization comes in. Here, we will look at a very simple ‘brute-force’ optimization for a single or double-layer ARC.

-
+
import numpy as np
 import os
 import matplotlib.pyplot as plt
@@ -193,106 +193,111 @@ 

Section 6b: Optimizing an ARC

from rayflare.transfer_matrix_method import tmm_structure from rayflare.options import default_options import seaborn as sns
+
+
WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The Poisson - Drift-Diffusion solver will not be available because the ddModel fortran library could not be imported.
+name 'dd' is not defined
+
+
+
/Users/z3533914/.pyenv/versions/3.11.5/lib/python3.11/site-packages/solcore/registries.py:73: UserWarning: Optics solver 'RCWA' will not be available. An installation of S4 has not been found.
+  warn(
+

Setting up

We set some options, as in previous examples, setting the wavelengths and defining the incident spectrum. We are going to do a partially coherent calculation, treating the ARC as a coherent layer and the thick Si layer as incoherent (no thin-film interference).

-
-
opts = State()
-
-wavelengths = np.linspace(300, 1200, 800)*1e-9
-
-AM15g = LightSource(source_type="standard", version="AM1.5g", output_units="photon_flux_per_m")
-spectrum = AM15g.spectrum(wavelengths)[1]
-normalised_spectrum = spectrum/np.max(spectrum)
-
-opts.wavelength = wavelengths
-opts.coherency_list = ['c', 'i']
-opts.optics_method = 'TMM'
-opts.position = 100e-6
-opts.no_back_reflection = False
-
-Si = material("Si")()
-SiN = material("Si3N4")()
-Ag = material("Ag")()
-Air = material("Air")()
+
+
opts = State()
+
+wavelengths = np.linspace(300, 1200, 800)*1e-9
+
+AM15g = LightSource(source_type="standard", version="AM1.5g", output_units="photon_flux_per_m")
+spectrum = AM15g.spectrum(wavelengths)[1]
+normalised_spectrum = spectrum/np.max(spectrum)
+
+opts.wavelength = wavelengths
+opts.coherency_list = ['c', 'i']
+opts.optics_method = 'TMM'
+opts.position = 100e-6
+opts.no_back_reflection = False
+
+Si = material("Si")()
+SiN = material("Si3N4")()
+Ag = material("Ag")()
+Air = material("Air")()

Single-layer ARC

Here, we will calculate the behaviour of a single-layer SiN anti-reflection coating on Si while changing the ARC thickness between 0 and 200 nm. We will consider two values to optimize: the mean reflectance mean_R, and the reflectance weighted by the photon flux in an AM1.5G spectrum (weighted_R). The reason for considering the second value is that it is more useful to suppress reflection at wavelengths where there are more photons which could be absorbed by the cell (up to the cell’s bandgap).

We will loop through the different ARC thicknesses in d_range, build the structure for each case, and then calculate the reflectance. We then save the mean reflected and weighted mean reflectance in the corresponding arrays. We also plot the reflectance for each 15th loop (this is just so the plot does not get too crowded).

-
-
d_range = np.linspace(0, 200, 200)
-
-mean_R = np.empty_like(d_range)
-weighted_R = np.empty_like(d_range)
-
-cols = sns.cubehelix_palette(np.ceil(len(d_range)/15))
-
-plt.figure()
-jcol = 0
-
-for i1, d in enumerate(d_range):
-
-    struct = SolarCell([Layer(si(d, 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)
-    solar_cell_solver(struct, task='optics', user_options=opts)
-
-    if i1 % 15 == 0:
-        plt.plot(wavelengths*1e9, struct.reflected, label=str(np.round(d, 0)), color=cols[jcol])
-        jcol += 1
-
-    mean_R[i1] = np.mean(struct.reflected)
-    weighted_R[i1] = np.mean(struct.reflected*normalised_spectrum)
-
-plt.legend()
-plt.show()
+
+
d_range = np.linspace(0, 200, 200)
+
+mean_R = np.empty_like(d_range)
+weighted_R = np.empty_like(d_range)
+
+cols = sns.cubehelix_palette(np.ceil(len(d_range)/15))
+
+plt.figure()
+jcol = 0
+
+for i1, d in enumerate(d_range):
+
+    struct = SolarCell([Layer(si(d, 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)
+    solar_cell_solver(struct, task='optics', user_options=opts)
+
+    if i1 % 15 == 0:
+        plt.plot(wavelengths*1e9, struct.reflected, label=str(np.round(d, 0)), color=cols[jcol])
+        jcol += 1
+
+    mean_R[i1] = np.mean(struct.reflected)
+    weighted_R[i1] = np.mean(struct.reflected*normalised_spectrum)
+
+plt.legend()
+plt.show()

We now find at which index mean_R and weighted_R are minimised using np.argmin, and use this to print the ARC thickness at which this occurs (rounded to 1 decimal place).

-
-
print('Minimum mean reflection occurs at d = ' + str(np.round(d_range[np.argmin(mean_R)], 1)) + ' nm')
-print('Minimum weighted reflection occurs at d = ' + str(np.round(d_range[np.argmin(weighted_R)], 1)) + ' nm')
+
+
print('Minimum mean reflection occurs at d = ' + str(np.round(d_range[np.argmin(mean_R)], 1)) + ' nm')
+print('Minimum weighted reflection occurs at d = ' + str(np.round(d_range[np.argmin(weighted_R)], 1)) + ' nm')
Minimum mean reflection occurs at d = 67.3 nm
 Minimum weighted reflection occurs at d = 74.4 nm

We see that the values of \(d\) for the two different ways of optimizing are very similar, but not exactly the same, as we would expect. The minimum in both cases occurs around 70 nm. We can also plot the variation of the mean and weighted \(R\) with ARC thickness \(d\):

-
-
plt.figure()
-plt.plot(d_range, mean_R, label='Mean reflection')
-plt.plot(d_range[np.argmin(mean_R)], np.min(mean_R), 'ok')
-plt.plot(d_range, weighted_R, label='Weighted mean reflection')
-plt.plot(d_range[np.argmin(weighted_R)], np.min(weighted_R), 'ok')
-plt.xlabel('d$_{SiN}$')
-plt.ylabel('(Weighted) mean reflection 300-1200 nm')
-plt.legend()
-plt.show()
+
+
plt.figure()
+plt.plot(d_range, mean_R, label='Mean reflection')
+plt.plot(d_range[np.argmin(mean_R)], np.min(mean_R), 'ok')
+plt.plot(d_range, weighted_R, label='Weighted mean reflection')
+plt.plot(d_range[np.argmin(weighted_R)], np.min(weighted_R), 'ok')
+plt.xlabel('d$_{SiN}$')
+plt.ylabel('(Weighted) mean reflection 300-1200 nm')
+plt.legend()
+plt.show()

Now, to see what the reflectance looks like for the optimized structure, we make new tmm_structures with the optimal values and calculate and plot the reflectance:

-
-
struct_1 = SolarCell([Layer(si(d_range[np.argmin(mean_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)
-solar_cell_solver(struct_1, task='optics', user_options=opts)
-R_1 = struct_1.reflected
-
-struct_2 = SolarCell([Layer(si(d_range[np.argmin(weighted_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)
-solar_cell_solver(struct_2, task='optics', user_options=opts)
-R_2 = struct_2.reflected
-
-plt.figure()
-plt.plot(wavelengths*1e9, R_1, label='Mean R minimum')
-plt.plot(wavelengths*1e9, R_2, label='Weighted R minimum')
-plt.legend()
-plt.xlabel("Wavelength (nm)")
-plt.ylabel("R")
-plt.show()
-
-
INFO: Solving optics of the solar cell...
-INFO: Solving optics of the solar cell...
-
+
+
struct_1 = SolarCell([Layer(si(d_range[np.argmin(mean_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)
+solar_cell_solver(struct_1, task='optics', user_options=opts)
+R_1 = struct_1.reflected
+
+struct_2 = SolarCell([Layer(si(d_range[np.argmin(weighted_R)], 'nm'), SiN), Layer(si('120um'), Si)], substrate=Ag)
+solar_cell_solver(struct_2, task='optics', user_options=opts)
+R_2 = struct_2.reflected
+
+plt.figure()
+plt.plot(wavelengths*1e9, R_1, label='Mean R minimum')
+plt.plot(wavelengths*1e9, R_2, label='Weighted R minimum')
+plt.legend()
+plt.xlabel("Wavelength (nm)")
+plt.ylabel("R")
+plt.show()
Treating layer(s) 1 incoherently
 Calculating RAT...
@@ -302,7 +307,7 @@ 

Single-layer ARC

Calculating absorption profile...
-

+

We see that the two reflectance curves are very similar, as expected because the layer thicknesses are very similar.

@@ -311,25 +316,16 @@

Single-layer ARC

Double-layer ARC

We will now consider a similar situation, but for a double-layer MgF\(_2\)/Ta\(_2\)O\(_5\) ARC on GaAs.

Solcore can directly interface with the database from www.refractiveindex.info, which contains around 3000 sets of data for a large number of different materials. Before the first use, it is necessary to download the database. This only needs to be done once, so you can comment this line out after it’s done:

-
-
download_db(confirm=True) # only needs to be done once
+
+
download_db(confirm=True) # only needs to be done once
Database file found at /Users/z3533914/.solcore/nk/nk.db
 Making request to https://refractiveindex.info/download/database/rii-database-2021-07-18.zip
-Downloaded and extracting...
-Wrote /var/folders/wh/w5k56r_927j4yp3mh91bggfc0000gq/T/tmpfnrk4_hu/database from https://refractiveindex.info/download/database/rii-database-2021-07-18.zip
-LOG: 2746,other,PtAl2,Chen : Bad Material YAML File.
-***Wrote SQLite DB on  /Users/z3533914/.solcore/nk/nk.db
-
-
-
/Users/z3533914/.pyenv/versions/3.11.5/lib/python3.11/site-packages/solcore/material_data/refractiveindex_info_DB/dbmaterial.py:278: RuntimeWarning: invalid value encountered in sqrt
-  n = numpy.sqrt(nsq)
-/Users/z3533914/.pyenv/versions/3.11.5/lib/python3.11/site-packages/solcore/material_data/refractiveindex_info_DB/dbmaterial.py:299: RuntimeWarning: invalid value encountered in sqrt
-  n = numpy.sqrt(n)
+Downloaded and extracting...

We search for materials in the refractiveindex.info database, and use only the part of the solar spectrum relevant for absorption in GaAs (in this case, there is no benefit to reducing absorption above the GaAs bandgap around 900 nm). We will only consider the weighted mean \(R\) in this case. Since all the layers in the structure are relatively thin compared to the wavelengths of light, we do a coherent calculation.

-
+
pageid_MgF2 = search_db(os.path.join("MgF2", "Rodriguez-de Marcos"))[0][0]
 pageid_Ta2O5 = search_db(os.path.join("Ta2O5", "Rodriguez-de Marcos"))[0][0]
 
@@ -350,7 +346,7 @@ 

Double-layer ARC

opts.position = 20e-6

We now have two thicknesses to loop through; otherwise, the procedure is similar to the single-layer ARC example.

-
+
for i1, d_MgF2 in enumerate(MgF2_thickness):
     for j1, d_Ta2O5 in enumerate(Ta2O5_thickness):
         struct = SolarCell([Layer(si(d_MgF2, 'nm'), MgF2), Layer(si(d_Ta2O5, 'nm'), Ta2O5),
@@ -365,7 +361,7 @@ 

Double-layer ARC

ri, ci = np.unravel_index(weighted_R_matrix.argmin(), weighted_R_matrix.shape)

We plot the total absorption (\(1-R\)) in the structure with the optimized ARC, and print the thicknesses of MgF\(_2\) and Ta\(_2\)O\(_5\) at which this occurs:

-
+
plt.figure()
 plt.imshow(1-weighted_R_matrix, extent=[min(Ta2O5_thickness), max(Ta2O5_thickness),
                                         min(MgF2_thickness), max(MgF2_thickness)],
@@ -378,12 +374,6 @@ 

Double-layer ARC

print("Minimum reflection occurs at MgF2 / Ta2O5 thicknesses of %.1f / %.1f nm " % (MgF2_thickness[ri], Ta2O5_thickness[ci]))
-
-

-
-
-
Minimum reflection occurs at MgF2 / Ta2O5 thicknesses of 73.7 / 53.7 nm 
-

For these two examples, where we are only trying to optimize one and two parameters respectively across a relatively small range, using a method (TMM) which executes quickly, brute force searching is possible. However, as we introduce more parameters, a wider parameter space, and slower simulation methods, it may no longer be computationally tractable; in that case, using for example differential evolution or other types of numerical optimization may be more appropriate (see this example).

diff --git a/docs/solcore-workshop-2/notebooks/6b-arc_optimization_files/figure-html/cell-11-output-1.png b/docs/solcore-workshop-2/notebooks/6b-arc_optimization_files/figure-html/cell-11-output-1.png deleted file mode 100644 index 9ed94a434b55fb68f37aead476132663f65952a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20589 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 UtsB6j|1g*3R4x|ET)+4K0VFjsL;wH) diff --git a/docs/solcore-workshop-2/notebooks/6b-arc_optimization_files/figure-html/cell-7-output-3.png b/docs/solcore-workshop-2/notebooks/6b-arc_optimization_files/figure-html/cell-7-output-3.png deleted file mode 100644 index 7961439bdab03396b25bc2e1082b6d7c3708fc6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29916 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 diff --git a/docs/solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html b/docs/solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html index b553175..78843f2 100644 --- a/docs/solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html +++ b/docs/solcore-workshop-2/notebooks/8-grating_pyramids_OPTOS.html @@ -186,7 +186,7 @@

Section 8: Textured Si

Setting up

First, importing relevant packages:

-
+
import numpy as np
 import os
 
@@ -209,7 +209,7 @@ 

Setting up

from sparse import load_npz

Setting options (taking the default options for everything not specified explicitly):

-
+
angle_degrees_in = 8 # same as in Fraunhofer paper
 
 wavelengths = np.linspace(900, 1200, 20) * 1e-9
@@ -222,18 +222,18 @@ 

Setting up

options.theta_in = angle_degrees_in * np.pi / 180 # incidence angle (polar angle) options.n_theta_bins = 30 options.c_azimuth = 0.25 -options.n_rays = 1e5 # number of rays per wavelength in ray-tracing +options.n_rays = 5e4 # number of rays per wavelength in ray-tracing options.project_name = "OPTOS_comparison" options.orders = 60 # number of RCWA orders to use (more = better convergence, but slower) options.pol = "u" # unpolarized light -options.only_incidence_angle = False +options.only_incidence_angle = True options.RCWA_method = "Inkstone"

Defining the structures

Now, set up the grating basis vectors for the RCWA calculations and define the grating structure. These are squares, rotated by 45 degrees. The halfwidth is calculated based on the area fill factor of the etched pillars given in the paper.

-
+
x = 1000
 
 d_vectors = ((x, 0), (0, x))
@@ -247,7 +247,7 @@ 

Defining the struc )]

Now we define the pyramid texture for the front surface in case (2) and (3) and make the four possible different surfaces: planar front and rear, front with pyramids, rear with grating. We specify the method to use to calculate the redistribution matrices in each case and create the bulk layer.

-
+
surf = regular_pyramids(elevation_angle=55, upright=False)
 
 front_surf_pyramids = Interface(
@@ -272,7 +272,7 @@ 

Defining the struc bulk_Si = BulkLayer(200e-6, Si, name="Si_bulk")

Now we create the different structures and ‘process’ them (this will calculate the relevant matrices if necessary, or do nothing if it finds the matrices have previously been calculated and the files already exist). We don’t need to process the final structure because it will use matrices calculated for SC_fig6 and SC_fig7.

-
+
SC_fig6 = Structure(
     [front_surf_planar, bulk_Si, back_surf_grating], incidence=Air, transmission=Air
 )
@@ -283,118 +283,216 @@ 

Defining the struc [front_surf_pyramids, bulk_Si, back_surf_grating], incidence=Air, transmission=Air ) -process_structure(SC_fig6, options, save_location='current') +process_structure(SC_fig6, options, save_location='current') # if you want to overwrite previous results, add overwrite=Trues process_structure(SC_fig7, options, save_location='current')

+
+
INFO: Making matrix for planar surface using TMM for element 0 in structure
+INFO: RCWA calculation for element 2 in structure
+INFO: RCWA calculation for wavelength = 947.3684210526316 nm
+INFO: RCWA calculation for wavelength = 915.7894736842105 nm
+INFO: RCWA calculation for wavelength = 978.9473684210526 nm
+INFO: RCWA calculation for wavelength = 1010.5263157894736 nm
+INFO: RCWA calculation for wavelength = 994.7368421052631 nm
+INFO: RCWA calculation for wavelength = 931.578947368421 nm
+INFO: RCWA calculation for wavelength = 1026.3157894736842 nm
+INFO: RCWA calculation for wavelength = 900.0000000000001 nm
+INFO: RCWA calculation for wavelength = 1042.1052631578948 nm
+INFO: RCWA calculation for wavelength = 963.1578947368421 nm
+INFO: RCWA calculation for wavelength = 1057.8947368421054 nm
+INFO: RCWA calculation for wavelength = 1073.6842105263158 nm
+INFO: RCWA calculation for wavelength = 1089.4736842105265 nm
+INFO: RCWA calculation for wavelength = 1105.2631578947369 nm
+INFO: RCWA calculation for wavelength = 1121.0526315789475 nm
+INFO: RCWA calculation for wavelength = 1136.842105263158 nm
+INFO: RCWA calculation for wavelength = 1152.6315789473683 nm
+INFO: RCWA calculation for wavelength = 1168.421052631579 nm
+INFO: RCWA calculation for wavelength = 1184.2105263157896 nm
+INFO: RCWA calculation for wavelength = 1200.0000000000002 nm
+INFO: Ray tracing with Fresnel equations for element 0 in structure
+INFO: Calculating matrix only for incidence theta/phi
+INFO: RT calculation for wavelength = 931.578947368421 nm
+INFO: RT calculation for wavelength = 900.0000000000001 nm
+INFO: RT calculation for wavelength = 915.7894736842105 nm
+INFO: RT calculation for wavelength = 947.3684210526316 nm
+INFO: RT calculation for wavelength = 963.1578947368421 nm
+INFO: RT calculation for wavelength = 978.9473684210526 nm
+INFO: RT calculation for wavelength = 994.7368421052631 nm
+INFO: RT calculation for wavelength = 1010.5263157894736 nm
+INFO: RT calculation for wavelength = 1042.1052631578948 nm
+INFO: RT calculation for wavelength = 1026.3157894736842 nm
+INFO: RT calculation for wavelength = 1057.8947368421054 nm
+INFO: RT calculation for wavelength = 1073.6842105263158 nm
+INFO: RT calculation for wavelength = 1089.4736842105265 nm
+INFO: RT calculation for wavelength = 1105.2631578947369 nm
+INFO: RT calculation for wavelength = 1136.842105263158 nm
+INFO: RT calculation for wavelength = 1152.6315789473683 nm
+INFO: RT calculation for wavelength = 1121.0526315789475 nm
+INFO: RT calculation for wavelength = 1168.421052631579 nm
+INFO: RT calculation for wavelength = 1184.2105263157896 nm
+INFO: RT calculation for wavelength = 1200.0000000000002 nm
+INFO: RT calculation for wavelength = 900.0000000000001 nm
+INFO: RT calculation for wavelength = 915.7894736842105 nm
+INFO: RT calculation for wavelength = 931.578947368421 nm
+INFO: RT calculation for wavelength = 947.3684210526316 nm
+INFO: RT calculation for wavelength = 963.1578947368421 nm
+INFO: RT calculation for wavelength = 978.9473684210526 nm
+INFO: RT calculation for wavelength = 994.7368421052631 nm
+INFO: RT calculation for wavelength = 1010.5263157894736 nm
+INFO: RT calculation for wavelength = 1026.3157894736842 nm
+INFO: RT calculation for wavelength = 1042.1052631578948 nm
+INFO: RT calculation for wavelength = 1057.8947368421054 nm
+INFO: RT calculation for wavelength = 1073.6842105263158 nm
+INFO: RT calculation for wavelength = 1089.4736842105265 nm
+INFO: RT calculation for wavelength = 1105.2631578947369 nm
+INFO: RT calculation for wavelength = 1121.0526315789475 nm
+INFO: RT calculation for wavelength = 1136.842105263158 nm
+INFO: RT calculation for wavelength = 1152.6315789473683 nm
+INFO: RT calculation for wavelength = 1168.421052631579 nm
+INFO: RT calculation for wavelength = 1184.2105263157896 nm
+INFO: RT calculation for wavelength = 1200.0000000000002 nm
+INFO: Making matrix for planar surface using TMM for element 2 in structure
+
+
+
WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+WARNING: The RCWA solver will not be available because an S4 installation has not been found.
+

Calculating R/A/T

Then we ask RayFlare to calculate the reflection, transmission and absorption through matrix multiplication, and get the required result out (absorption in the bulk) for each cell. We also load the results from the reference paper to compare them to the ones calculated with RayFlare.

-
-
results_fig6 = calculate_RAT(SC_fig6, options, save_location='current')
-results_fig7 = calculate_RAT(SC_fig7, options, save_location='current')
-results_fig8 = calculate_RAT(SC_fig8, options, save_location='current')
-
-RAT_fig6 = results_fig6[0]
-RAT_fig7 = results_fig7[0]
-RAT_fig8 = results_fig8[0]
-
-sim_fig6 = np.loadtxt("data/optos_fig6_sim.csv", delimiter=",")
-sim_fig7 = np.loadtxt("data/optos_fig7_sim.csv", delimiter=",")
-sim_fig8 = np.loadtxt("data/optos_fig8_sim.csv", delimiter=",")
+
+
results_fig6 = calculate_RAT(SC_fig6, options, save_location='current')
+results_fig7 = calculate_RAT(SC_fig7, options, save_location='current')
+results_fig8 = calculate_RAT(SC_fig8, options, save_location='current')
+
+RAT_fig6 = results_fig6[0]
+RAT_fig7 = results_fig7[0]
+RAT_fig8 = results_fig8[0]
+
+sim_fig6 = np.loadtxt("data/optos_fig6_sim.csv", delimiter=",")
+sim_fig7 = np.loadtxt("data/optos_fig7_sim.csv", delimiter=",")
+sim_fig8 = np.loadtxt("data/optos_fig8_sim.csv", delimiter=",")

Finally, we use TMM to calculate the absorption in a structure with a planar front and planar rear, as a reference.

-
-
struc = tmm_structure([Layer(si("200um"), Si)], incidence=Air, transmission=Air)
-options.coherent = False
-options.coherency_list = ["i"]
-RAT = tmm_structure.calculate(struc, options)
+
+
struc = tmm_structure([Layer(si("200um"), Si)], incidence=Air, transmission=Air)
+options.coherent = False
+options.coherency_list = ["i"]
+RAT = tmm_structure.calculate(struc, options)

Plotting

Plot everything together, including data from the reference paper for comparison:

-
-
palhf = sns.color_palette("hls", 4)
-
-fig = plt.figure()
-plt.plot(sim_fig6[:, 0], sim_fig6[:, 1],
-    "--", color=palhf[0], label="OPTOS - rear grating (1)")
-plt.plot(wavelengths * 1e9, RAT_fig6["A_bulk"][0],
-    "-o", color=palhf[0], label="RayFlare - rear grating (1)", fillstyle="none")
-plt.plot(sim_fig7[:, 0], sim_fig7[:, 1],
-    "--", color=palhf[1], label="OPTOS - front pyramids (2)",)
-plt.plot(wavelengths * 1e9, RAT_fig7["A_bulk"][0],
-    "-o", color=palhf[1], label="RayFlare - front pyramids (2)", fillstyle="none")
-plt.plot(sim_fig8[:, 0], sim_fig8[:, 1],
-    "--", color=palhf[2], label="OPTOS - grating + pyramids (3)")
-plt.plot(wavelengths * 1e9, RAT_fig8["A_bulk"][0],
-    "-o", color=palhf[2],label="RayFlare - grating + pyramids (3)", fillstyle="none",)
-plt.plot(wavelengths * 1e9, RAT["A_per_layer"][:, 0], "-k", label="Planar")
-plt.legend(loc="lower left")
-plt.xlabel("Wavelength (nm)")
-plt.ylabel("Absorption in Si")
-plt.xlim([900, 1200])
-plt.ylim([0, 1])
-plt.show()
+
+
palhf = sns.color_palette("hls", 4)
+
+fig = plt.figure()
+plt.plot(sim_fig6[:, 0], sim_fig6[:, 1],
+    "--", color=palhf[0], label="OPTOS - rear grating (1)")
+plt.plot(wavelengths * 1e9, RAT_fig6["A_bulk"][0],
+    "-o", color=palhf[0], label="RayFlare - rear grating (1)", fillstyle="none")
+plt.plot(sim_fig7[:, 0], sim_fig7[:, 1],
+    "--", color=palhf[1], label="OPTOS - front pyramids (2)",)
+plt.plot(wavelengths * 1e9, RAT_fig7["A_bulk"][0],
+    "-o", color=palhf[1], label="RayFlare - front pyramids (2)", fillstyle="none")
+plt.plot(sim_fig8[:, 0], sim_fig8[:, 1],
+    "--", color=palhf[2], label="OPTOS - grating + pyramids (3)")
+plt.plot(wavelengths * 1e9, RAT_fig8["A_bulk"][0],
+    "-o", color=palhf[2],label="RayFlare - grating + pyramids (3)", fillstyle="none",)
+plt.plot(wavelengths * 1e9, RAT["A_per_layer"][:, 0], "-k", label="Planar")
+plt.legend(loc="lower left")
+plt.xlabel("Wavelength (nm)")
+plt.ylabel("Absorption in Si")
+plt.xlim([900, 1200])
+plt.ylim([0, 1])
+plt.show()
+
+

+

We can see good agreement between the reference values and our calculated values. The structure with rear grating also behaves identically to the planar TMM reference case at the short wavelengths where front surface reflection dominates the result, as expected. Clearly, the pyramids perform much better overall, giving a large boost in the absorption at long wavelengths and also reducing the reflection significantly at shorter wavelengths. Plotting reflection and transmission emphasises this:

-
-
fig = plt.figure()
-plt.plot(wavelengths * 1e9,RAT_fig6["R"][0],
-    "-o", color=palhf[0], label="RayFlare - rear grating (1)", fillstyle="none")
-plt.plot(wavelengths * 1e9, RAT_fig7["R"][0],
-    "-o", color=palhf[1], label="RayFlare - front pyramids (2)", fillstyle="none")
-plt.plot(wavelengths * 1e9, RAT_fig8["R"][0],
-    "-o", color=palhf[2], label="RayFlare - grating + pyramids (3)", fillstyle="none")
-
-plt.plot(wavelengths * 1e9, RAT_fig6["T"][0], "--o", color=palhf[0])
-plt.plot(wavelengths * 1e9, RAT_fig7["T"][0], "--o", color=palhf[1])
-plt.plot(wavelengths * 1e9, RAT_fig8["T"][0], "--o", color=palhf[2])
-
-# these are just to create the legend:
-plt.plot(-1, 0, "k-o", label="R", fillstyle="none")
-plt.plot(-1, 0, "k--o", label="T")
-
-plt.legend()
-plt.xlabel("Wavelength (nm)")
-plt.ylabel("Reflected/transmitted fraction")
-plt.xlim([900, 1200])
-plt.ylim([0, 0.6])
-plt.show()
+
+
fig = plt.figure()
+plt.plot(wavelengths * 1e9,RAT_fig6["R"][0],
+    "-o", color=palhf[0], label="RayFlare - rear grating (1)", fillstyle="none")
+plt.plot(wavelengths * 1e9, RAT_fig7["R"][0],
+    "-o", color=palhf[1], label="RayFlare - front pyramids (2)", fillstyle="none")
+plt.plot(wavelengths * 1e9, RAT_fig8["R"][0],
+    "-o", color=palhf[2], label="RayFlare - grating + pyramids (3)", fillstyle="none")
+
+plt.plot(wavelengths * 1e9, RAT_fig6["T"][0], "--o", color=palhf[0])
+plt.plot(wavelengths * 1e9, RAT_fig7["T"][0], "--o", color=palhf[1])
+plt.plot(wavelengths * 1e9, RAT_fig8["T"][0], "--o", color=palhf[2])
+
+# these are just to create the legend:
+plt.plot(-1, 0, "k-o", label="R", fillstyle="none")
+plt.plot(-1, 0, "k--o", label="T")
+
+plt.legend()
+plt.xlabel("Wavelength (nm)")
+plt.ylabel("Reflected/transmitted fraction")
+plt.xlim([900, 1200])
+plt.ylim([0, 0.6])
+plt.show()
+
+

+

Redistribution matrices

Plot the redistribution matrix for the rear grating (summed over azimuthal angles) at 1100 nm:

-
-
theta_intv, phi_intv, angle_vector = make_angle_vector(
-    options["n_theta_bins"], options["phi_symmetry"], options["c_azimuth"])
-
-path = get_savepath(save_location='current', project_name=options.project_name)
-sprs = load_npz(os.path.join(path, SC_fig6[2].name + "frontRT.npz"))
-
-wl_to_plot = 1100e-9
-wl_index = np.argmin(np.abs(wavelengths - wl_to_plot))
-
-full = sprs[wl_index].todense()
-
-summat = theta_summary(full, angle_vector, options["n_theta_bins"], "front")
-summat_r = summat[: options["n_theta_bins"], :]
-summat_r = summat_r.rename({ r"$\theta_{in}$": r"$\sin(\theta_{in})$",
-        r"$\theta_{out}$": r"$\sin(\theta_{out})$"})
-
-summat_r = summat_r.assign_coords({r"$\sin(\theta_{in})$": np.sin(summat_r.coords[r"$\sin(\theta_{in})$"]).data,
-    r"$\sin(\theta_{out})$": np.sin(summat_r.coords[r"$\sin(\theta_{out})$"]).data})
-
-palhf = sns.cubehelix_palette(256, start=0.5, rot=-0.9)
-palhf.reverse()
-seamap = mpl.colors.ListedColormap(palhf)
-
-fig = plt.figure()
-ax = plt.subplot(111)
-ax = summat_r.plot.imshow(ax=ax, cmap=seamap, vmax=0.3)
-plt.show()
+
+
theta_intv, phi_intv, angle_vector = make_angle_vector(
+    options["n_theta_bins"], options["phi_symmetry"], options["c_azimuth"])
+
+path = get_savepath(save_location='current', project_name=options.project_name)
+sprs = load_npz(os.path.join(path, SC_fig6[2].name + "frontRT.npz"))
+
+wl_to_plot = 1100e-9
+wl_index = np.argmin(np.abs(wavelengths - wl_to_plot))
+
+full = sprs[wl_index].todense()
+
+summat = theta_summary(full, angle_vector, options["n_theta_bins"], "front")
+summat_r = summat[: options["n_theta_bins"], :]
+summat_r = summat_r.rename({ r"$\theta_{in}$": r"$\sin(\theta_{in})$",
+        r"$\theta_{out}$": r"$\sin(\theta_{out})$"})
+
+summat_r = summat_r.assign_coords({r"$\sin(\theta_{in})$": np.sin(summat_r.coords[r"$\sin(\theta_{in})$"]).data,
+    r"$\sin(\theta_{out})$": np.sin(summat_r.coords[r"$\sin(\theta_{out})$"]).data})
+
+palhf = sns.cubehelix_palette(256, start=0.5, rot=-0.9)
+palhf.reverse()
+seamap = mpl.colors.ListedColormap(palhf)
+
+fig = plt.figure()
+ax = plt.subplot(111)
+ax = summat_r.plot.imshow(ax=ax, cmap=seamap, vmax=0.3)
+plt.show()
+
+

+
diff --git a/docs/solcore-workshop-2/windows_installation.txt b/docs/solcore-workshop-2/windows_installation.txt index a82e9da..6dc7d4f 100644 --- a/docs/solcore-workshop-2/windows_installation.txt +++ b/docs/solcore-workshop-2/windows_installation.txt @@ -32,8 +32,10 @@ from rayflare.transfer_matrix_method import tmm_structure print("Success!") - If this prints the "Success!" to your terminal, things are installed. Do - not worry about any warnings which appear. + If this prints the "Success!" to your terminal, things are installed. Note: you + will get a warning message which says "WARNING: The RCWA solver will not be + available because an S4 installation has not been found." - this is fine, do + not worry about it. 8. We will also be using Jupyter notebooks during the workshop (these are files which let you combine Python code blocks, normal text, images etc.). First,