diff --git a/docs/requirements.txt b/docs/requirements.txt index 2ff3af24..4d3e30fa 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,2 @@ -recommonmark \ No newline at end of file +recommonmark + diff --git a/docs/source/Quasi3D/EL_Prediction.png b/docs/source/Quasi3D/EL_Prediction.png new file mode 100644 index 00000000..80fd25e0 Binary files /dev/null and b/docs/source/Quasi3D/EL_Prediction.png differ diff --git a/docs/source/Quasi3D/HGridPattern.png b/docs/source/Quasi3D/HGridPattern.png new file mode 100644 index 00000000..8b75ef46 Binary files /dev/null and b/docs/source/Quasi3D/HGridPattern.png differ diff --git a/docs/source/Quasi3D/Layer_Voltages.png b/docs/source/Quasi3D/Layer_Voltages.png new file mode 100644 index 00000000..895c1049 Binary files /dev/null and b/docs/source/Quasi3D/Layer_Voltages.png differ diff --git a/docs/source/Quasi3D/quasi3D.rst b/docs/source/Quasi3D/quasi3D.rst index 2c698653..d850f4bf 100755 --- a/docs/source/Quasi3D/quasi3D.rst +++ b/docs/source/Quasi3D/quasi3D.rst @@ -1,7 +1,8 @@ Quasi-3D solar cell solver ========================== -- Example: :doc:`Quasi-3D 3J solar cell <../Examples/example_quasi3D_cell>` +- Example: :doc:`CPV Grid Spice Example (IPython Notebook) <../Examples/cpv_grid_spice_example.ipynb>` +- Example: :doc:`CPV Grid Spice Example (Python) <../Examples/cpv_grid_spice_example.py>` The quasi-3D solar cell model included in Solcore uses a SPICE-based electrical network to model the flow of injected current through the solar cell. The plane of the cell is discretized into many elements, each of them representing a small portion of the cell. Depending on the location of the element - exposed to the sunlight or underneath a metal finger - the IV curve of the cell will be the light IV or the dark IV. Each element is linked to their neighbours with resistors, representing the lateral current flow and dependent on the sheet resistance of the cells. This method can be applied to any number of junctions. @@ -15,86 +16,354 @@ Specifically for the modelling and optimization of the front grid of solar cells In-plane discretization ----------------------- -There are two regions in the plane: the metal and the aperture. These two are provided to Solcore as -grey scale images that will work as masks. The resolution of the images, -in pixels, will define the in-plane discretization. By default, the -aspect ratio of the pixels in the image will be 1:1, but this can be set -to a different value in order to reduce the number of elements and -improve speed. For example, the in-plane discretization of Fig. -[fig:spice\_overview]a has an aspect ratio :math:`A_r=L_y/L_x = 4`, with -:math:`L_x` and :math:`L_y` the pixel size in each direction. - -The values -of the pixels in the metal mask are <55 where there is no metal (the -aperture area), >200 where there is metal and the external electrical -contacts (the boundaries with fixed, externally set voltage values) and -any other value in between to represent regions with metal but not fixed -voltage. The pixels of the illumination mask - which become the aperture -mask after removing the areas shadowed by the metal - can have any value -between 0 and 255. These values divided by 255 will indicate the -intensity of the sunlight at that pixel relative to the maximum -intensity. +There are two physical regions in the plane: the metal and the aperture. These two are provided to Solcore as a +grey scale image that defines a mapping between pixels and the layers: +* Metal: + + * **White** is a bus bar (value >=80% white) + + * **Gray** is a grid finger (20% white < value < 80% white) + +* Aperture: + + * **Black** is an absence of any metal (value <= 20% white) + + +`GridPattern` helper objects can be used to generate these images, for example, +:: + # The width of the bus bar in pixels + bus_px = 10 + + # the number and width of the grid fingers in pixels + fingers_px = [4, 4, 4, 4, 4, 4] + + # the edge offset (set to zero if you want metal to go all the way to the edge) + offset_px = 3 + + # the size of the image in pixels + nx, ny = 120, 120 + + # the physical size of the solar cell in metres + size = (0.01, 0.01) + + # Use a grid pattern object to make the metalisation image + grid = HGridPattern(bus_px, fingers_px, offset_px=offset_px, nx=nx, ny=ny) + plt.imshow(grid.as_array(), cmap="gray") + +The above code generates the image, + +.. image:: HGridPattern.png + :align: center + + +The resolution of the images, in pixels, will define the in-plane discretization. However, the physical size +of the solar cell needs to be specified to give each pixel dimensions. For +example, + +* the image above is 120px x 120px +* size tuple `size = (0.01, 0.01)` + +Therefore, each pixel 1cm / 120 or approximately 83 micrometers. + +Different aspect ratios can be used to reduce the number of elements and improve speed by specifying a different cell size. + +Currently only `HGridPattern` exists, but other grids can be generated by subclass the `GridPattern` object and implementing the required methods. + +What is the difference between the bus bar and the grid fingers? +---------------------------------------------------------------- + +The only difference between the bus bar and the grid fingers is how the former is used in the SPICE model. To run a simulation SPICE must attach a voltage source to the metalisation. The bus bar metal defines these locations. + +Because of this, the bus will always have the applied potential where as the grid fingers will be at a potential defined by the current flowing through them and the surrounding cells. + +Node Size +--------- The minimum total number of nodes where SPICE will need to calculate the -voltages will be -N\ :math:`\times`\ M\ :math:`\times`\ 2\ :math:`\times`\ Q, with N and M -the number of pixels in both in-plane directions and Q the number of -junctions, which require 2 nodes each. To this, the front and back metal -contacts could add a maximum of 2(N\ :math:`\times`\ M) nodes. Exploiting -symmetries of the problem as well as choosing an appropriate pixel +voltages will be :math:`N \times M \times 2 \times Q` + +* N and M are the number of pixels in both in-plane directions +* Q the number of junctions, which require 2 nodes each. + +To this, the front and back metal contacts could add a maximum of :math:`2(N \times M)` nodes. + +Exploiting symmetries of the problem as well as choosing an appropriate pixel aspect ratio will significantly reduce the number of nodes and therefore the time required for the computation of the problem. +Illumination Map +---------------- + +The spatial distribution of illumination over the solar cell surface can be included in the simulation using an illumination map array. + +This is an numpy array with the same dimensions as the grid pattern. For example, +:: + + # Homogeneous illumination + illumination_map = np.ones(nx * ny).reshape((nx, ny)) + +following on from the previous code example, this will construct an array of size 120x120. The illumination is homogeneous because all elements in the array have the same value. To change the spatial distribution simply provide different values in the range 0 to 1. Where zero implies no illumination. + Vertical discretization ----------------------- -First, the solar cell is solved in order to obtain the parameters for the 2-diode -model at the given illumination conditions. These parameters are then -used to replicate the 2-diode model in SPICE. The :math:`I_{SC}` is -scaled in each pixel by the intensity of the illumination given by the -illumination mask. Sheet resistances above and below each junction, -:math:`R_{sh}(top)` and :math:`R_{sh}(bot)`, account for the lateral -transport. Beneath the metal, there is no current source, as the region -is in the dark, and there are extra resistances accounting for the -contact between the metal and the semiconductor :math:`R_c` and the -transport along the metal finger :math:`R_s`. Given that the pixels can be -asymmetric, these resistances need to be defined in both in-plane -directions, :math:`x` and :math:`y`: - -.. math:: - - \begin{aligned} - R_{sh}^x &= \frac{1}{A_r} R_{sh} \\ - R_{sh}^y &= A_r R_{sh} \\ - R_s^x &= \frac{1}{hA_r} \rho_m \\ - R_s^y &= \frac{A_r}{h} \rho_m \\ - R_c &= R_{back} = \frac{1}{L_x^2 A_r} \rho_c\end{aligned} - -where :math:`h` is the height of the metal, :math:`\rho_m` their linear -resistivity and :math:`\rho_c` the contact resistivity between metal and -semiconductor. The sheet resistance of a stack of semiconductor layers -:math:`R_{sh}` is equal to the combination in parallel of the individual -sheet resistances. Using the single junction example of the figure, :math:`R_{sh}(top)` will be given by: - -.. math:: \frac{1}{R_{sh}(top)} = \frac{1}{R_{sh}(window)} + \frac{1}{R_{sh}(emitter)} - -Each of these can be estimated from the thickness of the layer -:math:`d`, the majority carrier mobility :math:`\mu` and the doping -:math:`N` as: - -.. math:: \frac{1}{R_{sh}} = qd\mu N - -If the solar cell has been defined using only the DA and PDD junction -models, this information is already available for all the layers of the -structure. For junctions using the DB and two diode models, -:math:`R_{sh}` will need to be provided for the top and bottom regions -of each junction. Intrinsic layers will be ignored as they do not -contribute to the lateral current transport. - -Quasi-3D solver functions -------------------------- - -.. automodule:: solcore.spice.quasi_3D_solver +The vertical discretization relies on assembling different SPICE unit cells to correctly represent the structure. Internally, each SPICE unit cell is a Python object, these are first assembled into a 3D grid objects and then processed to derive the netlist. These objects are contained in the module, + +- Unit Cell Module: :doc:`solcore/spice/model.py <../solcore/spice/model.py>` + +We closely follow the model of [#Ref1]_ M. Steiner et al., please review the paper for an understanding how the model functions. + +In this document we will discuss how to use the SolCore implementation. + +Define a function dictionary for each cell in the structure. For example, a single-junction solar cell can be defined as, +:: + + # Define junction parameters with a Python dictionary + junctions = [ + { + "jsc": 30000, + "emitter_sheet_resistance": 100.0, + "j01": 4e-16, + "j02": 2e-7, + "Eg": 1.41, + "n1": 1.0, + "n2": 2.0 + } + ] + +The parameters are: + +* `jsc`, the short-circuit current generated by the junction in A / m2. +* `emitter_sheet_resistance`, the sheet resistance of the emitter region in Ohm per square. +* `j01`, the saturation current density in the neutral region in A / m2. +* `j02`, the saturation current density in the bulk region in A / m2. +* `Eg`, the bandgap of the material in eV (this one is no SI units!). +* `n1`, the ideality factor of the `j01` diode, default is 1. +* `n2`, the ideality factor of the `j02` diode, default is 2. + +Note that shunt resistance is not currently included in this modelling because for concentrator solar cells it is so large as to be negligible, but it could be added. + +Generate Netlist +---------------- + +Use the `generate_netlist` function to process all the inputs discussed so far to a SPICE net list, +:: + + # Generate a SPICE netlist from a metal and illumiation images, the solar cell size and the junction information + netlist = generate_netlist( + grid, + illumination_map, + size, + junctions, + ) + +Netlist generation is highly efficient, no "wires" are needed to connect the unit cells together. Instead, the cells are connected by proper use of net labels. This seems to have improved the solved speed over previous implementations. + +Note +==== + +The base layer and rear contact layers are not modelled as distributed elements. This has been done to follow the implementation of Steiner and also speeds up computation time. + +Solve Netlist +------------- + +The netlist is solved by stepping the voltage to find the maximum power point, +:: + + v_start = -0.1 # the starting voltage of the sweep + v_stop = 1.5 # the end voltage of the sweep + v_step = 0.01 # the step size of the sweep + result = solve_netlist(netlist, temperature, v_start, v_stop, v_step) + +The module provides functions that process and plot the `result` object to return useful information. For example, the IV curve, +:: + + v, i = get_characterisic_curve(result) + plot_characteristic_curve(v, i) + +The maximum power point, +:: + + vmax, pmax, maxidx = get_maximum_power_point(result) + # vmax = the voltage at the maximum power point + # pmax = the maximum power + # maxidx = the index in the IV curve of the maximum power point + +Layer voltage can be plotted to show voltage maps, +:: + + voltages = get_node_voltages(result) + voltages.shape # (120, 120, 3, 161) + +Here, `voltages` is a 3 + 1 dimensional array. The first three dimensions correspond to the physical x, y, and z locations in the discretization, and the last dimension corresponds to the number of steps in the voltage sweep. + +The first z index is the metal layer, the second z index is the PV (emitter) layer, and the third is the base and buffer layers. + +The helper function plots both the metal and PV layer voltages, +:: + + plot_surface_voltages(voltages, bias_index=maxidx) + +.. image:: Layer_Voltages.png + :align: center + +A generalised Planck estimate of the electroluminescence intensity can be made using, +:: + + pv_layer_idx = 1 # index = 1 is the PV layer + pv_layer_voltages = voltages[:, :, pv_layer_idx, maxidx] + el = get_electroluminescence(pv_layer_voltages, is_metal=grid.is_metal) + plot_electroluminescence(el) + +Note, some additional information is needed to mask off the metal layers such that the image predicts what might be actually seen. + +.. image:: EL_Prediction.png + :align: center + +A Detailed Example +------------------ + +Let's create a Solcore solar cell model based on the solar cell structure above and get it to calculate the short-circuit current. +:: + + from solcore.structure import Junction + from solcore.solar_cell import SolarCell + from solcore.solar_cell_solver import solar_cell_solver + from solcore.light_source import LightSource + + def get_jsc(concentrationX): + junction_model = Junction( + kind='2D', + T=temperature, + reff=1, + jref=300, + Eg=1.4, + A=1, + R_sheet_top=100, + R_sheet_bot=1e-16, + R_shunt=1e16, + n=3.5 + ) + + solar_cell_model = SolarCell([junction_model], T=temperature) + wl = np.linspace(350, 2000, 301) * 1e-9 + light_source = LightSource( + source_type="standard", + version="AM1.5g", + x=wl, + output_units="photon_flux_per_m", + concentration=concentrationX + ) + + options = { + "light_iv": True, + "wavelength": wl, + "light_source": light_source, + "optics_method": "BL" + } + solar_cell_solver(solar_cell_model, 'iv', user_options=options) + + jsc = solar_cell_model(0).jsc + return jsc + + # Get the JSC for 100x concentration + jsc = get_jsc(100) + +Create a second function that wraps the SPICE model and returns the device's efficiency. Inside this function, it calls solcore to estimate the JSC using the above `get_jsc` function, +:: + + def get_efficiency(concentrationX, power_in=1000.0): + + bus_px = 10 + fingers_px = [4, 4, 4, 4, 4, 4] + offset_px = 3 + nx, ny = 120, 120 + grid = HGridPattern(bus_px, fingers_px, offset_px=offset_px, nx=nx, ny=ny) + + # Homogeneous illumination + illumination_map = np.ones(nx * ny).reshape((nx, ny)) + + # The size of the solar is 3mm x 3mm + size = (0.003, 0.003) # meters + + # Define a list of properies that describe each junction in the solar cell. + # NB: currently only one junction is working. + junctions = [ + { + "jsc": get_jsc(concentrationX), # solcore is calculating this for us! + "emitter_sheet_resistance": 100.0, + "j01": 4e-16, + "j02": 2e-7, + "Eg": 1.41, + "n1": 1.0, + "n2": 2.0 + } + ] + + temperature = 300.0 + + netlist = generate_netlist( + grid, + illumination_map, + size, + junctions, + temperature=temperature + ) + + result = solve_netlist(netlist, temperature, 0.0, 1.5, 0.01) + + vmax, pmax, maxidx = get_maximum_power_point(result) + + p_per_m2 = pmax / size[0] / size[1] + efficiency = p_per_m2 / (concentrationX * power_in) + return efficiency + +Finally, let's loop over a few concentration values to see if we can plot a concentration vs. efficiency plot. +:: + + effs = list() + x_values = [1, 10, 100, 200, 500, 1000] + for x in x_values: + effs.append(get_efficiency(x)) + + plt.semilogx(x_values, 100 * np.array(effs)) + plt.grid(linestyle="dotted") + plt.xlabel("Concentration") + plt.ylabel("Efficiency (%)") + plt.show() + + +References +---------- + +.. [#Ref1] M. Steiner et al., "Validated front contact grid simulation for GaAs solar cells under concentrated sunlight", Progress in Photovoltaics, Volume 19, Issue 1, January 2011, Pages 73-83. DOI: 10.1002/pip.989. + + +Netlist Generation and Solution Functions +----------------------------------------- + +.. automodule:: solcore.spice.netlist :members: :undoc-members: + +Result Processing and Plotting Functions +---------------------------------------- + +.. automodule:: solcore.spice.result + :members: + :undoc-members: + +Spice Unit Cell Model Objects +----------------------------- + +.. automodule:: solcore.spice.model + :members: + :undoc-members: + +Grid Generation Objects +----------------------- + +.. automodule:: solcore.spice.grid + :members: + :undoc-members: \ No newline at end of file diff --git a/examples/cpv_grid_spice_example.ipynb b/examples/cpv_grid_spice_example.ipynb new file mode 100644 index 00000000..41c4bc7f --- /dev/null +++ b/examples/cpv_grid_spice_example.ipynb @@ -0,0 +1,804 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Grid Simulation of a Concentrator Solar Cell\n", + "\n", + "This example walks through how to use the classes and functions in `solcore.spice` to simulate different grid structures of concentrator solar cells. We are going to preproduce some of the figures published by Steiner et al. [1]\n", + "\n", + "## References\n", + "[1] M. Steiner et al., Validated front contact grid simulation for GaAs solar cells under concentrated sunlight, Progress in Photovoltaics, Volume 19, Issue 1, January 2011, Pages 73-83. DOI: 10.1002/pip.989\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Grid Pattern\n", + "\n", + "The `solcore.spice.grid.HGridPattern` class can generate different grid metalisation patterns. Let's see what this class can do." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/crystals.py:8: SyntaxWarning: invalid escape sequence '\\G'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/absorption_calculator/sopra_db.py:80: SyntaxWarning: invalid escape sequence '\\ '\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/absorption_calculator/sopra_db.py:90: SyntaxWarning: invalid escape sequence '\\ '\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/absorption_calculator/sopra_db.py:196: SyntaxWarning: invalid escape sequence '\\d'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/absorption_calculator/sopra_db.py:284: SyntaxWarning: invalid escape sequence '\\d'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/absorption_calculator/adachi_alpha.py:61: SyntaxWarning: invalid escape sequence '\\D'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/absorption_calculator/adachi_alpha.py:63: SyntaxWarning: invalid escape sequence '\\D'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/light_source/smarts.py:64: SyntaxWarning: invalid escape sequence '\\/'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/material_system/material_system.py:433: SyntaxWarning: invalid escape sequence '\\m'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/sesame_drift_diffusion/solve_pdd.py:354: SyntaxWarning: invalid escape sequence '\\ '\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/units_system/units_system.py:45: SyntaxWarning: invalid escape sequence '\\.'\n", + "/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/units_system/units_system.py:46: SyntaxWarning: invalid escape sequence '\\+'\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "WARNING: The RCWA solver will not be available because an S4 installation has not been found.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/dan/Dropbox/Exciton Labs Ltd/Clients/UNSW/solcore5/.mesonpy/editable/install/Users/dan/.pyenv/versions/3.12.2/lib/python3.12/site-packages/solcore/registries.py:73: UserWarning: Optics solver 'RCWA' will not be available. An installation of S4 has not been found.\n", + " warn(\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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+1xcs8S6z7V1f52kfHACAHBuSOo7KQBAaiNSAACziBQAwCwiBQAwK2kj1djYqMGDBysrK0vl5eXatm1bokeKm/r6eo0aNUoDBgxQQUGBJk2apLa2tphzjh8/rurqauXn56t///6aPHmyQqFQgibuHQsXLpTH41FNTU10X6qu++DBg7rllluUn5+v7OxsDR8+XDt27Iged85p3rx5GjhwoLKzsxUIBLRv374ETvz99PT0qK6uTiUlJcrOztZFF12kRx55JOZ93FJhzZs3b9YNN9ygwsJCeTwerV27Nub4N1nj4cOHVVVVpZycHOXm5mratGk6evToWVxFgrkktGrVKpeRkeH+9Kc/uQ8++MDdeeedLjc314VCoUSPFheVlZVu+fLlbs+ePW737t3uuuuuc8XFxe7o0aPRc+666y5XVFTkmpqa3I4dO9yVV17pRo8encCp42vbtm1u8ODB7tJLL3UzZ86M7k/FdR8+fNhdeOGF7rbbbnMtLS3uk08+cW+99Zb7+OOPo+csXLjQeb1et3btWvfee++5n//8566kpMR98cUXCZz8u1uwYIHLz89369atc/v373erV692/fv3d3/4wx+i56TCmv/617+6Bx980L366qtOkluzZk3M8W+yxmuvvdZddtllbuvWre5vf/ub+9GPfuRuvvnms7ySxEnKSF1xxRWuuro6+nFPT48rLCx09fX1CZyq93R0dDhJbtOmTc455zo7O13fvn3d6tWro+d89NFHTpJrbm5O1Jhxc+TIETdkyBC3YcMG95Of/CQaqVRd9wMPPODGjh17xuORSMT5/X73u9/9Lrqvs7PTZWZmupdffvlsjBh3EyZMcHfccUfMvhtvvNFVVVU551JzzadG6pus8cMPP3SS3Pbt26PnvPnmm87j8biDBw+etdkTKem+3XfixAm1trYqEAhE96WlpSkQCKi5uTmBk/Werq4uSVJeXp4kqbW1VSdPnoz5GpSWlqq4uDglvgbV1dWaMGFCzPqk1F3366+/rrKyMt10000qKCjQiBEj9Nxzz0WP79+/X8FgMGbdXq9X5eXlSbvu0aNHq6mpSXv37pUkvffee9qyZYvGjx8vKTXXfKpvssbm5mbl5uaqrKwsek4gEFBaWppaWlrO+syJkHRvMPvZZ5+pp6dHPp8vZr/P59M//vGPBE3VeyKRiGpqajRmzBgNGzZMkhQMBpWRkaHc3NyYc30+n4LBYAKmjJ9Vq1Zp586d2r59+1eOpeq6P/nkEy1dulSzZ8/Wb37zG23fvl333XefMjIyNHXq1OjaTvd7PlnXPXfuXIXDYZWWlqpPnz7q6enRggULVFVVJUkpueZTfZM1BoNBFRQUxBxPT09XXl5eynwdvk7SRepcU11drT179mjLli2JHqXXtbe3a+bMmdqwYYOysrISPc5ZE4lEVFZWpscee0ySNGLECO3Zs0fLli3T1KlTEzxd73jllVe0YsUKrVy5Updccol2796tmpoaFRYWpuya8d0k3bf7LrjgAvXp0+crT3SFQiH5/f4ETdU7ZsyYoXXr1untt9/WoEGDovv9fr9OnDihzs7OmPOT/WvQ2tqqjo4OXX755UpPT1d6ero2bdqkxYsXKz09XT6fLyXXPXDgQF188cUx+4YOHaoDBw5IUnRtqfR7/v7779fcuXM1ZcoUDR8+XLfeeqtmzZql+vp6Sam55lN9kzX6/X51dHTEHP/yyy91+PDhlPk6fJ2ki1RGRoZGjhyppqam6L5IJKKmpiZVVFQkcLL4cc5pxowZWrNmjTZu3KiSkpKY4yNHjlTfvn1jvgZtbW06cOBAUn8Nxo0bp/fff1+7d++ObmVlZaqqqor+OhXXPWbMmK/8FYO9e/fqwgsvlCSVlJTI7/fHrDscDqulpSVp1/35559/5R+669OnjyKRiKTUXPOpvskaKyoq1NnZqdbW1ug5GzduVCQSUXl5+VmfOSES/eTGd7Fq1SqXmZnpXnjhBffhhx+66dOnu9zcXBcMBhM9Wlzcfffdzuv1unfeecd9+umn0e3zzz+PnnPXXXe54uJit3HjRrdjxw5XUVHhKioqEjh17/jvp/ucS811b9u2zaWnp7sFCxa4ffv2uRUrVrjzzjvP/fnPf46es3DhQpebm+tee+019/e//91NnDgx6R7H/m9Tp051P/jBD6KPoL/66qvuggsucHPmzImekwprPnLkiNu1a5fbtWuXk+SefPJJt2vXLvfPf/7TOffN1njttde6ESNGuJaWFrdlyxY3ZMgQHkFPBkuWLHHFxcUuIyPDXXHFFW7r1q2JHiluJJ12W758efScL774wt1zzz3u/PPPd+edd577xS9+4T799NPEDd1LTo1Uqq77jTfecMOGDXOZmZmutLTUPfvsszHHI5GIq6urcz6fz2VmZrpx48a5tra2BE37/YXDYTdz5kxXXFzssrKy3A9/+EP34IMPuu7u7ug5qbDmt99++7T/L0+dOtU5983W+O9//9vdfPPNrn///i4nJ8fdfvvt7siRIwlYTWLwT3UAAMxKup9JAQDOHUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGb9P8P6YsHHKED2AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from solcore.spice.grid import HGridPattern\n", + "import matplotlib.pyplot as plt\n", + "\n", + "bus_px = 10\n", + "fingers_px = [4, 4, 4, 4, 4, 4]\n", + "offset_px = 3\n", + "nx, ny = 120, 120\n", + "grid = HGridPattern(bus_px, fingers_px, offset_px=offset_px, nx=nx, ny=ny)\n", + "plt.imshow(grid.as_array(), cmap=\"gray\")\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This grid pattern always has two bus bars on the top and bottom, the size of the bus bar in the y-direction is specified by `bus_px`, in this case 10 pixels.\n", + "\n", + "The metalisation does not extend all the way to the edges of the solar cell, this offset is specfied by `offset_px`, in this case 3 pixels.\n", + "\n", + "Grid fingers are always equally spaced; the number and width of grid fingers are specified by an array of pixel widths; this is a required argument. In this case, there six finger all of width 4 pixels.\n", + "\n", + "The size of the image is specified by the `nx` and `ny` which sets the number of pixels in the x and y directions, respectively.\n", + "\n", + "Some useful methods:\n", + " * `as_array()`\n", + " * `save_as_image()`\n", + "\n", + "We have already seen `as_array()` used to plot the image above." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " ...,\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0],\n", + " [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grid.as_array()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To save the image to disk use `save_as_image()`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "grid.save_as_image(\"demo_grid.png\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can tell the notebook to render this image from disk." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/jpeg": "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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAAAAAAcD2kOAAAA4ElEQVR4Ae3bMQ6DQBDF0IWDcf9bAd1KuPbQOFViRX+iJ9qs1WtI4Hjv3EO39pn36rk/zb7r8Jh31FGPCFwXz7CxrMXG8vlWTzWxpRK1BMvZqGkilaglWM5GTROpRC3BcjZqmkglagmWs1HTRCpRS7CcjZomUolaguVs1DSRStQSLGejpolUopZgORs1TaQStQTL2ahpIpWoJVjORk0TqUQtwXI2appIJWoJlrNR00QqUUuwnI2aJlKJWoLlbNQ0kUrUEixno6aJVPqfhATL2Z5qmkglagmWs79R86dUJIEH0AoFyRIJtfgAAAAASUVORK5CYII=", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from IPython.display import display\n", + "from PIL import Image\n", + "display(Image.open(\"demo_grid.png\"))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Colour scheme convention\n", + "\n", + "The colors in the image hold a specific meaning for Solcore:\n", + "* White is a bus bar\n", + "* Gray is a grid finger (50%)\n", + "* Black is an absence of any metal\n", + "\n", + "In the code to follow, we will be sweeping out an IV curve for this solar cell. The distinction between a bus bar and a grid finger is that former is connect directly to the bias voltage source that is sweep to calculate the characteristic curve." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create a netlist\n", + "\n", + "In the SPICE simulation, a netlist describes the elements and connections between them. We are going to use the helper function to generate this netlist for us, given some high-level input parameters that describe the solar cell.\n", + "\n", + "The basic structure of the function we will use looks like this,\n", + "\n", + "```python\n", + " temperature = 300.0\n", + " netlist = generate_netlist(\n", + " grid,\n", + " illumination_map,\n", + " size,\n", + " junctions,\n", + " temperature=temperature\n", + " )\n", + "```\n", + "\n", + "We have already seen the first argument, `grid`. Let's take a look at the others.\n", + "\n", + "The `illumination_map` is a 2D array of the same size and grid image that contains the relative intensity of illumination across the solar cell's surface. A value of 1 indicates that the intensity is at its maximum, whereas a value of zero indicates that there is no illumination intensity at all. Furthermore, to simulate entirely uniform illumination, we just need to create an array of one.\n", + "\n", + "```python\n", + " import numpy as np\n", + " illumination_map = np.ones((nx, ny))\n", + "```\n", + "\n", + "The next argument is size; this is a tuple of the width (x-direction) and length (y-direction) of a solar cell. Here, the solar cell we want to simulate is approximately 3mm by 3mm, therefore,\n", + "\n", + "```python\n", + "size = (0.003, 0.003) # specifc size this in meters\n", + "```\n", + "\n", + "Finally, junctions is a list of Python dictionaries containing information about each junction in the solar cell.\n", + "\n", + "```python\n", + " junctions = [\n", + " {\n", + " \"jsc\": jsc,\n", + " \"emitter_sheet_resistance\": 100.0,\n", + " \"j01\": 4e-16,\n", + " \"j02\": 2e-7,\n", + " \"Eg\": 1.41,\n", + " \"n1\": 1.0,\n", + " \"n2\": 2.0\n", + " }\n", + " ]\n", + "```\n", + "\n", + "The parameters are:\n", + " - `jsc`, the short-circuit current generated by the junction in A / m2.\n", + " - `emitter_sheet_resistance`, the sheet resistance of the emitter region in Ohm per square.\n", + " - `j01`, the saturation current density in the neutral region in A / m2.\n", + " - `j02`, the saturation current density in the bulk region in A / m2.\n", + " - `Eg`, the bandgap of the material in eV (this one is no SI units!).\n", + " - `n1`, the ideality factor of the `j01` diode, default is 1.\n", + " - `n2`, the ideality factor of the `j02` diode, default is 2.\n", + "\n", + "Note that shunt resistance is not currently included in this modelling because for concentrator solar cells and is so large as to be negligible.\n", + "\n", + "Let's actually generate the netlist." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + " * HEADER\n", + " .options TNOM=26.850000000000023 TEMP=26.850000000000023\n", + " vin in 0 DC 0\n", + " \n", + " * HEADER\n", + " .model __D1_0 D(is=2.5e-25,n=1.0,eg=1.41)\n", + " .model __D2_0 D(is=1.2499999999999999e-16,n=2.0,eg=1.41)\n", + " \n", + " * BUS\n", + " R_METAL_X1_3_3_0 NX_3_3_0 in 0.0058333333333333345\n", + " R_METAL_X2_3_3_0 in NX_4_3_0 0.0058333333333333345\n", + " R_METAL_Y1_3_3_0 NY_3_3_0 in 0.0058333333333333345\n", + " R_METAL_Y2_3_3_0 in NY_3_4_0 0.005833333333333\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from solcore.spice.netlist import generate_netlist\n", + "\n", + "\n", + "# Homogeneous illumination\n", + "illumination_map = np.ones(nx * ny).reshape((nx, ny))\n", + "\n", + "# The size of the solar is 3mm x 3mm\n", + "size = (0.003, 0.003) # meters\n", + "\n", + "# Define a list of properies that describe each junction in the solar cell.\n", + "# NB: currently only one junction is working.\n", + "junctions = [\n", + " {\n", + " \"jsc\": 30000,\n", + " \"emitter_sheet_resistance\": 100.0,\n", + " \"j01\": 4e-16,\n", + " \"j02\": 2e-7,\n", + " \"Eg\": 1.41,\n", + " \"n1\": 1.0,\n", + " \"n2\": 2.0\n", + " }\n", + "]\n", + "\n", + "temperature = 300.0\n", + "\n", + "netlist = generate_netlist(\n", + " grid,\n", + " illumination_map,\n", + " size,\n", + " junctions,\n", + " temperature=temperature\n", + ")\n", + "\n", + "# preview some of text\n", + "print(netlist[:500])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As you can see, the netlist is just a string. The details of the netlist are not important for this tutorial, so we will move on.\n", + "\n", + "# Solve the netlist\n", + "\n", + "SPICE must digest and solve the netlist. The result is voltage at all nodes and current through all elements. We need to specify a voltage range and step size when calling the solver function. It may take time to solve this depending on the netlist size. It took me about a minute on a modern laptop to run this." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "from solcore.spice.netlist import solve_netlist\n", + "v_start = -0.1\n", + "v_stop = 1.5\n", + "v_step = 0.01\n", + "result = solve_netlist(netlist, temperature, v_start, v_stop, v_step)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Getting useful data from the result object\n", + "\n", + "A result is returned, which can be passed to the helper function to get the information we want; these can be found in the module `solcore.spice.result`. Let's import the functions to assist in obtaining and plotting the IV curve." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## IV Curve" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from solcore.spice.result import get_characterisic_curve, plot_characteristic_curve\n", + "\n", + "v, i = get_characterisic_curve(result)\n", + "plot_characteristic_curve(v, i)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Maximum power point" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's get the maximum power point information." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.9500000000000006 0.1884503672066743 105\n" + ] + } + ], + "source": [ + "from solcore.spice.result import get_maximum_power_point\n", + "vmax, pmax, maxidx = get_maximum_power_point(result)\n", + "print(vmax, pmax, maxidx)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here `vmax` and `pmax` are the voltage and power at the maximum power point, respectively.\n", + "\n", + "`maxidx` is the index in the bias voltage array that corresponds to the maximum power points. For example," + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "v[maxidx] == vmax" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Layer voltages\n", + "\n", + "We can make nice plots of surface voltages using the following functions:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(120, 120, 3, 161)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from solcore.spice.result import get_node_voltages, plot_surface_voltages\n", + "\n", + "voltages = get_node_voltages(result)\n", + "voltages.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, `voltages` is a 3 + 1 dimensional array. The first three dimensions correspond to the physical x, y, and z locations in the discretization, and the last dimension corresponds to the number of steps in the voltage sweep.\n", + "\n", + "The first z index is the metal layer, the second z index is the PV (emitter) layer, and the third is the base and buffer layers.\n", + "\n", + "The helper function plots both the metal and PV layer voltages." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA44AAAGmCAYAAAAzl9rmAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAADDrklEQVR4nOzdeXwTZf4H8M8kaZLSk7OlyFHQpYgKCFJBBFTWcoiKioooiIgXqNB1EVaEggfrAeKBVlRAOeRYFV1ZQSgisgIqyv68QFAULLQoCoVCr8z8/khmMpOZpEk7JZ3wefPKi3TO55lnZp5Mnm+eR5AkSQIRERERERFRELZoJ4CIiIiIiIjqNz44EhERERERUUh8cCQiIiIiIqKQ+OBIREREREREIfHBkYiIiIiIiELigyMRERERERGFxAdHIiIiIiIiCokPjkRERERERBQSHxyJiIiIiIgoJD440in1888/QxAELFy4MNpJsbSFCxdCEAT8/PPP0U4KEREF6Nu3L/r27RvtZFANtWnTBrfeemu0k0FU7/DBMYbIDxOCIGDz5s26+ZIkoWXLlhAEAVdccUWN9vHiiy+ekoe+jRs3QhAE/Otf/6rzfdWlyspKNGnSBL169Qq6jFwu559/fq32darKhojIitR1pNFr69atdbbvAwcOIC8vDzt27NDNW7p0KebMmVNn+zbSt29fnHPOOad0n3Vh9uzZEAQB69evD7rMK6+8AkEQ8N5779V4P9999x3y8vL4ZS2d9vjgGIPcbjeWLl2qm/7xxx/j119/hcvlqvG2+XASmbi4OAwdOhSffvopfvnlF8NlNm3ahF9//RU333xzrfbFsiEiqt6MGTOwaNEi3evMM880bR8ffvghPvzwQ+XvAwcOYPr06fXmwTFW3HjjjbDZbIafeWRLly5F48aNMWDAgBrv57vvvsP06dP54EinPT44xqCBAwdi5cqVqKqq0kxfunQpunbtivT09CilLHZJkoSTJ08azhs+fDgkScKbb75pOH/p0qWw2Wy48cYb6zKJREQEYMCAAbj55pt1ryZNmpi2D6fTCafTadr2IiWKIsrKyqK2f7OVlpYaTs/IyMAll1yCt99+G+Xl5br5hYWF2LRpE4YOHYq4uLi6TiZRzOODYwwaNmwYDh8+jHXr1inTKioq8K9//Qs33XST4TqiKGLOnDno2LEj3G430tLScOedd+LPP/9UlmnTpg2+/fZbfPzxx0poj/wbjj/++AMPPPAAzj33XCQmJiI5ORkDBgzA//73vzrN69NPP42ePXuicePGiI+PR9euXXXhrX369EGnTp0M12/fvj1ycnKUv8M5DoD3WFxxxRVYu3YtunXrhvj4eLz88suG+7jooovQpk0bw29EKysr8a9//QuXXHIJMjIyAAAbNmzAxRdfjISEBKSmpuKqq67C999/H/I4mFU2v/zyC6688kokJCSgWbNmmDBhAtauXQtBELBx40bNstu2bUP//v2RkpKCBg0aoE+fPvjvf/+rWebYsWMYP3482rRpA5fLhWbNmuGvf/0rvvzyy5D5ISKKFvm3+E8//TTmzp2Ltm3bokGDBrj88suxf/9+SJKERx55BGeccQbi4+Nx1VVX4Y8//tBsQ/0bx40bN+KCCy4AAIwaNUq5Ry9cuBB9+/bF6tWr8csvvyjT27Rpo2ynvLwc06ZNw5lnngmXy4WWLVti4sSJuockQRAwbtw4LFmyBB07doTL5cKaNWtqdRz+7//+D7feeivatm0Lt9uN9PR03HbbbTh8+LCyzEcffQRBEPDOO+/o1l+6dCkEQcCWLVuUaTt37sR1112HRo0awe12o1u3broQUjmk+OOPP8Y999yDZs2a4YwzzgiazptvvhlHjx7F6tWrdfOWLVsGURQxfPhwAN4H0L/97W9o2bIlXC4X2rdvj6effhqSJAXd/sKFCzF06FAAwCWXXKKUk1wnvvvuuxg0aBAyMjLgcrnQrl07PPLII/B4PLptyedTfHw8unfvjk8++cTw97Dhlvu6devQq1cvpKamIjExEe3bt8c//vGPoHkha9i0aRMGDx6MjIwMCIKAVatWVbvOxo0bcf7558PlcuHMM880jEArLCzEzTffrHxmPvfcc/HFF19ElDZHREuTJbRp0wY9evTAm2++qYRmfPDBBzh69ChuvPFGPPfcc7p17rzzTixcuBCjRo3Cfffdh7179+KFF17AV199hf/+97+Ii4vDnDlzcO+99yIxMREPPfQQACAtLQ0A8NNPP2HVqlUYOnQoMjMzUVxcjJdffhl9+vTBd999pzwUme3ZZ5/FlVdeieHDh6OiogLLli3D0KFD8f7772PQoEEAgFtuuQVjxozBN998o/lNx+eff44ffvgBU6ZMieg4yHbt2oVh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tGvXDk8//TSOHz+u299vv/0GwPt7SnU4EwA0a9YMGRkZhuNtERHFKvlLP6N7dEJCgu5eCXjrpMLCQsPfIZ08eTJkT6O1JX+pGlh3zJkzx3D5Jk2aYMCAAVi8eDGWLFmC/v37a76YbNasGfr27YuXX34ZBw8e1K0v1xu1IQ99tXjxYixfvhx9+vTR9FY6cOBAeDweTUsoADzzzDMQBCHkl5nBys/oOFVUVODFF1/ULNetWzc0btwYr7zyimaM7SVLluhCnMMt98AhYAAoUUCsY+un5ORkzcusB8cePXqgoKBAM23dunVKj8aA9/oIbJj44YcfQn5hYoQtjjEunObnPn364M4778TMmTOxY8cOXH755YiLi8Pu3buxcuVKPPvss8rvI7t27YqXXnoJjz76KM4880w0a9YMl156Ka644grMmDEDo0aNQs+ePfH1119jyZIltf4t21tvvaV8GxiYr0GDBmH27Nno378/brrpJhw6dAhz587FmWeeif/7v//TrdOlSxecc845yg/PA4eDiOQ41NS1116Le+65B++++y5atmyp+YYS8IZ/DhgwAD169MDo0aOV4ThSUlKqDWeobdnceeedeOGFFzBs2DDcf//9aN68OZYsWaKEJsrffNpsNrz66qsYMGAAOnbsiFGjRqFFixYoLCzERx99hOTkZPz73//GsWPHcMYZZ+C6665Dp06dkJiYiPXr1+Pzzz/HrFmzanUcKTySVAVJqqp+wTC2QxQrPvjgA8N6pWfPnnX2++t27dohNTUV+fn5SEpKQkJCArKzs5GZmYmuXbti+fLlyM3NxQUXXIDExEQMHjwYt9xyC1asWIG77roLH330ES666CJ4PB7s3LkTK1asUMYRrqnffvsNjz76qG56ZmYmhg8fjt69e+PJJ59EZWUlWrRogQ8//FDXkqY2YsQIpY40+gJ27ty56NWrF84991yMGTMGbdu2RXFxMbZs2YJff/211uM+q4e+AoAZM2Zo5g8ePBiXXHIJHnroIfz888/o1KkTPvzwQ7z77rsYP368Ek1jpHPnzrDb7XjiiSdw9OhRuFwuXHrppejZsycaNmyIkSNH4r777oMgCFi0aJHugdvpdCIvLw/33nsvLr30Ulx//fX4+eefsXDhQl3fAuGW+4wZM7Bp0yYMGjQIrVu3xqFDh/Diiy/ijDPOQK9evWp1LMkr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Le6++27cd999eP311wEARUVFAIC0tDTNemlpacq8QDNnzkRKSoryatmypdnJJiIiijrWoUREVF+Z/uAoiiLOP/98PP744+jSpQvuuOMOjBkzBvn5+TXe5uTJk3H06FHltX//fhNTTEQUm/j7DOthHUpEVD+wDtUz/cGxefPmOPvsszXTOnTogH379gEA0tPTAQDFxcWaZYqLi5V5gVwuF5KTkzUvIiIKTYRg2otODdahRET1A+tQPdMfHC+66CLs2rVLM+2HH35A69atAXh/5J+eno6CggJlfklJCbZt24YePXqYnRwiIiLLYB1KRET1lem9qk6YMAE9e/bE448/juuvvx6fffYZ5s2bh3nz5gEABEHA+PHj8eijj+Kss85CZmYmHn74YWRkZODqq682OzlERKcvs0JkYijMpr6LtTpUhBTtJNRYLI29RtZm1XPRytc/ANahBkx/cLzgggvwzjvvYPLkyZgxYwYyMzMxZ84cDB8+XFlm4sSJKC0txR133IEjR46gV69eWLNmDdxut9nJISI6bZk18LBVP7RYEetQIqL6gXWonukPjgBwxRVX4Iorrgg6XxAEzJgxAzNmzKiL3RMREVkW61AiIqqP6uTBMRaJUlW0k2AqQfREOwk1ZuW0B7JyXqyc9kCxdn3LzOrNLZZ6hKNaEKOdACKKefXoPsM6VI8PjkREMUqEOXVwParHiYiITgnWoXp8cAyTJMVO6woAwMqtRVZOeyAr58XKaQ8Qc9c30WlAEiP4Fl80vRN5ovotzHM+ouuITnt8cCQiilEMsyEiIqoZ1qF6fHAkIopRomROb26ixXtUJyIiihTrUD3GboRJlKoMX5YlevQvq7By2gNZOS9WTnuAmLu+iaJIVL2IiADeFyKxadMmDB48GBkZGRAEAatWrap2nY0bN+L888+Hy+XCmWeeiYULF+qWmTt3Ltq0aQO3243s7Gx89tlnEaeND45ERDFKgmDai4iI6HQSrTq0tLQUnTp1wty5c8Nafu/evRg0aBAuueQS7NixA+PHj8ftt9+OtWvXKsssX74cubm5mDZtGr788kt06tQJOTk5OHToUERp44NjmCSpyvBlVYIo6l5WYeW0B7JyXqyc9kCxdn3L5MGLzXhFKpJvNisrKzFjxgy0a9cObrcbnTp1wpo1azTL5OXlQRAEzSsrK0uzzLx589C3b18k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+eWXw2az6UYzbWhoiNzB1UtPT8eOHTvg9XrR1NSEzMxMLFu2DKNGjeoyPYMHD8a1116LY8eOAQAyMjLg9/vR3Nwc1eso7jcjI0M3uquSTnGdWGl3uVxISUnpMj1ERGQeRtehZsFQVSIi6pbD4YDL5Yp6xWo42u125Ofno7q6Wl0mSRKqq6tRWFgYdx9OpxNZWVkIBoOoqKjAjBkzuly3ra0Nx48fx4gRIwAA+fn5SE5OjtrvkSNHUFdXp+63sLAQ//rXv6JGd925cydcLhfGjh2rriNuQ1mnu7QTERGZHUdVJSIiQ23duhWzZ8/Gq6++iokTJ2LdunXYtm0bDh8+jOHDh2PWrFnIysrCmjVrAAD79u1DfX098vLyUF9fj1WrVqG2thb79+9Xew+XLFmCe+65Bzk5OTh16hRWrlyJAwcO4NChQ0hPTwcAzJ8/H3/729+wadMmuFwuLFq0CACwe/duAOHpOPLy8pCZmYkXXngBbrcbjzzyCB577DGsXr0aQHg6ju985ztYsGABHn30UezatQtPPvkkKisrUVRU9C0fSSIiov6DoapERGSoBx98EI2NjVixYgXcbjfy8vJQVVWlPiNZV1cHq1ULePF6vVi+fDlOnDiB1NRUTJ8+HZs3b44KOT158iRmzpyJpqYmpKenY/Lkydi7d6/aaASAtWvXwmq1ori4GD6fD0VFRXj55ZfVz202G/76179i/vz5KCwsxCWXXILZs2ejrKxMXWfkyJGorKzE4sWLUV5ejiuuuAJvvPEGG41ERDTgsceRiIiIiIiI4uIzjkRERERERBQXG45EREREREQUFxuOREREREREFBcbjkRERERERBQXG45EREREREQUFxuOREREREREFBcbjkRERERERBQXG45EREREREQUFxuOREREREREFBcbjkRERERERBQXG45EREREREQUFxuOREREREREFNf/AyhNPrVC4e5iAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_surface_voltages(voltages, bias_index=maxidx)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Electroluminescence prediction\n", + "We can make a prediction of the electroluminescene distribution emitted by the solar cells using the following helper functions:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZkAAAGfCAYAAACN/K/TAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAABfn0lEQVR4nO29e3xU1bn//9kzSSYhNy5CQiRApCjIRREQERQvEUTkiPIVtWmLiGLbACJHK7QFi6IRWxUvFNRfD7Q9UCs9xVYr8EKqUHu4GaUVtYhHLHgJeIEkJOQys9fvj5m9Z+3MymQms+eyk8/b15bMvqz97Gf2rLWey1pLE0IIEEIIIXHAlWwBCCGEdFzYyBBCCIkbbGQIIYTEDTYyhBBC4gYbGUIIIXGDjQwhhJC4wUaGEEJI3GAjQwghJG6wkSGEEBI32MgQQgiJG2xkCCEkAezcuRNTp05FUVERNE3DSy+9FNX1DQ0NuPXWWzFs2DCkpaVh2rRpyvPWr1+P8847D126dEHv3r1x22234euvv479AdoJGxlCCEkAdXV1OO+887Bq1ap2Xe/z+ZCVlYX58+ejtLRUec7f//53fO9738Ps2bPx3nvvYePGjdi7dy/uuOOOWESPCTYyhBCSACZPnozly5fj+uuvVx5vbGzEPffcgzPPPBPZ2dkYM2YM3njjDfN4dnY2Vq9ejTvuuAOFhYXKMnbt2oX+/ftj/vz5KCkpwfjx43HnnXdi79698XikiGAjQwghKcDcuXOxa9cuvPDCC/jnP/+JG2+8EVdffTUOHToUcRljx47F0aNH8eqrr0IIgWPHjuEPf/gDrrnmmjhKHh42MoQQkmSOHDmCtWvXYuPGjbjkkkswYMAA3HPPPRg/fjzWrl0bcTnjxo3D+vXrcdNNNyEjIwOFhYXIz89vt4vODtjIOIT+/fvj1ltvNT+/8cYb0DTNYk4nm5Yyxsqtt96K/v3721ZeIvnZz34GTdOScu9PPvkEmqZh3bp1Sbk/iZ53330XPp8PZ599NnJycsxtx44d+L//+7+Iy3n//fdx1113YenSpaisrMSWLVvwySef4Pvf/34cpQ9PWtLu7CDWrVuHWbNmmZ89Hg/69u2LiRMnYsmSJSgoKEiidNHx6quvYu/evfjZz36WNBnCVb533nkn1qxZkxA5NmzYgOPHj2PBggUJuR8hrXHq1Cm43W5UVlbC7XZbjuXk5ERcTkVFBcaNG4d7770XADB8+HBkZ2fjkksuwfLly9G7d29b5Y4ENjJR8MADD6CkpAQNDQ148803sXr1arz66qs4cOAAunTpklBZLr30Upw+fRoZGRlRXffqq69i1apVSW1kAOCqq67C9773vZD9Z599dsJk2LBhAw4cONDhGpl+/frh9OnTSE9PT7YoJEJGjBgBn8+H48eP45JLLml3OfX19UhLs1brRqOVrEWQ2chEweTJkzFq1CgAwO23344ePXrg8ccfx5/+9Cfccsstymvq6uqQnZ1tuywulwuZmZm2l5sozj77bHznO99JthgR09DQgIyMDLhcqe9h1jTN0e9GR+XUqVP46KOPzM+HDx/G/v370b17d5x99tkoKyvD9773PTz22GMYMWIEvvzyS2zfvh3Dhw/HlClTAPjdYU1NTfjmm29QW1uL/fv3AwDOP/98AMDUqVNxxx13YPXq1Zg0aRK++OILLFiwABdeeCGKiooS/ch+BGmTtWvXCgBi3759lv2vvPKKACAeeughIYQQM2fOFNnZ2eKjjz4SkydPFjk5OeK6664TQgjh8/nEE088Ic4991zh8XhEr169xJw5c8Q333xjKVPXdfHggw+KM888U2RlZYnLLrtMHDhwQPTr10/MnDnTPO/1118XAMTrr79uuX737t1i8uTJomvXrqJLly5i2LBhYuXKlaZ8AEI2A7tlbA0Aory8vM3zZs6cKfr162fZF6mMQgjx6quviksvvVTk5OSI3NxcMWrUKLF+/XohhBATJkwI0YNxL0O3v/vd78RPfvITUVRUJDRNEydOnBBCCPHiiy+KCy64QGRmZooePXqIsrIy8emnn1ruff/991t0e/jwYQFArF27VqmP+++/P+TagwcPirKyMpGXlyfOOOMM8dOf/lToui6OHDki/uM//kPk5uaKgoIC8Ytf/MJSnupexrv56aefiuuuu05kZ2eLM844Q/znf/6n8Hq97dLxvn37xMSJE0WPHj1EZmam6N+/v5g1a1ZIWStXrhRDhw4VHo9HnHHGGWLSpEkhv6Xf/va3pk67desmbrrpJnHkyBHLORMmTBBDhgwR7733nrjssstEVlaWKCoqEitWrAjRaUNDg1i6dKkYMGCAyMjIEH369BH33nuvaGhoCDk3URjvVcvN+M00NTWJpUuXiv79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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from solcore.spice.result import get_electroluminescence, plot_electroluminescence\n", + "\n", + "pv_layer_idx = 1 # index = 1 is the PV layer\n", + "pv_layer_voltages = voltages[:, :, pv_layer_idx, maxidx]\n", + "el = get_electroluminescence(pv_layer_voltages, is_metal=grid.is_metal)\n", + "plot_electroluminescence(el)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The `is_metal` argument is optional, but it improves the prediction by reduce emission from regions containing metal to zero." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A more detailed example using Solcore to calculate the short-circuit current\n", + "\n", + "Let's create a Solcore solar cell model based on the solar cell structure above and get it to calculate the short-circuit current." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solving IV of the junctions...\n", + "Solving IV of the tunnel junctions...\n", + "Solving IV of the total solar cell...\n" + ] + }, + { + "data": { + "text/plain": [ + "32491.025503548084" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from solcore.structure import Junction\n", + "from solcore.solar_cell import SolarCell\n", + "from solcore.solar_cell_solver import solar_cell_solver\n", + "from solcore.light_source import LightSource\n", + "\n", + "def get_jsc(concentrationX):\n", + " junction_model = Junction(\n", + " kind='2D',\n", + " T=temperature,\n", + " reff=1,\n", + " jref=300,\n", + " Eg=1.4,\n", + " A=1,\n", + " R_sheet_top=100,\n", + " R_sheet_bot=1e-16,\n", + " R_shunt=1e16,\n", + " n=3.5\n", + " )\n", + "\n", + " solar_cell_model = SolarCell([junction_model], T=temperature)\n", + " wl = np.linspace(350, 2000, 301) * 1e-9\n", + " light_source = LightSource(\n", + " source_type=\"standard\",\n", + " version=\"AM1.5g\",\n", + " x=wl,\n", + " output_units=\"photon_flux_per_m\",\n", + " concentration=concentrationX\n", + " )\n", + "\n", + " options = {\n", + " \"light_iv\": True,\n", + " \"wavelength\": wl,\n", + " \"light_source\": light_source,\n", + " \"optics_method\": \"BL\"\n", + " }\n", + " solar_cell_solver(solar_cell_model, 'iv', user_options=options)\n", + "\n", + " jsc = solar_cell_model(0).jsc\n", + " return jsc\n", + "\n", + "# Get the JSC for 100x concentration\n", + "get_jsc(100)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a second function that wraps the SPICE model and returns the device's efficiency. Inside this function, it calls solcore to estimate the JSC." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "def get_efficiency(concentrationX, power_in=1000.0):\n", + " \n", + " bus_px = 10\n", + " fingers_px = [4, 4, 4, 4, 4, 4]\n", + " offset_px = 3\n", + " nx, ny = 120, 120\n", + " grid = HGridPattern(bus_px, fingers_px, offset_px=offset_px, nx=nx, ny=ny)\n", + "\n", + " # Homogeneous illumination\n", + " illumination_map = np.ones(nx * ny).reshape((nx, ny))\n", + "\n", + " # The size of the solar is 3mm x 3mm\n", + " size = (0.003, 0.003) # meters\n", + "\n", + " # Define a list of properies that describe each junction in the solar cell.\n", + " # NB: currently only one junction is working.\n", + " junctions = [\n", + " {\n", + " \"jsc\": get_jsc(concentrationX), # solcore is calculating this for us!\n", + " \"emitter_sheet_resistance\": 100.0,\n", + " \"j01\": 4e-16,\n", + " \"j02\": 2e-7,\n", + " \"Eg\": 1.41,\n", + " \"n1\": 1.0,\n", + " \"n2\": 2.0\n", + " }\n", + " ]\n", + "\n", + " temperature = 300.0\n", + "\n", + " netlist = generate_netlist(\n", + " grid,\n", + " illumination_map,\n", + " size,\n", + " junctions,\n", + " temperature=temperature\n", + " )\n", + "\n", + " result = solve_netlist(netlist, temperature, 0.0, 1.5, 0.01)\n", + "\n", + " vmax, pmax, maxidx = get_maximum_power_point(result)\n", + " \n", + " p_per_m2 = pmax / size[0] / size[1]\n", + " efficiency = p_per_m2 / (concentrationX * power_in)\n", + " return efficiency\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, let's loop over a few concentration values to see if we can plot a concentration vs. efficiency plot." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solving IV of the junctions...\n", + "Solving IV of the tunnel junctions...\n", + "Solving IV of the total solar cell...\n", + "Solving IV of the junctions...\n", + "Solving IV of the tunnel junctions...\n", + "Solving IV of the total solar cell...\n", + "Solving IV of the junctions...\n", + "Solving IV of the tunnel junctions...\n", + "Solving IV of the total solar cell...\n", + "Solving IV of the junctions...\n", + "Solving IV of the tunnel junctions...\n", + "Solving IV of the total solar cell...\n", + "Solving IV of the junctions...\n", + "Solving IV of the tunnel junctions...\n", + "Solving IV of the total solar cell...\n", + "Solving IV of the junctions...\n", + "Solving IV of the tunnel junctions...\n", + "Solving IV of the total solar cell...\n" + ] + }, + { + "data": { + "image/png": "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zJXvJCdEYkJiFFyyivf3nfv7sCcxSq66XMx8++237S70nTRpEr799lufNMpfyLKM/Px83Vdxk7kwV6QF5sq32kZn1u8pg6KYerXGeRklV10uZoKCglBdXX3O45WVlbrfzpiIiKg7LBkfj/BgK46dbkZ64Um9m9PjdbmYWbhwIR599FHU1dW5H6utrcWvf/1rXHHFFT5tnNFZLBYkJyfrPrxG5sJckRaYK98KCbTg2ksGAGjdr6mnMkquulzM/OlPf0J5eTmSkpIwb948zJs3D4MHD0ZVVRWef/55LdpoWLIsIycnR/fhNTIX5oq0wFz5XttU07aCalTW6b8IVg9GyVWXi5mEhATk5eXhj3/8I8aMGYPJkyfjpZdewtdff43ExEQt2mhoISEhejeBTIi5Ii0wV741vG84pg6OhqIC/83quQuBjZAr3meGiIjoIm3KrcAv/puLvhFByHhkPqwWr3YJorN05fd3p1bsbt68GVdddRUCAgKwefPm8z536dKlnW+pn5MkCTk5OZg0aRIXP5PPMFekBeZKG1cm90N0WCCq7U5sO3gCi8b207tJ3coouerUOy9fvhxVVVWIi4s773YGgiDoPm/WnQRBQO/evSEIgt5NIRNhrkgLzJU2gqwWXH/pAPx95xG8s6esxxUzRslVp8bDFEVx746tKEqHX10tZNLT07FkyRLEx8dDEARs3Lixw+feddddEAQBL774YpfeQ0sWiwXDhg3TfRU3mQtzRVpgrrRz89TWzSfTD59E2akmnVvTvYySq04VM9HR0aipqQEA3HHHHaivr/fJmzc2NmLChAlYu3bteZ+3YcMG7N69G/Hx8T55X1+RJAmZmZmQJEnvppCJMFekBeZKOwNjQjF7RCwAYH1Wz7pM2yi56lQx09LSArvdDgB488034XA4fPLmV111FZ588klcc801HT6noqIC9913H9555x0EBAT45H19RRRFJCQkQBS54It8h7kiLTBX2mq7TPv9veVwSj1nuYVRctWpNTPTp0/H8uXLMXnyZKiqivvvv7/DS7Fef/11nzVOURTccssteOihhzB27NhO/YzT6YTT+d3GX21FWNsUWNt/LRaLx7EkSRAEwX0siiJEUezw2OVywWKxICkpCS6XC4IgQBAEuFwu9yIoSZI8jgMCAqCqqvu4bWqu7VhRFFit1g6PZVmGqqru4/b6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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "effs = list()\n", + "x_values = [1, 10, 100, 200, 500, 1000]\n", + "for x in x_values:\n", + " effs.append(get_efficiency(x))\n", + "\n", + "plt.semilogx(x_values, 100 * np.array(effs))\n", + "plt.grid(linestyle=\"dotted\")\n", + "plt.xlabel(\"Concentration\")\n", + "plt.ylabel(\"Efficiency (%)\")\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "solcore_env", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/cpv_grid_spice_example.py b/examples/cpv_grid_spice_example.py new file mode 100644 index 00000000..ec4efed0 --- /dev/null +++ b/examples/cpv_grid_spice_example.py @@ -0,0 +1,72 @@ +import numpy as np +from solcore.spice.grid import HGridPattern +from solcore.spice.netlist import generate_netlist, solve_netlist +from solcore.spice.result import ( + get_characterisic_curve, + get_electroluminescence, + get_maximum_power_point, + get_node_voltages, + plot_characteristic_curve, + plot_electroluminescence, + plot_surface_voltages +) + +if __name__ == "__main__": + + # Cell short-circuit current + jsc = 3000.0 + + # Temperature + temperature = 300.0 + + # Grid pattern + nx, ny = 120, 120 + cell_grid = HGridPattern(10, [4, 4, 4, 4, 4, 4], 3, nx=nx, ny=ny) + + # Homogeneous illumination + cell_illumination_map = np.ones(nx * ny).reshape((nx, ny)) + + # The size of the solar is 3mm x 3mm + cell_size = (0.003, 0.003) # meters + + # Define a list of properies that describe each junction in the solar cell. + # NB: currently only one junction is working. + junctions = [ + { + "jsc": jsc, + "emitter_sheet_resistance": 100.0, + "j01": 4e-16, + "j02": 2e-7, + "Eg": 1.41, + "n1": 1.0, + "n2": 2.0 + } + ] + + netlist = generate_netlist( + cell_grid, + cell_illumination_map, + cell_size, + junctions, + temperature=300, + show_plots=True + ) + + print("") + print("This simulation will take a few minutes to run, please wait for results to appear...") + result = solve_netlist(netlist, temperature, -0.1, 1.5, 0.01) + + V, I = get_characterisic_curve(result) + + plot_characteristic_curve(V, I) + + vmax, pmax, maxidx = get_maximum_power_point(result) + + voltages = get_node_voltages(result) + + plot_surface_voltages(voltages, bias_index=maxidx) + + pv_surface_voltages = voltages[:, :, 1, maxidx] + el = get_electroluminescence(pv_surface_voltages, is_metal=cell_grid.is_metal) + + plot_electroluminescence(el) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index cd9dca70..a4ce7d0d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,8 @@ dependencies = [ "yabox", "joblib", "solsesame", + "PySpice", + "pixie-python" ] dynamic = ["version"] @@ -71,9 +73,6 @@ package = 'solcore' "Build" = ["spin.cmds.meson.build", "spin.cmds.meson.test"] "Extensions" = ['.spin/cmds.py:codecov', '.spin/cmds.py:install_dependencies'] -[tool.pytest.ini_options] -addopts = "--cov=solcore --cov-report=html:htmlcov -p no:warnings -n \"auto\" -v" - [tool.isort] line_length = 88 multi_line_output = 3 diff --git a/solcore/spice/__init__.py b/solcore/spice/__init__.py index 4623fa31..e60516b7 100755 --- a/solcore/spice/__init__.py +++ b/solcore/spice/__init__.py @@ -1,3 +1,3 @@ from .spice import solve_circuit, SpiceSolverError from .pv_module_solver import solve_pv_module -from .quasi_3D_solver import solve_quasi_3D +from .quasi_3D_solver import solve_quasi_3D \ No newline at end of file diff --git a/solcore/spice/grid.py b/solcore/spice/grid.py new file mode 100644 index 00000000..70ddb785 --- /dev/null +++ b/solcore/spice/grid.py @@ -0,0 +1,141 @@ +"""Classes that generate a metalisation pattern for a solar cell. +""" + + +import numpy as np +import pixie +from PIL import Image, ImageOps +import tempfile +from pathlib import Path + + +class GridPattern: + """Representation of a metalisation pattern on the front surface of a solar cell. + + Instead of instantiating this class directly, subclass and implement the `draw` method to render a grid pattern. + + Discussion + ---------- + You should use three grayscale pixel values to illustrate the solar cell metalization: + - black (0.0), represents no metalisation + - grey (0.5), represents grid fingers + - white (1.0), represents the bus bar. + """ + def draw(self) -> pixie.Image: + raise NotImplementedError("The draw() method should be implemented by subclasses to draw specific grid patterns.") + + def save_as_image(self, path): + image: pixie.Image = self.draw() + image.write_file(path) # This file is seems to be corrupt! + img = Image.open(path) # But, it can be opened by PIL and re-saved. + + # The shape of this array will be something like (300, 300, 4) + # because pixie saves colours as RGBA. We need to conver this + # to a gray scale image + img = ImageOps.grayscale(img) + img.save(path) + + def as_array(self) -> np.ndarray: + # Write the image to a temporary directory, + # load the image back using PIL and return + # the data as an array. + with tempfile.TemporaryDirectory() as dirname: + path = Path(dirname) / "grid.png" # file name does matter + self.save_as_image(path.as_posix()) + img = Image.open(path.as_posix()) + return np.asarray(img) + + @property + def is_metal(self) -> np.ndarray: + """Return a bool array where the pattern contains metal. + """ + pattern = self.as_array() + return np.where((pattern / pattern.max()) > 0.2, True, False) + + +class HGridPattern(GridPattern): + """A classic H pattern concenrator solar cell pattern. + """ + + def __init__(self, bus_px_width, finger_px_widths, offset_px=5, nx=300, ny=300): + self.bus_px_width = bus_px_width + self.finger_px_widths = finger_px_widths + self.offset_px = offset_px + self.nx = nx + self.ny = ny + + def draw(self) -> pixie.Image: + + bus_px_width = self.bus_px_width + finger_px_widths = self.finger_px_widths + offset_px = self.offset_px + nx = self.nx + ny = self.ny + + BUS_PAINT = pixie.Paint(pixie.SOLID_PAINT) + BUS_PAINT.color = pixie.Color(1, 1, 1, 1) # White + + FINGER_PAINT = pixie.Paint(pixie.SOLID_PAINT) + FINGER_PAINT.color = pixie.Color(0.5, 0.5, 0.5, 1) # Gray + + # Fill the image with black i.e. no metal. We are going + # to draw on top of this canvas using the BUS_PAINT and + # the FINGER_PAINT paints. + self.image = image = pixie.Image(nx, ny) + BLACK = pixie.Color(0, 0, 0, 1) + image.fill(BLACK) + + + # NB Top-left corner is the (0, 0) + ctx = image.new_context() + ctx.fill_style = BUS_PAINT + ctx.fill_rect(offset_px, offset_px, nx - 2 * offset_px, bus_px_width) + ctx.fill_rect(offset_px , ny - offset_px - bus_px_width, nx - 2 * offset_px, bus_px_width) + + # The image now looks like this, with the bus bars drawn + # + # *************** + # *************** + # + # + # + # + # *************** + # *************** + # + + ctx = image.new_context() + ctx.stroke_style = FINGER_PAINT + f_origin_y = np.rint(bus_px_width + offset_px) + f_length = np.rint(ny - 2 * offset_px - 2 * bus_px_width) + n = len(finger_px_widths) + w = nx - 2 * offset_px # width of mask + d = w / (2*n) # the half-spacing between fingers + f_x = [offset_px + d] # location of first grid finger + for idx in range(1, n): + f_x.append(f_x[idx-1] + 2*d) + + # Round the x locations to the nearest integer, this avoid + # the drawing tool kit from blending the colors + f_x = np.rint(np.array(f_x)) + + + for f_origin_x, f_width in zip(f_x, finger_px_widths): + + ctx.stroke_segment(f_origin_x, f_origin_y, f_origin_x, f_origin_y + f_length) + + # The image now looks like this, with the n grid fingers drawn, here n = 3 + # + # *************** + # *************** + # | | | + # | | | + # | | | + # | | | + # *************** + # *************** + # + + return image + + \ No newline at end of file diff --git a/solcore/spice/model.py b/solcore/spice/model.py new file mode 100644 index 00000000..cf27894a --- /dev/null +++ b/solcore/spice/model.py @@ -0,0 +1,367 @@ +"""The classes help to create a distributed SPICE model for a solar cell. +Think of these building blocks as sub-circuits that you can combine into a +3D structure to build the solar cell. +""" + + +class Header: + """A class representing header information for the SPICE netlist.""" + + def __init__( + self, + temperature : float = 300.0 + ): + """ + Parameters + ---------- + temperature : float (Optional) + The temperature in Kelvin + """ + self.temperature = temperature + + def netlist(self): + return f""" + * HEADER + .options TNOM={self.temperature - 273.15} TEMP={self.temperature - 273.15} + vin in 0 DC 0 + """ + + +class Diodes: + """A class representing header information for the SPICE file that contains diode models""" + + def __init__( + self, + Eg: float, + j01: float, + j02: float, + area: float, + n1: float = 1.0, + n2: float = 2.0, + junction_idx: int = 0 + ): + """ + Parameters + ---------- + Eg : float + Band gap in Joules. + j01 : float + Saturation current density in neutral region in amps per metre sq. + j02 : float + Saturation current density in the bulk region in amps per metre sq. + area : float + The top surface area of this segment + n1 : float (Optional) + Ideality factor, default n1 = 1 + n2 : float (Optional) + Ideality factor, default n2 = 2 + """ + self.Eg = Eg + self.j01 = j01 + self.j02 = j02 + self.area = area + self.n1 = n1 + self.n2 = n2 + self.junction_idx = int(junction_idx) + + def netlist(self): + return f""" + * HEADER + .model __D1_{self.junction_idx} D(is={self.area * self.j01},n={self.n1},eg={self.Eg}) + .model __D2_{self.junction_idx} D(is={self.area * self.j02},n={self.n2},eg={self.Eg}) + """ + + +class Metal: + """A unit cell representing a SPICE model of metal grid finger. + + The resistance of the cell is calculated using the geometric + properties of the contact and the resistivity of the metal. + """ + + def __init__( + self, + idx, + metal_height: float, + x_length: float, + y_length: float, + resistivity_metal: float, + resistivity_contact: float + ): + """ + Parameters + ---------- + idx : Tuple + The 3D index of this element in the grid e.g. (1, 2, 3) + metal_height : float + The metalisation height of the grid finger in meters for this cell + x_length : float + The metalisation width of the grid finger in meters for this cell. This + depends on the resolution of the discretiation in the X direction. + y_length : float + The metalisation width of the grid finger in meters for this cell. This + depends on the resolution of the discretiation in the Y direction. + resistivity_metal : float + The resistivity of the metal in Ohm meter for this cell. + resistivity_contact : float + The resistivity of the metal-semiconductor contact in Ohm meter^2 for + this cell. + """ + self.idx = idx + self.metal_height = metal_height + self.x_length = x_length + self.y_length = y_length + self.resistivity_metal = resistivity_metal + self.resistivity_contact = resistivity_contact + self.left = f"NX_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.near = f"NY_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.top = f"N_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.right = f"NX_{self.idx[0]+1}_{self.idx[1]}_{self.idx[2]}" + self.far = f"NY_{self.idx[0]}_{self.idx[1]+1}_{self.idx[2]}" + self.bottom = f"N_{self.idx[0]}_{self.idx[1]}_{self.idx[2]+1}" + self.centre = f"N_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.element = f"{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + + def netlist(self): + """Return the SPICE netlist for this cell. + + Parameters + ---------- + idx : Tuple + The (i, j, k) indexes of this cell's location in the grid. + """ + r_contact = self.resistivity_contact / (self.x_length * self.y_length) # usually ~ 5 mOhms + r_metal = self.resistivity_metal * self.y_length / (self.metal_height * self.x_length) # usually ~ 1 Ohm + + return f""" + * METAL + R_METAL_X1_{self.element} {self.left} {self.centre} {r_metal/2} + R_METAL_X2_{self.element} {self.centre} {self.right} {r_metal/2} + R_METAL_Y1_{self.element} {self.near} {self.centre} {r_metal/2} + R_METAL_Y2_{self.element} {self.centre} {self.far} {r_metal/2} + R_METAL_SEMI_Z_{self.element} {self.centre} {self.bottom} {r_contact} + """ + + +class Bus: + """A unit cell representing a SPICE model of metal bus bar segment. + + The Bus bar class is very similar to the Metal class with one important + exception: the voltage of this node connects to the a voltage source + for sweeping the bias. Thus these nodes are all at the same voltage. + """ + + def __init__( + self, + idx, + metal_height: float, + x_length: float, + y_length: float, + resistivity_metal: float, + resistivity_contact: float + ): + """ + Parameters + ---------- + idx : Tuple + The 3D index of this element in the grid e.g. (1, 2, 3) + metal_height : float + The metalisation height of the grid finger in meters for this cell + x_length : float + The metalisation width of the grid finger in meters for this cell. This + depends on the resolution of the discretiation in the X direction. + y_length : float + The metalisation width of the grid finger in meters for this cell. This + depends on the resolution of the discretiation in the Y direction. + resistivity_metal : float + The resistivity of the metal in Ohm meter for this cell. + resistivity_contact : float + The resistivity of the metal-semiconductor contact in Ohm meter for + this cell. + """ + self.idx = idx + self.height = metal_height + self.width = x_length + self.length = y_length + self.resistivity_metal = resistivity_metal + self.resistivity_contact = resistivity_contact + self.left = f"NX_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.near = f"NY_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.top = "in" + self.right = f"NX_{self.idx[0]+1}_{self.idx[1]}_{self.idx[2]}" + self.far = f"NY_{self.idx[0]}_{self.idx[1]+1}_{self.idx[2]}" + self.bottom = f"N_{self.idx[0]}_{self.idx[1]}_{self.idx[2]+1}" + self.centre = "in" + self.element = f"{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + + def netlist(self): + """Return the SPICE netlist for this cell. + """ + r_metal = self.resistivity_metal * self.length / (self.height * self.width) + r_contact = self.resistivity_contact / (self.width * self.length) + + return f""" + * BUS + R_METAL_X1_{self.element} {self.left} {self.centre} {r_metal/2} + R_METAL_X2_{self.element} {self.centre} {self.right} {r_metal/2} + R_METAL_Y1_{self.element} {self.near} {self.centre} {r_metal/2} + R_METAL_Y2_{self.element} {self.centre} {self.far} {r_metal/2} + R_METAL_SEMI_Z_{self.element} {self.centre} {self.bottom} {r_contact} + """ + + +class Device: + """Two-diode model of a solar cell. + + The two diode model: + - Current source connected from the bottom to the centre node + - A j01 diode connected from the centre node (anode) to the + bottom node (cathode) + - A j02 diode connected from the centre node (anode) to the + bottom node (cathode) + """ + + def __init__( + self, + idx, + x_length: float, + y_length: float, + jsc: float, + sheet_resistance: float, + relative_illumination_intensity: float = 0.0, + junction_idx : int = 0 + ): + """ + Parameters + ---------- + idx : Tuple + The 3D index of this element in the grid e.g. (1, 2, 3) + x_length : float + The width of this cell. This depends on the resolution of the + discretiation in the X direction. + y_length : float + The height of this cell. This depends on the resolution of the + discretiation in the Y direction. + jsc : float + The short-circuit current density (amps per metre sq.) generated by the solar cell. + sheet_resistance : float + The sheet resistance of the emitter in Ohms / square. + relative_illumination_intensity : float (Default: 0.0) + A number from 0 to 1 describing the intensity of light this node will generate. This + number scales the current generated by the current source. + junction_idx : int (Default: 0) + Needed when constructing a model of a multijunction solar cell. + """ + self.idx = idx + self.x_length = x_length + self.y_length = y_length + self.jsc = jsc + self.sheet_resistance = sheet_resistance + self.relative_illumination_intensity = relative_illumination_intensity + self.junction_idx = int(junction_idx) + + self.left = f"NX_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.near = f"NY_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.top = f"N_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.right = f"NX_{self.idx[0]+1}_{self.idx[1]}_{self.idx[2]}" + self.far = f"NY_{self.idx[0]}_{self.idx[1]+1}_{self.idx[2]}" + self.bottom = f"N_{self.idx[0]}_{self.idx[1]}_{self.idx[2]+1}" + self.centre = f"N_{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + self.element = f"{self.idx[0]}_{self.idx[1]}_{self.idx[2]}" + + + def netlist(self): + # illumination_factor is a number between 0 and 1 to account for the + # intensity of light on this cell. + area = self.x_length * self.y_length + isc = self.jsc * area * self.relative_illumination_intensity + + # The resistances are calculated from the resistivity which + # can be different in the X and Y direction if the cell's + # dimensions are different in those directions + r_sheet_x = self.sheet_resistance * self.y_length / self.x_length + r_sheet_y = self.sheet_resistance * self.x_length / self.y_length + + return f""" + * DEVICE + R_SHEET_X1_{self.element} {self.left} {self.centre} {r_sheet_x/2} + R_SHEET_X2_{self.element} {self.centre} {self.right} {r_sheet_x/2} + R_SHEET_Y1_{self.element} {self.near} {self.centre} {r_sheet_y/2} + R_SHEET_Y2_{self.element} {self.centre} {self.far} {r_sheet_y/2} + D1_{self.element} {self.centre} {self.bottom} __D1_{self.junction_idx} + D2_{self.element} {self.centre} {self.bottom} __D2_{self.junction_idx} + I1_{self.element} {self.bottom} {self.centre} DC {isc} + """ + + +class Base: + """Representation of a base layer. This layer is not distributed. It is + simply a single resistor, only one of these models is needed per solar + cell junction. + """ + def __init__( + self, + idx, + area: float, + base_buffer_specific_contact_resistivity: float + ): + """ + Parameters + ---------- + idx : Tuple + The 3D index of this element in the grid e.g. (1, 2, 3) + area : float + The full surface area of the solar cell. + base_buffer_specific_contact_resistivity : float + The specific contact resistivity (Ohm m2) of the base + buffer layers i.e. + any layer before the rear contact layer. + """ + self.idx = idx + self.area = area + self.base_buffer_specific_contact_resistivity = base_buffer_specific_contact_resistivity + + def netlist(self): + # FIXME: need to include element name so this can stack in MJ cells. + r_base = self.base_buffer_specific_contact_resistivity / self.area # Approx 1 mOhms + k = self.idx[2] + return f""" + * BASE + R_BASE_Z N_0_0_{k} N_0_0_{k+1} {r_base} + """ + + +class RearContact: + """Representation of a rear contact. This layer is not distributed. It is + simply a single resistor, only one of these models is needed per solar + cell junction. + """ + def __init__( + self, + idx, + area: float, + rear_contact_specific_contact_resistivity: float + ): + """ + Parameters + ---------- + idx : Tuple + The 3D index of this element in the grid e.g. (1, 2, 3) + area : float + The full surface area of the solar cell. + rear_contact_specific_contact_resistivity : float + The resistivity (Ohm m) of the rear contact layer. + """ + self.idx = idx + self.area = area + self.rear_contact_specific_contact_resistivity = rear_contact_specific_contact_resistivity + + def netlist(self): + # FIXME: need to include element name so this can stack in MJ cells. + r_rear_contact = self.rear_contact_specific_contact_resistivity / self.area # Approx 1 mOhms + k = self.idx[2] + return f""" + * REAR CONTACT + R_REAR_CONTACT_Z N_0_0_{k} 0 {r_rear_contact} + """ + + diff --git a/solcore/spice/netlist.py b/solcore/spice/netlist.py new file mode 100644 index 00000000..d7ab724e --- /dev/null +++ b/solcore/spice/netlist.py @@ -0,0 +1,374 @@ +import numpy as np +import matplotlib.pyplot as plt +import itertools +from PySpice.Spice.Netlist import Circuit +from solcore.spice.grid import GridPattern +from solcore.spice.model import ( + Header, + Diodes, + Metal, + Bus, + Device, + Base, + RearContact +) +from typing import TYPE_CHECKING, Optional +if TYPE_CHECKING: + pass + + +def generate_netlist( + cell_metalisation_pattern: np.ndarray | GridPattern, + cell_illumination_map: np.ndarray, + cell_size: tuple[float, float], + junctions: list[dict], + metal_height: float = 3e-6, + metal_resistivity: float = 3.5e-8, + metal_semiconductor_specific_contact_resistivity: float = 6.34e-10, + base_buffer_specific_contact_resistivity: float = 1.2e-8, + rear_contact_specific_contact_resistivity: float = 3.5e-6, + temperature: float = 300.0, + show_plots=False +) -> str: + """ + Returns a string that is a SPICE netlist. + + Parameters + ---------- + cell_metalisation_pattern : np.ndarray | GridPattern + A 2D array showing how metalisation is applied to the solar cell, a GridPattern object, + or a Path to an image specified as a string or a pathlib.Path + + The 2D image will be interpretted as followed where "px" is the gray scale value of the pixel: + - Bus bar: px > 0.8 + - Grid finger: 0.2 < px < 0.8 + - No Metal: px < 0.2 + + If the 2D array is read from an image file it will be normalised and values scaled between 0 and 1. + + cell_illumination_map: np.ndarray + A 2D array providing the illumination distribution over the solar cell's surface. + + cell_size : Tuple[float, float] + The tuple gives the edge length in the x and y direction of solar cell. This is used to + calculate the length and width of each pixel in the input image. Units: m + + junction : List[Dict] + A list of dictionaries containing solar cell junction parameters. All keys are required, for example, + + junctions = [ + { + "jsc": 30000, # A / m2 + "emitter_sheet_resistance": 100.0, # Ohm / sq + "j01": 4e-16, # A / m2 + "j02": 2e-7, # A / m2 + "Eg": 1.41, # eV + "n1": 1.0, # dimensionless + "n2": 2.0 # dimensionless + } + ] + + This has been implemented as a list to support multi-junction devices, however, that is not yet + working. + + metal_height : float + The height of the bus bar and the grid fingers. Units: m + + metal_resistivity : float + The resisitivity of the metal used to form the bus bar and grid fingers. Units: Ohm m + + metal_semiconductor_specific_contact_resistivity : float + The specific contact resisitivty of the metal-semiconductor layer. Units: Ohm m2 + + base_buffer_specific_contact_resistivity : float + The specific contact resisitivty of the base and buffer layers. Units: Ohm m2 + + rear_contact_specific_contact_resistivity : float + The specific contact resisitivty of the rear contact layer. Units: Ohm m2 + + temperature : float + The temperature of the solar cell. Unit: K + + show_plots : bool + Plot some of the input data, this is useful for debugging the metalisation and illumination images. + + Discussion + ---------- + + The net list is intended to be run using PySpice Circuit objects; for this reason, the `.DC` command + is not included, nor is the `.end` statement. When PySpice runs, it will append these to the net + list. To run the net list in an external simulator, simply append the two lines. + + .DC vin -0.1 1.4 0.1 + .end + + The first line is the `.DC` command that tells SPICE to sweep the voltage; in this example, the + voltage starts at -0.1 and ends at 1.4 in steps of 0.1 volts. The second line is a command that + tells SPICE it has reached the end of the netlist. + """ + + # Check we have all the information we need to continue + must_haves = [ + "jsc", + "emitter_sheet_resistance", + "j01", + "j02", + "Eg", + "n1", + "n2" + ] + try: + for junction in junctions: + for key in must_haves: + junction[key] + except KeyError: + raise KeyError(f"Do all your junction dictionaries have the required keys? The key '{key}' is missing.") + + if isinstance(cell_metalisation_pattern, GridPattern): + cell_metalisation_pattern = cell_metalisation_pattern.as_array() + + if not (cell_metalisation_pattern.shape == cell_illumination_map.shape): + raise ValueError(f"The metalisation mask {cell_metalisation_pattern.shape} and cell illumination map {cell_illumination_map.shape} need to have the same size.") + + # The first layer of the solar cell contain SPICE model for the metalisation + layers, generation_map = _create_grid_layer( + cell_metalisation_pattern=cell_metalisation_pattern, + cell_illumination_map=cell_illumination_map, + cell_size=cell_size, + metal_height=metal_height, + metal_resistivity=metal_resistivity, + metal_semiconductor_specific_contact_resistivity=metal_semiconductor_specific_contact_resistivity, + show_plots=show_plots + ) + X, Y = layers.shape[:2] + unit_x = cell_size[0] / X + unit_y = cell_size[1] / Y + + # For each junction create a layer containing a SPICE model of the PV cell. + # This model defines diodes we also need to save the associated + # header information. + headers = [Header(temperature=temperature)] + for junction in junctions: + # Twiddle the dict around a bit so we can call the function below easily + junction.update({"generation_map": generation_map}) + jsc = junction.pop("jsc") + layers, header_info = _update_layers_with_junction_model(layers, cell_size, jsc, **junction) + headers.append(header_info) + + # TODO: is this part sensible? Maybe we should treat the Base model as a sheet? + # Add a buffer layer SPICE model. Note that this is not a distributed model, + # it is just a single resistor that connects from N_0_0_z to N_0_0_z+1, where z + # is the index of base layer. + layers = np.dstack((layers, np.array([None] * X * Y).reshape((X, Y, 1)))) + idx = (0, 0, layers.shape[2] - 1) + layers[idx] = Base( + idx, + area=cell_size[0] * cell_size[1], + base_buffer_specific_contact_resistivity=base_buffer_specific_contact_resistivity + ) + + # Add a rear contact layer SPICE model. Note that this is not a distributed model, + # it is just a single resistor that connects to the N_0_0_z node, where z + # is the index of the rear contact layer. + layers = np.dstack((layers, np.array([None] * X * Y).reshape((X, Y, 1)))) + idx = (0, 0, layers.shape[2] - 1) + layers[0, 0, -1] = RearContact(idx, cell_size[0] * cell_size[1], rear_contact_specific_contact_resistivity=rear_contact_specific_contact_resistivity) + + # Convert the model objects to a net list string + netlist = [info.netlist() for info in headers] + X, Y, Z = layers.shape + for (k, i, j) in itertools.product(range(Z), range(X), range(Y)): + idx = (i, j, k) + if layers[idx]: + netlist.append(layers[idx].netlist()) + + # netlist is list of strings, let's convert that into a single string so we can + # throw it into SPICE + netlist = "".join(netlist) + return netlist + + +def solve_netlist(net: str, temperature: float, Vstart: float, Vstop: float, Vstep : float): + celsius = temperature - 273.15 + from solcore.spice.spice import spice as SpiceConfig + + with open("grid.net", "w") as f: + f.write(net) + + cir = Circuit(net) + simulator = cir.simulator(temperature=celsius, nominal_temperature=celsius, spice_command=SpiceConfig.engine) + return simulator.dc(vin=slice(Vstart, Vstop, Vstep)) + + +# +# Helper function private to this module +# + + +def _create_grid_layer( + cell_metalisation_pattern: np.ndarray | GridPattern, # the cells that are grid fingers + cell_illumination_map: np.ndarray, + cell_size: tuple[float, float], # cell_size = (x_distance, y_distance), the edge lengths of the solar cell, assumes rectangular shape. + metal_height: float = 3e-6, # Height: m, of grid fingers + metal_resistivity: float = 3.5e-6, # Resistivity: Ohm m, of the metal used for front contacts + metal_semiconductor_specific_contact_resistivity: float = 6.34e-6, # Specific contact resistivity: Ohm m2, of metal-semiconductor layer + show_plots=False +): + """Internal function that returns SPICE objects from cell and grid information. + + Parameters + ---------- + cell_metalisation_pattern : np.ndarray | GridPattern + A 2D array or a GridPattern object showing how metalisation is applied to the solar cell. + + The 2D image will be interpretted as followed where "px" is the gray scale value of the pixel: + - Bus bar: px > 0.8 + - Grid finger: 0.2 < px < 0.8 + - No Metal: px < 0.2 + + cell_illumination_map: np.ndarray + A 2D array showing the illumination distribution over the solar cell's surface. + + cell_size : Tuple[float, float] + The tuple gives the edge length in the x and y direction of solar cell. This is used to + calculate the length and width of each pixel in the input image. Units: m + + metal_height : float + The height of the bus bar and the grid fingers. Units: m + + metal_resistivity : float + The resisitivity of the metal used to form the bus bar and grid fingers. Units: Ohm m + + metal_semiconductor_specific_contact_resistivity : float + The specific contact resisitivty of the metal-semiconductor layer. Units: Ohm m2 + + show_plots : bool + Plot some of the input data, this is useful for debugging the metalisation and illumination images. + """ + if isinstance(cell_metalisation_pattern, GridPattern): + cell_metalisation_pattern = cell_metalisation_pattern.as_array() + + if not (cell_metalisation_pattern.shape == cell_illumination_map.shape): + raise ValueError(f"The metalisation mask {cell_metalisation_pattern.shape} and cell illumination map {cell_illumination_map.shape} need to have the same size.") + + # The image of the metalisation can be broken down into three distinct parts: + # 1. The bus + # 2. The grid fingers + # 3. The device (i.e. the area without any metal) + # The metalisation map is a gray scale image, any region that is above 90% + # white is mapped to the bus, any region less that 10% white is mapped + # as the device and region between 40% and 60% is mapped to the grid fingers. + norm_metalisation_map = cell_metalisation_pattern / cell_metalisation_pattern.max() + is_bus = np.where(norm_metalisation_map > 0.8, 1, 0) + is_finger = np.where((norm_metalisation_map > 0.20)&(norm_metalisation_map < 0.80), 1, 0) + is_not_metal = np.where(norm_metalisation_map < 0.2, 1, 0) + + if show_plots: + + # These plots show how the image has been processed. If the metalisation + # is not behaving then this should show you where things are going wrong. + fig, ax = plt.subplots(2, 2) + + ax[0, 0].matshow(norm_metalisation_map, cmap="gray") + ax[0, 0].set_title("Grid Image") + + ax[0, 1].matshow(is_bus, cmap="gray") + ax[0, 1].set_title("Bus bar only") + + ax[1, 0].matshow(is_finger, cmap="gray") + ax[1, 0].set_title("Grid fingers only") + + ax[1, 1].matshow(is_not_metal, cmap="gray") + ax[1, 1].set_title("Solar cell only") + + fig.tight_layout() + plt.show() + + # Create a 3D matrix to hold each cell: + # - Cells with indices [:,:,0] are Metal or Bus objects + # - Cells with indices [:,:,1] are semiconductor device cells + X, Y = cell_illumination_map.shape + xscale, yscale = cell_size + unit_width = xscale / X # the width of each spice cell + unit_length = yscale / Y # the length of each spice cell + grid = np.array([None] * X * Y).reshape(X, Y, 1) + + for idx in itertools.product(range(X), range(Y), [0]): + i, j, k = idx + # Layer #0 + if is_bus[i, j]: + grid[i, j, k] = Bus(idx, metal_height, unit_width, unit_length, metal_resistivity, metal_semiconductor_specific_contact_resistivity) + elif is_finger[i, j]: + grid[i, j, k] = Metal(idx, metal_height, unit_width, unit_length, metal_resistivity, metal_semiconductor_specific_contact_resistivity) + + # Make a "generation map", this does not correspond to the illumiation map + # because of shading by the metalisation cells. Here we assume that any + # metalisation reduces the generation in that cell to zero. + has_generation = np.where(~np.where((is_bus | is_finger), True, False), 1, 0) + generation_map = has_generation * cell_illumination_map + + if show_plots: + fig, (ax1, ax2) = plt.subplots(ncols=2) + ax1.matshow(cell_illumination_map, vmin=0.0, vmax=1.0) + ax1.set_title("Illumination map") + + p2 = ax2.matshow(generation_map, vmin=0.0, vmax=1.0) + ax2.set_title("Generation map") + + fig.subplots_adjust(right=0.8) + cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7]) + fig.colorbar(p2, cax=cbar_ax) + plt.show() + + return grid, generation_map + + +def _update_layers_with_junction_model( + layers: np.ndarray, + cell_size: tuple[float, float], + jsc: float, # Jsc: A / m2, short-circuit current generated by the solar cell (convention: positive) + emitter_sheet_resistance: float = 100, # The emitter sheet resistance + j01: float = 4.0e-20, + j02: float = 2e-11, + Eg: float = 1.41, + n1: float = 1.0, + n2: float = 2.0, + generation_map: Optional[np.ndarray] = None +): + """Internal function that appends solar cell SPICE objects to the layer structure. + """ + X, Y, Z = layers.shape + xscale, yscale = cell_size + unit_width = xscale / X # the width of each spice cell + unit_length = yscale / Y # the length of each spice cell + area = unit_length * unit_width + + def get_relative_illumination_intensity(i, j): + if generation_map is not None: + return generation_map[i, j] + return 0.0 + + # 0 if this is the first device layer, + # 1 is this is the second device layer etc. + junction_idx = len([isinstance(x, Device) for x in layers[0,0,:] if isinstance(x, Device)]) + layers = np.dstack((layers, np.array([None] * X * Y).reshape((X, Y, 1)))) + X, Y, Z = layers.shape + k = Z - 1 + # NOTE: the device layer at the edge should be a different type, but it not yet implemented. + + for idx in itertools.product(range(X), range(Y), [k]): + layers[idx] = Device( + idx, + unit_width, + unit_length, + jsc, + emitter_sheet_resistance, + relative_illumination_intensity=get_relative_illumination_intensity(*idx[:2]), + junction_idx=junction_idx + ) + layers[idx].bottom = f"N_0_0_{idx[2]+1}" + + # Create diode model that need to appear in the SPICE header + header = Diodes(Eg, j01, j02, area, n1=n1, n2=n2, junction_idx=junction_idx) + return layers, header + diff --git a/solcore/spice/result.py b/solcore/spice/result.py new file mode 100644 index 00000000..ae068715 --- /dev/null +++ b/solcore/spice/result.py @@ -0,0 +1,289 @@ +"""Functions to extract useful results from the SPICE simulation data. +""" + + +import numpy as np +from numpy import ndarray +import matplotlib.pyplot as plt +import itertools +from pathlib import Path +from typing import TYPE_CHECKING, Optional, Union +from PySpice.Probe.WaveForm import DcAnalysis + + +def get_characterisic_curve(result: DcAnalysis) -> tuple[ndarray, ndarray]: + """Return the solar cells IV curve from the PySpice object. + + Parameters + ---------- + result : DcAnalysis + A PySpice analysis object containg solution of the net. + + Returns + ------- + tuple : (ndarray, ndarray) + A tuple like (voltage, current). + """ + voltage = result.sweep.as_ndarray() + current = result["vin"].as_ndarray() + return (voltage, current) + + +def get_maximum_power_point(result: DcAnalysis) -> tuple[float, float, int]: + """ + Parameters + ---------- + result : DcAnalysis + A PySpice analysis object containg solution of the net. + + Returns + ------- + tuple : (float, float, int) + A tuple like (vmax, pmax, maxidx), where: + - vmax is the voltage at maximum power (units: V) + - pmax is the maximum power (units: W) + - maxidx is the index in the characterisic curve + corresponding to the maximum power point. + """ + v, i = get_characterisic_curve(result) + p = v * i + idx = np.argmax(p) + vmax = v[idx] + return vmax, p[idx], idx + + +def get_electroluminescence(voltage: ndarray, is_metal=Optional[ndarray], temperature=300.0) -> ndarray: + """Returns voltage scaled by the Boltzmann approximation so they return values proportional to emission intensity. + + Parameters + ---------- + voltage : ndarray + Should be a 2D array containing layer voltages. For example, + + voltages = get_node_voltages(result) + vmax, pmax, maxidx = get_maximum_power_point(result) + layer_idx = 1 + voltage = voltages[:, :, layer_index, maxidx] + get_electroluminescence(voltage) + + Here the second layer is selected which is the voltage between the surface + of the solar cell to ground. + + is_metal : ndarray (Optional, Default = None) + An optional array that is used to mask the prediced electroluminesence. + + Moreover, metalisation blocks the EL, use this array + to tell the function where the metal is location so that it can + reduce the EL to zero in those regions. + + temperature : float (Optiona, Default = 300.0) + The temperature of the solar cell in Kelvins. + + Returns + ------- + el : ndarray + An array the same shape as the input with values proportional to photon flux. + """ + q = 1.6e-19 + k = 1.3e-23 + el = np.exp( q * voltage / (k * temperature) ) + if is_metal is not None: + el[is_metal] = 0.0 + return el + + +def get_node_voltages(result: DcAnalysis, empty=float("nan")): + """A 3+1 dimensional array of voltage. + + Parameters + ---------- + result : DcAnalysis + A PySpice analysis object containg solution of the net. + + empty : float + The value to use for nodes that do not have a corresponding model. This + occurs in the Base and Rear Contact layers because layers contain a + single object for the whole layer. + + Returns + ------- + voltages : ndarray + Dimensions are as follows: + + X, Y, Z, N = voltages.shape + + Where X, Y, Z are dimensions of the 3D discretisation and N + is the number of voltage steps used in the DC sweep. + + For exmaple, say voltage index 10 corresponding the maximum + power point index, then to get all voltages of the metal layer, + + voltages[:, :, 0, 10] + + to get all voltages of the emitter layer, + + voltages[:, :, 1, 10] + """ + node_names = result.nodes.keys() + node_names = [x for x in node_names if x.startswith("n")] # node labels only, not voltage source etc. + + # Get the grid size from the result, we could pass this in, but it easy to determine + xidxs, yidxs, zidxs = set(), set(), set() + for key in node_names: + x, y, z = key.split("_")[1:] + xidxs.add(int(x)) + yidxs.add(int(y)) + zidxs.add(int(z)) + + # The number of nodes in each dimension + X, Y, Z = max(xidxs), max(yidxs), max(zidxs) + + # Empty array with the size we need, this will contain a voltage + # at the node coordinate, we can return this so that user can + # plot voltage distribution and EL simuations + bias_voltages = result.sweep.as_ndarray() + N = bias_voltages.size + voltages = np.array([empty] * X * Y * Z * N).reshape((X, Y, Z, N)) + + # Use the cartesian product to flatten this nested loop - a bit nicer to read + for i, j, k in itertools.product(range(X), range(Y), range(Z)): + node_name = f"n_{i}_{j}_{k}" + if node_name in result.nodes.keys(): + voltages[i, j, k, :] = result[node_name].as_ndarray() + elif k==0 and "in" in result.nodes.keys(): + voltages[i, j, k, :] = result["in"].as_ndarray() + + return voltages + + +def plot_characteristic_curve(V, I, show=True, path : None | str | Path = None): + """Plot the characteristic curve + + Parameters + ---------- + V : ndarray + Voltage values + I : ndarray + Current values + show : bool (Default: True) + Immediately render the plot using `plt.show()`. + path : Optional, str, Path + Saved plot image to location and file type given, will skip calling `plot.show()`. + """ + plt.plot(V, I, label="IV curve") + plt.xlabel("Bias (V)") + plt.ylabel("Current (A)") + plt.ylim(ymin=0, ymax=np.max(I)*1.1) + plt.grid(ls="dotted") + + if show: + plt.show() + return + + if path is not None: + plt.savefig(path) + + +def plot_surface_voltages(voltages, bias_index, show=True, path=None): + """Plots the voltage distribution across the surface of the solar cell. + + Parameters + ---------- + voltages : numpy.ndarray + 4D array of voltages returned from `get_node_voltages`. Dimensions are: + 1. X position index + 2. Y position index + 3. Z layer index + 4. Bias voltage index + bias_index : int + The index corresponding to the bias voltage to plot. Usually + this is the voltage at the maximum power point returned from + `get_maximum_power_point`. + show : bool (Default: True) + Immediately render the plot using `plt.show()`. + path : Optional, str, Path + Saved plot image to location and file type given, will skip calling `plot.show()`. + """ + + fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(11, 5)) + cx1 = ax1.matshow(voltages[:, :, 0, bias_index], cmap="inferno") + ax1.set_title("Metal Layer Voltages") + fig.colorbar(cx1) + + cx2 = ax2.matshow(voltages[:, :, 1, bias_index], cmap="inferno") + ax2.set_title("Emitter Layer Voltages") + fig.colorbar(cx2) + + if show: + plt.show() + return + + if path is not None: + plt.savefig(path) + + +def plot_surface_voltages_shared_colormap(voltages, index, show=True, path=None): + """Plots the voltage distribution across the surface of the solar cell with a single color bar. + + Parameters + ---------- + voltages : numpy.ndarray + 4D array of voltages returned from `get_node_voltages`. Dimensions are: + 1. X position index + 2. Y position index + 3. Z layer index + 4. Bias voltage index + bias_index : int + The index corresponding to the bias voltage to plot. Usually + this is the voltage at the maximum power point returned from + `get_maximum_power_point`. + show : bool (Default: True) + Immediately render the plot using `plt.show()`. + path : Optional, str, Path + Saved plot image to location and file type given, will skip calling `plot.show()`. + """ + + vmin, vmax = np.nanmin(voltages[:, :, :2, index]), np.nanmax(voltages[:, :, :2, index]) + fig, axes = plt.subplots(ncols=2, figsize=(11, 5)) + for layer_idx, ax in enumerate(axes.flat): + im = ax.matshow(voltages[:, :, layer_idx, index], vmin=vmin, vmax=vmax, cmap="inferno") + if layer_idx == 0: + ax.set_title("Metal Layer Voltages") + else: + ax.set_title("Emitter Layer Voltages") + + fig.subplots_adjust(right=0.8) + cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7]) + fig.colorbar(im, cax=cbar_ax) + + if show: + plt.show() + return + + if path is not None: + plt.savefig(path) + + +def plot_electroluminescence(el, show=True, path=None): + """Plots the voltage distribution across the surface of the solar cell. + + Parameters + ---------- + el : numpy.ndarray + 2D array of EL intensity returned from `get_electroluminescence` + show : bool (Default: True) + Display the plot immediately. + path : bool (Optional) + If `show=False` path can point to a save location for the plot. + """ + + cx1 = plt.matshow(el, cmap="inferno") + plt.title("Predicted Electroluminescene") + plt.colorbar(cx1) + if show: + plt.show() + return + + if path is not None: + plt.savefig(path) + \ No newline at end of file diff --git a/tests/test_spice_grid.py b/tests/test_spice_grid.py new file mode 100644 index 00000000..f180048d --- /dev/null +++ b/tests/test_spice_grid.py @@ -0,0 +1,200 @@ +from solcore.spice.model import Header, Diodes, Metal, Bus, Device, Base, RearContact + + +def test_model_header(): + """Test Header class contains correct netlist values + """ + # Test parameter maps to the netlist + model = Header(temperature=100.0) + net = model.netlist() + degC = f"{100 - 273.15}" + assert degC in net + + # Test default value maps to netlist + model = Header() + net = model.netlist() + degC = f"{300 - 273.15}" + assert degC in net + + +def test_model_diodes(): + """Test Diodes class init + """ + model = Diodes(Eg=1.4, j01=1.0, j02=1.0, area=1.0) + net = model.netlist() + assert "D1" in net + assert "D2" in net + + +def test_model_metal(): + """Test net labels on the metal class + """ + + # test node labels + idx = i, j, k = (0, 0, 0) + model = Metal(idx, 1.0, 1.0, 1.0, 1.0, 1.0) + assert model.left == f"NX_{i}_{j}_{k}" + assert model.right == f"NX_{i+1}_{j}_{k}" + assert model.near == f"NY_{i}_{j}_{k}" + assert model.near == f"NY_{i}_{j}_{k}" + assert model.top == f"N_{i}_{j}_{k}" + assert model.bottom == f"N_{i}_{j}_{k+1}" + assert model.centre == f"N_{i}_{j}_{0}" + + # test element prefix + assert model.element == "0_0_0" + + +def test_model_bus(): + """Test net labels on the Bus class + """ + + # test node labels + idx = i, j, k = (0, 0, 0) + model = Bus(idx, 1.0, 1.0, 1.0, 1.0, 1.0) + assert model.left == f"NX_{i}_{j}_{k}" + assert model.right == f"NX_{i+1}_{j}_{k}" + assert model.near == f"NY_{i}_{j}_{k}" + assert model.near == f"NY_{i}_{j}_{k}" + assert model.top == f"in" + assert model.bottom == f"N_{i}_{j}_{k+1}" + assert model.centre == f"in" + + # test element prefix + assert model.element == "0_0_0" + + +def test_model_device(): + """Test net labels on the Device class + """ + idx = i, j, k = (0, 0, 0) + model = Device(idx, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0) + assert model.left == f"NX_{i}_{j}_{k}" + assert model.right == f"NX_{i+1}_{j}_{k}" + assert model.near == f"NY_{i}_{j}_{k}" + assert model.near == f"NY_{i}_{j}_{k}" + assert model.top == f"N_0_0_0" + assert model.bottom == f"N_{i}_{j}_{k+1}" + assert model.centre == f"N_0_0_0" + + # test element prefix + assert model.element == "0_0_0" + + +def test_model_base(): + idx = (0, 0, 0) + model = Base(idx, 1.0, 1.0) + # netlist: connections are correct + assert "R_BASE_Z N_0_0_0 N_0_0_1" in model.netlist() + + +def test_model_rearcontact(): + idx = (0, 0, 0) + model = RearContact(idx, 1.0, 1.0) + # netlist: connections are correct + assert "R_REAR_CONTACT_Z N_0_0_0 0" in model.netlist() + +def test_example_calculation(): + import numpy as np + from solcore.structure import Junction + from solcore.solar_cell import SolarCell + from solcore.solar_cell_solver import solar_cell_solver + from solcore.light_source import LightSource + from solcore.spice.grid import HGridPattern + from solcore.spice.netlist import generate_netlist, solve_netlist + from solcore.spice.result import get_maximum_power_point + + temperature = 300.0 + + def get_jsc(concentrationX): + junction_model = Junction( + kind='2D', + T=temperature, + reff=1, + jref=300, + Eg=1.4, + A=1, + R_sheet_top=100, + R_sheet_bot=1e-16, + R_shunt=1e16, + n=3.5 + ) + + solar_cell_model = SolarCell([junction_model], T=temperature) + wl = np.linspace(350, 2000, 301) * 1e-9 + light_source = LightSource( + source_type="standard", + version="AM1.5g", + x=wl, + output_units="photon_flux_per_m", + concentration=concentrationX + ) + + options = { + "light_iv": True, + "wavelength": wl, + "light_source": light_source, + "optics_method": "BL" + } + solar_cell_solver(solar_cell_model, 'iv', user_options=options) + + jsc = solar_cell_model(0).jsc + return jsc + + def get_efficiency(concentrationX, power_in=1000.0): + + bus_px = 3 + fingers_px = [2, 2, 2, 2] + offset_px = 1 + nx, ny = 12, 12 + grid = HGridPattern(bus_px, fingers_px, offset_px=offset_px, nx=nx, ny=ny) + + # Homogeneous illumination + illumination_map = np.ones(nx * ny).reshape((nx, ny)) + + # The size of the solar is 3mm x 3mm + size = (0.003, 0.003) # meters + + # Define a list of properies that describe each junction in the solar cell. + # NB: currently only one junction is working. + junctions = [ + { + "jsc": get_jsc(concentrationX), # solcore is calculating this for us! + "emitter_sheet_resistance": 100.0, + "j01": 4e-16, + "j02": 2e-7, + "Eg": 1.41, + "n1": 1.0, + "n2": 2.0 + } + ] + + temperature = 300.0 + + netlist = generate_netlist( + grid, + illumination_map, + size, + junctions, + temperature=temperature + ) + + result = solve_netlist(netlist, temperature, 0.0, 1.5, 0.01) + + vmax, pmax, maxidx = get_maximum_power_point(result) + + p_per_m2 = pmax / size[0] / size[1] + efficiency = p_per_m2 / (concentrationX * power_in) + return efficiency + + # Get the JSC for 100x concentration + pin = 1000 # W / m2 + jsc = get_jsc(100) + eta = get_efficiency(jsc, power_in=pin) + + # The actually efficiency value is non-sense because the grid is too small + # to make the test run quick! + assert eta > 0.0007 + assert eta < 0.0008 + +