{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Diffuse IAM Calculation\n\nIntegrating an IAM model across angles to determine the overall reflection\nloss for diffuse irradiance.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The fraction of light reflected from the front of a module depends on the\nangle of incidence (AOI) of the light compared to the panel surface.  The\ngreater the AOI, the larger the reflected fraction is.  The incident angle\nmodifier (IAM) is defined as the ratio of light transmitted at the given\nAOI to transmitted light at normal incidence.\nSeveral models exist to calculate the IAM for a given incidence\nangle (e.g. :py:func:`pvlib.iam.ashrae`, :py:func:`pvlib.iam.martin_ruiz`,\n:py:func:`pvlib.iam.sapm`, :py:func:`pvlib.iam.physical`).\nHowever, evaluating the IAM for diffuse light is\nnot as straightforward because it comes from all directions and therefore\nhas a range of angles of incidence.  Here we show how to integrate the effect\nof AOI reflection across this AOI range using the process described in [1]_.\nIn particular, we will recreate Figures 3, 4, and 5 in that paper.\n\n## References\n .. [1] B. Marion \"Numerical method for angle-of-incidence correction\n    factors for diffuse radiation incident photovoltaic modules\",\n    Solar Energy, Volume 147, Pages 344-348. 2017.\n    DOI: 10.1016/j.solener.2017.03.027\n\n .. [2] Duffie, John A. & Beckman, William A. (2013). Solar Engineering\n    of Thermal Processes.  DOI: 10.1002/9781118671603\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from pvlib.iam import marion_diffuse, physical\nimport numpy as np\nimport matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## IAM Model\n\nThe IAM model used to generate the figures in [1]_ uses Snell's, Fresnel's,\nand Beer's laws to determine the fraction of light transmitted through the\nair-glass interface as a function of AOI.\nThe function :py:func:`pvlib.iam.physical` implements this model, except it\nalso includes an exponential term to model attenuation in the glazing layer.\nTo be faithful to Marion's implementation, we will disable this extinction\nterm by setting the attenuation coefficient ``K`` parameter to zero.\nFor more details on this IAM model, see [2]_.\n\nMarion generated diffuse irradiance modifiers for two cases:  a standard\nuncoated glass with index of refraction n=1.526 and a glass with\nanti-reflective (AR) coating with n=1.3.\nComparing the IAM model across AOI recreates Figure 3 in [1]_:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "aoi = np.arange(0, 91)\niam_no_coating = physical(aoi, n=1.526, K=0)\niam_ar_coating = physical(aoi, n=1.3, K=0)\n\nplt.plot(aoi, iam_ar_coating, c='b', label='$F_b$, AR coated, n=1.3')\nplt.plot(aoi, iam_no_coating, c='r', label='$F_b$, uncoated, n=1.526')\nplt.xlabel(r'Angle-of-Incidence, AOI $(\\degree)$')\nplt.ylabel('Diffuse Incidence Angle Modifier')\nplt.legend()\nplt.ylim([0, 1.2])\nplt.grid()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Diffuse sky, ground, and horizon IAM\n\nNow that we have an AOI model, we use :py:func:`pvlib.iam.marion_diffuse`\nto integrate it across solid angle and determine diffuse irradiance IAM.\nMarion defines three types of diffuse irradiance:\nsky, horizon, and ground-reflected.  The diffuse IAM value is evaluated\nindependently for each type.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "tilts = np.arange(0, 91, 2.5)\n\n# marion_diffuse calculates all three IAM values (sky, horizon, ground)\niam_no_coating = marion_diffuse('physical', tilts, n=1.526, K=0)\niam_ar_coating = marion_diffuse('physical', tilts, n=1.3, K=0)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "First we recreate Figure 4 in [1]_, showing the dependence of the sky diffuse\nincidence angle modifier on module tilt.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.plot(tilts, iam_ar_coating['sky'], c='b', marker='^',\n         label='$F_{sky}$, AR coated, n=1.3')\nplt.plot(tilts, iam_no_coating['sky'], c='r', marker='x',\n         label='$F_{sky}$, uncoated, n=1.526')\nplt.ylim([0.9, 1.0])\nplt.xlabel(r'PV Module Tilt, $\\beta (\\degree)$')\nplt.ylabel('Diffuse Incidence Angle Modifier')\nplt.grid()\nplt.legend()\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Now we recreate Figure 5 in [1]_, showing the dependence of the diffuse iam\nvalues for horizon and ground diffuse irradiance on module tilt.  Note that\n:py:func:`pvlib.iam.marion_diffuse` defaults to using 1800 points for the\nhorizon case (instead of 180 like the others) to match [1]_.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "plt.plot(tilts, iam_ar_coating['horizon'], c='b', marker='^',\n         label='$F_{hor}$, AR coated, n=1.3')\nplt.plot(tilts, iam_no_coating['horizon'], c='r', marker='x',\n         label='$F_{hor}$, uncoated, n=1.526')\nplt.plot(tilts, iam_ar_coating['ground'], c='b', marker='s',\n         label='$F_{grd}$, AR coated, n=1.3')\nplt.plot(tilts, iam_no_coating['ground'], c='r', marker='+',\n         label='$F_{grd}$, uncoated, n=1.526')\nplt.xlabel(r'PV Module Tilt, $\\beta (\\degree)$')\nplt.ylabel('Diffuse Incidence Angle Modifier')\nplt.grid()\nplt.legend()\nplt.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.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}