DAS  3.1.6 - 18/09/2017
SOLPOS.C
Go to the documentation of this file.
1 /*============================================================================
2 * Contains:
3 * S_date (computes month/day from day number)
4 * INPUTS: S_year, S_daynum
5 * OUTPUTS: S_year, S_month, S_day
6 *
7 * S_solpos (computes solar position and intensity
8 * from time and place)
9 * INPUTS: S_month, S_day, S_latitude, S_longitude, S_timezone
10 * OPTIONAL: S_year, S_hour, S_minute, S_second,
11 * S_press, S_temp, S_tilt, S_aspect
12 * OUTPUTS: EVERY variable beginning with "S_"
13 * (defined beneath this comment block)
14 *
15 * Usage:
16 * In calling program, just after other 'includes', insert:
17 *
18 * #include "solpos.h"
19 *
20 * Martin Rymes
21 * National Renewable Energy Laboratory
22 * 25 March 1998
23 *
24 * 27 April 1999 REVISION: Corrected leap year in S_date.
25 * 14 January 2000 REVISION: Corrected leap year in S_solpos.
26 *----------------------------------------------------------------------------*/
27 #include <math.h>
28 #include <string.h>
29 #include <stdio.h>
30 
31 
32 
33 int S_day = -99; /* Day of month (May 27 = 27, etc.) */
34 int S_daynum = -999; /* Day number (day of year; Feb 1 = 32 ) */
35 int S_hour = 12; /* Hour of day, 0 - 23 */
36 int S_minute = 0; /* Minute of hour, 0 - 59 */
37 int S_month = -99; /* Month number (Jan = 1, Feb = 2, etc.) */
38 int S_second = 0; /* Second of minute, 0 - 59 */
39 int S_year = 2001; /* 4-digit year (2-digit is assumed 19xx) */
40 
41 double S_amass; /* Relative optical airmass */
42 double S_ampress; /* Pressure-corrected airmass */
43 double S_aspect = 180.0; /* Azimuth of panel surface (direction it
44  faces) N=0, E=90, S=180, W=270 */
45 double S_azim; /* Solar azimuth angle: N=0, E=90, S=180, W=270 */
46 double S_cosinc; /* Cosine of solar incidence angle on panel */
47 double S_dayang; /* Day angle (daynum*360/year-length) degrees */
48 double S_declin; /* Declination--zenith angle of solar noon
49  at equator, degrees NORTH */
50 double S_eclong; /* Ecliptic longitude, degrees */
51 double S_ecobli; /* Obliquity of ecliptic */
52 double S_ectime; /* Time of ecliptic calculations */
53 double S_elevref; /* Solar elevation angle,
54  deg. from horizon, refracted */
55 double S_eqntim; /* Equation of time (TST - LMT), minutes */
56 double S_erv; /* Earth radius vector
57  (multiplied to solar constant) */
58 double S_etr; /* Extraterrestrial (top-of-atmosphere) W/sq m
59  global horizontal solar irradiance */
60 double S_etrn; /* Extraterrestrial (top-of-atmosphere) W/sq m
61  direct normal solar irradiance */
62 double S_etrtilt; /* Extraterrestrial (top-of-atmosphere) W/sq m
63  global irradiance on a tilted surface */
64 double S_gmst; /* Greenwich mean sidereal time, hours */
65 double S_hrang; /* Hour angle--hour of sun from solar noon,
66  degrees WEST */
67 double S_julday; /* Julian Day of 1 JAN 2000 minus 2,400,000 days
68  (in order to regain single precision) */
69 double S_latitude = -99.0; /* Latitude, degrees north (south negative) */
70 double S_longitude = -999.0; /* Longitude, degrees east (west negative) */
71 double S_lmst; /* Local mean sidereal time, degrees */
72 double S_mnanom; /* Mean anomaly, degrees */
73 double S_mnlong; /* Mean longitude, degrees */
74 double S_rascen; /* Right ascension, degrees */
75 double S_press = 1013.0; /* Surface pressure, millibars */
76 double S_prime; /* Factor that normalizes Kt, Kn, etc. */
77 double S_sbcf; /* Shadow-band correction factor */
78 double S_solcon = 1367.0; /* Solar constant, 1367 W/sq m */
79 double S_ssha; /* Sunset(/rise) hour angle, degrees */
80 double S_sunrise; /* Sunrise time, minutes from midnight,
81  local, no refraction */
82 double S_sunset; /* Sunset time, minutes from midnight,
83  local, no refraction */
84 double S_temp = 0.0; /* Ambient dry-bulb temperature, degrees C */
85 double S_tilt = 0.0; /* Degrees tilt from horizontal of panel */
86 double S_timezone = -99.0; /* Time zone, east (west negative).
87  USA: Mountain = -7, Central = -6, etc. */
88 double S_tst; /* True solar time, minutes from midnight */
89 double S_tstfix; /* True solar time - local standard time */
90 double S_unprime; /* Factor that denormalizes Kt', Kn', etc. */
91 double S_utime; /* Universal (Greenwich) standard time */
92 double S_zenetr; /* Solar zenith angle,
93  no atmospheric correction (= ETR) */
94 double S_zenref; /* Solar zenith angle,
95  deg. from zenith, refracted */
96 
97 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
98 *
99 * Temporary variables used only in this file:
100 *
101 *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
102 static int ndy; /* Temporary S_daynum */
103 static int leap; /* Leap year counter */
104 static int imon; /* Month (month_days) array counter */
105 static int lenyr[2] = { 365, 366 };
106  /* length of year; 0 = non-leap, 1 = leap year */
107 static int month_days[2][13] = { 0, 0, 31, 59, 90, 120, 151,
108  181, 212, 243, 273, 304, 334,
109  0, 0, 31, 60, 91, 121, 152,
110  182, 213, 244, 274, 305, 335 };
111  /* cumulative number of days prior to beginning of month */
112 
113 static double bottom; /* denomerator (bottom) of the fraction */
114 static double c2; /* cosine of d2 */
115 static double ca; /* cosine of the solar azimuth angle */
116 static double cd; /* cosine of the day angle or declination */
117 static double cdcl; /* ( cd * cl ) */
118 static double ce; /* cosine of the solar elevation */
119 static double cecl; /* ( ce * cl ) */
120 static double ch; /* cosine of the hour angle */
121 static double cl; /* cosine of the latitude */
122 static double cp; /* cosine of the panel aspect */
123 static double cssha; /* cosine of the sunset hour angle */
124 static double ct; /* cosine of the panel tilt */
125 static double cz; /* cosine of the solar zenith angle */
126 static double d2; /* Double S_dayang */
127 static double degrad = 57.295779513;
128  /* converts from radians to degrees */
129 static double delta; /* difference between current year and 1949 */
130 static double elev; /* temporary elevation angle */
131 static double p; /* used to compute S_sbcf */
132 static double prestemp; /* temporary pressure/temperature correction */
133 static double raddeg = 0.0174532925;
134  /* converts from degrees to radians */
135 static double refcor; /* temporary refraction correction */
136 static double s2; /* sine of d2 */
137 static double sa; /* sine of the solar azimuth angle */
138 static double sd; /* sine of the day angle or declination */
139 static double se; /* sine of the solar elevation */
140 static double sl; /* sine of the latitude */
141 static double sp; /* sine of the panel aspect */
142 static double st; /* sine of the panel tilt */
143 static double sz; /* sine of the solar zenith angle */
144 static double tanelev; /* tangent of the solar elevation angle */
145 static double t1; /* used to compute S_sbcf */
146 static double t2; /* used to compute S_sbcf */
147 static double top; /* numerator (top) of the fraction */
148 
149 /*============================================================================
150 * Integer function S_date, adapted from the VAX solar libraries
151 *
152 * This function computes the month/day from the day number.
153 *
154 * Requires:
155 * Year and day number:
156 * S_year NOTE: 2-digit year "xx" is assumed "19xx"
157 * DEFAULT S_year = 2001
158 * S_daynum RANGE: -1 to a large positive integer
159 *
160 * Returns:
161 * Year, month, day:
162 * S_year
163 * S_month
164 * S_day
165 *----------------------------------------------------------------------------*/
166 int S_date (void)
167 {
168  /* We will allow -1 (in order to adjust to the previous year) but no
169 less */
170  if ( S_daynum < -1 ) {
171  printf ( "S_date => Please fix the day number: %10d\n", S_daynum );
172  return ( -1 );
173  }
174 
175  /* If a 2-digit year "xx" is given, assume "19xx" */
176  if ( S_year < 100 )
177  S_year += 1900;
178 
179  /* Set the leap year switch */
180  if ( ((S_year % 4) == 0) &&
181  ( ((S_year % 100) != 0) || ((S_year % 400) == 0) ) )
182  leap = 1;
183  else
184  leap = 0;
185 
186  /* If S_daynum is a large number, it is in a future year */
187  ndy = S_daynum;
188  while ( ndy > lenyr[leap] ) {
189  ++S_year;
190  ndy -= lenyr[leap];
191  if ( ((S_year % 4) == 0) &&
192  ( ((S_year % 100) != 0) || ((S_year % 400) == 0) ) )
193  leap = 1;
194  else
195  leap = 0;
196  }
197 
198  /* A non-positive day number indicates the previous year */
199  if ( ndy <= 0 ) {
200  --S_year;
201  leap = 0;
202  ndy += 365;
203  }
204 
205  /* Now that the year is fixed, find the month */
206  imon = 12;
207  while ( ndy <= month_days [leap][imon] )
208  --imon;
209 
210  /* Set the month and day of month */
211  S_month = imon;
212  S_day = ndy - month_days[leap][imon];
213 
214  return ( 0 );
215 }
216 /*============================================================================
217 * Integer function S_solpos, adapted from the VAX solar libraries
218 *
219 * This function calculates the apparent solar position and the
220 * intensity of the sun (theoretical maximum solar energy) from
221 * time and place on Earth.
222 *
223 * Requires:
224 * Date and time:
225 * S_year DEFAULT 2001
226 * S_month
227 * S_day
228 * S_hour DEFAULT 12
229 * S_minute DEFAULT 0
230 * S_second DEFAULT 0
231 * Location:
232 * S_latitude
233 * S_longitude
234 * Location/time adjuster:
235 * S_timezone
236 * Atmospheric pressure and temperature:
237 * S_press DEFAULT 1013.0 mb
238 * S_temp DEFAULT 10.0 degrees C
239 * Tilt of flat surface that receives solar energy:
240 * S_aspect DEFAULT 180 (South)
241 * S_tilt DEFAULT 0 (Horizontal)
242 *
243 * Returns:
244 * everything defined at the top of this listing.
245 *----------------------------------------------------------------------------*/
246 int S_solpos (void)
247 {
248  /* No absurd dates, please. */
249  if ( (S_month < 1) || (S_month > 12) )
250  {
251  printf ( "S_solpos => Please fix the month: %10d\n", S_month );
252  return ( -1 );
253  }
254  else if ( (S_day < 1) || (S_day > 31 ) )
255  {
256  printf ( "S_solpos => Please fix the day of month: %10d\n", S_day );
257  return ( -1 );
258  }
259 
260  /* No absurd times, please. */
261  if ( (S_hour < 0) || (S_hour > 23) )
262  {
263  printf ( "S_solpos => Please fix the hour: %10d\n", S_hour );
264  return ( -1 );
265  }
266  else if ( (S_minute < 0) || (S_minute > 59) )
267  {
268  printf ( "S_solpos => Please fix the minute: %10d\n", S_minute );
269  return ( -1 );
270  }
271  else if ( (S_second < 0) || (S_second > 59) )
272  {
273  printf ( "S_solpos => Please fix the second: %10d\n", S_second );
274  return ( -1 );
275  }
276  else if ( (S_timezone < -12.0) || (S_timezone > 12.0) )
277  {
278  printf ( "S_solpos => Please fix the time zone: %10.4f\n",
279 S_timezone );
280  return ( -1 );
281  }
282  /* No absurd locations, please. */
283  if ( fabs (S_longitude) > 180.0 ) {
284  printf ( "S_solpos => Please fix the longitude: %10.4f\n",
285 S_longitude );
286  return ( -1 );
287  }
288  else if ( fabs (S_latitude) > 90.0 ) {
289  printf ( "S_solpos => Please fix the latitude: %10.4f\n",
290 S_latitude );
291  return ( -1 );
292  }
293 
294  /* No silly temperatures or pressures, please. */
295  if ( fabs (S_temp) > 100.0 ) {
296  printf ( "S_solpos => Please fix the temperature: %10.4f\n", S_temp );
297  return ( -1 );
298  }
299  else if ( (S_press < 0.0) || (S_press > 2000.0) ) {
300  printf ( "S_solpos => Please fix the pressure: %10.4f\n", S_press );
301  return ( -1 );
302  }
303 
304  /* Day number */
305  /* (convert day-of-month to day-of-year (non-leap)) */
307 
308  /* (if no year was entered, give it an arbitrary 2001. Also, turn
309  2-digit years into 19xx. Note that if the year > 1999, it had
310  better be 4-digit) */
311  if ( S_year < 0 )
312  S_year = 2001;
313  else if ( S_year < 100 )
314  S_year += 1900;
315 
316  /* (now adjust for leap year) */
317  if ( ((S_year % 4) == 0) &&
318  ( ((S_year % 100) != 0) || ((S_year % 400) == 0) ) &&
319  (S_month > 2) )
320  S_daynum += 1;
321 
322  /* Day angle */
323  /* Iqbal, M. 1983. An Introduction to Solar Radiation.
324  Academic Press, NY., page 3 */
325  S_dayang = 360.0 * ( S_daynum - 1 ) / 365.0;
326 
327  /* Earth radius vector * solar constant = solar energy */
328  /* Spencer, J. W. 1971. Fourier series representation of the
329 position
330  of the sun. Search 2 (5), page 172 */
331  sd = sin (raddeg * S_dayang);
332  cd = cos (raddeg * S_dayang);
333  d2 = 2.0 * S_dayang;
334  c2 = cos (raddeg * d2);
335  s2 = sin (raddeg * d2);
336 
337  S_erv = 1.000110 + 0.034221 * cd + 0.001280 * sd;
338  S_erv += 0.000719 * c2 + 0.000077 * s2;
339 
340  /* Universal Coordinated (Greenwich standard) time */
341  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
342  approximate solar position (1950-2050). Solar Energy 40 (3),
343  pp. 227-235. */
344  S_utime = S_hour * 3600.0 + S_minute * 60.0 + S_second;
345  S_utime = S_utime / 3600.0 - S_timezone;
346 
347  /* Julian Day minus 2,400,000 days (to eliminate roundoff errors) */
348  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
349  approximate solar position (1950-2050). Solar Energy 40 (3),
350  pp. 227-235. */
351 
352  delta = S_year - 1949;
353  leap = (int) ( delta / 4.0 );
354  S_julday = 32916.5 + delta * 365.0 + leap + S_daynum + S_utime / 24.0;
355 
356  if ( ( (S_year % 100) == 0 ) && ( (S_year % 400) != 0) )
357  --S_julday;
358 
359  /* Time used in the calculation of ecliptic coordinates */
360  /* Noon 1 JAN 2000 = 2,400,000 + 51,545 days Julian Date */
361  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
362  approximate solar position (1950-2050). Solar Energy 40 (3),
363  pp. 227-235. */
364  S_ectime = S_julday - 51545.0;
365 
366  /* Mean longitude */
367  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
368  approximate solar position (1950-2050). Solar Energy 40 (3),
369  pp. 227-235. */
370  S_mnlong = 280.460 + 0.9856474 * S_ectime;
371 
372  /* (dump the multiples of 360, so the answer is between 0 and 360) */
373  S_mnlong -= 360.0 * (int) ( S_mnlong / 360.0 );
374  if ( S_mnlong < 0.0 )
375  S_mnlong += 360.0;
376 
377  /* Mean anomaly */
378  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
379  approximate solar position (1950-2050). Solar Energy 40 (3),
380  pp. 227-235. */
381  S_mnanom = 357.528 + 0.9856003 * S_ectime;
382 
383  /* (dump the multiples of 360, so the answer is between 0 and 360) */
384  S_mnanom -= 360.0 * (int) ( S_mnanom / 360.0 );
385  if ( S_mnanom < 0.0 )
386  S_mnanom += 360.0;
387 
388  /* Ecliptic longitude */
389  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
390  approximate solar position (1950-2050). Solar Energy 40 (3),
391  pp. 227-235. */
392  S_eclong = S_mnlong + 1.915 * sin ( S_mnanom * raddeg ) +
393  0.020 * sin ( 2.0 * S_mnanom * raddeg );
394 
395  /* (dump the multiples of 360, so the answer is between 0 and 360) */
396  S_eclong -= 360.0 * (int) ( S_eclong / 360.0 );
397  if ( S_eclong < 0.0 )
398  S_eclong += 360.0;
399 
400  /* Obliquity of the ecliptic */
401  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
402  approximate solar position (1950-2050). Solar Energy 40 (3),
403  pp. 227-235. */
404  S_ecobli = 23.439 + 4.0e-07 * S_ectime;
405 
406  /* Declination */
407  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
408  approximate solar position (1950-2050). Solar Energy 40 (3),
409  pp. 227-235. */
410  S_declin = degrad * asin ( sin (S_ecobli * raddeg) *
411  sin (S_eclong * raddeg) );
412 
413  /* Right ascension */
414  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
415  approximate solar position (1950-2050). Solar Energy 40 (3),
416  pp. 227-235. */
417  top = cos ( raddeg * S_ecobli ) * sin ( raddeg * S_eclong );
418  bottom = cos ( raddeg * S_eclong );
419 
420  S_rascen = degrad * atan2 ( top, bottom );
421 
422  /* (make it a positive angle) */
423  if ( S_rascen < 0.0 )
424  S_rascen += 360.0;
425 
426  /* Greenwich mean sidereal time */
427  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
428  approximate solar position (1950-2050). Solar Energy 40 (3),
429  pp. 227-235. */
430  S_gmst = 6.697375 + 0.0657098242 * S_ectime + S_utime;
431 
432  /* (dump the multiples of 24, so the answer is between 0 and 24) */
433  S_gmst -= 24.0 * (int) ( S_gmst / 24.0 );
434  if ( S_gmst < 0.0 )
435  S_gmst += 24.0;
436 
437  /* Local mean sidereal time */
438  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
439  approximate solar position (1950-2050). Solar Energy 40 (3),
440  pp. 227-235. */
441  S_lmst = S_gmst * 15.0 + S_longitude;
442 
443  /* (dump the multiples of 360, so the answer is between 0 and 360) */
444  S_lmst -= 360.0 * (int) ( S_lmst / 360.0 );
445  if ( S_lmst < 0.)
446  S_lmst += 360.0;
447 
448  /* Hour angle */
449  /* Michalsky, J. 1988. The Astronomical Almanac's algorithm for
450  approximate solar position (1950-2050). Solar Energy 40 (3),
451  pp. 227-235. */
452  S_hrang = S_lmst - S_rascen;
453 
454  /* (force it between -180 and 180 degrees) */
455  if ( S_hrang < -180.0 )
456  S_hrang += 360.0;
457  else if ( S_hrang > 180.0 )
458  S_hrang -= 360.0;
459 
460  /* ETR solar zenith angle */
461  /* Iqbal, M. 1983. An Introduction to Solar Radiation.
462  Academic Press, NY., page 15 */
463  cd = cos ( raddeg * S_declin );
464  ch = cos ( raddeg * S_hrang );
465  cl = cos ( raddeg * S_latitude );
466  sd = sin ( raddeg * S_declin );
467  sl = sin ( raddeg * S_latitude );
468 
469  cz = sd * sl + cd * cl * ch;
470 
471  /* (watch out for the roundoff errors) */
472  if ( fabs (cz) > 1.0 ) {
473  if ( cz >= 0.0 )
474  cz = 1.0;
475  else
476  cz = -1.0;
477  }
478 
479  S_zenetr = acos ( cz ) * degrad;
480 
481  /* (limit the degrees below the horizon to 9 [+90 -> 99]) */
482  // if ( S_zenetr > 99.0 )
483  // S_zenetr = 99.0;
484 
485  /* Sunset hour angle */
486  /* Iqbal, M. 1983. An Introduction to Solar Radiation.
487  Academic Press, NY., page 16 */
488  S_ssha = 90.0;
489  cdcl = cd * cl;
490 
491  if ( fabs ( cdcl ) >= 0.001 ) {
492  cssha = -sl * sd / cdcl;
493 
494  /* This keeps the cosine from blowing on roundoff */
495  if ( cssha < -1.0 )
496  S_ssha = 180.0;
497  else if ( cssha > 1.0 )
498  S_ssha = 0.0;
499  else
500  S_ssha = degrad * acos ( cssha );
501  }
502 
503  /* Shadowband correction factor */
504  /* Drummond, A. J. 1956. A contribution to absolute pyrheliometry.
505  Q. J. R. Meteorol. Soc. 82, pp. 481-493 */
506  p = 0.1526 * pow (cd,3);
507  t1 = sl * sd * S_ssha * raddeg;
508  t2 = cl * cd * sin ( S_ssha * raddeg );
509  S_sbcf = 0.04 + 1.0 / ( 1.0 - p * ( t1 + t2 ) );
510 
511  /* TST -> True Solar Time = local standard time + TSTfix */
512  /* Iqbal, M. 1983. An Introduction to Solar Radiation.
513  Academic Press, NY., page 13 */
514  S_tst = ( 180.0 + S_hrang ) * 4.0;
515  S_tstfix = S_tst - S_hour * 60.0 - S_minute - S_second / 60.0;
516  S_eqntim = S_tstfix + 60.0 * S_timezone - 4.0 * S_longitude;
517 
518  /* Sunrise and sunset times */
519  if ( S_ssha <= 1.0 ) {
520  S_sunrise = 2999.0;
521  S_sunset = -2999.0;
522  }
523  else if ( S_ssha >= 179.0 ) {
524  S_sunrise = -2999.0;
525  S_sunset = 2999.0;
526  }
527  else {
528  S_sunrise = 720.0 - 4.0 * S_ssha - S_tstfix;
529  S_sunset = 720.0 + 4.0 * S_ssha - S_tstfix;
530  }
531 
532  /* Solar azimuth angle */
533  /* Iqbal, M. 1983. An Introduction to Solar Radiation.
534  Academic Press, NY., page 15 */
535  ce = sin ( raddeg * S_zenetr );
536  se = cos ( raddeg * S_zenetr );
537 
538  S_azim = 180.0;
539  cecl = ce * cl;
540  if ( fabs ( cecl ) >= 0.001 ) {
541  ca = ( se * sl - sd ) / cecl;
542  if ( ca > 1.0 )
543  ca = 1.0;
544  else if ( ca < -1.0 )
545  ca = -1.0;
546 
547  S_azim = 180.0 - acos ( ca ) * degrad;
548  if ( S_hrang > 0 )
549  S_azim = 360.0 - S_azim;
550  }
551 
552  /* Refraction correction */
553  /* Zimmerman, John C. 1981. Sun-pointing programs and their
554 accuracy.
555  SAND81-0761, Experimental Systems Operation Division 4721,
556  Sandia National Laboratories, Albuquerque, NM. */
557 
558  elev = 90.0 - S_zenetr;
559 
560  /* If the sun is near zenith, the algorithm bombs; refraction near 0 */
561  if ( elev > 85.0 )
562  refcor = 0.0;
563 
564  /* Otherwise, we have refraction */
565  else {
566  tanelev = tan ( raddeg * elev );
567  if ( elev >= 5.0 )
568  refcor = 58.1 / tanelev -
569  0.07 / ( pow (tanelev,3) ) +
570  0.000086 / ( pow (tanelev,5) );
571  else if ( elev >= -0.575 )
572  refcor = 1735.0 + elev * ( -518.2 + elev * ( 103.4 +
573  elev * ( -12.79 + elev * 0.711 ) ) );
574  else
575  refcor = -20.774 / tanelev;
576 
577  prestemp = ( S_press * 283.0 ) / ( 1013.0 * ( 273.0 + S_temp ) );
578  refcor *= prestemp / 3600.0;
579  }
580 
581  /* Refracted solar elevation angle */
582  S_elevref = elev + refcor;
583 
584  /* (limit the degrees below the horizon to 9) */
585 // if ( S_elevref < -9.0 )
586 // S_elevref = -9.0;
587 
588  /* Refracted solar zenith angle */
589  S_zenref = 90. - S_elevref;
590 
591  /* Airmass */
592  /* Kasten, F. and Young, A. 1989. Revised optical air mass
593 tables and
594  approximation formula. Applied Optics 28 (22), pp. 4735-4738 */
595  cz = cos ( raddeg * S_zenref );
596  if ( S_zenref > 93.0 )
597  S_amass = -1.0;
598  else
599  S_amass = 1.0 / ( cz + 0.50572 * pow ((96.07995 - S_zenref),-1.6364) );
600 
601  S_ampress = S_amass * S_press / 1013.0;
602 
603  /* Prime and Unprime */
604  /* Prime converts Kt to normalized Kt', etc.
605  Unprime deconverts Kt' to Kt, etc. */
606  /* Perez, R., P. Ineichen, Seals, R., & Zelenka, A. 1990. Making
607 full use
608  of the clearness index for parameterizing hourly insolation
609 conditions.
610  Solar Energy 45 (2), pp. 111-114 */
611  S_unprime = 1.031 * exp ( -1.4 / ( 0.9 + 9.4 / S_amass ) ) + 0.1;
612  S_prime = 1.0 / S_unprime;
613 
614  /* Cosine of the angle between the sun and a tipped flat surface,
615  useful for calculating solar energy on tilted surfaces */
616  ca = cos ( raddeg * S_azim );
617  cp = cos ( raddeg * S_aspect );
618  ct = cos ( raddeg * S_tilt );
619  sa = sin ( raddeg * S_azim );
620  sp = sin ( raddeg * S_aspect );
621  st = sin ( raddeg * S_tilt );
622  sz = sin ( raddeg * S_zenref );
623  S_cosinc = cz * ct + sz * st * ( ca * cp + sa * sp );
624 
625  /* Extraterrestrial (top-of-atmosphere) solar irradiance */
626  if ( cz > 0.0 ) {
627  S_etrn = S_solcon * S_erv;
628  S_etr = S_etrn * cz;
629  }
630  else {
631  S_etrn = 0.0;
632  S_etr = 0.0;
633  }
634 
635  if ( S_cosinc > 0.0 )
637  else
638  S_etrtilt = 0.0;
639 
640  return ( 0 );
641 }
static double s2
Definition: SOLPOS.C:136
double S_mnanom
T: Mean anomaly, degrees */.
Definition: SOLPOS.C:72
double S_zenetr
Definition: SOLPOS.C:92
double S_julday
Definition: SOLPOS.C:67
double S_etr
Definition: SOLPOS.C:58
double S_press
Definition: SOLPOS.C:75
static double ce
Definition: SOLPOS.C:118
static double prestemp
Definition: SOLPOS.C:132
double S_gmst
T: Greenwich mean sidereal time, hours */.
Definition: SOLPOS.C:64
static double ca
Definition: SOLPOS.C:115
static double c2
Definition: SOLPOS.C:114
static double ct
Definition: SOLPOS.C:124
double S_tst
T: True solar time, minutes from midnight */.
Definition: SOLPOS.C:88
double S_temp
Definition: SOLPOS.C:84
static double sp
Definition: SOLPOS.C:141
double S_dayang
T: Day angle (daynum*360/year-length) degrees.
Definition: SOLPOS.C:47
int S_minute
I: Minute of hour, 0 - 59, DEFAULT = 0 I: Minute of hour, 0 - 59, DEFAULT = 0.
Definition: SOLPOS.C:36
static double sa
Definition: SOLPOS.C:137
double S_timezone
Definition: SOLPOS.C:86
int S_second
I: Second of minute, 0 - 59, DEFAULT = 0 I: Second of minute, 0 - 59, DEFAULT = 0.
Definition: SOLPOS.C:38
int S_hour
I: Hour of day, 0 - 23, DEFAULT = 12 I: Hour of day, 0 - 23, DEFAULT = 12.
Definition: SOLPOS.C:35
int S_solpos(void)
Returns ..... This function calculates the apparent solar position and intensity (theoretical maximu...
Definition: SOLPOS.C:246
static double cssha
Definition: SOLPOS.C:123
double S_sunset
Definition: SOLPOS.C:82
double S_latitude
I: Latitude, degrees north (south negative) */.
Definition: SOLPOS.C:69
double S_eqntim
T: Equation of time (TST - LMT), minutes */.
Definition: SOLPOS.C:55
double S_tstfix
T: True solar time - local standard time */.
Definition: SOLPOS.C:89
static double ch
Definition: SOLPOS.C:120
double S_rascen
T: Right ascension, degrees */.
Definition: SOLPOS.C:74
static double t1
Definition: SOLPOS.C:145
double S_prime
O: Factor that normalizes Kt, Kn, etc. */.
Definition: SOLPOS.C:76
static double delta
Definition: SOLPOS.C:129
double S_eclong
T: Ecliptic longitude, degrees */.
Definition: SOLPOS.C:50
double S_hrang
Definition: SOLPOS.C:65
double S_cosinc
O: Cosine of solar incidence angle on panel.
Definition: SOLPOS.C:46
double S_sbcf
O: Shadow-band correction factor */.
Definition: SOLPOS.C:77
static double cd
Definition: SOLPOS.C:116
int S_date(void)
Returns date. This function calculates the month and day of month, given the day number (number of d...
Definition: SOLPOS.C:166
double S_elevref
Definition: SOLPOS.C:53
static int ndy
Definition: SOLPOS.C:102
double S_lmst
T: Local mean sidereal time, degrees */.
Definition: SOLPOS.C:71
static int lenyr[2]
Definition: SOLPOS.C:105
double S_aspect
Definition: SOLPOS.C:43
double S_ectime
T: Time of ecliptic calculations */.
Definition: SOLPOS.C:52
double S_ampress
O: Pressure-corrected airmass.
Definition: SOLPOS.C:42
static int imon
Definition: SOLPOS.C:104
double S_etrtilt
Definition: SOLPOS.C:62
static double sl
Definition: SOLPOS.C:140
int S_daynum
I/O: Day number (day of year; Feb 1 = 32 ) I/O: Day number (day of year; Feb 1 = 32 ) S_date needs th...
Definition: SOLPOS.C:34
double S_sunrise
Definition: SOLPOS.C:80
int S_day
I/O: Day of month (May 27 = 27, etc.) I/O: Day of month (May 27 = 27, etc.) S_solpos needs this...
Definition: SOLPOS.C:33
double S_utime
T: Universal (Greenwich) standard time */.
Definition: SOLPOS.C:91
static double tanelev
Definition: SOLPOS.C:144
static double se
Definition: SOLPOS.C:139
static double p
Definition: SOLPOS.C:131
static double cecl
Definition: SOLPOS.C:119
static double sd
Definition: SOLPOS.C:138
double S_mnlong
T: Mean longitude, degrees */.
Definition: SOLPOS.C:73
static double d2
Definition: SOLPOS.C:126
static int leap
Definition: SOLPOS.C:103
double S_ecobli
T: Obliquity of ecliptic */.
Definition: SOLPOS.C:51
static double refcor
Definition: SOLPOS.C:135
double S_ssha
T: Sunset(/rise) hour angle, degrees */.
Definition: SOLPOS.C:79
static int month_days[2][13]
Definition: SOLPOS.C:107
static double sz
Definition: SOLPOS.C:143
int S_year
I: 4-digit year (2-digit is assumed 19xx) I: 4-digit year (2-digit is assumed 19xx) DEFAULT = 2001...
Definition: SOLPOS.C:39
static double st
Definition: SOLPOS.C:142
double S_zenref
Definition: SOLPOS.C:94
double S_solcon
T: Solar constant, 1367 W/sq m */.
Definition: SOLPOS.C:78
static double bottom
Definition: SOLPOS.C:113
int S_month
I/O: Month number (Jan = 1, Feb = 2, etc.) I/O: Month number (Jan = 1, Feb = 2, etc.) S_solpos needs this, but S_date will calculate it from S_daynum.
Definition: SOLPOS.C:37
double S_declin
Definition: SOLPOS.C:48
static double elev
Definition: SOLPOS.C:130
double S_unprime
O: Factor that denormalizes Kt&#39;, Kn&#39;, etc. */.
Definition: SOLPOS.C:90
double S_amass
O: Relative optical airmass.
Definition: SOLPOS.C:41
double S_erv
Definition: SOLPOS.C:56
static double cz
Definition: SOLPOS.C:125
static double degrad
Definition: SOLPOS.C:127
static double t2
Definition: SOLPOS.C:146
static double top
Definition: SOLPOS.C:147
double S_tilt
I: Degrees tilt from horizontal of panel */.
Definition: SOLPOS.C:85
static double cp
Definition: SOLPOS.C:122
static double raddeg
Definition: SOLPOS.C:133
static double cl
Definition: SOLPOS.C:121
double S_etrn
Definition: SOLPOS.C:60
static double cdcl
Definition: SOLPOS.C:117
double S_longitude
I: Longitude, degrees east (west negative) */.
Definition: SOLPOS.C:70
double S_azim
O: Solar azimuth angle: N=0, E=90, S=180, W=270.
Definition: SOLPOS.C:45
______________________________________________________________________________________
Generated on Mon Sep 18 2017 11:44:09 for DAS - Rel. 3.1.6 - 18/09/2017.