Last updated on .
Version: v1.1 Date: July 1, 1999 Contact: Isaac Held
Computes the diurnally varying zenith angle, and a non-dimensional incident solar flux at the top of the atmosphere, taking into account the varying Earth-Sun distance in the orbital ellipse. Also provides averages suitable for use in diurnally-averaged and sesaonally-averaged models. Useful for simple energy balance climate models as well as GCMs.
The orbital geometry (eccentricity, obliquity, longitude of the perihelion) defaults to the current conditions for Earth, but can be changed. Time can be managed using the calendar options and the time_types defined by time_manager_mod, in which case the solar day is constrained to be 86400 seconds and the length of the year is determined by the kind of calendar chosen (i.e., no_leap (365 solar days) or Julian (365.25 solar days)) Or these can be bypassed. Diurnal averages are computed analytically, assuming that the Earth-Sun distance does not change significantly over one day. The diurnally varying incident solar flux can also be averaged over a specified time interval (the model time-step), so that there is no time truncation error in the time-averaged irradiance. The module initializes itself when first called, and computes a table of finely-spaced orbital positions as a function of time, using 4th-order Runge-Kutta, which is then interpolated upon. The solar fluxes are normalized so that multiplication by the "solar constant" produces the correct flux at the top of the atmosphere In particular, the average over the sphere is equal to 1/4 for an eccentricity of 0.0 . When the eccentricity, ecc, is non-zero, the average over the sphere is (1/4)* [(1.0 - ecc**2)**(-0.5)], as appropriate for a fixed solar constant The geometry of the Earth-Sum system, and the equations underlying these computations, are described in astronomy.ps
Utilities_mod Time_manager_mod This module has been tested using v1.0 of both of these modules
use astronomy_mod [,only: get_orbital_parameters, & set_orbital_parameters, & get_ref_date_of_ae , & set_ref_date_of_ae , & diurnal_solar , & daily_mean_solar , & annual_mean_solar ] set_orbital_parameters : resets values of orbital parameters (if not called, parameters default to present day earth conditions) get_orbital_parameters : returns values of orbital parameters set_ref_date_of_ae : relates calendar to orbit by setting date of autumnal equinox in northern hem. (if not called, parameters default to present day earth conditions) get_ref_date_of_ae : returns date of autumnal equinox diurnal_solar : returns instantaneous cos(zenith angle), cosz, and "normalized solar flux" = cosz*(((a/r)**2), where r is the earth-sun distance and a is the semi-major axis of the orbital ellipse these instantaneous values can also be averaged over any time interval < 12 hours daily_mean_solar : returns daily averaged normalized irradiance and an effective zenith angle that would produce the correct total irradiance if the sun where fixed at that position in the sky for the daylight hours only. annual_mean_solar : returns annually averaged flux and effective zenith angle by averaging output from daily_mean_solar over the year. the effective zenith angle is obtained by weighting the daily effective zenith angle by the daily averaged flux notes: 1) there is no namelist 2) no data files or restart files are required 3) a line is appended to the file logfile.out containing the version number of the module
there is no public data
========================================================================== call set_orbital_parameters(ecc, obliq, per) input: ecc, real eccentricity of orbital ellipse, nondimensional obliq, real obliquity (angle between rotation axis and plane of orbit), in degrees (not radians) per, real orbital angle between perihelion and autumnal equinox in the northern hemisphere, in degrees (not radians) ( 0.0 => perihelion at nh autumnal equinox 90.0 => perihelion at nh winter solstice 180.0 => perihelion at nh vernal equinox 270.0 => perihelion at nh summer solstice if this routine is not called the values will default to ecc = 0.01671 obliq = 23.439 per = 102.932 ========================================================================== call get_orbital_parameters(ecc, obliq, per) output: ecc , real obliq , real per , real (see set_orbital_parameters above) ========================================================================== call set_ref_date_of_ae(day, month, year, [second, minute, hour]) input: day, integer day of month month, integer number of month (1 -12) year, integer optional input: second, integer (0-59) minute, integer (0-59) hour, integer hour of day (0-23) (second, minute, hour) default to (0,0,0) if all three are not in argument list if this routine is not called the values will default to day = 23 month = 9 year = 1998 hour = 5 minute = 37 second = 0 note: if a calendar with no leap years is chosen, autumnal equinox will occur at the same date each year if the julian calendar is chosen, autumnal equinox will drift by 1/4 day for three years, and then shift back on the fourth year; it is for this reason that a year must be chosen while setting the autumnal equinox ========================================================================== call get_ref_date_of_ae(day, month, year, second, minute, hour) output: day , integer month , integer year , integer second , integer minute , integer hour , integer (see set_ref_date_of_ae above) ========================================================================== a) call diurnal_solar(cosz, solar, lat, lon, time, [dt_time]) or b) call diurnal_solar(cosz, solar, lat, lon, ut, ot, [dt]) (this interface has two permissible forms) option a: for those using time_manager_mod for time-keeping input: lat -- real, dimension(:,:) latitudes of 2-d array of points at which output is desired, in radians lon -- real, dimension(:,:) longitudes of 2-d array of points at which output is desired, in radians (these arrays are 2d to allow for general grids; if the grid is lon-lat then lon(i,:) = lon(i) and lat(:,j) = lat(j) ) time -- type(time_type) the universal time for which output is desired (universal time = time at 0 longitude) (time_type is provided by time_manager_mod) optional input: dt_time -- type(time_type) if present, output is averaged analytically over interval between time and time + dt_time (this option should always be turned on in a diurnal gcm to avoid time truncation error in the total incident flux) output: cosz -- real, dimension(:,:) cosine of the zenith angle, the angle that the sun makes with the local vertical. nondimensional solar -- real, dimension(:,:) normalized solar irradiance, solar = cosz*((a/r)**2), where r is the earth-sun distance and a is the semi-major axis of the orbital ellipse. nondimensional cosz(:,:) and solar(:,:) must conform exactly to lat(:,:) and lon(:,:) cosz is set to 0.0 in polar night alternative dimensions: one can also call this routine with 1-dimensional or 0-dimensional input and output, as long as the input and output conform exactly real, dimension(:) :: cosz, solar, lat, lon or real :: cosz, solar, lat, lon option b: for those not using time_manager_mod for time-keeping input: lat -- as in a lon -- as in a ut -- real universal time of day (time at 0 longitude) in radians length of day = 2*pi ot -- real orbital time, time of year (time = 0 at autumnal equinox in northern hem!) in radians length of year = 2*pi optional input: dt -- real if present, output is averaged analytically over interval between ut and ut+dt in radians, where 2*pi = length of day (must be less than pi) output: as in a alternative dimensions: as in a ========================================================================== a) call daily_mean_solar(cosz, solar, lat, time) or b) call daily_mean_solar(cosz, solar, lat, ot) option a: for those using time_manager_mod for time-keeping input: lat -- real, dimension(:,:) latitudes of 2-d array of points at which output is desired, in radians (this array is 2d to allow for general grids; if the grid is lon-lat then lat(:,j) = lat(j) ) time -- type(time_type) the universal time for which output is desired (universal time = time at 0 longitude) (time_type is provided by time_manager_mod) output: cosz -- real, dimension(:,:) cosine of an effective zenith angle that would produce the correct daily mean flux if the sun where fixed at that position for the daylight hours. dimensionless solar -- real, dimension(:,:) diurnally averaged normalized solar flux, solar = cosz*((a/r)**2)*h/pi where h is the "half-day-length" in radians (so h/pi is the fraction of the day in which the sun is shining ) and where r is the earth-sun distance and a is the semi-major axis of the orbital ellipse dimensionless cosz(:,:) and solar(:,:) must conform exactly to lat(:,:) cosz is set to 0.0 in polar night alternative dimensions: one can also call this routine with 1-dimensional or 0-dimensional input and output, as long as the input and output conform exactly real, dimension(:) :: cosz, solar, lat or real :: cosz, solar, lat option b: for those not using time_manager_mod for time-keeping input: lat -- as in a ot -- real orbital time, time of year (time = 0 at autumnal equinox in northern hem!) in radians length of year = 2*pi output: as in a alternative dimensions: as in a ========================================================================== call annual_mean_solar(cosz, solar, lat) input: lat -- real, dimension(:,:) latitudes at which result is desired in radians (this array is 2d to allow for general grids; if the grid is lon-lat then lat(:,j) = lat(j) ) output: solar -- real, dimension(:,:) annual mean normalized solar flux, computed by averaging the output of daily_mean_solar around the year nondimensional cosz -- real, dimension(:,:) cosine of effective zenith angle, = sum(cosz *solar)/sum(solar), where cosz and solar are the output from daily mean solar, and sum represents an integration over the year. nondimensional input and output dimensions must conform exactly alternative dimensions: input and output can also be 1d real, dimension(:) :: cosz, solar, lat -- as usual, all dimensions must conform exactly
There is no namelist
There is no diagnostic output
No data sets are used
v1.1 is a documented and cleaned-up version of v1.0 It should reproduce v1.0 exactly
A list of error messages by routine and what it means.
See astronomy.ps
On the T90, compiler must be 3.1.0.0 or later
None needed
None needed
None known
The orbital integration becomes inaccurate if the eccentricity approaches unity (of no concern for the Earth) Because the diurnal averages are computed analytically by assuming that the earth-sun distance is constant within the day, daily_mean_solar and annual_mean_solar are only accurate if length of solar day << length of year (also not of concern for the Earth) One must be careful when constructing a diurnal GCM with a modified rotation rate. Changing the rotation rate in constants_mod, which is where the dynamical core looks for the rotation rate, will not change the length of the solar day. In the current version of the time manager, the length of the solar day is fixed to 86400 seconds, so one would have to use the option B form of the call to diurnal_solar. As of July, 1999 the atmospheric model is not set up to handle this. The issue does not arise in non-diurnal models. (Ideally, one should always have (2*pi)/solar_day = (2*pi)/siderial_day - (2*pi)/year where (2*pi)/siderial_day is the angular velocity of the rotation)
If time_manager_mod were generalized, there would be no need for the two forms of the calls to diurnal_solar and daily_solar, and the GCM could be coded for arbitrary rotation rate in a more transparent way