From 5e13df383a19e9c6483bc78a5885a49549cc9877 Mon Sep 17 00:00:00 2001 From: danieljfarrell Date: Mon, 22 Jul 2024 20:37:39 +0100 Subject: [PATCH 1/5] Update to distributed SPICE model simulation We have refactored the netlist generation code to use model objects that generate a netlist. The netlist is solved using PySpice. This removes the need for code in Solcore to kick off a simulation and process the result using text parsing. I have not looked too closely, but parser code is usually quite brittle; changes to the net list can break it. Handing this over to PySpice improves the situation. A result object is passed around to helper functions to generate useful information such as the IV curve, maximum power point, voltages of the different layers, and electroluminescence prediction. The distributed model closely aligns with the methodology of Steiner et al. DOI:10.1002/pip.989, except for the absence of the perimeter recombination diode. This model lacks shunt resistances, but adding them could broaden its application beyond concentrator solar cells. This code is standalone; it uses basic Python types to define the solar cell's junction rather than using Solcore's Junction class. Future changes may want to alter this, but I'm uncertain about the value that Junction offers; it seems to resemble an OrderedDict. Perhaps this would unlock useful integration with other Solcore features. A nice feature of the code is a class for generating grid metalization patterns: GridPattern. This offers a general interface for subclassing, enabling the creation of various grid types. The user needs to implement a function called `draw()` and use the pixie-python drawing API to render the desired grid pattern. A HGridPattern subclass has been implemented here. This class offers some useful functionality, such as being able to save the grid pattern to an image file, which uses pillow (PIL). We have added a sparse example script. We have added a much more detailed Python Notebook file that guides the user through the entire process, from basic simulation to computing a concentration vs. efficiency plot. --- examples/cpv_grid_spice_example.ipynb | 756 ++++++++++++++++++++++++++ examples/cpv_grid_spice_example.py | 72 +++ solcore/spice/grid.py | 142 +++++ solcore/spice/model.py | 372 +++++++++++++ solcore/spice/netlist.py | 383 +++++++++++++ solcore/spice/result.py | 290 ++++++++++ 6 files changed, 2015 insertions(+) create mode 100644 examples/cpv_grid_spice_example.ipynb create mode 100644 examples/cpv_grid_spice_example.py create mode 100644 solcore/spice/grid.py create mode 100644 solcore/spice/model.py create mode 100644 solcore/spice/netlist.py create mode 100644 solcore/spice/result.py diff --git a/examples/cpv_grid_spice_example.ipynb b/examples/cpv_grid_spice_example.ipynb new file mode 100644 index 00000000..13a0152d --- /dev/null +++ b/examples/cpv_grid_spice_example.ipynb @@ -0,0 +1,756 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Grid Simulation of a Concentrator Solar Cell\n", + "\n", + "This example, walksthrough the how to use the classes and function in `solcore.spice` to simulate different grid structures of concentrator solar cell. 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": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAakAAAGhCAYAAADbf0s2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAcSklEQVR4nO3df2yV9fn/8dcppT8Eempreg4drXSOpCjokGItEOfkZBXRwSRumGpQiUwtSiER6bSYoVhkTjuwwjQONQOZJIJKJoYUhRFLgQJO1BWMZDTgOZ1j7QGUgj3v7x+ffE92EOavU851Ds9Hcif0vu9z93pX5Jm7vTl4nHNOAAAYlJboAQAAOBMiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADArYZFqbGzU4MGDlZWVpfLycm3bti1RowAAjEpIpP7yl79o9uzZevjhh7Vz505ddtllqqysVEdHRyLGAQAY5UnEG8yWl5dr1KhRevrppyVJkUhERUVFuvfeezV37tyvfX0kEtGhQ4c0YMAAeTye3h4XABBnzjkdOXJEhYWFSks78/1S+lmcSZJ04sQJtba2qra2NrovLS1NgUBAzc3Np31Nd3e3uru7ox8fPHhQF198ca/PCgDoXe3t7Ro0aNAZj5/1b/d99tln6unpkc/ni9nv8/kUDAZP+5r6+np5vd7oRqAAIDUMGDDgfx5Piqf7amtr1dXVFd3a29sTPRIAIA6+7kc2Z/3bfRdccIH69OmjUCgUsz8UCsnv95/2NZmZmcrMzDwb4wEADDnrd1IZGRkaOXKkmpqaovsikYiamppUUVFxtscBABh21u+kJGn27NmaOnWqysrKdMUVV6ihoUHHjh3T7bffnohxAABGJSRSv/rVr/Svf/1L8+bNUzAY1I9//GOtX7/+Kw9TAADObQn5e1LfVzgcltfrTfQYAIDvqaurSzk5OWc8npA7qbMlCfsLACkhXm+0kBSPoAMAzk1ECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYFZ6ogfoTR6Pp9c/x1VXXXXa/Zs3b+71z51IqbzuVF7b/5LK607ltf0vqbBu7qQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgVtwjVV9fr1GjRmnAgAEqKCjQpEmT1NbWFnPO8ePHVV1drfz8fPXv31+TJ09WKBSK9ygAgCQX90ht2rRJ1dXV2rp1qzZs2KCTJ0/qZz/7mY4dOxY9Z9asWXrjjTe0evVqbdq0SYcOHdKNN94Y71EAAEkuPd4XXL9+fczHL7zwggoKCtTa2qqrrrpKXV1dev7557Vy5Updc801kqTly5dr6NCh2rp1q6688sp4jwQASFK9/jOprq4uSVJeXp4kqbW1VSdPnlQgEIieU1paquLiYjU3N5/2Gt3d3QqHwzEbACD19WqkIpGIampqNGbMGA0bNkySFAwGlZGRodzc3JhzfT6fgsHgaa9TX18vr9cb3YqKinpzbACAEb0aqerqau3Zs0erVq36Xtepra1VV1dXdGtvb4/ThAAAy+L+M6n/b8aMGVq3bp02b96sQYMGRff7/X6dOHFCnZ2dMXdToVBIfr//tNfKzMxUZmZmb40KADAq7ndSzjnNmDFDa9as0caNG1VSUhJzfOTIkerbt6+ampqi+9ra2nTgwAFVVFTEexwAQBKL+51UdXW1Vq5cqddee00DBgyI/pzJ6/UqOztbXq9X06ZN0+zZs5WXl6ecnBzde++9qqio4Mk+AECMuEdq6dKlkqSrr746Zv/y5ct12223SZKeeuoppaWlafLkyeru7lZlZaWeeeaZeI8CAEhycY+Uc+5rz8nKylJjY6MaGxvj/ekBACmE9+4DAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZvV6pBYuXCiPx6OamprovuPHj6u6ulr5+fnq37+/Jk+erFAo1NujAACSTK9Gavv27frjH/+oSy+9NGb/rFmz9MYbb2j16tXatGmTDh06pBtvvLE3RwEAJKFei9TRo0dVVVWl5557Tueff350f1dXl55//nk9+eSTuuaaazRy5EgtX75c7777rrZu3dpb4wAAklCvRaq6uloTJkxQIBCI2d/a2qqTJ0/G7C8tLVVxcbGam5tPe63u7m6Fw+GYDQCQ+tJ746KrVq3Szp07tX379q8cCwaDysjIUG5ubsx+n8+nYDB42uvV19frt7/9bW+MCgAwLO53Uu3t7Zo5c6ZWrFihrKysuFyztrZWXV1d0a29vT0u1wUA2Bb3SLW2tqqjo0OXX3650tPTlZ6erk2bNmnx4sVKT0+Xz+fTiRMn1NnZGfO6UCgkv99/2mtmZmYqJycnZgMApL64f7tv3Lhxev/992P23X777SotLdUDDzygoqIi9e3bV01NTZo8ebIkqa2tTQcOHFBFRUW8xwEAJLG4R2rAgAEaNmxYzL5+/fopPz8/un/atGmaPXu28vLylJOTo3vvvVcVFRW68sor4z0OACCJ9cqDE1/nqaeeUlpamiZPnqzu7m5VVlbqmWeeScQoAADDzkqk3nnnnZiPs7Ky1NjYqMbGxrPx6QEASYr37gMAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYBaRAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFm9EqmDBw/qlltuUX5+vrKzszV8+HDt2LEjetw5p3nz5mngwIHKzs5WIBDQvn37emMUAEASi3uk/vOf/2jMmDHq27ev3nzzTX344Yf6/e9/r/PPPz96zqJFi7R48WItW7ZMLS0t6tevnyorK3X8+PF4jwMASGLp8b7g448/rqKiIi1fvjy6r6SkJPpr55waGhr00EMPaeLEiZKkl156ST6fT2vXrtWUKVPiPRIAIEnF/U7q9ddfV1lZmW666SYVFBRoxIgReu6556LH9+/fr2AwqEAgEN3n9XpVXl6u5ubm016zu7tb4XA4ZgMApL64R+qTTz7R0qVLNWTIEL311lu6++67dd999+nFF1+UJAWDQUmSz+eLeZ3P54seO1V9fb28Xm90KyoqivfYAACD4h6pSCSiyy+/XI899phGjBih6dOn684779SyZcu+8zVra2vV1dUV3drb2+M4MQDAqrhHauDAgbr44otj9g0dOlQHDhyQJPn9fklSKBSKOScUCkWPnSozM1M5OTkxGwAg9cU9UmPGjFFbW1vMvr179+rCCy+U9H8PUfj9fjU1NUWPh8NhtbS0qKKiIt7jAACSWNyf7ps1a5ZGjx6txx57TL/85S+1bds2Pfvss3r22WclSR6PRzU1NXr00Uc1ZMgQlZSUqK6uToWFhZo0aVK8xwEAJLG4R2rUqFFas2aNamtrNX/+fJWUlKihoUFVVVXRc+bMmaNjx45p+vTp6uzs1NixY7V+/XplZWXFexwAQBKLe6Qk6frrr9f1119/xuMej0fz58/X/Pnze+PTAwBSBO/dBwAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMyKe6R6enpUV1enkpISZWdn66KLLtIjjzwi51z0HOec5s2bp4EDByo7O1uBQED79u2L9ygAgCQX90g9/vjjWrp0qZ5++ml99NFHevzxx7Vo0SItWbIkes6iRYu0ePFiLVu2TC0tLerXr58qKyt1/PjxeI8DAEhi6fG+4LvvvquJEydqwoQJkqTBgwfr5Zdf1rZt2yT9311UQ0ODHnroIU2cOFGS9NJLL8nn82nt2rWaMmVKvEcCACSpuN9JjR49Wk1NTdq7d68k6b333tOWLVs0fvx4SdL+/fsVDAYVCASir/F6vSovL1dzc3O8xwEAJLG430nNnTtX4XBYpaWl6tOnj3p6erRgwQJVVVVJkoLBoCTJ5/PFvM7n80WPnaq7u1vd3d3Rj8PhcLzHBgAYFPc7qVdeeUUrVqzQypUrtXPnTr344ot64okn9OKLL37na9bX18vr9Ua3oqKiOE4MALAq7pG6//77NXfuXE2ZMkXDhw/XrbfeqlmzZqm+vl6S5Pf7JUmhUCjmdaFQKHrsVLW1terq6opu7e3t8R4bAGBQ3CP1+eefKy0t9rJ9+vRRJBKRJJWUlMjv96upqSl6PBwOq6WlRRUVFae9ZmZmpnJycmI2AEDqi/vPpG644QYtWLBAxcXFuuSSS7Rr1y49+eSTuuOOOyRJHo9HNTU1evTRRzVkyBCVlJSorq5OhYWFmjRpUrzHAQAksbhHasmSJaqrq9M999yjjo4OFRYW6te//rXmzZsXPWfOnDk6duyYpk+frs7OTo0dO1br169XVlZWvMcBACSxuEdqwIABamhoUENDwxnP8Xg8mj9/vubPnx/vTw8ASCG8dx8AwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMz61pHavHmzbrjhBhUWFsrj8Wjt2rUxx51zmjdvngYOHKjs7GwFAgHt27cv5pzDhw+rqqpKOTk5ys3N1bRp03T06NHvtRAAQOr51pE6duyYLrvsMjU2Np72+KJFi7R48WItW7ZMLS0t6tevnyorK3X8+PHoOVVVVfrggw+0YcMGrVu3Tps3b9b06dO/+yoAACkp/du+YPz48Ro/fvxpjznn1NDQoIceekgTJ06UJL300kvy+Xxau3atpkyZoo8++kjr16/X9u3bVVZWJklasmSJrrvuOj3xxBMqLCz8HssBAKSSuP5Mav/+/QoGgwoEAtF9Xq9X5eXlam5uliQ1NzcrNzc3GihJCgQCSktLU0tLy2mv293drXA4HLMBAFJfXCMVDAYlST6fL2a/z+eLHgsGgyooKIg5np6erry8vOg5p6qvr5fX641uRUVF8RwbAGBUUjzdV1tbq66urujW3t6e6JEAAGdBXCPl9/slSaFQKGZ/KBSKHvP7/ero6Ig5/uWXX+rw4cPRc06VmZmpnJycmA0AkPriGqmSkhL5/X41NTVF94XDYbW0tKiiokKSVFFRoc7OTrW2tkbP2bhxoyKRiMrLy+M5DgAgyX3rp/uOHj2qjz/+OPrx/v37tXv3buXl5am4uFg1NTV69NFHNWTIEJWUlKiurk6FhYWaNGmSJGno0KG69tprdeedd2rZsmU6efKkZsyYoSlTpvBkHwAgxreO1I4dO/TTn/40+vHs2bMlSVOnTtULL7ygOXPm6NixY5o+fbo6Ozs1duxYrV+/XllZWdHXrFixQjNmzNC4ceOUlpamyZMna/HixXFYDgAglXzrSF199dVyzp3xuMfj0fz58zV//vwznpOXl6eVK1d+208NADjHJMXTfQCAcxORAgCYRaQAAGYRKQCAWUQKAGAWkQIAmEWkAABmESkAgFlECgBgFpECAJhFpAAAZhEpAIBZRAoAYNa3fhf0ZPK/3q0dANB7PB5PXK7DnRQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMItIAQDMIlIAALOIFADALCIFADCLSAEAzCJSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMCs90QP0Jo/Hk+gRAADfA3dSAACziBQAwCwiBQAwi0gBAMwiUgAAs4gUAMAsIgUAMCspI+WcS/QIAIA4+Lo/z5MyUkeOHEn0CACAOPi6P889LglvSyKRiA4dOiTnnIqLi9Xe3q6cnJxEj3VWhMNhFRUVnVNrls7NdZ+La5ZY97mybuecjhw5osLCQqWlnfl+KSnfFiktLU2DBg1SOByWJOXk5JwT/1H/27m4ZuncXPe5uGaJdZ8LvF7v156TlN/uAwCcG4gUAMCspI5UZmamHn74YWVmZiZ6lLPmXFyzdG6u+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 is 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": 6, + "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": 6, + "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": 7, + "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": 12, + "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 have specific meaning to the solcore:\n", + "\n", + "* White is a bus bar\n", + "* Gray is a grid finger (50%)\n", + "* Black is an absence of any metal\n", + "\n", + "In code to follow, we will be sweeping out an IV curve for this solar cell. The distinction between bus bar and 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", + "A netlist describes the elements and connections between them in the SPICE simulation. We are going to use the helper function to generate this netlist for us given some high-level input parameters that describe our 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, the same size and grid image, that contains relative intensity of illumination across the surface of the solar cell. A value of 1 means the intensity is at maximum value, and value of zero means no illumination intensity at all. Moreover, to simulate entirely uniform illumination we just need to create an array of ones.\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 width (x-direction) and length (y-direction) of 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 list of Python dictionaries containing information about each junciton 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 generate 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 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 a shunt resistance is not currently included in this modelling because it is aimed a concentrator solar cells and so large as to be ignoreable.\n", + "\n", + "Let's actually generate the netlist." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "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 seet the netlist is just a string. The detail of the netlist are not important for this tutorial, so we will move on.\n", + "\n", + "# Solve the netlist\n", + "\n", + "SPICE must digest the netlist and solve it. The result is voltages at all nodes and current through all elements. We need to specific a voltage range and step size when calling the solver function. Note, depending on the size of the netlist this could take varying amount of time to solve. At the time of writing this take about a minute on a modern laptop." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "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 helper function to get the information we want, these can be found in the module `solcore.spice.result`. Let's import the functions to help get and plot the IV curve." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## IV Curve" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "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": 27, + "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. \n", + "\n", + "`maxidx` is the index in bias voltage array the corresponds to the maximum power points. For example," + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 28, + "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": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(120, 120, 3, 161)" + ] + }, + "execution_count": 34, + "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, z location in the discretisation 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 layer.\n", + "\n", + "The helper function plots both the metal and the pv layer voltages." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": 35, + "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 emitter by the solar cells using the following helper functions," + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "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": [ + "# 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": 42, + "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": 42, + "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": [ + "Make a second function that wraps the SPICE model and returns efficiency of the device. Inside this function it calls solcore to estimate the JSC." + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "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": 49, + "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/solcore/spice/grid.py b/solcore/spice/grid.py new file mode 100644 index 00000000..c624e7ee --- /dev/null +++ b/solcore/spice/grid.py @@ -0,0 +1,142 @@ +"""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. + + This class just defines an inteface and should be instantiated direclty, instead, + subclass this class and implement the `draw` method to render a grid pattern. + + Discussion + ---------- + Three grayscale pixel values should be used when drawing the solar cell metalisation: + - black (0.0), represents no metalisation + - grey (0.5), represents grid fingers + - white (1.0), represents 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..3afb0bfc --- /dev/null +++ b/solcore/spice/model.py @@ -0,0 +1,372 @@ +"""Classes that aid in the construction of a distributed SPICE model +of a solar cell. Think of these building blocks like sub-circuits that can be composed +together in a 3D structure to build the solar cell structure. +""" + + +class Header: + """A class representing header information for the SPICE file""" + + 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. + + There is really no difference between the the Metal and Bus classes, + other than, by definition, the bus bar is connected to the voltage + source that sweeps the solar cell's bias. + """ + + 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. + + Discussion + ---------- + From Ref. [1] height is 3e-6 metres, width is 9e-6 metres and resistiivty + is 3.5E-6 Ohm meters. + + [1] M. Steiner et al., 10.1002/pip.989 + """ + 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): + 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): + 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..60b468a6 --- /dev/null +++ b/solcore/spice/netlist.py @@ -0,0 +1,383 @@ +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, # 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. + junctions: list[dict], + metal_height: float = 3e-6, # Height: m, of grid fingers + metal_resistivity: float = 3.5e-8, # Resistivity: Ohm m, of the metal used for front contacts + metal_semiconductor_specific_contact_resistivity: float = 6.34e-10, # Specific contact resistivity: Ohm m2, of metal-semiconductor layer + base_buffer_specific_contact_resistivity: float = 1.2e-8, # Specific contact resistivity: Ohm m2, of base-buffer layer + rear_contact_specific_contact_resistivity: float = 3.5e-6, # Specific contact resistivity: Ohm m2, of the rear contact layer + temperature: float = 300.0, + show_plots=False +) -> str: + """ + Returns a string that is a SPICE netlist. + + Parameters + ---------- + cell_metalisation_pattern : np.ndarray | GridPattern | str | pathlib.Path + 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 | str | pathlib.Path + A 2D array or path to an image showing the illumination distribution over the solar cell's surface. + + If the 2D array is read from an image file it will be normalised and values scaled between 0 and 1. + + 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 a PySpice Circuit objects for this reason + a .DC command is not included nor is the .end statement. PySpice will append these + to the net list when it runs. To complete the net list so that is can be run 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 the performs a voltage sweep over a sensible range + for your solar cell, in this example the voltage starts at -0.1, 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 | str | pathlib.Path + 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 | str | pathlib.Path + A 2D array or path to an image showing the illumination distribution over the solar cell's surface. + + If the 2D array is read from an image file it will be normalised and values scaled between 0 and 1. + + 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..b42683b6 --- /dev/null +++ b/solcore/spice/result.py @@ -0,0 +1,290 @@ +"""Functions to extract useful results from the SPICE simulation data. +""" + + +import numpy as np +import matplotlib.pyplot as plt +import itertools +from pathlib import Path +from typing import TYPE_CHECKING, Optional, Union +if TYPE_CHECKING: + from numpy import ndarray + 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 From f355f95f6f6af2a73dffc5a335de239f0ccc595a Mon Sep 17 00:00:00 2001 From: danieljfarrell Date: Tue, 1 Oct 2024 12:06:45 +0100 Subject: [PATCH 2/5] Update documentation of new SPICE module --- docs/source/Quasi3D/EL_Prediction.png | Bin 0 -> 24626 bytes docs/source/Quasi3D/HGridPattern.png | Bin 0 -> 7389 bytes docs/source/Quasi3D/Layer_Voltages.png | Bin 0 -> 50241 bytes docs/source/Quasi3D/quasi3D.rst | 346 ++++++++++++++++++++----- examples/cpv_grid_spice_example.ipynb | 164 +++++++----- pyproject.toml | 3 - solcore/spice/__init__.py | 2 +- solcore/spice/grid.py | 11 +- solcore/spice/model.py | 21 +- solcore/spice/netlist.py | 55 ++-- solcore/spice/result.py | 8 +- 11 files changed, 425 insertions(+), 185 deletions(-) create mode 100644 docs/source/Quasi3D/EL_Prediction.png create mode 100644 docs/source/Quasi3D/HGridPattern.png create mode 100644 docs/source/Quasi3D/Layer_Voltages.png diff --git a/docs/source/Quasi3D/EL_Prediction.png b/docs/source/Quasi3D/EL_Prediction.png new file mode 100644 index 0000000000000000000000000000000000000000..80fd25e093874db705854b55807a20fc2b3b43b7 GIT binary patch literal 24626 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 z zKW;b<9AtKO_QMqoai$jBEp=Hu^dENjcTwJutNE)UmvvzZK(>brOVh@|VgOFa?Y1)% z`fCYr<&Zd0Iy*Z@(RK+{3QKmUytsR=8UYYiqAIgDuaxzTwKAjY=)uPB3Nt*2`3eL4xEX5@?_jT zU{Zz0t6uE|-*t3Ms$s=KR`snbTH`mu+-U<514$kYhu zmT;&&kdnipl5g731N~={l<5mU_2OH!ILk9Fejt`e{5s{}fs=ySw%Sd-`i76qfpZ|B z_pJG06CNJnRA(Uj*SrTxMDqE%(1WQ`8t!WXz9tKGeUGtK$HdrAinHVDH%&d(7t x8!j1K{l&-^L7FbmQZOP2W8XjXFh-zVvvl=U!=Y32@Td{N=op^MKXduce*kAghS&fA literal 0 HcmV?d00001 diff --git a/docs/source/Quasi3D/Layer_Voltages.png b/docs/source/Quasi3D/Layer_Voltages.png new file mode 100644 index 0000000000000000000000000000000000000000..895c1049ea55234b53b70689cdecc91731882115 GIT binary patch literal 50241 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 xS!nE`9wlF$ooh+q4qppJm?gabuRk@u`? literal 0 HcmV?d00001 diff --git a/docs/source/Quasi3D/quasi3D.rst b/docs/source/Quasi3D/quasi3D.rst index 2c698653..a87c1826 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,25 +16,37 @@ 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, + + bus_px = 10 # The width of the bus bar + fingers_px = [4, 4, 4, 4, 4, 4] # the number and width of the grid fingers + offset_px = 3 # the edge offset (metal does not go fully to the edges) + nx, ny = 120, 120 # the size of the image in pixels + size = (0.01, 0.01) # the physical size of the solar cell in metres + grid = HGridPattern(bus_px, fingers_px, offset_px=offset_px, nx=nx, ny=ny) + plt.imshow(grid.as_array(), cmap="gray") + +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, providing an image of 120px x 120px and a size tuple `size = (0.01, 0.01)` (see above) would make each pixel :math:`1cm / 120 \appox 83 micrometers`. Different aspect ratios can be +used to reduce the number of elements and improve speed by specifying a different cell size. + +The above code generates the image, + +.. image:: HGridPattern.png + :align: center + +Currently only `HGridPattern` exists, but other grids can be generated by subclass the `GridPattern` object and implementing the required methods. + +Note that, no electrical or optical difference exists between bus bar and grid finger. The only difference is that bus bar are used in the SPICE model as connections points to the voltage source that is sweept to generate the cells IV curve. Thus bus bars always have the applied voltage where as the voltage of grid fingers is subject to the current flowing through the cell. The minimum total number of nodes where SPICE will need to calculate the voltages will be @@ -45,56 +58,255 @@ 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 cells surface can be include in the simulation using an illimination 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 where each cell has value of 1, thus providing homogeneous illumination across the surface. The intensity of light is specified later, this is why the illumination map contains normalised values (ranging between 1 and 0). 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 of object 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 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. Please review the paper for an understanding how the model function. 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, + + 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 and 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, + + 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() + + +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 index 13a0152d..41c4bc7f 100644 --- a/examples/cpv_grid_spice_example.ipynb +++ b/examples/cpv_grid_spice_example.ipynb @@ -6,7 +6,7 @@ "source": [ "# Grid Simulation of a Concentrator Solar Cell\n", "\n", - "This example, walksthrough the how to use the classes and function in `solcore.spice` to simulate different grid structures of concentrator solar cell. We are going to preproduce some of the figures published by Steiner et al. [1]\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" @@ -23,16 +23,49 @@ }, { "cell_type": "code", - "execution_count": 17, + "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": 17, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" }, @@ -67,7 +100,7 @@ "\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 is specified by an array of pixel widths, this is a required argument. In this case there six finger all of width 4 pixels.\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", @@ -80,7 +113,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -95,7 +128,7 @@ " [0, 0, 0, ..., 0, 0, 0]], dtype=uint8)" ] }, - "execution_count": 6, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -118,7 +151,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -134,7 +167,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -161,13 +194,12 @@ "source": [ "## Colour scheme convention\n", "\n", - "The colors in the image have specific meaning to the solcore:\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 code to follow, we will be sweeping out an IV curve for this solar cell. The distinction between bus bar and grid finger is that former is connect directly to the bias voltage source that is sweep to calculate the characteristic curve." + "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." ] }, { @@ -176,7 +208,7 @@ "source": [ "# Create a netlist\n", "\n", - "A netlist describes the elements and connections between them in the SPICE simulation. We are going to use the helper function to generate this netlist for us given some high-level input parameters that describe our the solar cell.\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", @@ -191,22 +223,22 @@ " )\n", "```\n", "\n", - "We have already seen the first argument `grid` let's take a look at the others.\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, the same size and grid image, that contains relative intensity of illumination across the surface of the solar cell. A value of 1 means the intensity is at maximum value, and value of zero means no illumination intensity at all. Moreover, to simulate entirely uniform illumination we just need to create an array of ones.\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 width (x-direction) and length (y-direction) of solar cell. Here, the solar cell we want to simulate is approximately 3mm by 3mm, therefore,\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 list of Python dictionaries containing information about each junciton in the solar cell,\n", + "Finally, junctions is a list of Python dictionaries containing information about each junction in the solar cell.\n", "\n", "```python\n", " junctions = [\n", @@ -223,22 +255,22 @@ "```\n", "\n", "The parameters are:\n", - " * `jsc`, the short-circuit current generate 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 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", + " - `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 a shunt resistance is not currently included in this modelling because it is aimed a concentrator solar cells and so large as to be ignoreable.\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": 24, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -305,16 +337,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "As you can seet the netlist is just a string. The detail of the netlist are not important for this tutorial, so we will move on.\n", + "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 the netlist and solve it. The result is voltages at all nodes and current through all elements. We need to specific a voltage range and step size when calling the solver function. Note, depending on the size of the netlist this could take varying amount of time to solve. At the time of writing this take about a minute on a modern laptop." + "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": 25, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -331,14 +363,9 @@ "source": [ "# Getting useful data from the result object\n", "\n", - "A result is returned which can be passed to helper function to get the information we want, these can be found in the module `solcore.spice.result`. Let's import the functions to help get and plot the IV curve." + "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": [] - }, { "cell_type": "markdown", "metadata": {}, @@ -348,7 +375,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -385,7 +412,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -406,14 +433,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here `vmax` and `pmax` are the voltage and power at the maximum power point. \n", + "Here `vmax` and `pmax` are the voltage and power at the maximum power point, respectively.\n", "\n", - "`maxidx` is the index in bias voltage array the corresponds to the maximum power points. For example," + "`maxidx` is the index in the bias voltage array that corresponds to the maximum power points. For example," ] }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -422,7 +449,7 @@ "True" ] }, - "execution_count": 28, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -437,12 +464,12 @@ "source": [ "## Layer voltages\n", "\n", - "We can make nice plots of surface voltages using the following functions," + "We can make nice plots of surface voltages using the following functions:" ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -451,7 +478,7 @@ "(120, 120, 3, 161)" ] }, - "execution_count": 34, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -467,13 +494,27 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Here `voltages` is a 3 + 1 dimensional array. The first three dimensions correspond to the physical x, y, z location in the discretisation and the last dimension corresponds to the number of steps in the voltage sweep.\n", + "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 layer.\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 the pv layer voltages." + "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": {}, @@ -481,7 +522,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -504,12 +545,12 @@ "metadata": {}, "source": [ "# Electroluminescence prediction\n", - "We can make a prediction of the electroluminescene distribution emitter by the solar cells using the following helper functions," + "We can make a prediction of the electroluminescene distribution emitted by the solar cells using the following helper functions:" ] }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -536,14 +577,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# A more detailed example using solcore to calculate the short-circuit current\n", + "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." + "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": 42, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -561,7 +609,7 @@ "32491.025503548084" ] }, - "execution_count": 42, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -615,12 +663,12 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Make a second function that wraps the SPICE model and returns efficiency of the device. Inside this function it calls solcore to estimate the JSC." + "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": 47, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -675,12 +723,12 @@ "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." + "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": 49, + "execution_count": 16, "metadata": {}, "outputs": [ { diff --git a/pyproject.toml b/pyproject.toml index cd9dca70..22089c8c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,9 +71,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 index c624e7ee..70ddb785 100644 --- a/solcore/spice/grid.py +++ b/solcore/spice/grid.py @@ -12,15 +12,14 @@ class GridPattern: """Representation of a metalisation pattern on the front surface of a solar cell. - This class just defines an inteface and should be instantiated direclty, instead, - subclass this class and implement the `draw` method to render a grid pattern. + Instead of instantiating this class directly, subclass and implement the `draw` method to render a grid pattern. Discussion ---------- - Three grayscale pixel values should be used when drawing the solar cell metalisation: - - black (0.0), represents no metalisation - - grey (0.5), represents grid fingers - - white (1.0), represents bus bar. + 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.") diff --git a/solcore/spice/model.py b/solcore/spice/model.py index 3afb0bfc..4ffcf54b 100644 --- a/solcore/spice/model.py +++ b/solcore/spice/model.py @@ -1,11 +1,11 @@ -"""Classes that aid in the construction of a distributed SPICE model -of a solar cell. Think of these building blocks like sub-circuits that can be composed -together in a 3D structure to build the solar cell structure. +"""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 file""" + """A class representing header information for the SPICE netlist.""" def __init__( self, @@ -146,9 +146,9 @@ def netlist(self): class Bus: """A unit cell representing a SPICE model of metal bus bar segment. - There is really no difference between the the Metal and Bus classes, - other than, by definition, the bus bar is connected to the voltage - source that sweeps the solar cell's bias. + 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__( @@ -178,13 +178,6 @@ def __init__( resistivity_contact : float The resistivity of the metal-semiconductor contact in Ohm meter for this cell. - - Discussion - ---------- - From Ref. [1] height is 3e-6 metres, width is 9e-6 metres and resistiivty - is 3.5E-6 Ohm meters. - - [1] M. Steiner et al., 10.1002/pip.989 """ self.idx = idx self.height = metal_height diff --git a/solcore/spice/netlist.py b/solcore/spice/netlist.py index 60b468a6..d7ab724e 100644 --- a/solcore/spice/netlist.py +++ b/solcore/spice/netlist.py @@ -18,15 +18,15 @@ def generate_netlist( - cell_metalisation_pattern: np.ndarray | GridPattern, # the cells that are grid fingers + cell_metalisation_pattern: np.ndarray | GridPattern, 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. + cell_size: tuple[float, float], junctions: list[dict], - metal_height: float = 3e-6, # Height: m, of grid fingers - metal_resistivity: float = 3.5e-8, # Resistivity: Ohm m, of the metal used for front contacts - metal_semiconductor_specific_contact_resistivity: float = 6.34e-10, # Specific contact resistivity: Ohm m2, of metal-semiconductor layer - base_buffer_specific_contact_resistivity: float = 1.2e-8, # Specific contact resistivity: Ohm m2, of base-buffer layer - rear_contact_specific_contact_resistivity: float = 3.5e-6, # Specific contact resistivity: Ohm m2, of the rear contact layer + 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: @@ -35,7 +35,7 @@ def generate_netlist( Parameters ---------- - cell_metalisation_pattern : np.ndarray | GridPattern | str | pathlib.Path + 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 @@ -46,10 +46,8 @@ def generate_netlist( 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 | str | pathlib.Path - A 2D array or path to an image showing the illumination distribution over the solar cell's surface. - - 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 @@ -97,18 +95,16 @@ def generate_netlist( Discussion ---------- - The net list is intended to be run using a PySpice Circuit objects for this reason - a .DC command is not included nor is the .end statement. PySpice will append these - to the net list when it runs. To complete the net list so that is can be run in an - external simulator simply append the two lines + 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 the performs a voltage sweep over a sensible range - for your solar cell, in this example the voltage starts at -0.1, 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. + + 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 @@ -222,22 +218,17 @@ def _create_grid_layer( Parameters ---------- - cell_metalisation_pattern : np.ndarray | GridPattern | str | pathlib.Path - 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 - + 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 - 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 showing the illumination distribution over the solar cell's surface. - cell_illumination_map: np.ndarray | str | pathlib.Path - A 2D array or path to an image showing the illumination distribution over the solar cell's surface. - - If the 2D array is read from an image file it will be normalised and values scaled between 0 and 1. - 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 @@ -293,7 +284,7 @@ def _create_grid_layer( fig.tight_layout() plt.show() - # Create a 3D matrix to hold each cell: + # 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 diff --git a/solcore/spice/result.py b/solcore/spice/result.py index b42683b6..2fbd72d1 100644 --- a/solcore/spice/result.py +++ b/solcore/spice/result.py @@ -41,10 +41,10 @@ def get_maximum_power_point(result: DcAnalysis) -> tuple[float, float, int]: ------- 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. + - 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 From ff47205e7dc9798cb66ff68dc80df828c3650b8c Mon Sep 17 00:00:00 2001 From: danieljfarrell Date: Tue, 1 Oct 2024 12:45:53 +0100 Subject: [PATCH 3/5] Add unit test --- solcore/spice/model.py | 2 + solcore/spice/result.py | 5 +- tests/test_spice_grid.py | 199 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 tests/test_spice_grid.py diff --git a/solcore/spice/model.py b/solcore/spice/model.py index 4ffcf54b..cf27894a 100644 --- a/solcore/spice/model.py +++ b/solcore/spice/model.py @@ -321,6 +321,7 @@ def __init__( 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""" @@ -355,6 +356,7 @@ def __init__( 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""" diff --git a/solcore/spice/result.py b/solcore/spice/result.py index 2fbd72d1..ae068715 100644 --- a/solcore/spice/result.py +++ b/solcore/spice/result.py @@ -3,13 +3,12 @@ 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 -if TYPE_CHECKING: - from numpy import ndarray - from PySpice.Probe.WaveForm import DcAnalysis +from PySpice.Probe.WaveForm import DcAnalysis def get_characterisic_curve(result: DcAnalysis) -> tuple[ndarray, ndarray]: diff --git a/tests/test_spice_grid.py b/tests/test_spice_grid.py new file mode 100644 index 00000000..1c21e035 --- /dev/null +++ b/tests/test_spice_grid.py @@ -0,0 +1,199 @@ +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 + From 0f9f7ec12ed3b9ce9ed3154c2033fdf87d2b2bde Mon Sep 17 00:00:00 2001 From: danieljfarrell Date: Mon, 7 Oct 2024 12:21:39 +0100 Subject: [PATCH 4/5] Update Quasi 3D docs --- docs/requirements.txt | 3 +- docs/source/Quasi3D/quasi3D.rst | 111 ++++++++++++++++++++++++-------- tests/test_spice_grid.py | 1 + 3 files changed, 87 insertions(+), 28 deletions(-) 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/quasi3D.rst b/docs/source/Quasi3D/quasi3D.rst index a87c1826..d850f4bf 100755 --- a/docs/source/Quasi3D/quasi3D.rst +++ b/docs/source/Quasi3D/quasi3D.rst @@ -18,69 +18,108 @@ In-plane discretization 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) + + * **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) - + + * **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] - bus_px = 10 # The width of the bus bar - fingers_px = [4, 4, 4, 4, 4, 4] # the number and width of the grid fingers - offset_px = 3 # the edge offset (metal does not go fully to the edges) - nx, ny = 120, 120 # the size of the image in pixels - size = (0.01, 0.01) # the physical size of the solar cell in metres + # 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 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, providing an image of 120px x 120px and a size tuple `size = (0.01, 0.01)` (see above) would make each pixel :math:`1cm / 120 \appox 83 micrometers`. Different aspect ratios can be -used to reduce the number of elements and improve speed by specifying a different cell size. - 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. -Note that, no electrical or optical difference exists between bus bar and grid finger. The only difference is that bus bar are used in the SPICE model as connections points to the voltage source that is sweept to generate the cells IV curve. Thus bus bars always have the applied voltage where as the voltage of grid fingers is subject to the current flowing through the cell. +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 cells surface can be include in the simulation using an illimination map array. +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 where each cell has value of 1, thus providing homogeneous illumination across the surface. The intensity of light is specified later, this is why the illumination map contains normalised values (ranging between 1 and 0). +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 ----------------------- -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 of object and then processed to derive the netlist. These objects are contained in the module, +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 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. Please review the paper for an understanding how the model function. In this document we will discuss how to use the SolCore implementation. +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, @@ -94,6 +133,7 @@ Define a function dictionary for each cell in the structure. For example, a sing ] 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. @@ -102,13 +142,15 @@ The parameters are: * `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 and is so large as to be negligible, but it could be added. +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, @@ -116,7 +158,7 @@ Use the `generate_netlist` function to process all the inputs discussed so far t 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. +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 ==== @@ -127,6 +169,7 @@ 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 @@ -134,11 +177,13 @@ The netlist is solved by stepping the voltage to find the maximum power point, 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 @@ -146,6 +191,7 @@ The maximum power point, # 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) @@ -155,6 +201,7 @@ Here, `voltages` is a 3 + 1 dimensional array. The first three dimensions corres 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) @@ -162,6 +209,7 @@ The helper function plots both the metal and PV layer voltages, :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] @@ -177,6 +225,7 @@ 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 @@ -222,6 +271,7 @@ Let's create a Solcore solar cell model based on the solar cell structure above 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): @@ -270,6 +320,7 @@ Create a second function that wraps the SPICE model and returns the device's eff 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] @@ -283,6 +334,12 @@ Finally, let's loop over a few concentration values to see if we can plot a conc 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 ----------------------------------------- diff --git a/tests/test_spice_grid.py b/tests/test_spice_grid.py index 1c21e035..f180048d 100644 --- a/tests/test_spice_grid.py +++ b/tests/test_spice_grid.py @@ -197,3 +197,4 @@ def get_efficiency(concentrationX, power_in=1000.0): assert eta > 0.0007 assert eta < 0.0008 + From d85c5d2c50de4147658a452ad107cebb2177fe4f Mon Sep 17 00:00:00 2001 From: danieljfarrell Date: Mon, 7 Oct 2024 12:42:03 +0100 Subject: [PATCH 5/5] Add PySpice and pixie-python The netlist is solved using PySpice in the latest code, this simplifies the code a bit and also allows this code to be moved out of solcore (at a later date, if wanted). The new GridPattern classes use a pixel drawing API from Pixie (pixie-python module) --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 22089c8c..a4ce7d0d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,8 @@ dependencies = [ "yabox", "joblib", "solsesame", + "PySpice", + "pixie-python" ] dynamic = ["version"]