The time manager is designed as a module which provides public data members for communicating with the user interface (i.e., Fortran namelist), and public methods which wrap the ESMF library methods. The reasons for designing ``wrapper'' methods rather than making direct use of the methods provided by the ESMF library's Fortran 90 interface are:
The ESMF library has an object oriented design. In Fortran this implies a viewpoint in which each variable declared as one of the derived types is thought of as an independent object. Thus, for example, different objects (variables) of the ESMF defined type for representing a date could be based on different calendars, and there could be multiple instances of the time manager. But in the context of a single atmospheric simulation there is only one calendar being used, and only one time coordinate. Hence, only one time manager is necessary. The CAM specific interface is then simplified, for example, by maintaining the calendar type and the time manager ID as private module data which does not have to be passed through the public method argument lists.
The ESMF library methods all provide an optional argument for error checking. The CAM specific interface does not pass this argument, but the methods act as wrappers that carry out checking of all error codes and invoke a CAM (or CCSM) specific error handler as appropriate.
The only CAM specific simulation control option currently implemented is to support a ``perpetual calendar'' mode. This mode is described above in the requirements section. The perpetual mode is currently used by the model's ``aqua-planet'' mode which is a testing configuration for the physical parameterizations.
The user interface is implemented via Fortran namelist variables. These variables are public data in the time manager module.
Type | character(len=*) |
Default | 'NO_LEAP' |
Use | Calendar to use in date calculations. Supported calendars are 'NO_LEAP' (i.e., modern calendar, but without leap years) and 'GREGORIAN' (modern calendar). |
Type | integer |
Default | 1200 s (Eulerian dycore), 1800 s (Finite-volume dycore), 3600 s (SLD dycore) |
Use | Timestep size in seconds. dtime must evenly divide the number of seconds in a day. |
Type | integer |
Default | Read from the initial conditions input dataset |
Use | Year, month and day of the simulation start date. The values are encoded in an integer as year*10000 + month*100 + day. |
Type | integer |
Default | 0 if start_ymd is specified; otherwise it's read from the initial conditions input dataset |
Use | Time of day (UTC) of the simulation start date, in seconds. |
Type | integer |
Default | none |
Use | Year, month and day of the simulation stop date. The values are encoded in an integer as year*10000 + month*100 + day. If this value is specified it takes precedence over both nestep and nelapse. |
Type | integer |
Default | 0 |
Use | Time of day (UTC) of the simulation stop date, in seconds. |
Type | integer |
Default | none |
Use | If nestep > 0 then nestep is the number of timesteps to advance the solution past the start date. If nestep < 0 then the stop date is -nestep days past the start date. nestep is ignored if stop_ymd is set. |
Type | integer |
Default | none |
Use | If nelapse > 0 then nelapse is the number of timesteps to advance the solution past the start date (on an initial run) or past the restart date (on a restart run). If nelapse < 0 then the stop date is -nelapse days past the start or restart date (again depending on run type). nelapse is ignored if either stop_ymd or nestep is set. |
Type | integer |
Default | from year, month, and day components of the start date |
Use | Year, month and day of the time coordinate's reference date. The values are encoded in an integer as year*10000 + month*100 + day. |
Type | integer |
Default | from the time of day component of the start date |
Use | Time of day (UTC) of the time coordinate's reference date, in seconds. |
Type | logical |
Default | false |
Use | Set to .true. to specify that the run will use a perpetual calendar. If perpetual_ymd is not set then read the perpetual day from the initial file. |
Type | integer |
Default | none |
Use | Perpetual date specified as year*1000 + month*100 + day. This date overrides the date from the initial file. If running in ``aqua-planet'' mode then perpetual_ymd is ignored and the perpetual date is set to 321. |
This section provides an overview of the design and functionality of the API. The following is a summary of the time manager's public methods in UML notation. In UML a method prototype has the syntax ``method-name (argument-list) :return-type'', where each argument in the comma separated list is expressed as ``intent arg-name:type''. The intent of an argument is one of the keywords in, out, or inout. Optional arguments are enclosed in brackets ``[ ]''. For methods which don't have a return value the ``:return-type'' is left off.
The API does not currently implement any alarm functionality because it is not yet fully functional in the ESMF library.
subroutine timemgr_preset()
timemgr_preset is used for run-time initialization of namelist variables. Most namelist variables are statically initialized in the time manager module. This method is currently used only for dtime whose default value depends on the dycore. This method is provided because dtime is used before the time manager is initialized (which happens after the header of the initial conditions file is read to obtain the default start date).
subroutine timemgr_init()
timemgr_init initializes the time manager module for an initial run. Before timemgr_init is called it is assumed that the namelist has been read, and the date in the initial conditions file has been read.
subroutine timemgr_restart()
timemgr_restart initializes the time manager module for a restart run. Before timemgr_restart is called it is assumed that the namelist has been read, and the restart data has been read from the restart file by a call to timemgr_read_restart.
subroutine advance_timestep()
advance_timestep advances the time manager by one timestep. This includes updating the date and time information at the beginning and end of the new timestep, and updating the alarms.
function get_step_size() integer :: get_step_size
get_step_size returns the current timestep size in seconds.
function get_nstep() integer :: get_nstep
get_nstep returns the current timestep number.
subroutine get_curr_date(yr, mon, day, tod, offset) integer, intent(out) :: yr, mon, day, tod integer, optional, intent(in) :: offset
get_curr_date returns the components of the date corresponding to the end of the current timestep. When the optional offset argument is specified the current date is incremented by offset seconds (may be negative). The date components are: year (yr); month (mon); day of month (day); and time of day in seconds past 0Z (tod).
subroutine get_prev_date(yr, mon, day, tod) integer, intent(out) :: yr, mon, day, tod
get_prev_date returns the components of the date corresponding to the beginning of the current timestep. The date components are: year (yr); month (mon); day of month (day); and time of day in seconds past 0Z (tod).
subroutine get_start_date(yr, mon, day, tod) integer, intent(out) :: yr, mon, day, tod
get_start_date returns the components of the date corresponding to the starting date for the simulation. The date components are: year (yr); month (mon); day of month (day); and time of day in seconds past 0Z (tod).
subroutine get_ref_date(yr, mon, day, tod) integer, intent(out) :: yr, mon, day, tod
get_ref_date returns the components of the reference date part of the time coordinate. The date components are: year (yr); month (mon); day of month (day); and time of day in seconds past 0Z (tod).
subroutine get_perp_date(yr, mon, day, tod) integer, intent(out) :: yr, mon, day, tod
get_perp_date returns the components of the perpetual date corresponding to the end of the current timestep. The date components are: year (yr); month (mon); day of month (day); and time of day in seconds past 0Z (tod).
subroutine get_curr_time(days, seconds) integer, intent(out) :: days, seconds
get_curr_time returns the time at the end of the current timestep. days and seconds contain the components of the time interval in units of days and seconds respectively.
function get_curr_calday(offset) real(r8) :: get_curr_calday integer, optional, intent(in) :: offset
get_curr_calday returns the calendar day at the end of the current timestep. In perpetual mode the get_curr_calday returns the perpetual calendar day. When the optional offset argument is specified the current date (or perpetual date) is incremented by offset seconds (may be negative) before converting the date to a calendar day. The real kind, r8, specifies an 8-byte real value.
function is_first_step() logical :: is_first_step
is_first_step returns true during the initialization phase of an initial run. This phase lasts from the point at which the time manager is initialized until the first call to advance_timestep. In the CCM3 this phase was indicated by the conditional if(nstep==0)...
function is_first_restart_step() logical :: is_first_restart_step
is_first_restart_step returns true during the initialization phase of a restart run. This phase lasts from the point at which the time manager is restart until the next call to advance_timestep. In the CCM3 this phase was indicated by the conditional if(nstep==nrstrt)...
function is_last_step() logical :: is_last_step
is_last_step returns true during the final timestep of a run.
function is_end_curr_day() logical :: is_end_curr_day
is_end_curr_day returns true during the final timestep of each day. The final timestep of a day is the one whose ending date is equal to or later than 0Z of the next day.
function is_end_curr_month() logical :: is_end_curr_month
is_end_curr_month returns true during the final timestep of each month. The final timestep of a month is the one whose ending date is equal to or later than 0Z of the first day of the next month.
subroutine timemgr_write_restart(ftn_unit) integer, intent(in) :: ftn_unit
timemgr_write_restart writes the state of the time manager to a binary file attached to Fortran unit ftn_unit. It is assumed that when running with MPI this method is only called from the master process.
subroutine timemgr_read_restart(ftn_unit) integer, intent(in) :: ftn_unit
timemgr_read_restart reads the state of the time manager from a binary file attached to Fortran unit ftn_unit. It is assumed that when running with MPI this method is only called from the master process.