<p><b>croesch@ucar.edu</b> 2012-03-01 12:29:25 -0700 (Thu, 01 Mar 2012)</p><p>Update the ESMF libraries to support no-leap and 360 day calendars.  Update the registry to specify the calendar using character strings.<br>
<br>
M    src/core_hyd_atmos/Registry<br>
M    src/core_init_nhyd_atmos/Registry<br>
M    src/core_sw/Registry<br>
M    src/external/esmf_time_f90/ESMF_Calendar.F90<br>
M    src/external/esmf_time_f90/ESMF_Stubs.F90<br>
M    src/core_nhyd_atmos/Registry<br>
M    src/core_ocean/Registry<br>
M    src/framework/mpas_timekeeping.F<br>
</p><hr noshade><pre><font color="gray">Modified: trunk/mpas/src/core_hyd_atmos/Registry
===================================================================
--- trunk/mpas/src/core_hyd_atmos/Registry        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/core_hyd_atmos/Registry        2012-03-01 19:29:25 UTC (rev 1564)
@@ -4,7 +4,7 @@
 namelist integer   sw_model config_test_case            5
 namelist character sw_model config_time_integration     SRK3
 namelist real      sw_model config_dt                   172.8
-namelist integer   sw_model config_calendar_type        MPAS_360DAY
+namelist character sw_model config_calendar_type        360day
 namelist character sw_model config_start_time           0000-01-01_00:00:00
 namelist character sw_model config_stop_time            none
 namelist character sw_model config_run_duration         none

Modified: trunk/mpas/src/core_init_nhyd_atmos/Registry
===================================================================
--- trunk/mpas/src/core_init_nhyd_atmos/Registry        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/core_init_nhyd_atmos/Registry        2012-03-01 19:29:25 UTC (rev 1564)
@@ -2,7 +2,7 @@
 % namelist  type  namelist_record  name  default_value
 %
 namelist integer   nhyd_model config_test_case            7
-namelist integer   nhyd_model config_calendar_type        MPAS_GREGORIAN
+namelist character nhyd_model config_calendar_type        gregorian
 namelist character nhyd_model config_start_time           none
 namelist character nhyd_model config_stop_time            none
 namelist integer   nhyd_model config_theta_adv_order      3

Modified: trunk/mpas/src/core_nhyd_atmos/Registry
===================================================================
--- trunk/mpas/src/core_nhyd_atmos/Registry        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/core_nhyd_atmos/Registry        2012-03-01 19:29:25 UTC (rev 1564)
@@ -4,7 +4,7 @@
 namelist integer   nhyd_model config_test_case            0
 namelist character nhyd_model config_time_integration     SRK3
 namelist real      nhyd_model config_dt                   600.0
-namelist integer   nhyd_model config_calendar_type        MPAS_GREGORIAN
+namelist character nhyd_model config_calendar_type        gregorian
 namelist character nhyd_model config_start_time           0000-01-01_00:00:00
 namelist character nhyd_model config_stop_time            none
 namelist character nhyd_model config_run_duration         none

Modified: trunk/mpas/src/core_ocean/Registry
===================================================================
--- trunk/mpas/src/core_ocean/Registry        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/core_ocean/Registry        2012-03-01 19:29:25 UTC (rev 1564)
@@ -5,7 +5,7 @@
 namelist character sw_model config_time_integration    RK4
 namelist logical   sw_model config_rk_filter_btr_mode  false
 namelist real      sw_model config_dt                  172.8
-namelist integer   sw_model config_calendar_type       MPAS_360DAY
+namelist character sw_model config_calendar_type       360day
 namelist character sw_model config_start_time          0000-01-01_00:00:00
 namelist character sw_model config_stop_time           none
 namelist character sw_model config_run_duration        none

Modified: trunk/mpas/src/core_sw/Registry
===================================================================
--- trunk/mpas/src/core_sw/Registry        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/core_sw/Registry        2012-03-01 19:29:25 UTC (rev 1564)
@@ -4,7 +4,7 @@
 namelist integer     sw_model  config_test_case             5
 namelist character   sw_model  config_time_integration      RK4
 namelist real        sw_model  config_dt                    172.8
-namelist integer     sw_model  config_calendar_type         MPAS_360DAY
+namelist character   sw_model  config_calendar_type         360day
 namelist character   sw_model  config_start_time            0000-01-01_00:00:00
 namelist character   sw_model  config_stop_time             none
 namelist character   sw_model  config_run_duration          none

Modified: trunk/mpas/src/external/esmf_time_f90/ESMF_Calendar.F90
===================================================================
--- trunk/mpas/src/external/esmf_time_f90/ESMF_Calendar.F90        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/external/esmf_time_f90/ESMF_Calendar.F90        2012-03-01 19:29:25 UTC (rev 1564)
@@ -51,14 +51,23 @@
 
 
       INTEGER, PARAMETER :: MONTHS_PER_YEAR = 12
-      INTEGER, PARAMETER :: mday(MONTHS_PER_YEAR)   &amp;
+
+      INTEGER, PARAMETER :: daysPerMonthNoLeap(MONTHS_PER_YEAR)   &amp;
                           = (/31,28,31,30,31,30,31,31,30,31,30,31/)
-      INTEGER, PARAMETER :: mdayleap(MONTHS_PER_YEAR) &amp;
+      INTEGER, PARAMETER :: daysPerMonthLeap(MONTHS_PER_YEAR) &amp;
                           = (/31,29,31,30,31,30,31,31,30,31,30,31/)
-      INTEGER, DIMENSION(365) :: daym
-      INTEGER, DIMENSION(366) :: daymleap
+      INTEGER, PARAMETER :: daysPerMonth360(MONTHS_PER_YEAR) &amp;
+                          = (/30,30,30,30,30,30,30,30,30,30,30,30/)
+
+      INTEGER, DIMENSION(MONTHS_PER_YEAR) :: mday 
+      INTEGER, DIMENSION(MONTHS_PER_YEAR) :: mdayleap 
+
+      INTEGER, DIMENSION(:), POINTER :: daym
+      INTEGER, DIMENSION(:), POINTER :: daymleap
+
       INTEGER :: mdaycum(0:MONTHS_PER_YEAR)
       INTEGER :: mdayleapcum(0:MONTHS_PER_YEAR)
+
       TYPE(ESMF_BaseTime), TARGET :: monthbdys(0:MONTHS_PER_YEAR)
       TYPE(ESMF_BaseTime), TARGET :: monthbdysleap(0:MONTHS_PER_YEAR)
 
@@ -152,6 +161,7 @@
 !
 ! !PUBLIC MEMBER FUNCTIONS:
       public ESMF_CalendarCreate
+      public ESMF_CalendarDestroy
 
 ! Required inherited and overridden ESMF_Base class methods
 
@@ -210,50 +220,61 @@
       type(ESMF_DaysPerYear) :: dayspy
 
       if ( present(rc) ) rc = ESMF_FAILURE
-! Calendar type is hard-coded.  Use ESMF library if more flexibility is 
-! needed.  
-#ifdef NO_LEAP_CALENDAR
-      if ( calendartype%caltype  /= ESMF_CAL_NOLEAP%caltype ) then
+
+      if ( calendartype % caltype  == ESMF_CAL_GREGORIAN % caltype ) then
+            ESMF_CalendarCreate % Type = ESMF_CAL_GREGORIAN
+            mday = daysPerMonthNoLeap
+            mdayleap = daysPerMonthLeap
+            allocate(daym(365))
+            allocate(daymleap(366))
+      else if ( calendartype % caltype  == ESMF_CAL_NOLEAP % caltype ) then
+            ESMF_CalendarCreate % Type = ESMF_CAL_NOLEAP
+            mday = daysPerMonthNoLeap
+            mdayleap = daysPerMonthNoLeap
+            allocate(daym(365))
+            allocate(daymleap(365))
+      else if ( calendartype % caltype  == ESMF_CAL_360DAY % caltype ) then
+            ESMF_CalendarCreate % Type = ESMF_CAL_360DAY
+            mday = daysPerMonth360
+            mdayleap = daysPerMonth360
+            allocate(daym(360))
+            allocate(daymleap(360))
+      else
          write(6,*) 'Not a valid calendar type for this implementation'
-         write(6,*) 'This implementation only allows ESMF_CAL_NOLEAP'
-         write(6,*) 'calender type set to     = ', calendartype%caltype
-         write(6,*) 'NO_LEAP calendar type is = ', ESMF_CAL_NOLEAP%caltype
+         write(6,*) 'The current implementation only supports ESMF_CAL_NOLEAP, ESMF_CAL_GREGORIAN, ESMF_CAL_360DAY'
          return
       end if
-      ESMF_CalendarCreate%Type = ESMF_CAL_NOLEAP
-#else
-      if ( calendartype%caltype  /= ESMF_CAL_GREGORIAN%caltype ) then
-         write(6,*) 'Not a valid calendar type for this implementation'
-         write(6,*) 'This implementation only allows ESMF_CAL_GREGORIAN'
-         write(6,*) 'calender type set to     = ', calendartype%caltype
-         write(6,*) 'GREGORIAN calendar type is = ', ESMF_CAL_GREGORIAN%caltype
-         return
-      end if
-      ESMF_CalendarCreate%Type = ESMF_CAL_GREGORIAN
-#endif
-! This is a bug on some systems -- need initial value set by compiler at 
-! startup.  
-! However, note that some older compilers do not support compile-time 
-! initialization of data members of Fortran derived data types.  For example, 
-! PGI 5.x compilers do not support this F95 feature.  See 
-! NO_DT_COMPONENT_INIT.  
-      ESMF_CalendarCreate%Set = .true.
-      ESMF_CalendarCreate%SecondsPerDay = SECONDS_PER_DAY
-! DaysPerYear and SecondsPerYear are incorrect for Gregorian calendars...  
-      dayspy%D = size(daym)
-!TBH:  TODO:  Replace DaysPerYear and SecondsPerYear with methods 
-!TBH:  TODO:  since they only make sense for the NO_LEAP calendar!  
-      ESMF_CalendarCreate%DaysPerYear = dayspy
-      ESMF_CalendarCreate%SecondsPerYear = ESMF_CalendarCreate%SecondsPerDay &amp;
-                                       * dayspy%D
-!TBH:  TODO:  use mdayleap for leap-year calendar
-      ESMF_CalendarCreate%DaysPerMonth(:) = mday(:)
 
+      ESMF_CalendarCreate % Set = .true.
+      ESMF_CalendarCreate % DaysPerMonth(:) = mday(:)
+      ESMF_CalendarCreate % SecondsPerDay = SECONDS_PER_DAY
+
+!TBH:  TODO:  Replace DaysPerYear and SecondsPerYear with methods
+!TBH:  TODO:  since they only make sense for the NO_LEAP calendar!
+      dayspy % D = size(daym)
+      ESMF_CalendarCreate % DaysPerYear = dayspy
+      ESMF_CalendarCreate % SecondsPerYear = ESMF_CalendarCreate % SecondsPerDay * dayspy % D
+
       if ( present(rc) ) rc = ESMF_SUCCESS
 
-      end function ESMF_CalendarCreate
+   end function ESMF_CalendarCreate
 
 
+   subroutine ESMF_CalendarDestroy(rc)
+
+      integer, intent(out), optional :: rc
+
+      if ( present(rc) ) rc = ESMF_FAILURE
+
+      deallocate(daym)
+      deallocate(daymleap)
+
+      if ( present(rc) ) rc = ESMF_SUCCESS
+
+   end subroutine ESMF_CalendarDestroy
+
+
+
 !==============================================================================
 !BOP
 ! !IROUTINE: ESMF_CalendarInitialized - check if calendar was created

Modified: trunk/mpas/src/external/esmf_time_f90/ESMF_Stubs.F90
===================================================================
--- trunk/mpas/src/external/esmf_time_f90/ESMF_Stubs.F90        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/external/esmf_time_f90/ESMF_Stubs.F90        2012-03-01 19:29:25 UTC (rev 1564)
@@ -91,6 +91,8 @@
 ! NOOP
    SUBROUTINE ESMF_Finalize( rc )
       USE esmf_basemod
+      USE esmf_calendarmod
+
       INTEGER, INTENT(  OUT), OPTIONAL :: rc
 #if (defined SPMD) || (defined COUP_CSM)
 #include &lt;mpif.h&gt;
@@ -98,6 +100,8 @@
       LOGICAL :: flag
       INTEGER :: ier
 
+      CALL ESMF_CalendarDestroy()
+
       IF ( PRESENT( rc ) ) rc = ESMF_SUCCESS
 #if (defined SPMD) || (defined COUP_CSM)
       CALL MPI_Finalized( flag, ier )

Modified: trunk/mpas/src/framework/mpas_timekeeping.F
===================================================================
--- trunk/mpas/src/framework/mpas_timekeeping.F        2012-03-01 18:33:02 UTC (rev 1563)
+++ trunk/mpas/src/framework/mpas_timekeeping.F        2012-03-01 19:29:25 UTC (rev 1564)
@@ -114,15 +114,16 @@
 
       implicit none
 
-      integer, intent(in) :: calendar 
+      character (len=*), intent(in) :: calendar 
 
-      TheCalendar = calendar
-
-      if (TheCalendar == MPAS_GREGORIAN) then
+      if (trim(calendar) == 'gregorian') then
+         TheCalendar = MPAS_GREGORIAN
          call ESMF_Initialize(defaultCalendar=ESMF_CAL_GREGORIAN)
-      else if (TheCalendar == MPAS_GREGORIAN_NOLEAP) then
+      else if (trim(calendar) == 'gregorian_noleap') then
+         TheCalendar = MPAS_GREGORIAN_NOLEAP
          call ESMF_Initialize(defaultCalendar=ESMF_CAL_NOLEAP)
-      else if (TheCalendar == MPAS_360DAY) then
+      else if (trim(calendar) == '360day') then
+         TheCalendar = MPAS_360DAY
          call ESMF_Initialize(defaultCalendar=ESMF_CAL_360DAY)
       else
          write(0,*) 'ERROR: mpas_timekeeping_init: Invalid calendar type'

</font>
</pre>