1 |
/* |
2 |
THIS CODE COMES FROM APPENDIX A.6 OF REPORT NREL/TP-560-34302 |
3 |
WHICH WAS OBTAINED FROM |
4 |
http://www.osti.gov/bridge/servlets/purl/15003974-iP3z6k/native/15003974.PDF |
5 |
*/ |
6 |
|
7 |
///////////////////////////////////////////// |
8 |
// HEADER FILE for SPA.C // |
9 |
// // |
10 |
// Solar Position Algorithm (SPA) // |
11 |
// for // |
12 |
// Solar Radiation Application // |
13 |
// // |
14 |
// May 12, 2003 // |
15 |
// // |
16 |
// Filename: SPA.H // |
17 |
// // |
18 |
// Afshin Michael Andreas // |
19 |
// afshin_andreas@nrel.gov (303)384-6383 // |
20 |
// // |
21 |
// Measurement & Instrumentation Team // |
22 |
// Solar Radiation Research Laboratory // |
23 |
// National Renewable Energy Laboratory // |
24 |
// 1617 Cole Blvd, Golden, CO 80401 // |
25 |
///////////////////////////////////////////// |
26 |
|
27 |
//////////////////////////////////////////////////////////////////////// |
28 |
// // |
29 |
// Usage: // |
30 |
// // |
31 |
// 1) In calling program, include this header file, // |
32 |
// by adding this line to the top of file: // |
33 |
// #include "spa.h" // |
34 |
// // |
35 |
// 2) In calling program, declare the SPA structure: // |
36 |
// spa_data spa; // |
37 |
// // |
38 |
// 3) Enter the required input values into SPA structure // |
39 |
// (input values listed in comments below) // |
40 |
// // |
41 |
// 4) Call the SPA calculate function and pass the SPA structure // |
42 |
// (prototype is declared at the end of this header file): // |
43 |
// spa_calculate(&spa); // |
44 |
// // |
45 |
// Selected output values (listed in comments below) will be // |
46 |
// computed and returned in the passed SPA structure. Output // |
47 |
// will based on function code selected from enumeration below. // |
48 |
// // |
49 |
// Note: A non-zero return code from spa_calculate() indicates that // |
50 |
// one of the input values did not pass simple bounds tests. // |
51 |
// The valid input ranges and return error codes are also // |
52 |
// listed below. // |
53 |
// // |
54 |
//////////////////////////////////////////////////////////////////////// |
55 |
|
56 |
#ifndef __solar_position_algorithm_header |
57 |
#define __solar_position_algorithm_header |
58 |
|
59 |
|
60 |
//enumeration for function codes to select desired final outputs from SPA |
61 |
enum { |
62 |
SPA_ZA, //calculate zenith and azimuth |
63 |
SPA_ZA_INC, //calculate zenith, azimuth, and incidence |
64 |
SPA_ZA_RTS, //calculate zenith, azimuth, and sun rise/transit/set values |
65 |
|
66 |
SPA_JD, // just calculate the julian day and return |
67 |
SPA_ZA_JD, // as SPA_ZA but don't calculate julian day afresh |
68 |
SPA_ZA_INC_JD, // as SPA_ZA_INC but don't calculate julian day afresh |
69 |
SPA_ZA_RTS_JD, // as SPA_ZA_RTS but don't calculate julian day afresh |
70 |
|
71 |
SPA_ALL, // calculate all SPA output values from datetime inputs |
72 |
}; |
73 |
|
74 |
typedef struct |
75 |
{ |
76 |
//----------------------INPUT VALUES------------------------ |
77 |
|
78 |
int year; // 4-digit year, valid range: -2000 to 6000, error code: 1 |
79 |
int month; // 2-digit month, valid range: 1 to 12, error code: 2 |
80 |
int day; // 2-digit day, valid range: 1 to 31, error code: 3 |
81 |
int hour; // Observer local hour, valid range: 0 to 24, error code: 4 |
82 |
int minute; // Observer local minute, valid range: 0 to 59, error code: 5 |
83 |
int second; // Observer local second, valid range: 0 to 59, error code: 6 |
84 |
|
85 |
double delta_t; // Difference between earth rotation time and terrestrial time |
86 |
// It is derived from observation only and is reported in this |
87 |
// bulletin: http://maia.usno.navy.mil/ser7/ser7.dat, |
88 |
// where delta_t = 32.184 + (TAI-UTC) + DUT1 |
89 |
// valid range: -8000 to 8000 seconds, error code: 7 |
90 |
|
91 |
double timezone; // Observer time zone (negative west of Greenwich) |
92 |
// valid range: -18 to 18 hours, error code: 8 |
93 |
|
94 |
double longitude; // Observer longitude (negative west of Greenwich) |
95 |
// valid range: -180 to 180 degrees, error code: 9 |
96 |
|
97 |
double latitude; // Observer latitude (negative south of equator) |
98 |
// valid range: -90 to 90 degrees, error code: 10 |
99 |
|
100 |
double elevation; // Observer elevation [meters] |
101 |
// valid range: -6500000 or higher meters, error code: 11 |
102 |
|
103 |
double pressure; // Annual average local pressure [millibars] |
104 |
// valid range: 0 to 5000 millibars, error code: 12 |
105 |
|
106 |
double temperature; // Annual average local temperature [degrees Celsius] |
107 |
// valid range: -273 to 6000 degrees Celsius, error code; 13 |
108 |
|
109 |
double slope; // Surface slope (measured from the horizontal plane) |
110 |
// valid range: -360 to 360 degrees, error code: 14 |
111 |
|
112 |
double azm_rotation; // Surface azimuth rotation (measured from south to projection of |
113 |
// surface normal on horizontal plane, negative west) |
114 |
// valid range: -360 to 360 degrees, error code: 15 |
115 |
|
116 |
double atmos_refract;// Atmospheric refraction at sunrise and sunset (0.5667 deg is typical) |
117 |
// valid range: -5 to 5 degrees, error code: 16 |
118 |
|
119 |
int function; // Switch to choose functions for desired output (from enumeration) |
120 |
|
121 |
//-----------------Intermediate OUTPUT VALUES-------------------- |
122 |
|
123 |
double jd; //Julian day |
124 |
double jc; //Julian century |
125 |
|
126 |
double jde; //Julian ephemeris day |
127 |
double jce; //Julian ephemeris century |
128 |
double jme; //Julian ephemeris millennium |
129 |
|
130 |
double l; //earth heliocentric longitude [degrees] |
131 |
double b; //earth heliocentric latitude [degrees] |
132 |
double r; //earth radius vector [Astronomical Units, AU] |
133 |
|
134 |
double theta; //geocentric longitude [degrees] |
135 |
double beta; //geocentric latitude [degrees] |
136 |
|
137 |
double x0; //mean elongation (moon-sun) [degrees] |
138 |
double x1; //mean anomaly (sun) [degrees] |
139 |
double x2; //mean anomaly (moon) [degrees] |
140 |
double x3; //argument latitude (moon) [degrees] |
141 |
double x4; //ascending longitude (moon) [degrees] |
142 |
|
143 |
double del_psi; //nutation longitude [degrees] |
144 |
double del_epsilon; //nutation obliquity [degrees] |
145 |
double epsilon0; //ecliptic mean obliquity [arc seconds] |
146 |
double epsilon; //ecliptic true obliquity [degrees] |
147 |
|
148 |
double del_tau; //aberration correction [degrees] |
149 |
double lamda; //apparent sun longitude [degrees] |
150 |
double nu0; //Greenwich mean sidereal time [degrees] |
151 |
double nu; //Greenwich sidereal time [degrees] |
152 |
|
153 |
double alpha; //geocentric sun right ascension [degrees] |
154 |
double delta; //geocentric sun declination [degrees] |
155 |
|
156 |
double h; //observer hour angle [degrees] |
157 |
double xi; //sun equatorial horizontal parallax [degrees] |
158 |
double del_alpha; //sun right ascension parallax [degrees] |
159 |
double delta_prime; //topocentric sun declination [degrees] |
160 |
double alpha_prime; //topocentric sun right ascension [degrees] |
161 |
double h_prime; //topocentric local hour angle [degrees] |
162 |
|
163 |
double e0; //topocentric elevation angle (uncorrected) [degrees] |
164 |
double del_e; //atmospheric refraction correction [degrees] |
165 |
double e; //topocentric elevation angle (corrected) [degrees] |
166 |
|
167 |
double eot; //equation of time [minutes] |
168 |
double srha; //sunrise hour angle [degrees] |
169 |
double ssha; //sunset hour angle [degrees] |
170 |
double sta; //sun transit altitude [degrees] |
171 |
|
172 |
//---------------------Final OUTPUT VALUES------------------------ |
173 |
|
174 |
double zenith; //topocentric zenith angle [degrees] |
175 |
double azimuth180; //topocentric azimuth angle (westward from south) [-180 to 180 degrees] |
176 |
double azimuth; //topocentric azimuth angle (eastward from north) [ 0 to 360 degrees] |
177 |
double incidence; //surface incidence angle [degrees] |
178 |
|
179 |
double suntransit; //local sun transit time (or solar noon) [fractional hour] |
180 |
double sunrise; //local sunrise time (+/- 30 seconds) [fractional hour] |
181 |
double sunset; //local sunset time (+/- 30 seconds) [fractional hour] |
182 |
|
183 |
} spa_data; |
184 |
|
185 |
//Calculate SPA output values (in structure) based on input values passed in structure |
186 |
int spa_calculate(spa_data *spa); |
187 |
|
188 |
//Calculate Julian Day, return #days. |
189 |
double julian_day (int year, int month, int day, int hour, int minute, int second, double tz); |
190 |
|
191 |
#endif |