Advertisement
Guest User

Calculating insolation

a guest
Nov 28th, 2012
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.45 KB | None | 0 0
  1. /*  solar.cpp: Calculates the solar energy received by places at different latitudes over the year
  2.  *  It is assumed that the earth revolves around the sun in a circular orbit taking exactly 365 days
  3.  *
  4.  *  Author: Raziman T V
  5.  *
  6.  *  License:
  7.  *  You may use this document for whatever purpose you desire, as long as the following conditions are satisfied:
  8.  *  1) You do not use it in a way that suggests that I endorse the use.
  9.  *  2) If you redistribute this code, I would be grateful if you credit me as the author of the code. This is not a requirement.
  10.  *  3) If this code is modified and redistributed with credit to me as the original author, the code should either contain a link
  11.  *     to the source where the unaltered code can be found, or state explicitly that the code has been altered significantly since.
  12.  */
  13.  
  14. # include <cstdio>
  15. # include <cmath>
  16.  
  17. /* Constants and global variables */
  18. const double pi=4*atan(1);
  19. const double epsilon=23.4*pi/180;                           //Tilt of the earth's rotational axis
  20. const double solar_contant=1361*86400;                      //Solar constant : J/day/m^2
  21. const int days_in_year=365;                             //Assume that 1 year = 365 synodic days
  22. const int divide_day_into=1440;                         //Number of parts to divide the day into for calculation
  23. const double integration_time=1/(double)divide_day_into;        //Integration time unit
  24. const int N_calc=days_in_year*divide_day_into;              //Total number of times for which stuff has to be calculated
  25. const double VE_time=31+28+20+0.5;                          //Assume that Vernal equinox occurs at noon on March 21
  26.  
  27. double h[N_calc],delta[N_calc];                         //Hour angle and declination of the sun for each time
  28.  
  29. /* Convert from ecliptic to equatorial coordinates */
  30. void ecliptic_to_equatorial(double lambda,double beta,double &alpha,double &delta)
  31. {
  32.     /*  sin[delta] = sin[beta] * cos[epsilon] + cos[beta] * sin[epsilon] * sin[lambda]
  33.      *  cos[delta] * sin[alpha] = cos[beta] * sin[lambda] * cos[epsilon] - sin[beta] * sin[epsilon]
  34.      *  cos[delta] * cos[alpha] = cos[beta] * cos[lambda]
  35.      */
  36.     delta=asin(sin(beta)*cos(epsilon)+cos(beta)*sin(epsilon)*sin(lambda));
  37.     alpha=atan2(cos(beta)*sin(lambda)*cos(epsilon)-sin(beta)*sin(epsilon),cos(beta)*cos(lambda));
  38. }
  39.  
  40. /* Convert from equatorial to horizontal coordinates */
  41. void equatorial_to_horizontal(double h,double delta,double phi,double &A,double &a)
  42. {
  43.     /*  sin[a] = sin[phi] * sin[delta] + cos[phi] * cos[delta] * cos[h]
  44.      *  cos[a] * cos[A] = cos[delta] * cos[h] * sin [phi] - sin[delta] * cos[phi]
  45.      *  cos[a] * sin[A] = cos[delta] * sin[h]
  46.      */
  47.     a=asin(sin(phi)*sin(delta)+cos(phi)*cos(delta)*cos(h));
  48.     A=atan2(cos(delta)*sin(h),cos(delta)*cos(h)*sin(phi)-sin(delta)*cos(phi));
  49. }
  50.  
  51. /* Convert from time (in days) since vernal equinox to Local Sidereal Time */
  52. double LST(double t_VE)
  53. {
  54.     /*  days_in_year synodic days = (days_in_year+1) sidereal days
  55.      *  Hence sidereal time progresses at the rate of 1+(1/days_in_year) times normal time
  56.      *  Sidereal time at vernal equinox is 12h
  57.      */
  58.     return fmod(t_VE*(1+1/(double)days_in_year)+0.5,1);
  59. }
  60.  
  61. /* Calculate the Hour angle and Declination of the sun for each time value */
  62. void init_HAdec()
  63. {
  64.     for(int day=0,arr=0;day<days_in_year;day++)
  65.     {
  66.         for(int i=0;i<divide_day_into;i++,arr++)
  67.         {
  68.             double t=day+(i+0.5)*integration_time;                      //Time, in days, since new year
  69.             double t_VE=fmod(t+days_in_year-VE_time,days_in_year);          //Time, in days, since vernal equinox
  70.             double lambda=2*pi*t_VE/days_in_year,beta=0,alpha;          //Ecliptic longitude, latitude and Right ascension of the sun
  71.             ecliptic_to_equatorial(lambda,beta,alpha,delta[arr]);           //Find RA and declination of the sun
  72.             h[arr]=2*pi*LST(t_VE)-alpha;                                //Calculate Hour angle of sun : HA = LST -RA
  73.         }
  74.     }
  75. }
  76.  
  77. int main()
  78. {
  79.     init_HAdec();
  80.     for(int lat=-90;lat<=90;lat++)
  81.     {
  82.         printf("%d\t",lat);
  83.         double phi=lat*pi/180;                                      //Latitude in radians
  84.         for(int day=0,arr=0;day<days_in_year;day++)
  85.         {
  86.             double daily_energy=0;                                  //Total energy received at a place with the given latitude over the day
  87.             for(int i=0;i<divide_day_into;i++,arr++)
  88.             {
  89.                 double a,A;                                         //Altitude and azimuth of the sun at the given place and time
  90.                 equatorial_to_horizontal(h[arr],delta[arr],phi,A,a);        //Calculate the altitude and azimuth values from HA and dec
  91.                 if(a>=0)daily_energy+=integration_time*sin(a)*solar_contant;//If the sun is above the horizon, increment the energy received
  92.             }
  93.             printf("%lf\t",daily_energy);
  94.         }
  95.         printf("\n");
  96.     }
  97.     return 0;
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement