예제 #1
0
def monthly_mean_daylight_hours(latitude, year=None):
    """
    Calculate mean daylight hours for each month of the year for a given latitude.

    :param latitude: Latitude [radians]
    :param year: Year for the daylight hours are required. The only effect of
        *year* is to change the number of days in Feb to 29 if it is a leap year.
        If left as the default, None, then a normal (non-leap) year is assumed.
    :return: Mean daily daylight hours of each month of a year [hours]
    :rtype: List of floats.
    """

    # validate the latitude argument
    _check_latitude_rad(latitude)

    # get the array of days for each month based on whether or not we're in a leap year
    if year is None or not calendar.isleap(year):
        month_days = _MONTH_DAYS_NONLEAP
    else:
        month_days = _MONTH_DAYS_LEAP
        
    # allocate an array of daylight hours for each of the 12 months of the year
    monthly_mean_dlh = np.zeros((12,))
    
    # keep count of the day of the year
    day_of_year = 1
    
    # loop over each calendar month to calculate the daylight hours for the month
    for i, days_in_month in enumerate(month_days):
        cumulative_daylight_hours = 0.0   # cumulative daylight hours for the month
        for _ in range(1, days_in_month + 1):
            daily_solar_declination = solar_declination(day_of_year)
            daily_sunset_hour_angle = sunset_hour_angle(latitude, daily_solar_declination)
            cumulative_daylight_hours += daylight_hours(daily_sunset_hour_angle)
            day_of_year += 1
        
        # calculate the mean daylight hours of the month
        monthly_mean_dlh[i] = cumulative_daylight_hours / days_in_month
        
    return monthly_mean_dlh
예제 #2
0
def sunset_hour_angle(latitude, sol_dec):
    """
    Calculate sunset hour angle (*Ws*) from latitude and solar
    declination.

    Based on FAO equation 25 in Allen et al (1998).

    :param latitude: Latitude [radians]. Note: *latitude* should be negative
        if in the southern hemisphere, positive if in the northern hemisphere.
    :param sol_dec: Solar declination [radians]. Can be calculated using ``sol_dec()``.
    :return: Sunset hour angle [radians].
    :rtype: float
    """
    # validate the latitude and solar declination angle arguments
    _check_latitude_rad(latitude)
    _check_sol_dec_rad(sol_dec)

    cos_sha = -math.tan(latitude) * math.tan(sol_dec)
    
    # If tmp is >= 1 there is no sunset, i.e. 24 hours of daylight
    # If tmp is <= 1 there is no sunrise, i.e. 24 hours of darkness
    # See http://www.itacanet.org/the-sun-as-a-source-of-energy/part-3-calculating-solar-angles/
    # Domain of acos is -1 <= x <= 1 radians (this is not mentioned in FAO-56!)
    return math.acos(min(max(cos_sha, -1.0), 1.0))