{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Diffuse Self-Shading\n\nModeling the reduction in diffuse irradiance caused by row-to-row diffuse\nshading.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The term \"self-shading\" usually refers to adjacent rows blocking direct\nirradiance and casting shadows on each other. However, the concept also\napplies to diffuse irradiance because rows block a portion of the sky\ndome even when the sun is high in the sky. The irradiance loss fraction\ndepends on how tightly the rows are packed and where on the module the\nloss is evaluated -- a point near the top of edge of a module will see\nmore of the sky than a point near the bottom edge.\n\nThis example uses the approach presented by Passias and K\u00e4llb\u00e4ck in [1]_\nand recreates two figures from that paper using\n:py:func:`pvlib.shading.masking_angle_passias` and\n:py:func:`pvlib.shading.sky_diffuse_passias`.\n\n## References\n .. [1] D. Passias and B. K\u00e4llb\u00e4ck, \"Shading effects in rows of solar cell\n    panels\", Solar Cells, Volume 11, Pages 281-291.  1984.\n    DOI: 10.1016/0379-6787(84)90017-6\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from pvlib import shading, irradiance\nimport matplotlib.pyplot as plt\nimport numpy as np"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First we'll recreate Figure 4, showing how the average masking angle varies\nwith array tilt and array packing. The masking angle of a given point on a\nmodule is the angle from horizontal to the next row's top edge and represents\nthe portion of the sky dome blocked by the next row. Because it changes\nfrom the bottom to the top of a module, the average across the module is\ncalculated. In [1]_, ``k`` refers to the ratio of row pitch to row slant\nheight (i.e. 1 / GCR).\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "surface_tilt = np.arange(0, 90, 0.5)\n\nplt.figure()\nfor k in [1, 1.5, 2, 2.5, 3, 4, 5, 7, 10]:\n    gcr = 1/k\n    psi = shading.masking_angle_passias(surface_tilt, gcr)\n    plt.plot(surface_tilt, psi, label=f'k={k}')\n\nplt.xlabel('Inclination angle [degrees]')\nplt.ylabel('Average masking angle [degrees]')\nplt.legend()\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "So as the array is packed tighter (decreasing ``k``), the average masking\nangle increases.\n\nNext we'll recreate Figure 5. Note that the y-axis here is the ratio of\ndiffuse plane of array irradiance (after accounting for shading) to diffuse\nhorizontal irradiance. This means that the deviation from 100% is due to the\ncombination of self-shading and the fact that being at a tilt blocks off\nthe portion of the sky behind the row. The first effect is modeled with\n:py:func:`pvlib.shading.sky_diffuse_passias` and the second with\n:py:func:`pvlib.irradiance.isotropic`.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.figure()\nfor k in [1, 1.5, 2, 10]:\n    gcr = 1/k\n    psi = shading.masking_angle_passias(surface_tilt, gcr)\n    shading_loss = shading.sky_diffuse_passias(psi)\n    transposition_ratio = irradiance.isotropic(surface_tilt, dhi=1.0)\n    relative_diffuse = transposition_ratio * (1-shading_loss) * 100  # %\n    plt.plot(surface_tilt, relative_diffuse, label=f'k={k}')\n\nplt.xlabel('Inclination angle [degrees]')\nplt.ylabel('Relative diffuse irradiance [%]')\nplt.ylim(0, 105)\nplt.legend()\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "As ``k`` decreases, GCR increases, so self-shading loss increases and\ncollected diffuse irradiance decreases.\n\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.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}