{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\nCalculating a module's IV curves\n================================\n\nExamples of modeling IV curves using a single-diode circuit equivalent model.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Calculating a module IV curve for certain operating conditions is a two-step\nprocess.  Multiple methods exist for both parts of the process.  Here we use\nthe De Soto model [1]_ to calculate the electrical parameters for an IV\ncurve at a certain irradiance and temperature using the module's\nbase characteristics at reference conditions.  Those parameters are then used\nto calculate the module's IV curve by solving the single-diode equation using\nthe Lambert W method.\n\nThe single-diode equation is a circuit-equivalent model of a PV\ncell and has five electrical parameters that depend on the operating\nconditions.  For more details on the single-diode equation and the five\nparameters, see the `PVPMC single diode page\n<https://pvpmc.sandia.gov/modeling-steps/2-dc-module-iv/diode-equivalent-circuit-models/>`_.\n\nReferences\n----------\n .. [1] W. De Soto et al., \"Improvement and validation of a model for\n    photovoltaic array performance\", Solar Energy, vol 80, pp. 78-88, 2006.\n\nCalculating IV Curves\n-----------------------\nThis example uses :py:meth:`pvlib.pvsystem.calcparams_desoto` to calculate\nthe 5 electrical parameters needed to solve the single-diode equation.\n:py:meth:`pvlib.pvsystem.singlediode` is then used to generate the IV curves.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from pvlib import pvsystem\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# Example module parameters for the Canadian Solar CS5P-220M:\nparameters = {\n    'Name': 'Canadian Solar CS5P-220M',\n    'BIPV': 'N',\n    'Date': '10/5/2009',\n    'T_NOCT': 42.4,\n    'A_c': 1.7,\n    'N_s': 96,\n    'I_sc_ref': 5.1,\n    'V_oc_ref': 59.4,\n    'I_mp_ref': 4.69,\n    'V_mp_ref': 46.9,\n    'alpha_sc': 0.004539,\n    'beta_oc': -0.22216,\n    'a_ref': 2.6373,\n    'I_L_ref': 5.114,\n    'I_o_ref': 8.196e-10,\n    'R_s': 1.065,\n    'R_sh_ref': 381.68,\n    'Adjust': 8.7,\n    'gamma_r': -0.476,\n    'Version': 'MM106',\n    'PTC': 200.1,\n    'Technology': 'Mono-c-Si',\n}\n\ncases = [\n    (1000, 55),\n    (800, 55),\n    (600, 55),\n    (400, 25),\n    (400, 40),\n    (400, 55)\n]\n\nconditions = pd.DataFrame(cases, columns=['Geff', 'Tcell'])\n\n# adjust the reference parameters according to the operating\n# conditions using the De Soto model:\nIL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(\n    conditions['Geff'],\n    conditions['Tcell'],\n    alpha_sc=parameters['alpha_sc'],\n    a_ref=parameters['a_ref'],\n    I_L_ref=parameters['I_L_ref'],\n    I_o_ref=parameters['I_o_ref'],\n    R_sh_ref=parameters['R_sh_ref'],\n    R_s=parameters['R_s'],\n    EgRef=1.121,\n    dEgdT=-0.0002677\n)\n\n# plug the parameters into the SDE and solve for IV curves:\ncurve_info = pvsystem.singlediode(\n    photocurrent=IL,\n    saturation_current=I0,\n    resistance_series=Rs,\n    resistance_shunt=Rsh,\n    nNsVth=nNsVth,\n    ivcurve_pnts=100,\n    method='lambertw'\n)\n\n# plot the calculated curves:\nplt.figure()\nfor i, case in conditions.iterrows():\n    label = (\n        \"$G_{eff}$ \" + f\"{case['Geff']} $W/m^2$\\n\"\n        \"$T_{cell}$ \" + f\"{case['Tcell']} $C$\"\n    )\n    plt.plot(curve_info['v'][i], curve_info['i'][i], label=label)\n    v_mp = curve_info['v_mp'][i]\n    i_mp = curve_info['i_mp'][i]\n    # mark the MPP\n    plt.plot([v_mp], [i_mp], ls='', marker='o', c='k')\n\nplt.legend(loc=(1.0, 0))\nplt.xlabel('Module voltage [V]')\nplt.ylabel('Module current [A]')\nplt.title(parameters['Name'])\nplt.show()\nplt.gcf().set_tight_layout(True)\n\n\n# draw trend arrows\ndef draw_arrow(ax, label, x0, y0, rotation, size, direction):\n    style = direction + 'arrow'\n    bbox_props = dict(boxstyle=style, fc=(0.8, 0.9, 0.9), ec=\"b\", lw=1)\n    t = ax.text(x0, y0, label, ha=\"left\", va=\"bottom\", rotation=rotation,\n                size=size, bbox=bbox_props, zorder=-1)\n\n    bb = t.get_bbox_patch()\n    bb.set_boxstyle(style, pad=0.6)\n\n\nax = plt.gca()\ndraw_arrow(ax, 'Irradiance', 20, 2.5, 90, 15, 'r')\ndraw_arrow(ax, 'Temperature', 35, 1, 0, 15, 'l')\n\nprint(pd.DataFrame({\n    'i_sc': curve_info['i_sc'],\n    'v_oc': curve_info['v_oc'],\n    'i_mp': curve_info['i_mp'],\n    'v_mp': curve_info['v_mp'],\n    'p_mp': curve_info['p_mp'],\n}))"
      ]
    }
  ],
  "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.3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}