ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/sun.c
(Generate patch)

Comparing ray/src/gen/sun.c (file contents):
Revision 2.2 by greg, Fri Oct 2 16:12:29 1992 UTC vs.
Revision 2.7 by greg, Thu Nov 7 23:15:07 2019 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1989 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *           SOLAR CALCULATIONS
6   *
7   *               3/31/87
8   *
9 + *              Michalsky algorithm added October 2019:
10 + *              "The Astronomical Almanac's Algorithm for Approximate
11 + *              Solar Position (1950-2050)" by Joseph J. Michalsky,
12 + *              published in 1988 in Solar Energy, Vol. 40, No. 3.
13 + *              Also added correction to sdec() (365 was 368 originally)
14 + *
15   */
16  
17   #include  <math.h>
18 + #include  "sun.h"
19  
20 < #define  PI  3.141592654
20 > #ifdef M_PI
21 > #define  PI     M_PI
22 > #else
23 > #define  PI     3.14159265358979323846
24 > #endif
25 > #undef DEG
26 > #define DEG     (PI/180.)
27  
18 double  s_latitude = 0.66;      /* site latitude (radians) */
19 double  s_longitude = 2.13;     /* site longitude (radians) */
20 double  s_meridian = 2.0944;    /* standard meridian (radians) */
28  
29 + double  s_latitude = 0.66;      /* site latitude (radians north of equator) */
30 + double  s_longitude = 2.13;     /* site longitude (radians west of Greenwich) */
31 + double  s_meridian = 120.*DEG;  /* standard meridian (radians west) */
32  
33 +
34   int
35 < jdate(month, day)               /* Julian date (days into year) */
36 < int  month, day;
35 > jdate(          /* Julian date (days into year) */
36 >        int month,
37 >        int day
38 > )
39   {
40          static short  mo_da[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
41          
# Line 31 | Line 44 | int  month, day;
44  
45  
46   double
47 < stadj(jd)               /* solar time adjustment from Julian date */
48 < int  jd;
47 > stadj(          /* solar time adjustment from Julian date */
48 >        int  jd
49 > )
50   {
51 <        return( 0.170 * sin( (4*PI/373) * (jd - 80) ) -
52 <                0.129 * sin( (2*PI/355) * (jd - 8) ) +
53 <                12 * (s_meridian - s_longitude) / PI );
51 >        return( 0.170 * sin( (4.*PI/373.) * (jd - 80) ) -
52 >                0.129 * sin( (2.*PI/355.) * (jd - 8) ) +
53 >                (12./PI) * (s_meridian - s_longitude) );
54   }
55  
56  
57   double
58 < sdec(jd)                /* solar declination angle from Julian date */
59 < int  jd;
58 > sdec(           /* solar declination angle from Julian date */
59 >        int  jd
60 > )
61   {
62 <        return( 0.4093 * sin( (2*PI/368) * (jd - 81) ) );
62 >        return( 0.4093 * sin( (2.*PI/365.) * (jd - 81) ) );
63   }
64  
65  
66   double
67 < salt(sd, st)    /* solar altitude from solar declination and solar time */
68 < double  sd, st;
67 > salt(   /* solar altitude from solar declination and solar time */
68 >        double sd,
69 >        double st
70 > )
71   {
72          return( asin( sin(s_latitude) * sin(sd) -
73 <                        cos(s_latitude) * cos(sd) * cos(st*(PI/12)) ) );
73 >                        cos(s_latitude) * cos(sd) * cos(st*(PI/12.)) ) );
74   }
75  
76  
77   double
78 < sazi(sd, st)    /* solar azimuth from solar declination and solar time */
79 < double  sd, st;
78 > sazi(   /* solar azimuth from solar declination and solar time */
79 >        double sd,
80 >        double st
81 > )
82   {
83 <        return( -atan2( cos(sd)*sin(st*(PI/12)),
83 >        return( -atan2( cos(sd)*sin(st*(PI/12.)),
84                          -cos(s_latitude)*sin(sd) -
85 <                        sin(s_latitude)*cos(sd)*cos(st*(PI/12)) ) );
85 >                        sin(s_latitude)*cos(sd)*cos(st*(PI/12.)) ) );
86 > }
87 >
88 >
89 > /****************** More accurate Michalsky algorithm ****************/
90 >
91 >
92 > /* circle normalization */
93 > static double
94 > norm_cir(double r, const double p)
95 > {
96 >        while (r < 0) r += p;
97 >        while (r >= p) r -= p;
98 >        return(r);
99 > }
100 >
101 >
102 > /* Almanac Julian date relative to noon UT on Jan 1, 2000 (fractional days) */
103 > double
104 > mjdate(int year, int month, int day, double hour)
105 > {
106 >        int     jd = jdate(month, day);
107 >        jd += (month > 2) & !(year&3);
108 >        jd += (year - 1949)*365 + (year - 1949)/4;
109 >        hour += s_meridian*(12./PI);
110 >        return(jd + hour*(1./24.) + (2432916.5-2451545.));
111 > }
112 >
113 >
114 > /* Solar declination (and solar time) from Almanac Julian date (fractional) */
115 > double
116 > msdec(double mjd, double *stp)
117 > {                                       /* Ecliptic coordinates (radians) */
118 >        double  L = norm_cir(280.460*DEG + 0.9856474*DEG*mjd, 2.*PI);
119 >        double  g = norm_cir(357.528*DEG + 0.9856003*DEG*mjd, 2.*PI);
120 >        double  l = L + 1.915*DEG*sin(g) + 0.020*DEG*sin(2.*g);
121 >        double  ep = 23.439*DEG - 4e-7*DEG*mjd;
122 >        double  sin_l = sin(l);
123 >
124 >        if (stp) {                      /* solar time requested, also? */
125 >                double  ra = atan2(sin_l*cos(ep), cos(l));
126 >                double  utime = 24.*(mjd - floor(mjd)) + 12.;
127 >                double  gmst = 6.697375 + 0.0657098242*mjd + utime;
128 >                double  lmst = gmst - s_longitude*(12./PI);
129 >
130 >                *stp = norm_cir(lmst - ra*(12./PI) + 12., 24.);
131 >        }
132 >        return(asin(sin(ep)*sin_l));    /* return solar declination angle */
133   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines