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