Sun position
Sun position algorithm
sun.h File Reference

sun.h - routines to calculate the Sun's position More...

Go to the source code of this file.

Functions

void sun_aaApparentApprox (double n, V3D_Vector *appV, double *dist_au)
 This function calculates an approximate Sun position in apparent coordinates using the algorithm given in the Astronomical Almanac. More...
 
void sun_nrelApp2 (double t_cy, const Sky0_Nut1980 *nut, V3D_Vector *appV, double *dist_au)
 This function calculates the Sun position in apparent coordinates, using the NREL SPA algorithm (see reference). More...
 
void sun_nrelApparent (double j2kTT_cy, Sky_TrueEquatorial *pos)
 Calculate the Sun's position as a unit vector and a distance, in apparent coordinates. More...
 
void sun_nrelTopocentric (double j2kUtc_d, const Sky_DeltaTs *deltas, const Sky_SiteProp *site, Sky_SiteHorizon *topo)
 Calls sun_nrelApparent() to calculate the Sun's position in apparent coordinates using the NREL Sun Position Algorithm, and then converts this to topocentric horizon coordinates at the specified site. More...
 
double sun_solarNoon (int year, int month, int day, const Sky_DeltaTs *deltas, const Sky_SiteProp *site, Sky_SiteHorizon *topo)
 Routine to calculate the time of solar noon (Sun transit) for the day specified by year, month and day. More...
 
double sun_riseSet (int year, int month, int day, bool getSunrise, const Sky_DeltaTs *deltas, const Sky_SiteProp *site, Sky_SiteHorizon *topo)
 Routine to calculate the time of sunrise or sunset for the day specified by year, month and day. More...
 

Detailed Description

sun.h - routines to calculate the Sun's position

Author
David Hoadley

Alternative routines which calculate the sun's position with differing levels of accuracy. The alternatives are

  • a low precision routine, taken from the Astronomical Almanac
  • a much more detailed, high precision routine, based on the Solar Position Algorithm, as published by the National Renewable Energy Laboratory (referred to as the NREL SPA throughout this software)

Rectangular coordinates are used wherever possible, to minimise the unnecessary recalculation of trigonometric functions.

References:
The Astronomical Almanac, 2007, page C24
Reda, Ibrahim and Andreas, Afshin, Solar Position Algorithm for Solar Radiation Applications. National Renewable Energy Laboratory publication no. NREL/TP-560-34302, June 2003, revised 2008.

Definition in file sun.h.

Function Documentation

◆ sun_aaApparentApprox()

void sun_aaApparentApprox ( double  n,
V3D_Vector appV,
double *  dist_au 
)

This function calculates an approximate Sun position in apparent coordinates using the algorithm given in the Astronomical Almanac.

The quoted accuracy is a precision of 0.01 degrees between 1950 and 2050.

Parameters
[in]nDays since J2000.0, UT1 timescale
[out]appVPosition vector of Sun in apparent coordinates (unit vector i.e. direction cosines)
[out]dist_auGeocentric distance of the Sun (Astronomical Units)
When to call this routine
Use this routine for a quick rough calculation of the Sun's position. If you need an accurate position, don't call this routine, call sun_nrelApparent() instead.
Reference:
The Astronomical Almanac, 2007, page C24

Definition at line 105 of file sun.c.

◆ sun_nrelApp2()

void sun_nrelApp2 ( double  t_cy,
const Sky0_Nut1980 nut,
V3D_Vector appV,
double *  dist_au 
)

This function calculates the Sun position in apparent coordinates, using the NREL SPA algorithm (see reference).

The quoted accuracy of this algorithm os 0.0003° (or about 1 arcsecond). It is much more computationally intensive than the approximate algorithm from the Astronomical Almanac implemented by the routine sun_aaApparentApprox().

Parameters
[in]t_cyJulian centuries since J2000.0, TT timescale
[in]nutNutation terms and obliquity of the ecliptic, as returned by functions sky0_nutationSpa() and sky0_epsilonSpa().
[out]appVPosition vector of Sun in apparent coordinates (unit vector i.e. direction cosines)
[out]dist_auGeocentric distance of the Sun (Astronomical Units)
When to call this function
In most cases, you will want to call sun_nrelApparent() or sun_nrelTopocentric() instead, and those functions call this function for you.
Reference:
Ibrahim Reda and Afshin Andreas, Solar Position Algorithm for Solar Radiation Applications National Renewable Energy Laboratory publication no. NREL/TP-560-34302, Revised January 2008

Definition at line 148 of file sun.c.

◆ sun_nrelApparent()

void sun_nrelApparent ( double  j2kTT_cy,
Sky_TrueEquatorial pos 
)

Calculate the Sun's position as a unit vector and a distance, in apparent coordinates.

It calls sun_nrelApp2() to obtain the Sun's position, after having called sky0_nutationSpa() to obtain the necessary nutation terms.

Parameters
[in]j2kTT_cyJulian centuries since J2000.0, TT timescale
[out]posTimestamped structure containing position data and the equation of the equinoxes
When to call this function
Because this function is computationally intensive, you may wish to limit your use of this function.
  • if you want the Sun's position at multiple sites simultaneously at a single time, call this function, then follow it with a call to routine sky0_appToTirs(), and then make a separate call to sky_siteTirsToTopo() for each of one those sites.
  • if you want the Sun's position at one or more sites at closely spaced times (e.g. for tracking the Sun), pass this function to the skyfast_init() function. skyfast_init() will call it for you several times, to fully calculate positions that will be saved and used later for interpolation by the skyfast_getApprox() function for tracking.
Alternatives:
  • If you want the Sun's position at a single site only at a single time, call sun_nrelTopocentric() instead, and it will call this function for you.
  • If you want the Sun's position at a single site for more than one time but the times are spaced more than a few hours apart, once again call sun_nrelTopocentric() instead.
  • If you want to track the sun, call skyfast_getApprox() instead. But this requires you to set up interpolation first with function skyfast_init() (and this function), as described above.

Examples
demo2_sun_tracking.c, and demo4_multiple_sites.c.

Definition at line 211 of file sun.c.

◆ sun_nrelTopocentric()

void sun_nrelTopocentric ( double  j2kUtc_d,
const Sky_DeltaTs deltas,
const Sky_SiteProp site,
Sky_SiteHorizon topo 
)

Calls sun_nrelApparent() to calculate the Sun's position in apparent coordinates using the NREL Sun Position Algorithm, and then converts this to topocentric horizon coordinates at the specified site.

Parameters
[in]j2kUtc_dUTC time in "J2KD" form - i.e days since J2000.0 (= JD - 2 451 545.0)
[in]deltasDelta T values, as set by the sky_initTime() (or sky_initTimeSimple() or sky_initTimeDetailed()) routines
[in]siteProperties of the observing site, particularly its geometric location on the surface of the Earth, as set by the sky_setSiteLocation() function (or sky_setSiteLoc2())
[out]topoTopocentric position, in both rectangular (unit vector) form, and as Azimuth and Elevation (altitude) angles
When to call this function
Use this function if you are calculating the Sun topocentric position once, for a single site. But if you are going to be calculating it repeatedly, or for multiple sites, use of this function will cause you to perform a great many needless recalculations. Use skyfast_getApprox(), followed by sky0_appToTirs() and sky_siteTirsToTopo() instead.

Examples
demo1_sun.c.

Definition at line 266 of file sun.c.

◆ sun_solarNoon()

double sun_solarNoon ( int  year,
int  month,
int  day,
const Sky_DeltaTs deltas,
const Sky_SiteProp site,
Sky_SiteHorizon topo 
)

Routine to calculate the time of solar noon (Sun transit) for the day specified by year, month and day.

This function uses the NREL SPA algorithm of sun_nrelTopocentric() to calculate the Sun's position.

Returns
Solar noon for the day given in year, month and day (returned as a J2KD date (= JD - 2 451 545.0), UTC timescale). To view this as a local date and time, add this value to site->timezone_d and pass the result to function sky_j2kdToCalTime().
Parameters
[in]year,month,dayDate for which solar noon is desired
[in]deltasDelta T values, as set by the sky_initTime() (or sky_initTimeSimple() or sky_initTimeDetailed()) routines
[in]siteProperties of the observing site, particularly its geometric location on the surface of the Earth and its time zone, as set by the sky_setSiteLocation() function (or sky_setSiteLoc2())
[out]topoOptional. Topocentric position of the Sun at transit, in both rectangular (unit vector) form, and as Azimuth and Elevation (altitude) angles. If you are not interested in these values, you can pass NULL to this parameter.

This routine uses an iterative approach. Two iterations is all that is needed to get a result within about 0.05 seconds.


Definition at line 310 of file sun.c.

◆ sun_riseSet()

double sun_riseSet ( int  year,
int  month,
int  day,
bool  getSunrise,
const Sky_DeltaTs deltas,
const Sky_SiteProp site,
Sky_SiteHorizon topo 
)

Routine to calculate the time of sunrise or sunset for the day specified by year, month and day.

This function uses the NREL SPA algorithm of sun_nrelTopocentric() to calculate the Sun's position.

Returns
Sunrise (or sunset) time for the day given in year, month and day (returned as a J2KD date (= JD - 2 451 545.0), UTC timescale). To view this as a local date and time, add this value to site->timezone_d and pass the result to function sky_j2kdToCalTime().
Parameters
[in]year,month,dayDate for which sunrise or sunset time is desired
[in]getSunriseIf true, get sunrise time. If false, get sunset time
[in]deltasDelta T values, as set by the sky_initTime() (or sky_initTimeSimple() or sky_initTimeDetailed()) routines
[in]siteProperties of the observing site, particularly its geometric location on the surface of the Earth and its time zone, as set by the sky_setSiteLocation() function (or sky_setSiteLoc2()) and sky_setSiteTimeZone().
[out]topoOptional. Topocentric position of the Sun at rise or set, in both rectangular (unit vector) form, and as Azimuth and Elevation (altitude) angles. If you are not interested in these values, you can pass NULL to this parameter.

This routine uses an iterative approach. It does two iterations.

Note
If the Sun does not rise (or set) on the specified day at the specified latitude, this function will return 0.0
This routine assumes a standard refraction at the horizon of 34 arcminutes. Although this is typical of sunrise/sunset calculations, it is not necessarily the actual refraction that will occur at any given place or time. So the results should be considered approximate. Don't expect it to be be any better than the nearest minute to the time at which the sun appears or disappears.

Definition at line 363 of file sun.c.