{
"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
}