pingswept/pysolar

Correct for panel angle

Closed this issue · 1 comments

The get_radiation_direct function nicely takes into account atmospheric effects, which I would not want to lose. However, the value returned is for a PV panel lying flat on the ground. Nobody would install a panel that way. What would be the correction to take into account the orientation of the panel relative to that tangent-to-the-earth position? The result might be greater or less than the horizontal situation so it is not just a dot-product between the normal vectors of the sun-position, the flat ground, and the panel orientation.

This is my first contact with this package, but if I get you correctly, what you want is something which I found implemented here, for example. The source is a book available here, if you have permissions.
This might be a draft:

def correct_radiation_for_terrain(r_beam, r_diff, slope, terrain_a, sun_z,
                              sun_a):
    """
    Correct radiation on a horizontal surface for terrain slope and azimuth.

    The equation is implemented from [1]_ (eq. 69), but sun and terrain azimuth
    angles are given from true north.

    Parameters
    ----------
    r_beam: float or array-like
        Direct beam radiation on a horizontal surface (W m-2).
    r_diff: float or array-like
        Diffuse radiation on a horizontal surface (W m-2).
    slope: float or array-like
        Terrain slope from horizontal (radians).
    terrain_a: float or array-like
        Terrain azimuth from true north (radians).
    sun_z: float or array-like
        Sun zenith angle (radians).
    sun_a: float or array-like
       Sun azimuth angle from true north (radians).

    Returns
    -------
    r_s: float or array-like
        Radiation on a slope with given properties.

    References
    ----------
    .. [1] : Ham, J. M. 2005. Useful Equations and Tables in Micrometeorology.
         In: J.L. Hatfield, J.M. Baker, editors, Micrometeorology in
         Agricultural Systems, Agron. Monogr. 47. ASA, CSSA, and SSSA,
         Madison, WI. p. 533-560. doi:10.2134/agronmonogr47.c23
    """

    r_s = r_beam * ((np.cos(sun_z) * np.cos(slope) + np.sin(sun_z) * np.sin(
        slope) * np.cos(sun_a - terrain_a)) / (np.cos(sun_z))) + r_diff

    return r_s

Unlike in the equation in the book, I think both terrain and sun azimuth should be given in radians from north, except there are other requirements (even though that does not change the equation). Is that what you wanted?