Exemplo n.º 1
0
def pvl_perez(SurfTilt,
              SurfAz,
              DHI,
              DNI,
              HExtra,
              SunZen,
              SunAz,
              AM,
              modelt='allsitescomposite1990'):
    ''' 
  Determine diffuse irradiance from the sky on a tilted surface using one of the Perez models

  Perez models determine the diffuse irradiance from the sky (ground
  reflected irradiance is not included in this algorithm) on a tilted
  surface using the surface tilt angle, surface azimuth angle, diffuse
  horizontal irradiance, direct normal irradiance, extraterrestrial
  irradiance, sun zenith angle, sun azimuth angle, and relative (not
  pressure-corrected) airmass. Optionally a selector may be used to use
  any of Perez's model coefficient sets.


  Parameters
  ----------
  
  SurfTilt : float or DataFrame
          Surface tilt angles in decimal degrees.
          SurfTilt must be >=0 and <=180. The tilt angle is defined as
          degrees from horizontal (e.g. surface facing up = 0, surface facing
          horizon = 90)

  SurfAz : float or DataFrame
          Surface azimuth angles in decimal degrees.
          SurfAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270).

  DHI : float or DataFrame
          diffuse horizontal irradiance in W/m^2. 
          DHI must be >=0.

  DNI : float or DataFrame
          direct normal irradiance in W/m^2. 
          DNI must be >=0.

  HExtra : float or DataFrame
          extraterrestrial normal irradiance in W/m^2. 
           HExtra must be >=0.
  
  SunZen : float or DataFrame
          apparent (refraction-corrected) zenith
          angles in decimal degrees. 
          SunZen must be >=0 and <=180.

  SunAz : float or DataFrame
          Sun azimuth angles in decimal degrees.
          SunAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, East = 90, West = 270).

  AM : float or DataFrame
          relative (not pressure-corrected) airmass 
          values. If AM is a DataFrame it must be of the same size as all other 
          DataFrame inputs. AM must be >=0 (careful using the 1/sec(z) model of AM
          generation)

  Other Parameters
  ----------------

  model : string (optional, default='allsitescomposite1990')

          a character string which selects the desired set of Perez
          coefficients. If model is not provided as an input, the default,
          '1990' will be used.
          All possible model selections are: 

          * '1990'
          * 'allsitescomposite1990' (same as '1990')
          * 'allsitescomposite1988'
          * 'sandiacomposite1988'
          * 'usacomposite1988'
          * 'france1988'
          * 'phoenix1988'
          * 'elmonte1988'
          * 'osage1988'
          * 'albuquerque1988'
          * 'capecanaveral1988'
          * 'albany1988'

  Returns
  --------

  SkyDiffuse : float or DataFrame

          the diffuse component of the solar radiation  on an
          arbitrarily tilted surface defined by the Perez model as given in
          reference [3].
          SkyDiffuse is the diffuse component ONLY and does not include the ground
          reflected irradiance or the irradiance due to the beam.
      

  References
  ----------

  [1] Loutzenhiser P.G. et. al. "Empirical validation of models to compute
  solar irradiance on inclined surfaces for building energy simulation"
  2007, Solar Energy vol. 81. pp. 254-267

  [2] Perez, R., Seals, R., Ineichen, P., Stewart, R., Menicucci, D., 1987. A new
  simplified version of the Perez diffuse irradiance model for tilted
  surfaces. Solar Energy 39(3), 221-232.

  [3] Perez, R., Ineichen, P., Seals, R., Michalsky, J., Stewart, R., 1990.
  Modeling daylight availability and irradiance components from direct
  and global irradiance. Solar Energy 44 (5), 271-289. 

  [4] Perez, R. et. al 1988. "The Development and Verification of the
  Perez Diffuse Radiation Model". SAND88-7030

  See also
  --------
  pvl_ephemeris
  pvl_extraradiation
  pvl_isotropicsky
  pvl_haydavies1980
  pvl_reindl1990
  pvl_klucher1979
  pvl_kingdiffuse
  pvl_relativeairmass

  '''
    Vars = locals()
    Expect = {
        'SurfTilt': ('num', 'x>=0'),
        'SurfAz': ('x>=-180'),
        'DHI': ('x>=0'),
        'DNI': ('x>=0'),
        'HExtra': ('x>=0'),
        'SunZen': ('x>=0'),
        'SunAz': ('x>=-180'),
        'AM': ('x>=0'),
        'modelt': ('default', 'default=allsitescomposite1990')
    }

    var = pvl_tools.Parse(Vars, Expect)

    kappa = 1.041  #for SunZen in radians
    z = var.SunZen * np.pi / 180  # # convert to radians

    Dhfilter = var.DHI > 0

    e = ((var.DHI[Dhfilter] + var.DNI[Dhfilter]) / var.DHI[Dhfilter] +
         kappa * z[Dhfilter]**3) / (1 + kappa * z[Dhfilter]**3).reindex_like(
             var.SunZen)

    ebin = pd.Series(np.zeros(var.DHI.shape[0]), index=e.index)

    # Select which bin e falls into
    ebin[(e < 1.065)] = 1
    ebin[(e >= 1.065) & (e < 1.23)] = 2
    ebin[(e >= 1.23) & (e < 1.5)] = 3
    ebin[(e >= 1.5) & (e < 1.95)] = 4
    ebin[(e >= 1.95) & (e < 2.8)] = 5
    ebin[(e >= 2.8) & (e < 4.5)] = 6
    ebin[(e >= 4.5) & (e < 6.2)] = 7
    ebin[e >= 6.2] = 8

    ebinfilter = ebin > 0
    ebin = ebin - 1  #correct for 0 indexing
    ebin[ebinfilter == False] = np.NaN
    ebin = ebin.dropna().astype(int)

    # This is added because in cases where the sun is below the horizon
    # (var.SunZen > 90) but there is still diffuse horizontal light (var.DHI>0), it is
    # possible that the airmass (var.AM) could be NaN, which messes up later
    # calculations. Instead, if the sun is down, and there is still var.DHI, we set
    # the airmass to the airmass value on the horizon (approximately 37-38).
    #var.AM(var.SunZen >=90 & var.DHI >0) = 37;

    var.HExtra[var.HExtra == 0] = .00000001  #very hacky, fix this
    delt = var.DHI * var.AM / var.HExtra

    #

    # The various possible sets of Perez coefficients are contained
    # in a subfunction to clean up the code.
    F1c, F2c = GetPerezCoefficients(var.modelt)

    F1 = F1c[ebin,
             0] + F1c[ebin, 1] * delt[ebinfilter] + F1c[ebin,
                                                        2] * z[ebinfilter]
    F1[F1 < 0] = 0
    F1 = F1.astype(float)

    F2 = F2c[ebin,
             0] + F2c[ebin, 1] * delt[ebinfilter] + F2c[ebin,
                                                        2] * z[ebinfilter]
    F2[F2 < 0] = 0
    F2 = F2.astype(float)

    A = pvl_tools.cosd(var.SurfTilt) * pvl_tools.cosd(
        var.SunZen) + pvl_tools.sind(var.SurfTilt) * pvl_tools.sind(
            var.SunZen) * pvl_tools.cosd(var.SunAz - var.SurfAz)
    #removed +180 from azimuth modifier: Rob Andrews October 19th 2012
    A[A < 0] = 0

    B = pvl_tools.cosd(var.SunZen)
    B[B < pvl_tools.cosd(85)] = pvl_tools.cosd(85)

    #Calculate Diffuse POA from sky dome

    #SkyDiffuse = pd.Series(np.zeros(var.DHI.shape[0]),index=data.index)

    SkyDiffuse = var.DHI[ebinfilter] * (
        0.5 * (1 - F1[ebinfilter]) *
        (1 + pvl_tools.cosd(var.SurfTilt)) + F1[ebinfilter] * A[ebinfilter] /
        B[ebinfilter] + F2[ebinfilter] * pvl_tools.sind(var.SurfTilt))
    SkyDiffuse[SkyDiffuse <= 0] = 0

    return pd.DataFrame({'In_Plane_SkyDiffuse': SkyDiffuse})
Exemplo n.º 2
0
def pvl_haydavies1980(SurfTilt, SurfAz, DHI, DNI, HExtra, SunZen, SunAz):
    '''
    Determine diffuse irradiance from the sky on a tilted surface using Hay & Davies' 1980 model

    
    Hay and Davies' 1980 model determines the diffuse irradiance from the sky
    (ground reflected irradiance is not included in this algorithm) on a
    tilted surface using the surface tilt angle, surface azimuth angle,
    diffuse horizontal irradiance, direct normal irradiance, 
    extraterrestrial irradiance, sun zenith angle, and sun azimuth angle.


    Parameters
    ----------

    SurfTilt : float or DataFrame
          Surface tilt angles in decimal degrees.
          SurfTilt must be >=0 and <=180. The tilt angle is defined as
          degrees from horizontal (e.g. surface facing up = 0, surface facing
          horizon = 90)

    SurfAz : float or DataFrame
          Surface azimuth angles in decimal degrees.
          SurfAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270).

    DHI : float or DataFrame
          diffuse horizontal irradiance in W/m^2. 
          DHI must be >=0.

    DNI : float or DataFrame
          direct normal irradiance in W/m^2. 
          DNI must be >=0.

    HExtra : float or DataFrame
          extraterrestrial normal irradiance in W/m^2. 
           HExtra must be >=0.

    SunZen : float or DataFrame
          apparent (refraction-corrected) zenith
          angles in decimal degrees. 
          SunZen must be >=0 and <=180.

    SunAz : float or DataFrame
          Sun azimuth angles in decimal degrees.
          SunAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, East = 90, West = 270).

    Returns
    --------

    SkyDiffuse : float or DataFrame

          the diffuse component of the solar radiation  on an
          arbitrarily tilted surface defined by the Perez model as given in
          reference [3].
          SkyDiffuse is the diffuse component ONLY and does not include the ground
          reflected irradiance or the irradiance due to the beam.

    References
    -----------
    [1] Loutzenhiser P.G. et. al. "Empirical validation of models to compute
    solar irradiance on inclined surfaces for building energy simulation"
    2007, Solar Energy vol. 81. pp. 254-267
    
    [2] Hay, J.E., Davies, J.A., 1980. Calculations of the solar radiation incident
    on an inclined surface. In: Hay, J.E., Won, T.K. (Eds.), Proc. of First
    Canadian Solar Radiation Data Workshop, 59. Ministry of Supply
    and Services, Canada.

    See Also
    --------
    pvl_ephemeris   
    pvl_extraradiation   
    pvl_isotropicsky
    pvl_reindl1990   
    pvl_perez 
    pvl_klucher1979   
    pvl_kingdiffuse
    pvl_spa

    '''

    Vars = locals()
    Expect = {
        'SurfTilt': ('num', 'x>=0'),
        'SurfAz': ('x>=-180'),
        'DHI': ('x>=0'),
        'DNI': ('x>=0'),
        'HExtra': ('x>=0'),
        'SunZen': ('x>=0'),
        'SunAz': ('x>=-180'),
    }
    var = pvl_tools.Parse(Vars, Expect)

    COSTT = pvl_tools.cosd(SurfTilt) * pvl_tools.cosd(SunZen) + pvl_tools.sind(
        SurfTilt) * pvl_tools.sind(SunZen) * pvl_tools.cosd(SunAz - SurfAz)

    RB = np.max(COSTT, 0) / np.max(pvl_tools.cosd(SunZen), 0.01745)

    AI = DNI / HExtra

    SkyDiffuse = DHI * ((AI * (RB) + (1 - AI) * (0.5) *
                         ((1 + pvl_tools.cosd(SurfTilt)))))

    return SkyDiffuse
Exemplo n.º 3
0
def pvl_physicaliam(K, L, n, theta):
    '''
    Determine the incidence angle modifier using refractive 
    index, glazing thickness, and extinction coefficient

    pvl_physicaliam calculates the incidence angle modifier as described in
    De Soto et al. "Improvement and validation of a model for photovoltaic
    array performance", section 3. The calculation is based upon a physical
    model of absorbtion and transmission through a cover. Required
    information includes, incident angle, cover extinction coefficient,
    cover thickness

    Note: The authors of this function believe that eqn. 14 in [1] is
    incorrect. This function uses the following equation in its place:
    theta_r = arcsin(1/n * sin(theta))

    Parameters
    ----------

    K : float

            The glazing extinction coefficient in units of 1/meters. Reference
            [1] indicates that a value of  4 is reasonable for "water white"
            glass. K must be a numeric scalar or vector with all values >=0. If K
            is a vector, it must be the same size as all other input vectors.

    L : float

            The glazing thickness in units of meters. Reference [1] indicates
            that 0.002 meters (2 mm) is reasonable for most glass-covered
            PV panels. L must be a numeric scalar or vector with all values >=0. 
            If L is a vector, it must be the same size as all other input vectors.

    n : float

            The effective index of refraction (unitless). Reference [1]
            indicates that a value of 1.526 is acceptable for glass. n must be a 
            numeric scalar or vector with all values >=0. If n is a vector, it 
            must be the same size as all other input vectors.

    theta :float

            The angle of incidence between the module normal vector and the
            sun-beam vector in degrees. Theta must be a numeric scalar or vector.
            For any values of theta where abs(theta)>90, IAM is set to 0. For any
            values of theta where -90 < theta < 0, theta is set to abs(theta) and
            evaluated. A warning will be generated if any(theta<0 or theta>90).

    Returns
    -------

    IAM : float

       The incident angle modifier as specified in eqns. 14-16 of [1].
         IAM is a column vector with the same number of elements as the
         largest input vector.

    References
    ----------

    [1] W. De Soto et al., "Improvement and validation of a model for
     photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
     2006.

    [2] Duffie, John A. & Beckman, William A.. (2006). Solar Engineering 
     of Thermal Processes, third edition. [Books24x7 version] Available 
     from http://common.books24x7.com/toc.aspx?bookid=17160. 

    See Also 
    --------
          
    pvl_getaoi   
    pvl_ephemeris   
    pvl_spa    
    pvl_ashraeiam

    '''
    Vars = locals()

    Expect = {'K': 'x >= 0', 'L': 'x >= 0', 'n': 'x >= 0', 'theta': 'num'}
    var = pvl_tools.Parse(Vars, Expect)

    if any((var.theta < 0) | (var.theta >= 90)):
        print(
            'Input incident angles <0 or >=90 detected For input angles with absolute value greater than 90, the '
            +
            'modifier is set to 0. For input angles between -90 and 0, the ' +
            'angle is changed to its absolute value and evaluated.')
        var.theta[(var.theta < 0) |
                  (var.theta >= 90)] = abs((var.theta < 0) | (var.theta >= 90))

    thetar_deg = pvl_tools.asind(1.0 / n * (pvl_tools.sind(theta)))

    tau = np.exp(-1.0 * (K * (L) / pvl_tools.cosd(thetar_deg))) * ((1 - 0.5 * (
        (((pvl_tools.sind(thetar_deg - theta))**2) /
         ((pvl_tools.sind(thetar_deg + theta))**2) +
         ((pvl_tools.tand(thetar_deg - theta))**2) /
         ((pvl_tools.tand(thetar_deg + theta))**2)))))

    zeroang = 1e-06

    thetar_deg0 = pvl_tools.asind(1.0 / n * (pvl_tools.sind(zeroang)))

    tau0 = np.exp(-1.0 * (K * (L) / pvl_tools.cosd(thetar_deg0))) * (
        (1 - 0.5 * ((((pvl_tools.sind(thetar_deg0 - zeroang))**2) /
                     ((pvl_tools.sind(thetar_deg0 + zeroang))**2) +
                     ((pvl_tools.tand(thetar_deg0 - zeroang))**2) /
                     ((pvl_tools.tand(thetar_deg0 + zeroang))**2)))))

    IAM = tau / tau0

    IAM[theta == 0] = 1

    IAM[abs(theta) > 90 | (IAM < 0)] = 0

    return IAM
Exemplo n.º 4
0
def pvl_klucher1979(SurfTilt, SurfAz, DHI, GHI, SunZen, SunAz):
    '''
    Determine diffuse irradiance from the sky on a tilted surface using Klucher's 1979 model


    Klucher's 1979 model determines the diffuse irradiance from the sky
    (ground reflected irradiance is not included in this algorithm) on a
    tilted surface using the surface tilt angle, surface azimuth angle,
    diffuse horizontal irradiance, direct normal irradiance, global
    horizontal irradiance, extraterrestrial irradiance, sun zenith angle,
    and sun azimuth angle.

    Parameters
    ----------

    SurfTilt : float or DataFrame
            Surface tilt angles in decimal degrees.
            SurfTilt must be >=0 and <=180. The tilt angle is defined as
            degrees from horizontal (e.g. surface facing up = 0, surface facing
            horizon = 90)

    SurfAz : float or DataFrame
            Surface azimuth angles in decimal degrees.
            SurfAz must be >=0 and <=360. The Azimuth convention is defined
            as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270).

    DHI : float or DataFrame
            diffuse horizontal irradiance in W/m^2. 
            DHI must be >=0.

    GHI : float or DataFrame
            Global  irradiance in W/m^2. 
            DNI must be >=0.

    SunZen : float or DataFrame
            apparent (refraction-corrected) zenith
            angles in decimal degrees. 
            SunZen must be >=0 and <=180.

    SunAz : float or DataFrame
            Sun azimuth angles in decimal degrees.
            SunAz must be >=0 and <=360. The Azimuth convention is defined
            as degrees east of north (e.g. North = 0, East = 90, West = 270).

    Returns
    -------
    SkyDiffuse : float or DataFrame

                the diffuse component of the solar radiation  on an
                arbitrarily tilted surface defined by the Klucher model as given in
                Loutzenhiser et. al (2007) equation 4.
                SkyDiffuse is the diffuse component ONLY and does not include the ground
                reflected irradiance or the irradiance due to the beam.
                SkyDiffuse is a column vector vector with a number of elements equal to
                the input vector(s).

    References
    ----------
    [1] Loutzenhiser P.G. et. al. "Empirical validation of models to compute
    solar irradiance on inclined surfaces for building energy simulation"
    2007, Solar Energy vol. 81. pp. 254-267

    [2] Klucher, T.M., 1979. Evaluation of models to predict insolation on tilted
    surfaces. Solar Energy 23 (2), 111-114.

    See also
    --------
    pvl_ephemeris   
    pvl_extraradiation   
    pvl_isotropicsky
    pvl_haydavies1980   
    pvl_perez 
    pvl_reindl1990  
    pvl_kingdiffuse

    '''
    Vars = locals()
    Expect = {
        'SurfTilt': ('num', 'x>=0'),
        'SurfAz': ('x>=-180'),
        'DHI': ('x>=0'),
        'GHI': ('x>=0'),
        'SunZen': ('x>=0'),
        'SunAz': ('x>=-180')
    }

    var = pvl_tools.Parse(Vars, Expect)

    GHI[GHI < DHI] = DHI
    GHI[GHI < 1e-06] = 1e-06

    COSTT = pvl_tools.cosd(SurfTilt) * pvl_tools.cosd(SunZen) + pvl_tools.sind(
        SurfTilt) * pvl_tools.sind(SunZen) * pvl_tools.cosd(SunAz - SurfAz)

    F = 1 - ((DHI / GHI)**2)

    SkyDiffuse = DHI * ((0.5 * ((1 + pvl_tools.cosd(SurfTilt))))) * ((1 + F * (
        ((pvl_tools.sind(SurfTilt / 2))**3)))) * ((1 + F * (((COSTT)**2)) * ((
            (pvl_tools.sind(SunZen))**3))))

    return SkyDiffuse
Exemplo n.º 5
0
def pvl_klucher1979(SurfTilt,SurfAz,DHI,GHI,SunZen,SunAz):
    '''
    Determine diffuse irradiance from the sky on a tilted surface using Klucher's 1979 model


    Klucher's 1979 model determines the diffuse irradiance from the sky
    (ground reflected irradiance is not included in this algorithm) on a
    tilted surface using the surface tilt angle, surface azimuth angle,
    diffuse horizontal irradiance, direct normal irradiance, global
    horizontal irradiance, extraterrestrial irradiance, sun zenith angle,
    and sun azimuth angle.

    Parameters
    ----------

    SurfTilt : float or DataFrame
            Surface tilt angles in decimal degrees.
            SurfTilt must be >=0 and <=180. The tilt angle is defined as
            degrees from horizontal (e.g. surface facing up = 0, surface facing
            horizon = 90)

    SurfAz : float or DataFrame
            Surface azimuth angles in decimal degrees.
            SurfAz must be >=0 and <=360. The Azimuth convention is defined
            as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270).

    DHI : float or DataFrame
            diffuse horizontal irradiance in W/m^2. 
            DHI must be >=0.

    GHI : float or DataFrame
            Global  irradiance in W/m^2. 
            DNI must be >=0.

    SunZen : float or DataFrame
            apparent (refraction-corrected) zenith
            angles in decimal degrees. 
            SunZen must be >=0 and <=180.

    SunAz : float or DataFrame
            Sun azimuth angles in decimal degrees.
            SunAz must be >=0 and <=360. The Azimuth convention is defined
            as degrees east of north (e.g. North = 0, East = 90, West = 270).

    Returns
    -------
    SkyDiffuse : float or DataFrame

                the diffuse component of the solar radiation  on an
                arbitrarily tilted surface defined by the Klucher model as given in
                Loutzenhiser et. al (2007) equation 4.
                SkyDiffuse is the diffuse component ONLY and does not include the ground
                reflected irradiance or the irradiance due to the beam.
                SkyDiffuse is a column vector vector with a number of elements equal to
                the input vector(s).

    References
    ----------
    [1] Loutzenhiser P.G. et. al. "Empirical validation of models to compute
    solar irradiance on inclined surfaces for building energy simulation"
    2007, Solar Energy vol. 81. pp. 254-267

    [2] Klucher, T.M., 1979. Evaluation of models to predict insolation on tilted
    surfaces. Solar Energy 23 (2), 111-114.

    See also
    --------
    pvl_ephemeris   
    pvl_extraradiation   
    pvl_isotropicsky
    pvl_haydavies1980   
    pvl_perez 
    pvl_reindl1990  
    pvl_kingdiffuse

    '''
    Vars=locals()
    Expect={'SurfTilt':('num','x>=0'),
            'SurfAz':('x>=-180'),
            'DHI':('x>=0'),
            'GHI':('x>=0'),
            'SunZen':('x>=0'),
            'SunAz':('x>=-180')
            }

    var=pvl_tools.Parse(Vars,Expect)

    GHI[GHI < DHI]=DHI
    GHI[GHI < 1e-06]=1e-06

    COSTT=pvl_tools.cosd(SurfTilt)*pvl_tools.cosd(SunZen) + pvl_tools.sind(SurfTilt)*pvl_tools.sind(SunZen)*pvl_tools.cosd(SunAz - SurfAz)

    F=1 - ((DHI / GHI) ** 2)

    SkyDiffuse=DHI*((0.5*((1 + pvl_tools.cosd(SurfTilt)))))*((1 + F*(((pvl_tools.sind(SurfTilt / 2)) ** 3))))*((1 + F*(((COSTT) ** 2))*(((pvl_tools.sind(SunZen)) ** 3))))

    return SkyDiffuse
Exemplo n.º 6
0
def pvl_perez(SurfTilt, SurfAz, DHI, DNI, HExtra, SunZen, SunAz, AM,modelt='allsitescomposite1990'):
  ''' 
  Determine diffuse irradiance from the sky on a tilted surface using one of the Perez models

  Perez models determine the diffuse irradiance from the sky (ground
  reflected irradiance is not included in this algorithm) on a tilted
  surface using the surface tilt angle, surface azimuth angle, diffuse
  horizontal irradiance, direct normal irradiance, extraterrestrial
  irradiance, sun zenith angle, sun azimuth angle, and relative (not
  pressure-corrected) airmass. Optionally a selector may be used to use
  any of Perez's model coefficient sets.


  Parameters
  ----------
  
  SurfTilt : float or DataFrame
          Surface tilt angles in decimal degrees.
          SurfTilt must be >=0 and <=180. The tilt angle is defined as
          degrees from horizontal (e.g. surface facing up = 0, surface facing
          horizon = 90)

  SurfAz : float or DataFrame
          Surface azimuth angles in decimal degrees.
          SurfAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270).

  DHI : float or DataFrame
          diffuse horizontal irradiance in W/m^2. 
          DHI must be >=0.

  DNI : float or DataFrame
          direct normal irradiance in W/m^2. 
          DNI must be >=0.

  HExtra : float or DataFrame
          extraterrestrial normal irradiance in W/m^2. 
           HExtra must be >=0.
  
  SunZen : float or DataFrame
          apparent (refraction-corrected) zenith
          angles in decimal degrees. 
          SunZen must be >=0 and <=180.

  SunAz : float or DataFrame
          Sun azimuth angles in decimal degrees.
          SunAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, East = 90, West = 270).

  AM : float or DataFrame
          relative (not pressure-corrected) airmass 
          values. If AM is a DataFrame it must be of the same size as all other 
          DataFrame inputs. AM must be >=0 (careful using the 1/sec(z) model of AM
          generation)

  Other Parameters
  ----------------

  model : string (optional, default='allsitescomposite1990')

          a character string which selects the desired set of Perez
          coefficients. If model is not provided as an input, the default,
          '1990' will be used.
          All possible model selections are: 

          * '1990'
          * 'allsitescomposite1990' (same as '1990')
          * 'allsitescomposite1988'
          * 'sandiacomposite1988'
          * 'usacomposite1988'
          * 'france1988'
          * 'phoenix1988'
          * 'elmonte1988'
          * 'osage1988'
          * 'albuquerque1988'
          * 'capecanaveral1988'
          * 'albany1988'

  Returns
  --------

  SkyDiffuse : float or DataFrame

          the diffuse component of the solar radiation  on an
          arbitrarily tilted surface defined by the Perez model as given in
          reference [3].
          SkyDiffuse is the diffuse component ONLY and does not include the ground
          reflected irradiance or the irradiance due to the beam.
      

  References
  ----------

  [1] Loutzenhiser P.G. et. al. "Empirical validation of models to compute
  solar irradiance on inclined surfaces for building energy simulation"
  2007, Solar Energy vol. 81. pp. 254-267

  [2] Perez, R., Seals, R., Ineichen, P., Stewart, R., Menicucci, D., 1987. A new
  simplified version of the Perez diffuse irradiance model for tilted
  surfaces. Solar Energy 39(3), 221-232.

  [3] Perez, R., Ineichen, P., Seals, R., Michalsky, J., Stewart, R., 1990.
  Modeling daylight availability and irradiance components from direct
  and global irradiance. Solar Energy 44 (5), 271-289. 

  [4] Perez, R. et. al 1988. "The Development and Verification of the
  Perez Diffuse Radiation Model". SAND88-7030

  See also
  --------
  pvl_ephemeris
  pvl_extraradiation
  pvl_isotropicsky
  pvl_haydavies1980
  pvl_reindl1990
  pvl_klucher1979
  pvl_kingdiffuse
  pvl_relativeairmass

  '''
  Vars=locals()
  Expect={'SurfTilt':('num','x>=0'),
      'SurfAz':('x>=-180'),
      'DHI':('x>=0'),
      'DNI':('x>=0'),
      'HExtra':('x>=0'),
      'SunZen':('x>=0'),
      'SunAz':('x>=-180'),
      'AM':('x>=0'),
      'modelt': ('default','default=allsitescomposite1990')}

  var=pvl_tools.Parse(Vars,Expect)

  kappa = 1.041 #for SunZen in radians
  z = var.SunZen*np.pi/180# # convert to radians

  Dhfilter = var.DHI > 0
  
  
  e = ((var.DHI[Dhfilter] + var.DNI[Dhfilter])/var.DHI[Dhfilter]+kappa*z[Dhfilter]**3)/(1+kappa*z[Dhfilter]**3).reindex_like(var.SunZen)
 


  ebin = pd.Series(np.zeros(var.DHI.shape[0]),index=e.index)

  # Select which bin e falls into
  ebin[(e<1.065)]= 1
  ebin[(e>=1.065) & (e<1.23)]= 2
  ebin[(e>=1.23) & (e<1.5)]= 3
  ebin[(e>=1.5) & (e<1.95)]= 4
  ebin[(e>=1.95) & (e<2.8)]= 5
  ebin[(e>=2.8) & (e<4.5)]= 6
  ebin[(e>=4.5) & (e<6.2)]= 7
  ebin[e>=6.2] = 8

  ebinfilter=ebin>0
  ebin=ebin-1 #correct for 0 indexing
  ebin[ebinfilter==False]=np.NaN
  ebin=ebin.dropna().astype(int)

  # This is added because in cases where the sun is below the horizon
  # (var.SunZen > 90) but there is still diffuse horizontal light (var.DHI>0), it is
  # possible that the airmass (var.AM) could be NaN, which messes up later
  # calculations. Instead, if the sun is down, and there is still var.DHI, we set
  # the airmass to the airmass value on the horizon (approximately 37-38).
  #var.AM(var.SunZen >=90 & var.DHI >0) = 37;

  var.HExtra[var.HExtra==0]=.00000001 #very hacky, fix this
  delt = var.DHI*var.AM/var.HExtra

  #

  # The various possible sets of Perez coefficients are contained
  # in a subfunction to clean up the code.
  F1c,F2c = GetPerezCoefficients(var.modelt)

  F1= F1c[ebin,0] + F1c[ebin,1]*delt[ebinfilter] + F1c[ebin,2]*z[ebinfilter]
  F1[F1<0]=0;
  F1=F1.astype(float)

  F2= F2c[ebin,0] + F2c[ebin,1]*delt[ebinfilter] + F2c[ebin,2]*z[ebinfilter]
  F2[F2<0]=0
  F2=F2.astype(float)

  A = pvl_tools.cosd(var.SurfTilt)*pvl_tools.cosd(var.SunZen) + pvl_tools.sind(var.SurfTilt)*pvl_tools.sind(var.SunZen)*pvl_tools.cosd(var.SunAz-var.SurfAz); #removed +180 from azimuth modifier: Rob Andrews October 19th 2012
  A[A < 0] = 0

  B = pvl_tools.cosd(var.SunZen);
  B[B < pvl_tools.cosd(85)] = pvl_tools.cosd(85)


  #Calculate Diffuse POA from sky dome

  #SkyDiffuse = pd.Series(np.zeros(var.DHI.shape[0]),index=data.index)

  SkyDiffuse = var.DHI[ebinfilter]*( 0.5* (1-F1[ebinfilter])*(1+pvl_tools.cosd(var.SurfTilt))+F1[ebinfilter] * A[ebinfilter]/ B[ebinfilter] + F2[ebinfilter]* pvl_tools.sind(var.SurfTilt))
  SkyDiffuse[SkyDiffuse <= 0]= 0


  return pd.DataFrame({'In_Plane_SkyDiffuse':SkyDiffuse})
Exemplo n.º 7
0
def pvl_reindl1990(SurfTilt, SurfAz, DHI, DNI, GHI, HExtra, SunZen, SunAz):
    '''
  Determine diffuse irradiance from the sky on a tilted surface using Reindl's 1990 model


  Reindl's 1990 model determines the diffuse irradiance from the sky
  (ground reflected irradiance is not included in this algorithm) on a
  tilted surface using the surface tilt angle, surface azimuth angle,
  diffuse horizontal irradiance, direct normal irradiance, global
  horizontal irradiance, extraterrestrial irradiance, sun zenith angle,
  and sun azimuth angle.

  Parameters
  ----------
    
  SurfTilt : DataFrame
          Surface tilt angles in decimal degrees.
          SurfTilt must be >=0 and <=180. The tilt angle is defined as
          degrees from horizontal (e.g. surface facing up = 0, surface facing
          horizon = 90)

  SurfAz : DataFrame
          Surface azimuth angles in decimal degrees.
          SurfAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270).

  DHI : DataFrame
          diffuse horizontal irradiance in W/m^2. 
          DHI must be >=0.

  DNI : DataFrame
          direct normal irradiance in W/m^2. 
          DNI must be >=0.

  GHI: DataFrame
          Global irradiance in W/m^2. 
          GHI must be >=0.

  HExtra : DataFrame
          extraterrestrial normal irradiance in W/m^2. 
           HExtra must be >=0.

  SunZen : DataFrame
          apparent (refraction-corrected) zenith
          angles in decimal degrees. 
          SunZen must be >=0 and <=180.

  SunAz : DataFrame
          Sun azimuth angles in decimal degrees.
          SunAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, East = 90, West = 270).

  Returns
  -------

  SkyDiffuse : DataFrame

           the diffuse component of the solar radiation  on an
           arbitrarily tilted surface defined by the Reindl model as given in
           Loutzenhiser et. al (2007) equation 8.
           SkyDiffuse is the diffuse component ONLY and does not include the ground
           reflected irradiance or the irradiance due to the beam.
           SkyDiffuse is a column vector vector with a number of elements equal to
           the input vector(s).


  Notes
  -----
  
     The POAskydiffuse calculation is generated from the Loutzenhiser et al.
     (2007) paper, equation 8. Note that I have removed the beam and ground
     reflectance portion of the equation and this generates ONLY the diffuse
     radiation from the sky and circumsolar, so the form of the equation
     varies slightly from equation 8.
  
  References
  ----------

  [1] Loutzenhiser P.G. et. al. "Empirical validation of models to compute
  solar irradiance on inclined surfaces for building energy simulation"
  2007, Solar Energy vol. 81. pp. 254-267

  [2] Reindl, D.T., Beckmann, W.A., Duffie, J.A., 1990a. Diffuse fraction
  correlations. Solar Energy 45(1), 1-7.

  [3] Reindl, D.T., Beckmann, W.A., Duffie, J.A., 1990b. Evaluation of hourly
  tilted surface radiation models. Solar Energy 45(1), 9-17.

  See Also 
  ---------
  pvl_ephemeris   
  pvl_extraradiation   
  pvl_isotropicsky
  pvl_haydavies1980   
  pvl_perez 
  pvl_klucher1979   
  pvl_kingdiffuse

  '''
    Vars = locals()
    Expect = {
        'SurfTilt': ('num', 'x>=0'),
        'SurfAz': ('num', 'x>=-180'),
        'DHI': ('num', 'x>=0'),
        'DNI': ('num', 'x>=0'),
        'GHI': ('num', 'x>=0'),
        'HExtra': ('num', 'x>=0'),
        'SunZen': ('num', 'x>=0'),
        'SunAz': ('num', 'x>=-180'),
    }

    var = pvl_tools.Parse(Vars, Expect)

    small = 1e-06

    COSTT = pvl_tools.cosd(SurfTilt) * pvl_tools.cosd(SunZen) + pvl_tools.sind(
        SurfTilt) * pvl_tools.sind(SunZen) * pvl_tools.cosd(SunAz - SurfAz)
    RB = np.max(COSTT, 0) / np.max(pvl_tools.cosd(SunZen), 0.01745)
    AI = DNI / HExtra
    GHI[GHI < small] = small
    HB = DNI * (pvl_tools.cosd(SunZen))
    HB[HB < 0] = 0
    GHI[GHI < 0] = 0
    F = np.sqrt(HB / GHI)
    SCUBE = (pvl_tools.sind(SurfTilt * (0.5)))**3

    SkyDiffuse = DHI * ((AI * (RB) + (1 - AI) * (0.5) *
                         ((1 + pvl_tools.cosd(SurfTilt))) * ((1 + F *
                                                              (SCUBE)))))

    return SkyDiffuse
Exemplo n.º 8
0
def pvl_haydavies1980(SurfTilt,SurfAz,DHI,DNI,HExtra,SunZen,SunAz):

    '''
    Determine diffuse irradiance from the sky on a tilted surface using Hay & Davies' 1980 model

    
    Hay and Davies' 1980 model determines the diffuse irradiance from the sky
    (ground reflected irradiance is not included in this algorithm) on a
    tilted surface using the surface tilt angle, surface azimuth angle,
    diffuse horizontal irradiance, direct normal irradiance, 
    extraterrestrial irradiance, sun zenith angle, and sun azimuth angle.


    Parameters
    ----------

    SurfTilt : float or DataFrame
          Surface tilt angles in decimal degrees.
          SurfTilt must be >=0 and <=180. The tilt angle is defined as
          degrees from horizontal (e.g. surface facing up = 0, surface facing
          horizon = 90)

    SurfAz : float or DataFrame
          Surface azimuth angles in decimal degrees.
          SurfAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, South=180 East = 90, West = 270).

    DHI : float or DataFrame
          diffuse horizontal irradiance in W/m^2. 
          DHI must be >=0.

    DNI : float or DataFrame
          direct normal irradiance in W/m^2. 
          DNI must be >=0.

    HExtra : float or DataFrame
          extraterrestrial normal irradiance in W/m^2. 
           HExtra must be >=0.

    SunZen : float or DataFrame
          apparent (refraction-corrected) zenith
          angles in decimal degrees. 
          SunZen must be >=0 and <=180.

    SunAz : float or DataFrame
          Sun azimuth angles in decimal degrees.
          SunAz must be >=0 and <=360. The Azimuth convention is defined
          as degrees east of north (e.g. North = 0, East = 90, West = 270).

    Returns
    --------

    SkyDiffuse : float or DataFrame

          the diffuse component of the solar radiation  on an
          arbitrarily tilted surface defined by the Perez model as given in
          reference [3].
          SkyDiffuse is the diffuse component ONLY and does not include the ground
          reflected irradiance or the irradiance due to the beam.

    References
    -----------
    [1] Loutzenhiser P.G. et. al. "Empirical validation of models to compute
    solar irradiance on inclined surfaces for building energy simulation"
    2007, Solar Energy vol. 81. pp. 254-267
    
    [2] Hay, J.E., Davies, J.A., 1980. Calculations of the solar radiation incident
    on an inclined surface. In: Hay, J.E., Won, T.K. (Eds.), Proc. of First
    Canadian Solar Radiation Data Workshop, 59. Ministry of Supply
    and Services, Canada.

    See Also
    --------
    pvl_ephemeris   
    pvl_extraradiation   
    pvl_isotropicsky
    pvl_reindl1990   
    pvl_perez 
    pvl_klucher1979   
    pvl_kingdiffuse
    pvl_spa

    '''

    Vars=locals()
    Expect={'SurfTilt':('num','x>=0'),
              'SurfAz':('x>=-180'),
              'DHI':('x>=0'),
              'DNI':('x>=0'),
              'HExtra':('x>=0'),
              'SunZen':('x>=0'),
              'SunAz':('x>=-180'),
              }
    var=pvl_tools.Parse(Vars,Expect)

    COSTT=pvl_tools.cosd(SurfTilt)*pvl_tools.cosd(SunZen) + pvl_tools.sind(SurfTilt)*pvl_tools.sind(SunZen)*pvl_tools.cosd(SunAz - SurfAz)

    RB=np.max(COSTT,0) / np.max(pvl_tools.cosd(SunZen),0.01745)

    AI=DNI / HExtra

    SkyDiffuse=DHI*((AI*(RB) + (1 - AI)*(0.5)*((1 + pvl_tools.cosd(SurfTilt)))))


    return SkyDiffuse
Exemplo n.º 9
0
def pvl_physicaliam(K,L,n,theta):

    '''
    Determine the incidence angle modifier using refractive 
    index, glazing thickness, and extinction coefficient

    pvl_physicaliam calculates the incidence angle modifier as described in
    De Soto et al. "Improvement and validation of a model for photovoltaic
    array performance", section 3. The calculation is based upon a physical
    model of absorbtion and transmission through a cover. Required
    information includes, incident angle, cover extinction coefficient,
    cover thickness

    Note: The authors of this function believe that eqn. 14 in [1] is
    incorrect. This function uses the following equation in its place:
    theta_r = arcsin(1/n * sin(theta))

    Parameters
    ----------

    K : float

            The glazing extinction coefficient in units of 1/meters. Reference
            [1] indicates that a value of  4 is reasonable for "water white"
            glass. K must be a numeric scalar or vector with all values >=0. If K
            is a vector, it must be the same size as all other input vectors.

    L : float

            The glazing thickness in units of meters. Reference [1] indicates
            that 0.002 meters (2 mm) is reasonable for most glass-covered
            PV panels. L must be a numeric scalar or vector with all values >=0. 
            If L is a vector, it must be the same size as all other input vectors.

    n : float

            The effective index of refraction (unitless). Reference [1]
            indicates that a value of 1.526 is acceptable for glass. n must be a 
            numeric scalar or vector with all values >=0. If n is a vector, it 
            must be the same size as all other input vectors.

    theta :float

            The angle of incidence between the module normal vector and the
            sun-beam vector in degrees. Theta must be a numeric scalar or vector.
            For any values of theta where abs(theta)>90, IAM is set to 0. For any
            values of theta where -90 < theta < 0, theta is set to abs(theta) and
            evaluated. A warning will be generated if any(theta<0 or theta>90).

    Returns
    -------

    IAM : float

       The incident angle modifier as specified in eqns. 14-16 of [1].
         IAM is a column vector with the same number of elements as the
         largest input vector.

    References
    ----------

    [1] W. De Soto et al., "Improvement and validation of a model for
     photovoltaic array performance", Solar Energy, vol 80, pp. 78-88,
     2006.

    [2] Duffie, John A. & Beckman, William A.. (2006). Solar Engineering 
     of Thermal Processes, third edition. [Books24x7 version] Available 
     from http://common.books24x7.com/toc.aspx?bookid=17160. 

    See Also 
    --------
          
    pvl_getaoi   
    pvl_ephemeris   
    pvl_spa    
    pvl_ashraeiam

    '''
    Vars=locals()

    Expect={'K':'x >= 0',
            'L':'x >= 0',
            'n':'x >= 0',
            'theta':'num'}
    var=pvl_tools.Parse(Vars,Expect)



    if any((var.theta < 0) | (var.theta >= 90)):
        print('Input incident angles <0 or >=90 detected For input angles with absolute value greater than 90, the ' + 'modifier is set to 0. For input angles between -90 and 0, the ' + 'angle is changed to its absolute value and evaluated.')
        var.theta[(var.theta < 0) | (var.theta >= 90)]=abs((var.theta < 0) | (var.theta >= 90))

    thetar_deg=pvl_tools.asind(1.0 / n*(pvl_tools.sind(theta)))

    tau=np.exp(- 1.0 * (K*(L) / pvl_tools.cosd(thetar_deg)))*((1 - 0.5*((((pvl_tools.sind(thetar_deg - theta)) ** 2) / ((pvl_tools.sind(thetar_deg + theta)) ** 2) + ((pvl_tools.tand(thetar_deg - theta)) ** 2) / ((pvl_tools.tand(thetar_deg + theta)) ** 2)))))
    
    zeroang=1e-06
    
    thetar_deg0=pvl_tools.asind(1.0 / n*(pvl_tools.sind(zeroang)))
    
    tau0=np.exp(- 1.0 * (K*(L) / pvl_tools.cosd(thetar_deg0)))*((1 - 0.5*((((pvl_tools.sind(thetar_deg0 - zeroang)) ** 2) / ((pvl_tools.sind(thetar_deg0 + zeroang)) ** 2) + ((pvl_tools.tand(thetar_deg0 - zeroang)) ** 2) / ((pvl_tools.tand(thetar_deg0 + zeroang)) ** 2)))))
    
    IAM=tau / tau0
    
    IAM[theta == 0]=1
    
    IAM[abs(theta) > 90 | (IAM < 0)]=0
    
    return IAM