{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from solcore.structure import Junction\n", "from solcore.solar_cell import SolarCell\n", "from solcore.light_source import LightSource\n", "from solcore.spice import solve_quasi_3D" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we load the masks defining the illumination pattern and the contacts. Both must be greyscale images
\n", "The solver expect images with values between 0 and 255 and imread of a PNG image is between 0 and 1, even when
\n", "it is in grey, so we scale it multiplying by 255. If the image were JPG, the result would be already in (0,255)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "illuminationMask = (plt.imread('../data/masks_illumination.png') * 255).astype(np.int)\n", "contactsMask = (plt.imread('../data/masks_sq.png') * 255).astype(np.int)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "nx, ny = illuminationMask.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For symmetry arguments (not completely true for the illumination), we can mode just 1/4 of the device and then
\n", "multiply the current by 4" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "illuminationMask = illuminationMask[int(nx / 2):, int(ny / 2):]\n", "contactsMask = contactsMask[int(nx / 2):, int(ny / 2):]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Size of the pixels (m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Lx = 10e-6\n", "Ly = 10e-6" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Height of the metal fingers (m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "h = 2.2e-6" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Contact resistance (Ohm m2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Rcontact = 3e-10" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Resistivity metal fingers (Ohm m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "Rline = 2e-8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Bias (V)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vini = 0\n", "vfin = 1.3\n", "step = 0.01" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "T = 298\n", "db_junction = Junction(kind='2D', T=T, reff=1, jref=300, Eg=0.66, A=1, R_sheet_top=100, R_sheet_bot=1e-16,\n", " R_shunt=1e16, n=3.5)\n", "db_junction2 = Junction(kind='2D', T=T, reff=1, jref=300, Eg=1.4, A=1, R_sheet_top=100, R_sheet_bot=1e-16,\n", " R_shunt=1e16, n=3.5)\n", "db_junction3 = Junction(kind='2D', T=T, reff=0.5, jref=300, Eg=1.8, A=1, R_sheet_top=100, R_sheet_bot=100,\n", " R_shunt=1e16, n=3.5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For a single junction, this will have >28800 nodes and for the full 3J it will be >86400, so it is worth to
\n", "exploit symmetries whenever possible. A smaller number of nodes also makes the solver more robust." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "my_solar_cell = SolarCell([db_junction2], T=T)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "wl = np.linspace(350, 2000, 301) * 1e-9\n", "light_source = LightSource(source_type='standard', version='AM1.5g', x=wl, output_units='photon_flux_per_m',\n", " concentration=100)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "options = {'light_iv': True, 'wavelength': wl, 'light_source': light_source, 'optics_method': 'BL'}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "V, I, Vall, Vmet = solve_quasi_3D(my_solar_cell, illuminationMask, contactsMask, options=options, Lx=Lx, Ly=Ly, h=h,\n", " R_back=1e-16, R_contact=Rcontact, R_line=Rline, bias_start=vini, bias_end=vfin,\n", " bias_step=step)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since we model 1/4 of the device, we multiply the current by 4" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "I = I * 4" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "plt.figure(1)\n", "plt.imshow(Vall[:, :, -2, -1])\n", "\n", "plt.figure(2)\n", "plt.semilogy(V, abs(I))\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.4" } }, "nbformat": 4, "nbformat_minor": 4 }