AMBHAS
sunlib.py
Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 # -*- coding: utf-8 -*-
00003 """
00004 Created on Mon Feb  7 11:53:29 2011
00005 @author: sat kumar tomer (http://civil.iisc.ernet.in/~satkumar/)
00006 
00007 """
00008 from __future__ import division
00009 import numpy as np
00010 import datetime as dt
00011 
00012 
00013 class sun():
00014     """
00015     This class estimate extral-terrestial solar radiation,
00016     sunset time, sunrise time, daylight hours
00017     
00018     Based on the article:
00019         Empirical Model for Estimating Global Solar Radiation
00020         on Horizontal Surfaces for Selected Cities in 
00021         the Six Geopolitical Zones in Nigeria
00022     By:
00023         M.S. Okundamiya and A.N. Nzeako
00024 
00025         
00026     Example:
00027         lat_deg = 11
00028         lon_deg = 76
00029         doy = 180
00030         foo = sun(doy, lat_deg, lon_deg)
00031         hourly_etr = foo.hourly_ETR(11.0)
00032         daily_etr = foo.daily_ETR()
00033         risetime, settime = foo.set_rise()
00034     """
00035     
00036 
00037     def __init__(self, doy, lat_deg, lon_deg, ze=5.5):
00038         """ initialise the class
00039         Input:
00040             doy:            day of year
00041             lat_deg:        latitude in degree ( south is negative)
00042             lon_deg:        longitude in degree (west is negative)
00043             ze :            time zone in hour
00044         """
00045         self.doy = doy
00046         self._lat_rad = lat_deg*np.pi/180
00047         
00048         self.lon_deg = lon_deg
00049         self.ze = ze
00050 
00051         
00052         
00053         self._Isc = 1367 # solar constant (W/m^2)
00054 
00055         B_deg = (doy-1)*360/365
00056         B_rad = B_deg*np.pi/180
00057         
00058         E = 3.82*(0.000075 + 0.001868*np.cos(B_rad) - 0.032077*np.sin(B_rad) \
00059                     - 0.0141615*np.cos(2*B_rad) -0.04089*np.sin(2*B_rad) )
00060         
00061         self._E = E        
00062         
00063         # declination
00064         delta = 0.4093*np.sin(2*np.pi*(284+doy)/365)
00065         self._delta = delta
00066     
00067         # relative distance of the earth from sun
00068         dr = 1 + 0.0033*np.cos(2*np.pi*doy/365)
00069         self.dr = dr
00070         
00071     def hourly_ETR(self,tc):
00072         """
00073         Input:
00074             tc:     local time in hours
00075         """
00076         ze = self.ze
00077         lat_rad = self._lat_rad
00078         E = self._E 
00079         delta = self._delta
00080         dr = self.dr
00081         
00082         ts = tc + E + self.lon_deg/15 - ze
00083         # hour angle
00084         w = ((ts-12)*15)/180.0*np.pi
00085         # hourly ETR
00086         I0 = self._Isc*dr*(np.sin(lat_rad)*np.sin(delta) + 
00087                 np.cos(lat_rad)*np.cos(delta)*np.cos(w))
00088         
00089         return I0
00090     
00091     def solar_zenith_angle(self,tc):
00092         """
00093         Input:
00094             tc:     local time in hours
00095         Output:
00096             sza:    solar zenith angle in radian
00097         """
00098         ze = self.ze
00099         lat_rad = self._lat_rad
00100         E = self._E 
00101         delta = self._delta
00102         
00103         ts = tc + E + self.lon_deg/15 - ze
00104         # hour angle
00105         w = ((ts-12)*15)/180.0*np.pi
00106         
00107         sza = np.arccos(np.sin(lat_rad)*np.sin(delta) + 
00108                 np.cos(lat_rad)*np.cos(delta)*np.cos(w))
00109         
00110         return sza
00111         
00112     def daily_ETR(self):
00113         """ 
00114         Returns the daily Extra Terrestial Radiation (ETR)
00115         Input:
00116             
00117         Output:
00118             
00119         """
00120         lat_rad = self._lat_rad
00121         delta = self._delta
00122         
00123         # sunset hour angle
00124         ws = np.arccos(-np.tan(lat_rad)*np.tan(delta))
00125         # maximum sunshine hour lenght
00126         self.N = ws*24/np.pi
00127 
00128         H0 = (1/np.pi)*self._Isc*self.dr*(ws*np.sin(delta)*np.sin(lat_rad) +
00129                 np.cos(delta)*np.cos(lat_rad))
00130                 
00131         return H0
00132     
00133     def set_rise(self):
00134         """
00135         Returns the sun set and rise time
00136         """
00137         lon_deg = self.lon_deg
00138         lat_rad = self._lat_rad
00139         delta = self._delta
00140         E = self._E
00141         ze = self.ze
00142         
00143         w1 = np.arccos(- np.tan(delta)*np.tan(lat_rad))
00144         ts1 = 12 - w1*180/np.pi/15 
00145         ts2 = 12 + w1*180/np.pi/15 
00146         
00147         tc1 = ts1 - E - lon_deg/15 + ze
00148         tc2 = ts2 - E - lon_deg/15 + ze
00149         
00150         return tc1, tc2
00151 
00152 
00153 def EarthDistance(dn):
00154     """
00155     module to calculate the earth distance in AU
00156     
00157     Input:
00158         dn:    julian day
00159     
00160     Output:
00161         D:     distance of earth to sun in AU
00162     """
00163     thetaD = 2*np.pi*dn/365
00164     a0 = 1.000110; a1 = 0.034221; b1 = 0.001280; 
00165     a2 = 0.000719; b2 = 0.000077;
00166     D = np.sqrt(a0+a1*np.cos(thetaD)+b1*np.cos(thetaD)+a2*np.cos(2*thetaD)+b2*np.cos(2*thetaD));
00167     return D
00168 
00169 def sun_rise_set(day,month,year,lw=-76.44,ln=11.95):
00170     """
00171     module to calculate the sunset and sunrise time
00172     
00173     Input:
00174         day:    day of the month (0-31)
00175         month:  month
00176         year:   year
00177         lw:     longitude (west positive)
00178         ln:     latitude (north positive)
00179     
00180     Output:
00181         Trise:     sunrise time in GMT+5.5
00182         Tset:      sunset time in GMT+5.5
00183         
00184     """
00185     
00186     Jdate = dt.date(year,month,day).toordinal()-dt.date(2000,1,1).toordinal() + 2451545
00187     n_star = (Jdate - 2451545 - 0.0009) - (lw/360.0)
00188     n = round(n_star)
00189     J_star = 2451545 + 0.0009 + (lw/360.0) + n
00190     
00191     M = np.mod(357.5291 + 0.98560028 * (J_star - 2451545), 360.0)
00192     C = (1.9148 * np.sin(M*np.pi/180)) + (0.0200 * np.sin(2 * M*np.pi/180)) + (0.0003 * np.sin(3 * M*np.pi/180))
00193     
00194     #Now, using C and M, calculate the ecliptical longitude of the sun.
00195     lam = np.mod(M + 102.9372 + C + 180,360)
00196     
00197     #Now there is enough data to calculate an accurate Julian date for solar noon.
00198     Jtransit = J_star + (0.0053 * np.sin(M*np.pi/180)) - (0.0069 * np.sin(2 * lam*np.pi/180))
00199     
00200     #To calculate the hour angle we need to find the declination of the sun
00201     delta = np.arcsin( np.sin(lam*np.pi/180) * np.sin(23.45*np.pi/180) )*180/np.pi
00202     
00203     #Now, calculate the hour angle, which corresponds to half of the arc length of 
00204     #the sun at this latitude at this declination of the sun
00205     H = np.arccos((np.sin(-0.83*np.pi/180) - np.sin(ln*np.pi/180) * np.sin(delta*np.pi/180)) / (np.cos(ln*np.pi/180) * np.cos(delta*np.pi/180)))*180/np.pi
00206     
00207     #Note: If H is undefined, then there is either no sunrise (in winter) or no sunset (in summer) for the supplied latitude.
00208     #Okay, time to go back through the approximation again, this time we use H in the calculation
00209     
00210     J_star_star = 2451545 + 0.0009 + ((H + lw)/360) + n
00211     #The values of M and λ from above don't really change from solar noon to sunset, so there is no need to recalculate them before calculating sunset.
00212     Jset = J_star_star + (0.0053 * np.sin(M*np.pi/180)) - (0.0069 * np.sin(2 * lam*np.pi/180))
00213     
00214     #Instead of going through that mess again, assume that solar noon is half-way between sunrise and sunset (valid for latitudes < 60) and approximate sunrise.
00215     Jrise = Jtransit - (Jset - Jtransit)
00216     
00217     Trise = np.mod(Jrise,1)*24+5.5-12
00218     
00219     Tset = np.mod(Jset,1)*24+5.5+12
00220     
00221     return Trise, Tset 
 All Classes Namespaces Files Functions Variables