PUBLIC INTERFACE / DATA / ROUTINES / NAMELIST / DIAGNOSTICS / CHANGES / ERRORS / REFERENCES / NOTES

Last updated on .


Astronomy_mod

     Version: v1.1
     Date:    July 1, 1999
     Contact: Isaac Held

OVERVIEW


     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



OTHER MODULES USED


     Utilities_mod
     Time_manager_mod

     This module has been tested using v1.0 of both of these modules


PUBLIC INTERFACE


  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
 


public data


    there is no public data


public routines


==========================================================================

 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



NAMELIST


    There is no namelist


DIAGNOSTIC FIELDS


     There is no diagnostic output 


DATA SETS


     No data sets are used


CHANGE HISTORY


     v1.1 is a documented and cleaned-up version of v1.0
     It should reproduce v1.0 exactly


ERROR MESSAGES


     A list of error messages by routine and what it means.


REFERENCES


    See  astronomy.ps


COMPILER SPECIFICS


     On the T90, compiler must be 3.1.0.0 or later


PRECOMPILER OPTIONS


     None needed


LOADER OPTIONS


     None needed


KNOWN BUGS


     None known


NOTES


     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)

         


FUTURE PLANS


     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