diff --git a/.github/workflows/extbuild.yml b/.github/workflows/extbuild.yml
index e1c69cd7..621ae36c 100644
--- a/.github/workflows/extbuild.yml
+++ b/.github/workflows/extbuild.yml
@@ -23,8 +23,8 @@ jobs:
ESMF_VERSION: v8.6.1
PNETCDF_VERSION: checkpoint.1.12.3
NETCDF_FORTRAN_VERSION: v4.6.1
- PIO_VERSION: pio2_6_2
- CDEPS_VERSION: cdeps1.0.36
+ PIO_VERSION: pio2_6_3
+ CDEPS_VERSION: cdeps1.0.49
steps:
- uses: actions/checkout@v4
# Build the ESMF library, if the cache contains a previous build
diff --git a/.github/workflows/srt.yml b/.github/workflows/srt.yml
index efec7ba8..5a45a82a 100644
--- a/.github/workflows/srt.yml
+++ b/.github/workflows/srt.yml
@@ -27,7 +27,7 @@ jobs:
LDFLAGS: "-L/usr/lib/x86_64-linux-gnu -lnetcdf -lnetcdff -lpnetcdf"
# Versions of all dependencies can be updated here
ESMF_VERSION: v8.6.1
- PARALLELIO_VERSION: pio2_6_2
+ PARALLELIO_VERSION: pio2_6_3
CIME_MODEL: cesm
CIME_DRIVER: nuopc
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -78,13 +78,14 @@ jobs:
# cpl7 is needed - i think that's a bug
- name: checkout externals
run: |
+ git config --global user.name "${GITHUB_ACTOR}"
+ git config --global user.email "${GITHUB_ACTOR_ID}+${GITHUB_ACTOR}@users.noreply.github.com"
pushd cesm
- ./bin/git-fleximod update ccs_config cdeps share mct parallelio
+ ./bin/git-fleximod update ccs_config cdeps share mct parallelio cime
cd ccs_config
git checkout main
- cd ../
- git clone https://github.com/ESMCI/cime
- cd cime
+ cd ../cime
+ git checkout master
if [[ ! -e "${PWD}/.gitmodules.bak" ]]
then
echo "Converting git@github.com to https://github.com urls in ${PWD}/.gitmodules"
@@ -172,6 +173,6 @@ jobs:
popd
# the following can be used by developers to login to the github server in case of errors
# see https://github.com/marketplace/actions/debugging-with-tmate for further details
- - name: Setup tmate session
- if: ${{ failure() }}
- uses: mxschmitt/action-tmate@v3
+# - name: Setup tmate session
+# if: ${{ failure() }}
+# uses: mxschmitt/action-tmate@v3
diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90
index 3b56bb95..a1a39a78 100644
--- a/cesm/driver/esm_time_mod.F90
+++ b/cesm/driver/esm_time_mod.F90
@@ -11,28 +11,26 @@ module esm_time_mod
use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet
use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_LOGMSG_ERROR
use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast
- use ESMF , only : ESMF_VMAllReduce, ESMF_REDUCE_MAX
+ use ESMF , only : ESMF_VMAllReduce, ESMF_REDUCE_MAX, ESMF_ClockGetAlarm
use ESMF , only : ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_GridCompIsPetLocal
use ESMF , only : operator(<), operator(/=), operator(+)
use ESMF , only : operator(-), operator(*) , operator(>=)
use ESMF , only : operator(<=), operator(>), operator(==)
use NUOPC , only : NUOPC_CompAttributeGet
use esm_utils_mod , only : chkerr
-
+ use nuopc_shr_methods , only : AlarmInit
+
implicit none
private ! default private
public :: esm_time_clockInit ! initialize driver clock (assumes default calendar)
-! private :: esm_time_timeInit
- private :: esm_time_alarmInit
private :: esm_time_date2ymd
! Clock and alarm options
character(len=*), private, parameter :: &
optNONE = "none" , &
optNever = "never" , &
- optNSteps = "nstep" , &
optNSeconds = "nsecond" , &
optNMinutes = "nminute" , &
optNHours = "nhour" , &
@@ -42,6 +40,7 @@ module esm_time_mod
optMonthly = "monthly" , &
optYearly = "yearly" , &
optDate = "date" , &
+ optEnd = "end" , &
optGLCCouplingPeriod = "glc_coupling_period"
! Module data
@@ -54,7 +53,7 @@ module esm_time_mod
!===============================================================================
subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintask, rc)
-
+ use nuopc_shr_methods, only : get_minimum_timestep, dtime_drv
! input/output variables
type(ESMF_GridComp) :: ensemble_driver, instance_driver
integer, intent(in) :: logunit
@@ -81,20 +80,11 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
integer :: stop_ymd ! Stop date (YYYYMMDD)
integer :: stop_tod ! Stop time-of-day
character(CS) :: stop_option ! Stop option units
- integer :: atm_cpl_dt ! Atmosphere coupling interval
- integer :: lnd_cpl_dt ! Land coupling interval
- integer :: ice_cpl_dt ! Sea-Ice coupling interval
- integer :: ocn_cpl_dt ! Ocean coupling interval
- integer :: glc_cpl_dt ! Glc coupling interval
- integer :: rof_cpl_dt ! Runoff coupling interval
- integer :: wav_cpl_dt ! Wav coupling interval
-! integer :: esp_cpl_dt ! Esp coupling interval
character(CS) :: glc_avg_period ! Glc avering coupling period
logical :: read_restart
character(len=CL) :: restart_file
character(len=CL) :: restart_pfile
character(len=CL) :: cvalue
- integer :: dtime_drv ! time-step to use
integer :: yr, mon, day ! Year, month, day as integers
integer :: unitn ! unit number
integer :: ierr ! Return code
@@ -122,44 +112,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) start_tod
- !---------------------------------------------------------------------------
- ! Determine driver clock timestep
- !---------------------------------------------------------------------------
-
- call NUOPC_CompAttributeGet(ensemble_driver, name="atm_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) atm_cpl_dt
-
- call NUOPC_CompAttributeGet(ensemble_driver, name="lnd_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) lnd_cpl_dt
-
- call NUOPC_CompAttributeGet(ensemble_driver, name="ice_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) ice_cpl_dt
-
- call NUOPC_CompAttributeGet(ensemble_driver, name="ocn_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) ocn_cpl_dt
-
- call NUOPC_CompAttributeGet(ensemble_driver, name="glc_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) glc_cpl_dt
-
- call NUOPC_CompAttributeGet(ensemble_driver, name="rof_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) rof_cpl_dt
-
- call NUOPC_CompAttributeGet(ensemble_driver, name="wav_cpl_dt", value=cvalue, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- read(cvalue,*) wav_cpl_dt
- dtime_drv = minval((/atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt/))
- if(maintask) then
- write(tmpstr,'(i10)') dtime_drv
- call ESMF_LogWrite(trim(subname)//': driver time interval is : '// trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc)
- write(logunit,*) trim(subname)//': driver time interval is : '// trim(tmpstr)
- endif
call ESMF_GridCompGet(ensemble_driver, vm=envm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -282,6 +235,12 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
call ESMF_TimeSet( RefTime, yy=yr, mm=mon, dd=day, s=ref_tod, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
+ dtime_drv = get_minimum_timestep(ensemble_driver, rc)
+ if(maintask) then
+ write(tmpstr,'(i10)') dtime_drv
+ call ESMF_LogWrite(trim(subname)//': driver time interval is : '// trim(tmpstr), ESMF_LOGMSG_INFO, rc=rc)
+ write(logunit,*) trim(subname)//': driver time interval is : '// trim(tmpstr)
+ endif
call ESMF_TimeIntervalSet( TimeStep, s=dtime_drv, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -335,7 +294,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
write(logunit,*) trim(subname)//': driver stop_tod: '// trim(tmpstr)
endif
- call esm_time_alarmInit(clock, &
+ call alarmInit(clock, &
alarm = alarm_stop, &
option = stop_option, &
opt_n = stop_n, &
@@ -368,258 +327,6 @@ end subroutine esm_time_clockInit
!===============================================================================
- subroutine esm_time_alarmInit( clock, alarm, option, &
- opt_n, opt_ymd, opt_tod, RefTime, alarmname, rc)
-
- ! Setup an alarm in a clock
- ! Notes: The ringtime sent to AlarmCreate MUST be the next alarm
- ! time. If you send an arbitrary but proper ringtime from the
- ! past and the ring interval, the alarm will always go off on the
- ! next clock advance and this will cause serious problems. Even
- ! if it makes sense to initialize an alarm with some reference
- ! time and the alarm interval, that reference time has to be
- ! advance forward to be >= the current time. In the logic below
- ! we set an appropriate "NextAlarm" and then we make sure to
- ! advance it properly based on the ring interval.
-
- ! input/output variables
- type(ESMF_Clock) , intent(inout) :: clock ! clock
- type(ESMF_Alarm) , intent(inout) :: alarm ! alarm
- character(len=*) , intent(in) :: option ! alarm option
- integer , optional , intent(in) :: opt_n ! alarm freq
- integer , optional , intent(in) :: opt_ymd ! alarm ymd
- integer , optional , intent(in) :: opt_tod ! alarm tod (sec)
- type(ESMF_Time) , optional , intent(in) :: RefTime ! ref time
- character(len=*) , optional , intent(in) :: alarmname ! alarm name
- integer , intent(inout) :: rc ! Return code
-
- ! local variables
- type(ESMF_Calendar) :: cal ! calendar
- integer :: lymd ! local ymd
- integer :: ltod ! local tod
- integer :: cyy,cmm,cdd,csec ! time info
- character(len=64) :: lalarmname ! local alarm name
- logical :: update_nextalarm ! update next alarm
- type(ESMF_Time) :: CurrTime ! Current Time
- type(ESMF_Time) :: NextAlarm ! Next restart alarm time
- type(ESMF_TimeInterval) :: AlarmInterval ! Alarm interval
- character(len=*), parameter :: subname = '(med_time_alarmInit): '
- !-------------------------------------------------------------------------------
-
- rc = ESMF_SUCCESS
-
- lalarmname = 'alarm_unknown'
- if (present(alarmname)) lalarmname = trim(alarmname)
- ltod = 0
- if (present(opt_tod)) ltod = opt_tod
- lymd = -1
- if (present(opt_ymd)) lymd = opt_ymd
-
- call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_TimeGet(CurrTime, yy=cyy, mm=cmm, dd=cdd, s=csec, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- ! initial guess of next alarm, this will be updated below
- if (present(RefTime)) then
- NextAlarm = RefTime
- else
- NextAlarm = CurrTime
- endif
-
- ! Get calendar from clock
- call ESMF_ClockGet(clock, calendar=cal, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- ! Error checks
- if (trim(option) == optdate) then
- if (.not. present(opt_ymd)) then
- call ESMF_LogWrite(trim(subname)//trim(option)//' requires opt_ymd', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- if (lymd < 0 .or. ltod < 0) then
- call ESMF_LogWrite(subname//trim(option)//'opt_ymd, opt_tod invalid', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- else if (&
- trim(option) == optNSteps .or. trim(option) == trim(optNSteps)//'s' .or. &
- trim(option) == optNSeconds .or. trim(option) == trim(optNSeconds)//'s' .or. &
- trim(option) == optNMinutes .or. trim(option) == trim(optNMinutes)//'s' .or. &
- trim(option) == optNHours .or. trim(option) == trim(optNHours)//'s' .or. &
- trim(option) == optNDays .or. trim(option) == trim(optNDays)//'s' .or. &
- trim(option) == optNMonths .or. trim(option) == trim(optNMonths)//'s' .or. &
- trim(option) == optNYears .or. trim(option) == trim(optNYears)//'s' ) then
- if (.not.present(opt_n)) then
- call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- if (opt_n <= 0) then
- call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- end if
-
- ! Determine inputs for call to create alarm
- selectcase (trim(option))
-
- case (optNONE)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optDate)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call esm_time_date2ymd(opt_ymd, cyy, cmm, cdd)
-
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=cdd, s=ltod, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optNever)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optNSteps,trim(optNSteps)//'s')
- call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNSeconds,trim(optNSeconds)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMinutes,trim(optNMinutes)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc)
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNHours,trim(optNHours)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNDays,trim(optNDays)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMonths,trim(optNMonths)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optMonthly)
- call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .true.
-
- case (optNYears, trim(optNYears)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optYearly)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .true.
-
- case default
- call ESMF_LogWrite(subname//'unknown option '//trim(option), ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
-
- end select
-
- ! --------------------------------------------------------------------------------
- ! --- AlarmInterval and NextAlarm should be set ---
- ! --------------------------------------------------------------------------------
-
- ! --- advance Next Alarm so it won't ring on first timestep for
- ! --- most options above. go back one alarminterval just to be careful
-
- if (update_nextalarm) then
- NextAlarm = NextAlarm - AlarmInterval
- do while (NextAlarm <= CurrTime)
- NextAlarm = NextAlarm + AlarmInterval
- enddo
- endif
-
- alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, &
- ringInterval=AlarmInterval, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- end subroutine esm_time_alarmInit
-
- !===============================================================================
-#ifdef UNUSEDFUNCTION
- subroutine esm_time_timeInit( Time, ymd, cal, tod, desc, logunit )
-
- ! Create the ESMF_Time object corresponding to the given input time, given in
- ! YMD (Year Month Day) and TOD (Time-of-day) format.
- ! Set the time by an integer as YYYYMMDD and integer seconds in the day
-
- ! input/output parameters:
- type(ESMF_Time) , intent(inout) :: Time ! ESMF time
- integer , intent(in) :: ymd ! year, month, day YYYYMMDD
- type(ESMF_Calendar) , intent(in) :: cal ! ESMF calendar
- integer , intent(in), optional :: tod ! time of day in seconds
- character(len=*) , intent(in), optional :: desc ! description of time to set
- integer , intent(in), optional :: logunit
-
- ! local variables
- integer :: yr, mon, day ! Year, month, day as integers
- integer :: ltod ! local tod
- character(len=256) :: ldesc ! local desc
- integer :: rc ! return code
- character(len=*), parameter :: subname = '(esm_time_m_ETimeInit) '
- !-------------------------------------------------------------------------------
-
- ltod = 0
- if (present(tod)) ltod = tod
- ldesc = ''
- if (present(desc)) ldesc = desc
-
- if ( (ymd < 0) .or. (ltod < 0) .or. (ltod > SecPerDay) )then
- if (present(logunit)) then
- write(logunit,*) subname//': ERROR yymmdd is a negative number or '// &
- 'time-of-day out of bounds', ymd, ltod
- end if
- call ESMF_LogWrite( subname//'ERROR: Bad input' , ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
-
- call esm_time_date2ymd (ymd,yr,mon,day)
-
- call ESMF_TimeSet( Time, yy=yr, mm=mon, dd=day, s=ltod, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- end subroutine esm_time_timeInit
-#endif
- !===============================================================================
-
subroutine esm_time_date2ymd (date, year, month, day)
! input/output variables
diff --git a/cesm/nuopc_cap_share/nuopc_shr_methods.F90 b/cesm/nuopc_cap_share/nuopc_shr_methods.F90
deleted file mode 100644
index 9062b27f..00000000
--- a/cesm/nuopc_cap_share/nuopc_shr_methods.F90
+++ /dev/null
@@ -1,859 +0,0 @@
-module nuopc_shr_methods
-
- use ESMF , only : operator(<), operator(/=), operator(+)
- use ESMF , only : operator(-), operator(*) , operator(>=)
- use ESMF , only : operator(<=), operator(>), operator(==)
- use ESMF , only : ESMF_LOGERR_PASSTHRU, ESMF_LogFoundError, ESMF_LOGMSG_ERROR, ESMF_MAXSTR
- use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_FAILURE
- use ESMF , only : ESMF_State, ESMF_StateGet
- use ESMF , only : ESMF_Field, ESMF_FieldGet
- use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_GridCompSet
- use ESMF , only : ESMF_GeomType_Flag, ESMF_FieldStatus_Flag
- use ESMF , only : ESMF_Mesh, ESMF_MeshGet
- use ESMF , only : ESMF_GEOMTYPE_MESH, ESMF_GEOMTYPE_GRID, ESMF_FIELDSTATUS_COMPLETE
- use ESMF , only : ESMF_Clock, ESMF_ClockCreate, ESMF_ClockGet, ESMF_ClockSet
- use ESMF , only : ESMF_ClockPrint, ESMF_ClockAdvance
- use ESMF , only : ESMF_Alarm, ESMF_AlarmCreate, ESMF_AlarmGet, ESMF_AlarmSet
- use ESMF , only : ESMF_Calendar, ESMF_CALKIND_NOLEAP, ESMF_CALKIND_GREGORIAN
- use ESMF , only : ESMF_Time, ESMF_TimeGet, ESMF_TimeSet
- use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet
- use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast, ESMF_VMGetCurrent
- use NUOPC , only : NUOPC_CompAttributeGet
- use NUOPC_Model , only : NUOPC_ModelGet
- use shr_kind_mod , only : r8 => shr_kind_r8, cl=>shr_kind_cl, cs=>shr_kind_cs
- use shr_sys_mod , only : shr_sys_abort
- use shr_log_mod , only : shr_log_setLogUnit
-
- implicit none
- private
-
- public :: memcheck
- public :: get_component_instance
- public :: set_component_logging
- public :: log_clock_advance
- public :: state_getscalar
- public :: state_setscalar
- public :: state_diagnose
- public :: alarmInit
- public :: chkerr
-
- private :: timeInit
- private :: field_getfldptr
-
- ! Clock and alarm options
- character(len=*), private, parameter :: &
- optNONE = "none" , &
- optNever = "never" , &
- optNSteps = "nsteps" , &
- optNStep = "nstep" , &
- optNSeconds = "nseconds" , &
- optNSecond = "nsecond" , &
- optNMinutes = "nminutes" , &
- optNMinute = "nminute" , &
- optNHours = "nhours" , &
- optNHour = "nhour" , &
- optNDays = "ndays" , &
- optNDay = "nday" , &
- optNMonths = "nmonths" , &
- optNMonth = "nmonth" , &
- optNYears = "nyears" , &
- optNYear = "nyear" , &
- optMonthly = "monthly" , &
- optYearly = "yearly" , &
- optEnd = "end" , &
- optDate = "date"
-
-
- ! Module data
- integer, parameter :: SecPerDay = 86400 ! Seconds per day
- integer, parameter :: memdebug_level=1
- character(len=1024) :: msgString
- character(len=*), parameter :: u_FILE_u = &
- __FILE__
-
-!===============================================================================
-contains
-!===============================================================================
-
- subroutine memcheck(string, level, maintask)
-
- ! input/output variables
- character(len=*) , intent(in) :: string
- integer , intent(in) :: level
- logical , intent(in) :: maintask
-
- ! local variables
- integer :: ierr
-#ifdef CESMCOUPLED
- integer, external :: GPTLprint_memusage
-#endif
- !-----------------------------------------------------------------------
-
-#ifdef CESMCOUPLED
- if ((maintask .and. memdebug_level > level) .or. memdebug_level > level+1) then
- ierr = GPTLprint_memusage(string)
- endif
-#endif
-
- end subroutine memcheck
-
-!===============================================================================
-
- subroutine get_component_instance(gcomp, inst_suffix, inst_index, rc)
-
- ! input/output variables
- type(ESMF_GridComp) :: gcomp
- character(len=*) , intent(out) :: inst_suffix
- integer , intent(out) :: inst_index
- integer , intent(out) :: rc
-
- ! local variables
- logical :: isPresent
- character(len=4) :: cvalue
- !-----------------------------------------------------------------------
-
- rc = ESMF_SUCCESS
-
- call NUOPC_CompAttributeGet(gcomp, name="inst_suffix", isPresent=isPresent, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- if (isPresent) then
- call NUOPC_CompAttributeGet(gcomp, name="inst_suffix", value=inst_suffix, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- cvalue = inst_suffix(2:)
- read(cvalue, *) inst_index
- else
- inst_suffix = ""
- inst_index=1
- endif
-
- end subroutine get_component_instance
-
-!===============================================================================
- subroutine set_component_logging(gcomp, maintask, logunit, shrlogunit, rc)
- use NUOPC, only: NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd
- ! input/output variables
- type(ESMF_GridComp) :: gcomp
- logical, intent(in) :: maintask
- integer, intent(out) :: logunit
- integer, intent(out) :: shrlogunit
- integer, intent(out) :: rc
-
- ! local variables
- character(len=CL) :: diro
- character(len=CL) :: logfile
- character(len=CL) :: inst_suffix
- integer :: inst_index ! Not used here
- integer :: n
- character(len=CL) :: name
- character(len=*), parameter :: subname = "("//__FILE__//": set_component_logging)"
- !-----------------------------------------------------------------------
-
- rc = ESMF_SUCCESS
-
- if (maintask) then
- call NUOPC_CompAttributeGet(gcomp, name="diro", value=diro, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call NUOPC_CompAttributeGet(gcomp, name="logfile", value=logfile, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call get_component_instance(gcomp, inst_suffix, inst_index, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- ! Multiinstance logfile name needs a correction
- if(len_trim(inst_suffix) > 0) then
- n = index(logfile, '.')
- logfile = logfile(1:n-1)//trim(inst_suffix)//logfile(n:)
- endif
-
- open(newunit=logunit,file=trim(diro)//"/"//trim(logfile))
-
- else
- logUnit = 6
- endif
-
- call ESMF_GridCompGet(gcomp, name=name, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_LogWrite(trim(subname)//": setting logunit for component: "//trim(name), ESMF_LOGMSG_INFO)
- call NUOPC_CompAttributeAdd(gcomp, (/"logunit"/), rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call NUOPC_CompAttributeSet(gcomp, "logunit", logunit, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call shr_log_setLogUnit (logunit)
- ! Still need to set this return value
- shrlogunit = logunit
- call ESMF_LogWrite(trim(subname)//": done for component "//trim(name), ESMF_LOGMSG_INFO)
- end subroutine set_component_logging
-
-!===============================================================================
-
- subroutine log_clock_advance(clock, component, logunit, rc)
-
- ! input/output variables
- type(ESMF_Clock) :: clock
- character(len=*) , intent(in) :: component
- integer , intent(in) :: logunit
- integer , intent(out) :: rc
-
- ! local variables
- character(len=CL) :: cvalue, prestring
- !-----------------------------------------------------------------------
-
- rc = ESMF_SUCCESS
-
- write(prestring, *) "------>Advancing ",trim(component)," from: "
- call ESMF_ClockPrint(clock, options="currTime", unit=cvalue, preString=trim(prestring), rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- write(logunit, *) trim(cvalue)
-
- call ESMF_ClockPrint(clock, options="stopTime", unit=cvalue, &
- preString="--------------------------------> to: ", rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- write(logunit, *) trim(cvalue)
-
- end subroutine log_clock_advance
-
-!===============================================================================
-
- subroutine state_getscalar(state, scalar_id, scalar_value, flds_scalar_name, flds_scalar_num, rc)
-
- ! ----------------------------------------------
- ! Get scalar data from State for a particular name and broadcast it to all other pets
- ! ----------------------------------------------
-
- ! input/output variables
- type(ESMF_State), intent(in) :: state
- integer, intent(in) :: scalar_id
- real(r8), intent(out) :: scalar_value
- character(len=*), intent(in) :: flds_scalar_name
- integer, intent(in) :: flds_scalar_num
- integer, intent(inout) :: rc
-
- ! local variables
- integer :: mytask, ierr, len
- type(ESMF_VM) :: vm
- type(ESMF_Field) :: field
- real(r8), pointer :: farrayptr(:,:)
- real(r8) :: tmp(1)
- character(len=*), parameter :: subname='(state_getscalar)'
- ! ----------------------------------------------
-
- rc = ESMF_SUCCESS
-
- call ESMF_VMGetCurrent(vm, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_VMGet(vm, localPet=mytask, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_StateGet(State, itemName=trim(flds_scalar_name), field=field, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- if (mytask == 0) then
- call ESMF_FieldGet(field, farrayPtr = farrayptr, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- if (scalar_id < 0 .or. scalar_id > flds_scalar_num) then
- call ESMF_LogWrite(trim(subname)//": ERROR in scalar_id", ESMF_LOGMSG_INFO, line=__LINE__, file=u_FILE_u)
- rc = ESMF_FAILURE
- if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return
- endif
- tmp(:) = farrayptr(scalar_id,:)
- endif
- call ESMF_VMBroadCast(vm, tmp, 1, 0, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- scalar_value = tmp(1)
-
- end subroutine state_getscalar
-
-!================================================================================
-
- subroutine state_setscalar(scalar_value, scalar_id, State, flds_scalar_name, flds_scalar_num, rc)
-
- ! ----------------------------------------------
- ! Set scalar data from State for a particular name
- ! ----------------------------------------------
-
- ! input/output arguments
- real(r8), intent(in) :: scalar_value
- integer, intent(in) :: scalar_id
- type(ESMF_State), intent(inout) :: State
- character(len=*), intent(in) :: flds_scalar_name
- integer, intent(in) :: flds_scalar_num
- integer, intent(inout) :: rc
-
- ! local variables
- integer :: mytask
- type(ESMF_Field) :: lfield
- type(ESMF_VM) :: vm
- real(r8), pointer :: farrayptr(:,:)
- character(len=*), parameter :: subname='(state_setscalar)'
- ! ----------------------------------------------
-
- rc = ESMF_SUCCESS
-
- call ESMF_VMGetCurrent(vm, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_VMGet(vm, localPet=mytask, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_StateGet(State, itemName=trim(flds_scalar_name), field=lfield, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- if (mytask == 0) then
- call ESMF_FieldGet(lfield, farrayPtr = farrayptr, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- if (scalar_id < 0 .or. scalar_id > flds_scalar_num) then
- call ESMF_LogWrite(trim(subname)//": ERROR in scalar_id", ESMF_LOGMSG_INFO)
- rc = ESMF_FAILURE
- return
- endif
- farrayptr(scalar_id,1) = scalar_value
- endif
-
- end subroutine state_setscalar
-
-!===============================================================================
-
- subroutine state_diagnose(State, string, rc)
-
- ! ----------------------------------------------
- ! Diagnose status of State
- ! ----------------------------------------------
-
- type(ESMF_State), intent(in) :: state
- character(len=*), intent(in) :: string
- integer , intent(out) :: rc
-
- ! local variables
- integer :: i,j,n
- type(ESMf_Field) :: lfield
- integer :: fieldCount, lrank
- character(ESMF_MAXSTR) ,pointer :: lfieldnamelist(:)
- real(r8), pointer :: dataPtr1d(:)
- real(r8), pointer :: dataPtr2d(:,:)
- character(len=*),parameter :: subname='(state_diagnose)'
- ! ----------------------------------------------
-
- call ESMF_StateGet(state, itemCount=fieldCount, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- allocate(lfieldnamelist(fieldCount))
-
- call ESMF_StateGet(state, itemNameList=lfieldnamelist, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- do n = 1, fieldCount
-
- call ESMF_StateGet(state, itemName=lfieldnamelist(n), field=lfield, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call field_getfldptr(lfield, fldptr1=dataPtr1d, fldptr2=dataPtr2d, rank=lrank, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- if (lrank == 0) then
- ! no local data
- elseif (lrank == 1) then
- if (size(dataPtr1d) > 0) then
- write(msgString,'(A,a)') trim(string)//': for 1d field '//trim(lfieldnamelist(n))
- call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
- write(msgString,'(A,3g14.7,i8)') trim(string)//': 1d field '//trim(lfieldnamelist(n)), &
- minval(dataPtr1d), maxval(dataPtr1d), sum(dataPtr1d), size(dataPtr1d)
- call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
- else
- write(msgString,'(A,a)') trim(string)//': '//trim(lfieldnamelist(n))," no data"
- call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
- endif
- elseif (lrank == 2) then
- if (size(dataPtr2d) > 0) then
- write(msgString,'(A,a)') trim(string)//': for 2d field '//trim(lfieldnamelist(n))
- call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
- write(msgString,'(A,3g14.7,i8)') trim(string)//': 2d field '//trim(lfieldnamelist(n)), &
- minval(dataPtr2d), maxval(dataPtr2d), sum(dataPtr2d), size(dataPtr2d)
- call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
- else
- write(msgString,'(A,a)') trim(string)//': '//trim(lfieldnamelist(n))," no data"
- call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
- endif
- else
- call ESMF_LogWrite(trim(subname)//": ERROR rank not supported ", ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- endif
- enddo
-
- deallocate(lfieldnamelist)
-
- end subroutine state_diagnose
-
-!===============================================================================
-
- subroutine field_getfldptr(field, fldptr1, fldptr2, rank, abort, rc)
-
- ! ----------------------------------------------
- ! for a field, determine rank and return fldptr1 or fldptr2
- ! abort is true by default and will abort if fldptr is not yet allocated in field
- ! rank returns 0, 1, or 2. 0 means fldptr not allocated and abort=false
- ! ----------------------------------------------
-
- ! input/output variables
- type(ESMF_Field) , intent(in) :: field
- real(r8), pointer , intent(inout), optional :: fldptr1(:)
- real(r8), pointer , intent(inout), optional :: fldptr2(:,:)
- integer , intent(out) , optional :: rank
- logical , intent(in) , optional :: abort
- integer , intent(out) , optional :: rc
-
- ! local variables
- type(ESMF_GeomType_Flag) :: geomtype
- type(ESMF_FieldStatus_Flag) :: status
- type(ESMF_Mesh) :: lmesh
- integer :: lrank, nnodes, nelements
- logical :: labort
- character(len=*), parameter :: subname='(field_getfldptr)'
- ! ----------------------------------------------
-
- if (.not.present(rc)) then
- call ESMF_LogWrite(trim(subname)//": ERROR rc not present ", &
- ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u)
- rc = ESMF_FAILURE
- return
- endif
-
- rc = ESMF_SUCCESS
-
- labort = .true.
- if (present(abort)) then
- labort = abort
- endif
- lrank = -99
-
- call ESMF_FieldGet(field, status=status, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- if (status /= ESMF_FIELDSTATUS_COMPLETE) then
- lrank = 0
- if (labort) then
- call ESMF_LogWrite(trim(subname)//": ERROR data not allocated ", ESMF_LOGMSG_INFO, rc=rc)
- rc = ESMF_FAILURE
- return
- else
- call ESMF_LogWrite(trim(subname)//": WARNING data not allocated ", ESMF_LOGMSG_INFO, rc=rc)
- endif
- else
-
- call ESMF_FieldGet(field, geomtype=geomtype, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- if (geomtype == ESMF_GEOMTYPE_GRID) then
- call ESMF_FieldGet(field, rank=lrank, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- elseif (geomtype == ESMF_GEOMTYPE_MESH) then
- call ESMF_FieldGet(field, rank=lrank, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call ESMF_FieldGet(field, mesh=lmesh, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call ESMF_MeshGet(lmesh, numOwnedNodes=nnodes, numOwnedElements=nelements, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- if (nnodes == 0 .and. nelements == 0) lrank = 0
- else
- call ESMF_LogWrite(trim(subname)//": ERROR geomtype not supported ", &
- ESMF_LOGMSG_INFO, rc=rc)
- rc = ESMF_FAILURE
- return
- endif ! geomtype
-
- if (lrank == 0) then
- call ESMF_LogWrite(trim(subname)//": no local nodes or elements ", &
- ESMF_LOGMSG_INFO)
- elseif (lrank == 1) then
- if (.not.present(fldptr1)) then
- call ESMF_LogWrite(trim(subname)//": ERROR missing rank=1 array ", &
- ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u)
- rc = ESMF_FAILURE
- return
- endif
- call ESMF_FieldGet(field, farrayPtr=fldptr1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- elseif (lrank == 2) then
- if (.not.present(fldptr2)) then
- call ESMF_LogWrite(trim(subname)//": ERROR missing rank=2 array ", &
- ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u)
- rc = ESMF_FAILURE
- return
- endif
- call ESMF_FieldGet(field, farrayPtr=fldptr2, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- else
- call ESMF_LogWrite(trim(subname)//": ERROR in rank ", &
- ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u)
- rc = ESMF_FAILURE
- return
- endif
-
- endif ! status
-
- if (present(rank)) then
- rank = lrank
- endif
-
- end subroutine field_getfldptr
-
-!===============================================================================
-
- subroutine alarmInit( clock, alarm, option, &
- opt_n, opt_ymd, opt_tod, RefTime, alarmname, rc)
-
- ! Setup an alarm in a clock
- ! Notes: The ringtime sent to AlarmCreate MUST be the next alarm
- ! time. If you send an arbitrary but proper ringtime from the
- ! past and the ring interval, the alarm will always go off on the
- ! next clock advance and this will cause serious problems. Even
- ! if it makes sense to initialize an alarm with some reference
- ! time and the alarm interval, that reference time has to be
- ! advance forward to be >= the current time. In the logic below
- ! we set an appropriate "NextAlarm" and then we make sure to
- ! advance it properly based on the ring interval.
-
- ! input/output variables
- type(ESMF_Clock) , intent(inout) :: clock ! clock
- type(ESMF_Alarm) , intent(inout) :: alarm ! alarm
- character(len=*) , intent(in) :: option ! alarm option
- integer , optional , intent(in) :: opt_n ! alarm freq
- integer , optional , intent(in) :: opt_ymd ! alarm ymd
- integer , optional , intent(in) :: opt_tod ! alarm tod (sec)
- type(ESMF_Time) , optional , intent(in) :: RefTime ! ref time
- character(len=*) , optional , intent(in) :: alarmname ! alarm name
- integer , intent(inout) :: rc ! Return code
-
- ! local variables
- type(ESMF_Calendar) :: cal ! calendar
- integer :: lymd ! local ymd
- integer :: ltod ! local tod
- integer :: cyy,cmm,cdd,csec ! time info
- character(len=64) :: lalarmname ! local alarm name
- logical :: update_nextalarm ! update next alarm
- type(ESMF_Time) :: CurrTime ! Current Time
- type(ESMF_Time) :: NextAlarm ! Next restart alarm time
- type(ESMF_TimeInterval) :: AlarmInterval ! Alarm interval
- integer :: sec
- character(len=*), parameter :: subname = '(set_alarmInit): '
- !-------------------------------------------------------------------------------
-
- rc = ESMF_SUCCESS
-
- lalarmname = 'alarm_unknown'
- if (present(alarmname)) lalarmname = trim(alarmname)
- ltod = 0
- if (present(opt_tod)) ltod = opt_tod
- lymd = -1
- if (present(opt_ymd)) lymd = opt_ymd
-
- call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_TimeGet(CurrTime, yy=cyy, mm=cmm, dd=cdd, s=csec, rc=rc )
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- ! initial guess of next alarm, this will be updated below
- if (present(RefTime)) then
- NextAlarm = RefTime
- else
- NextAlarm = CurrTime
- endif
-
- ! Determine calendar
- call ESMF_ClockGet(clock, calendar=cal)
-
- ! Determine inputs for call to create alarm
- selectcase (trim(option))
-
- case (optNONE)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optNever)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optEnd)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optDate)
- if (.not. present(opt_ymd)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_ymd')
- end if
- if (lymd < 0 .or. ltod < 0) then
- call shr_sys_abort(subname//trim(option)//'opt_ymd, opt_tod invalid')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call timeInit(NextAlarm, lymd, cal, ltod, rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optNSteps)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNStep)
- if (.not.present(opt_n)) call shr_sys_abort(subname//trim(option)//' requires opt_n')
- if (opt_n <= 0) call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNSeconds)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNSecond)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMinutes)
- call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMinute)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNHours)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNHour)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNDays)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNDay)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMonths)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMonth)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optMonthly)
- call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=1, s=0, calendar=cal, rc=rc )
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .true.
-
- case (optNYears)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNYear)
- if (.not.present(opt_n)) then
- call shr_sys_abort(subname//trim(option)//' requires opt_n')
- end if
- if (opt_n <= 0) then
- call shr_sys_abort(subname//trim(option)//' invalid opt_n')
- end if
- call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optYearly)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc )
- if (chkerr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .true.
-
- case default
- call shr_sys_abort(subname//'unknown option '//trim(option))
-
- end select
-
- ! --------------------------------------------------------------------------------
- ! --- AlarmInterval and NextAlarm should be set ---
- ! --------------------------------------------------------------------------------
-
- ! --- advance Next Alarm so it won't ring on first timestep for
- ! --- most options above. go back one alarminterval just to be careful
-
- if (update_nextalarm) then
- NextAlarm = NextAlarm - AlarmInterval
- do while (NextAlarm <= CurrTime)
- NextAlarm = NextAlarm + AlarmInterval
- enddo
- endif
- alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, &
- ringInterval=AlarmInterval, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- end subroutine alarmInit
-
-!===============================================================================
-
- subroutine timeInit( Time, ymd, cal, tod, rc)
-
- ! Create the ESMF_Time object corresponding to the given input time,
- ! given in YMD (Year Month Day) and TOD (Time-of-day) format.
- ! Set the time by an integer as YYYYMMDD and integer seconds in the day
-
- ! input/output parameters:
- type(ESMF_Time) , intent(inout) :: Time ! ESMF time
- integer , intent(in) :: ymd ! year, month, day YYYYMMDD
- type(ESMF_Calendar) , intent(in) :: cal ! ESMF calendar
- integer , intent(in) :: tod ! time of day in seconds
- integer , intent(out) :: rc
-
- ! local variables
- integer :: year, mon, day ! year, month, day as integers
- integer :: tdate ! temporary date
- character(len=*), parameter :: subname='(timeInit)'
- !-------------------------------------------------------------------------------
-
- rc = ESMF_SUCCESS
-
- if ( (ymd < 0) .or. (tod < 0) .or. (tod > SecPerDay) )then
- call shr_sys_abort( subname//'ERROR yymmdd is a negative number or time-of-day out of bounds' )
- end if
-
- tdate = abs(ymd)
- year = int(tdate/10000)
- if (ymd < 0) year = -year
- mon = int( mod(tdate,10000)/ 100)
- day = mod(tdate, 100)
-
- call ESMF_TimeSet( Time, yy=year, mm=mon, dd=day, s=tod, calendar=cal, rc=rc )
- if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- end subroutine timeInit
-
-!===============================================================================
-
- logical function chkerr(rc, line, file)
-
- integer, intent(in) :: rc
- integer, intent(in) :: line
- character(len=*), intent(in) :: file
-
- integer :: lrc
-
- chkerr = .false.
- lrc = rc
- if (ESMF_LogFoundError(rcToCheck=lrc, msg=ESMF_LOGERR_PASSTHRU, line=line, file=file)) then
- chkerr = .true.
- endif
- end function chkerr
-
-end module nuopc_shr_methods
diff --git a/cime_config/buildnml b/cime_config/buildnml
index 13d04514..44116d98 100755
--- a/cime_config/buildnml
+++ b/cime_config/buildnml
@@ -50,7 +50,10 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files):
config["continue_run"] = ".true." if case.get_value("CONTINUE_RUN") else ".false."
config["flux_epbal"] = "ocn" if case.get_value("CPL_EPBAL") == "ocn" else "off"
config["mask_grid"] = case.get_value("MASK_GRID")
- config["rest_option"] = case.get_value("REST_OPTION")
+ for val in ("HIST", "REST", "STOP"):
+ config[val.lower()+"_option"] = case.get_value(val+"_OPTION")
+
+
config["comp_ocn"] = case.get_value("COMP_OCN")
atm_grid = case.get_value("ATM_GRID")
@@ -199,6 +202,19 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files):
coupling_times[comp.lower() + "_cpl_dt"] = cpl_dt
mindt = min(mindt, cpl_dt)
+ # Here we convert "nsteps" to "nseconds", this simplifies the fortran
+
+ for val in ("REST", "HIST", "STOP"):
+ if case.get_value(val+"_OPTION") == "nsteps":
+ nsteps = case.get_value(val+"_N")
+ if val == "REST":
+ nmlgen.set_value("restart_n", value=mindt*nsteps)
+ elif val == "HIST":
+ nmlgen.set_value("history_n", value=mindt*nsteps)
+ else:
+ nmlgen.set_value("stop_n", value=mindt*nsteps)
+
+
# sanity check
comp_atm = case.get_value("COMP_ATM")
if comp_atm is not None and comp_atm not in ("datm", "xatm", "satm"):
@@ -305,7 +321,7 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files):
for item in case.get_values("COMP_CLASSES"):
comp = case.get_value("COMP_" + item)
- if case.get_value(f"PIO_ASYNC_INTERFACE", {"compclass":item}):
+ if case.get_value("PIO_ASYNC_INTERFACE", {"compclass":item}):
asyncio = True
valid = True
@@ -608,8 +624,6 @@ def buildnml(case, caseroot, component):
if component != "drv":
raise AttributeError
- # Do a check here of ESMF VERSION, requires 8.1.0 or newer (8.2.0 or newer for esmf_aware_threading)
- esmf_aware_threading = case.get_value("ESMF_AWARE_THREADING")
esmfmkfile = os.getenv("ESMFMKFILE")
expect(
esmfmkfile and os.path.isfile(esmfmkfile),
@@ -623,7 +637,7 @@ def buildnml(case, caseroot, component):
major = line[-2] if "MAJOR" in line else major
minor = line[-2] if "MINOR" in line else minor
logger.debug("ESMF version major {} minor {}".format(major, minor))
- expect(int(major) >= 8 and int(minor) >=4, "ESMF version should be 8.4.1 or newer")
+ expect(int(major) >= 8 and int(minor) >=6, "ESMF version should be 8.6.1 or newer")
confdir = os.path.join(case.get_value("CASEBUILD"), "cplconf")
if not os.path.isdir(confdir):
diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml
index 0d06f235..63e1b09a 100644
--- a/cime_config/config_component.xml
+++ b/cime_config/config_component.xml
@@ -334,7 +334,7 @@
run_begin_stop_restart
env_run.xml
- Run start time-of-day
+ Run start time-of-day, units are seconds with values from 0 to 86400.
diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml
index c24170de..0d72779b 100644
--- a/cime_config/namelist_definition_drv.xml
+++ b/cime_config/namelist_definition_drv.xml
@@ -233,17 +233,15 @@
-
-
-
-
+
logical
nuopc
ALLCOMP_attributes
.false.
- .true.
+ .false.
+ .false.
@@ -256,6 +254,10 @@
+
+
+
+
char
orbital
@@ -1117,13 +1119,12 @@
char
time
ALLCOMP_attributes
- none,never,nsteps,nseconds,nminutes,nhours,ndays,nmonths,nyears,monthly,yearly,date,end
+ none,never,nseconds,nminutes,nhours,ndays,nmonths,nyears,monthly,yearly,date,end
mediator history snapshot option (used with history_n and history_ymd)
set by HIST_OPTION in env_run.xml.
history_option alarms are:
[none/never], turns option off
- [nsteps] , history snapshot every history_n nsteps , relative to current run start time
[nseconds] , history snapshot every history_n nseconds, relative to current run start time
[nminutes] , history snapshot every history_n nminutes, relative to current run start time
[nhours] , history snapshot every history_n nhours , relative to current run start time
@@ -1136,6 +1137,7 @@
$HIST_OPTION
+ nseconds
@@ -2720,12 +2722,11 @@
char
time
CLOCK_attributes
- none,never,nsteps,nseconds,nminutes,nhours,ndays,monthly,nmonths,nyears,date,end
+ none,never,nseconds,nminutes,nhours,ndays,monthly,nmonths,nyears,date,end
sets the run length with stop_n and stop_ymd
stop_option alarms are:
[none/never] , turns option off
- [nsteps] , stops every stop_n nsteps , relative to current run start time
[nseconds] , stops every stop_n nseconds, relative to current run start time
[nminutes] , stops every stop_n nminutes, relative to current run start time
[nhours] , stops every stop_n nhours , relative to current run start time
@@ -2739,6 +2740,7 @@
$STOP_OPTION
+ nseconds
@@ -2784,12 +2786,11 @@
char
time
CLOCK_attributes
- none,never,nsteps,nseconds,nminutes,nhours,ndays,nmonths,nyears,monthly,yearly,date,end
+ none,never,nseconds,nminutes,nhours,ndays,nmonths,nyears,monthly,yearly,date,end
sets the restart frequency with restart_n and restart_ymd
restart_option alarms are:
[none/never], turns option off
- [nsteps] , restarts every restart_n nsteps , relative to current run start time
[nseconds] , restarts every restart_n nseconds, relative to current run start time
[nminutes] , restarts every restart_n nminutes, relative to current run start time
[nhours] , restarts every restart_n nhours , relative to current run start time
@@ -2803,6 +2804,7 @@
$REST_OPTION
+ nseconds
diff --git a/cime_config/runseq/driver_config.py b/cime_config/runseq/driver_config.py
index 48dca7ba..dfdadc75 100644
--- a/cime_config/runseq/driver_config.py
+++ b/cime_config/runseq/driver_config.py
@@ -64,7 +64,7 @@ def __compute_glc(self, case, coupling_times):
# However will still need to call the exchange at the end if the stop_option
# is nsteps or days - or otherwise just every ndays
# Note that nsteps is the minimum component coupling time
- if (comp_glc == 'cism'):
+ if comp_glc == 'cism':
glc_coupling_time = coupling_times["glc_cpl_dt"]
if not case.get_value("CISM_EVOLVE"):
stop_option = case.get_value('STOP_OPTION')
@@ -77,15 +77,7 @@ def __compute_glc(self, case, coupling_times):
glc_coupling_time = stop_n * 86400
else:
glc_coupling_time = 86400
- elif (comp_glc == 'dglc'):
- glc_coupling_time = coupling_times["glc_cpl_dt"]
- is_test = case.get_value("TEST")
- if not is_test:
- stop_option = case.get_value('STOP_OPTION')
- if stop_option == 'nsteps':
- stop_n = case.get_value('STOP_N')
- glc_coupling_time = stop_n*coupling_times["atm_cpl_dt"]
- elif (comp_glc == 'xglc'):
+ elif comp_glc == 'dglc' or comp_glc == 'xglc':
glc_coupling_time = coupling_times["glc_cpl_dt"]
else:
glc_coupling_time = 0
diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt
index 9630b5e2..80be3d2e 100644
--- a/mediator/CMakeLists.txt
+++ b/mediator/CMakeLists.txt
@@ -4,7 +4,7 @@ set(SRCFILES esmFldsExchange_cesm_mod.F90 med_fraction_mod.F90
med_methods_mod.F90 med_phases_prep_ice_mod.F90
med_phases_restart_mod.F90 esmFldsExchange_hafs_mod.F90
med_internalstate_mod.F90 med_phases_aofluxes_mod.F90
- med_phases_prep_lnd_mod.F90 med_time_mod.F90
+ med_phases_prep_lnd_mod.F90
esmFldsExchange_ufs_mod.F90 med_io_mod.F90
med_phases_history_mod.F90 med_phases_prep_ocn_mod.F90
med_utils_mod.F90 esmFlds.F90 med_kind_mod.F90
diff --git a/mediator/Makefile b/mediator/Makefile
index 990fe58e..a353ff9a 100644
--- a/mediator/Makefile
+++ b/mediator/Makefile
@@ -39,7 +39,7 @@ esmFldsExchange_hafs_mod.o : med_kind_mod.o med_methods_mod.o esmFlds.o med_inte
med.o : med_kind_mod.o med_phases_profile_mod.o med_utils_mod.o med_phases_prep_rof_mod.o med_phases_aofluxes_mod.o \
med_phases_prep_ice_mod.o med_fraction_mod.o med_map_mod.o med_constants_mod.o med_phases_prep_wav_mod.o \
med_phases_prep_lnd_mod.o med_phases_history_mod.o med_phases_ocnalb_mod.o med_phases_restart_mod.o \
- med_time_mod.o med_internalstate_mod.o med_phases_prep_atm_mod.o esmFldsExchange_cesm_mod.o esmFldsExchange_ufs_mod.o \
+ med_internalstate_mod.o med_phases_prep_atm_mod.o esmFldsExchange_cesm_mod.o esmFldsExchange_ufs_mod.o \
esmFldsExchange_hafs_mod.o med_phases_prep_glc_mod.o esmFlds.o med_io_mod.o med_methods_mod.o med_phases_prep_ocn_mod.o \
med_phases_post_atm_mod.o med_phases_post_ice_mod.o med_phases_post_lnd_mod.o med_phases_post_glc_mod.o med_phases_post_rof_mod.o \
med_phases_post_wav_mod.o
@@ -50,7 +50,7 @@ med_map_mod.o : med_kind_mod.o med_internalstate_mod.o med_constants_mod.o med_m
med_merge_mod.o : med_kind_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o med_utils_mod.o
med_methods_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o
med_phases_aofluxes_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o
-med_phases_history_mod.o : med_kind_mod.o med_utils_mod.o med_time_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o med_io_mod.o esmFlds.o
+med_phases_history_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o med_io_mod.o esmFlds.o
med_phases_ocnalb_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o
med_phases_prep_atm_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_merge_mod.o med_map_mod.o med_constants_mod.o med_phases_ocnalb_mod.o med_internalstate_mod.o med_utils_mod.o
med_phases_prep_glc_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_map_mod.o med_constants_mod.o med_methods_mod.o esmFlds.o
@@ -68,6 +68,5 @@ med_phases_post_rof_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_m
med_phases_post_wav_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o
med_phases_profile_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o med_internalstate_mod.o med_time_mod.o
med_phases_restart_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_io_mod.o
-med_time_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o
med_utils_mod.o : med_kind_mod.o
-med_diag_mod.o : med_kind_mod.o med_time_mod.o med_utils_mod.o med_methods_mod.o med_internalstate_mod.o
+med_diag_mod.o : med_kind_mod.o med_utils_mod.o med_methods_mod.o med_internalstate_mod.o
diff --git a/mediator/med.F90 b/mediator/med.F90
index 3133c7f8..914e35ad 100644
--- a/mediator/med.F90
+++ b/mediator/med.F90
@@ -38,7 +38,6 @@ module MED
use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN
use med_methods_mod , only : clock_timeprint => med_methods_clock_timeprint
use med_utils_mod , only : memcheck => med_memcheck
- use med_time_mod , only : med_time_alarmInit
use med_internalstate_mod , only : InternalState, med_internalstate_init, med_internalstate_coupling
use med_internalstate_mod , only : med_internalstate_defaultmasks, logunit, maintask
use med_internalstate_mod , only : ncomps, compname
@@ -2261,7 +2260,9 @@ subroutine SetRunClock(gcomp, rc)
use ESMF , only : ESMF_ClockGetAlarmList
use NUOPC , only : NUOPC_CompCheckSetClock, NUOPC_CompAttributeGet
use NUOPC_Mediator , only : NUOPC_MediatorGet
-
+ ! NUOPC_shr_methods is now in cesm_share and cdeps
+ use nuopc_shr_methods, only : AlarmInit
+
! input/output variables
type(ESMF_GridComp) :: gcomp
integer, intent(out) :: rc
@@ -2318,7 +2319,7 @@ subroutine SetRunClock(gcomp, rc)
call NUOPC_CompAttributeGet(gcomp, name="stop_ymd", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) stop_ymd
- call med_time_alarmInit(mclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, &
+ call AlarmInit(mclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, &
alarmname='alarm_stop', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
stopalarmcreated = .true.
diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90
index 5e06f216..4c9ba6b4 100644
--- a/mediator/med_diag_mod.F90
+++ b/mediator/med_diag_mod.F90
@@ -31,7 +31,6 @@ module med_diag_mod
use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d
use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d
use med_methods_mod , only : fldbun_fldChk => med_methods_FB_FldChk
- use med_time_mod , only : alarmInit => med_time_alarmInit
use med_utils_mod , only : chkerr => med_utils_ChkErr
use perf_mod , only : t_startf, t_stopf
diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90
index a85d76bc..b910c1a6 100644
--- a/mediator/med_phases_aofluxes_mod.F90
+++ b/mediator/med_phases_aofluxes_mod.F90
@@ -1720,9 +1720,6 @@ subroutine set_aoflux_out_pointers(fldbun, lsize, aoflux_out, xgrid, rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call fldbun_getfldptr(fldbun, 'So_duu10n', aoflux_out%duu10n, xgrid=xgrid, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
-
- call fldbun_getfldptr(fldbun, 'So_u10withGust', aoflux_out%u10_withGust, xgrid=xgrid, rc=rc)
- if (chkerr(rc,__LINE__,u_FILE_u)) return
call fldbun_getfldptr(fldbun, 'So_u10res', aoflux_out%u10res, xgrid=xgrid, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
call fldbun_getfldptr(fldbun, 'Faox_taux', aoflux_out%taux, xgrid=xgrid, rc=rc)
@@ -1753,8 +1750,11 @@ subroutine set_aoflux_out_pointers(fldbun, lsize, aoflux_out, xgrid, rc)
if (add_gusts) then
call fldbun_getfldptr(fldbun, 'So_ugustOut', aoflux_out%ugust_out, xgrid=xgrid, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+ call fldbun_getfldptr(fldbun, 'So_u10withGust', aoflux_out%u10_withGust, xgrid=xgrid, rc=rc)
+ if (chkerr(rc,__LINE__,u_FILE_u)) return
else
allocate(aoflux_out%ugust_out(lsize)); aoflux_out%ugust_out(:) = 0._R8
+ allocate(aoflux_out%u10_withGust(lsize)); aoflux_out%u10_withGust(:) = 0._R8
end if
end subroutine set_aoflux_out_pointers
diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90
index c895d6c4..6859a6c9 100644
--- a/mediator/med_phases_history_mod.F90
+++ b/mediator/med_phases_history_mod.F90
@@ -21,7 +21,6 @@ module med_phases_history_mod
use med_utils_mod , only : chkerr => med_utils_ChkErr
use med_internalstate_mod , only : ncomps, compname
use med_internalstate_mod , only : InternalState, maintask, logunit
- use med_time_mod , only : med_time_alarmInit
use med_io_mod , only : med_io_write, med_io_wopen, med_io_enddef, med_io_close
use perf_mod , only : t_startf, t_stopf
use pio , only : file_desc_t
@@ -153,6 +152,7 @@ subroutine med_phases_history_write(gcomp, rc)
use ESMF , only : ESMF_Alarm, ESMF_AlarmSet
use ESMF , only : ESMF_FieldBundleIsCreated
use med_internalstate_mod, only : compocn, compatm
+ use nuopc_shr_methods , only : alarmInit
! input/output variables
type(ESMF_GridComp) :: gcomp
@@ -184,6 +184,7 @@ subroutine med_phases_history_write(gcomp, rc)
type(ESMF_TimeInterval) :: ringInterval
integer :: ringInterval_length
logical :: first_time = .true.
+
character(len=*), parameter :: subname='(med_phases_history_write)'
!---------------------------------------
@@ -221,7 +222,7 @@ subroutine med_phases_history_write(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_ClockGet(mclock, startTime=starttime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_time_alarmInit(mclock, alarm, option=hist_option_all_inst, opt_n=hist_n_all_inst, &
+ call alarmInit(mclock, alarm, option=hist_option_all_inst, opt_n=hist_n_all_inst, &
reftime=starttime, alarmname=alarmname, rc=rc)
call ESMF_AlarmSet(alarm, clock=mclock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -1550,7 +1551,7 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi
use NUOPC_Mediator, only : NUOPC_MediatorGet
use ESMF , only : ESMF_ClockCreate, ESMF_ClockGet, ESMF_ClockSet
- use med_time_mod , only : med_time_alarmInit
+ use nuopc_shr_methods, only: AlarmInit
! input/output variables
type(ESMF_GridComp) , intent(in) :: gcomp
@@ -1593,9 +1594,7 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi
hclock = ESMF_ClockCreate(mclock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- ! Initialize history alarm and advance history clock to trigger
- ! alarms then reset history clock back to mcurrtime
- call med_time_alarmInit(hclock, alarm, option=hist_option, opt_n=hist_n, &
+ call alarmInit(hclock, alarm, option=hist_option, opt_n=hist_n, &
reftime=StartTime, alarmname=trim(alarmname), advance_clock=.true., rc=rc)
! Write diagnostic info
diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90
index 80b20042..4eff5966 100644
--- a/mediator/med_phases_prep_glc_mod.F90
+++ b/mediator/med_phases_prep_glc_mod.F90
@@ -39,7 +39,7 @@ module med_phases_prep_glc_mod
use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d
use med_methods_mod , only : fldchk => med_methods_FB_FldChk
use med_utils_mod , only : chkerr => med_utils_ChkErr
- use med_time_mod , only : med_time_alarmInit
+ use nuopc_shr_methods , only : alarmInit
use glc_elevclass_mod , only : glc_get_num_elevation_classes
use glc_elevclass_mod , only : glc_get_elevation_classes
use glc_elevclass_mod , only : glc_get_fractional_icecov
@@ -532,7 +532,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc)
call NUOPC_CompAttributeGet(gcomp, name="glc_avg_period", value=glc_avg_period, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (trim(glc_avg_period) == 'yearly') then
- call med_time_alarmInit(prepglc_clock, glc_avg_alarm, 'yearly', alarmname='alarm_glc_avg', rc=rc)
+ call alarmInit(prepglc_clock, glc_avg_alarm, 'yearly', alarmname='alarm_glc_avg', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (maintask) then
write(logunit,'(a,i10)') trim(subname)//&
@@ -542,7 +542,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc)
call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
read(cvalue,*) glc_cpl_dt
- call med_time_alarmInit(prepglc_clock, glc_avg_alarm, 'nseconds', opt_n=glc_cpl_dt, alarmname='alarm_glc_avg', rc=rc)
+ call alarmInit(prepglc_clock, glc_avg_alarm, 'nseconds', opt_n=glc_cpl_dt, alarmname='alarm_glc_avg', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (maintask) then
write(logunit,'(a,i10)') trim(subname)//&
diff --git a/mediator/med_phases_profile_mod.F90 b/mediator/med_phases_profile_mod.F90
index dee849ae..75d7f4d9 100644
--- a/mediator/med_phases_profile_mod.F90
+++ b/mediator/med_phases_profile_mod.F90
@@ -9,7 +9,7 @@ module med_phases_profile_mod
use med_utils_mod , only : med_utils_chkerr, med_memcheck
use med_internalstate_mod , only : maintask, logunit
use med_utils_mod , only : chkerr => med_utils_ChkErr
- use med_time_mod , only : alarmInit => med_time_alarmInit
+ use nuopc_shr_methods , only : alarmInit
use perf_mod , only : t_startf, t_stopf
#ifdef CESMCOUPLED
use shr_mem_mod , only : shr_mem_getusage
@@ -53,7 +53,8 @@ subroutine med_phases_profile(gcomp, rc)
! local variables
character(len=CS) :: cpl_inst_tag
type(ESMF_Clock) :: clock
- type(ESMF_Time) :: wallclockTime, nextTime
+ type(ESMF_Time), save :: wallclockTime
+ type(ESMF_Time) :: nextTime
type(ESMF_Time) :: currTime
type(ESMF_Time), save :: prevTime
type(ESMF_TimeInterval) :: ringInterval, timestep
@@ -119,6 +120,12 @@ subroutine med_phases_profile(gcomp, rc)
call ESMF_TimeIntervalGet(timestep, d_r8=timestep_length, rc=rc)
if (chkerr(rc,__LINE__,u_FILE_u)) return
+
+ ! use gregorian calendar for wallclocktime
+ ! The s=0 is just to avoid an internal /0 error in esmf
+ call ESMF_TimeSet(wallclockTime, calkindflag=ESMF_CALKIND_GREGORIAN, s=0, rc=rc)
+ if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return
+
iterations = 1
else
@@ -170,9 +177,6 @@ subroutine med_phases_profile(gcomp, rc)
call ESMF_TimeGet(nexttime, timestring=nexttimestr, rc=rc)
if (med_utils_ChkErr(rc,__LINE__,u_FILE_u)) return
! get current wall clock time
- ! s=0 is to prevent an internal divide by 0 error in esmf
- call ESMF_TimeSet(wallclockTime, calkindflag=ESMF_CALKIND_GREGORIAN, s=0, rc=rc)
- if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSyncToRealTime(wallclockTime, rc=rc)
if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return
diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90
index 6bbdb6b7..887aab8d 100644
--- a/mediator/med_phases_restart_mod.F90
+++ b/mediator/med_phases_restart_mod.F90
@@ -25,7 +25,6 @@ module med_phases_restart_mod
logical :: write_restart_at_endofrun = .false.
logical :: whead(2) = (/.true. , .false./)
logical :: wdata(2) = (/.false., .true. /)
-
character(*), parameter :: u_FILE_u = &
__FILE__
@@ -47,7 +46,7 @@ subroutine med_phases_restart_alarm_init(gcomp, rc)
use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE
use NUOPC , only : NUOPC_CompAttributeGet
use NUOPC_Model , only : NUOPC_ModelGet
- use med_time_mod , only : med_time_AlarmInit
+ use nuopc_shr_methods, only : AlarmInit
! input/output variables
type(ESMF_GridComp) :: gcomp
@@ -83,8 +82,10 @@ subroutine med_phases_restart_alarm_init(gcomp, rc)
! Set alarm for instantaneous mediator restart output
call ESMF_ClockGet(mclock, currTime=mCurrTime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_time_alarmInit(mclock, alarm, option=restart_option, opt_n=restart_n, &
+
+ call alarmInit(mclock, alarm, option=restart_option, opt_n=restart_n, &
reftime=mcurrTime, alarmname='alarm_restart', rc=rc)
+
call ESMF_AlarmSet(alarm, clock=mclock, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
@@ -549,11 +550,6 @@ subroutine med_phases_restart_read(gcomp, rc)
if (maintask) then
call ESMF_LogWrite(trim(subname)//" read rpointer file = "//trim(restart_pfile), ESMF_LOGMSG_INFO)
open(newunit=unitn, file=restart_pfile, form='FORMATTED', status='old', iostat=ierr)
- if (ierr < 0) then
- call ESMF_LogWrite(trim(subname)//' rpointer file open returns error', ESMF_LOGMSG_INFO)
- rc=ESMF_Failure
- return
- end if
read (unitn,'(a)', iostat=ierr) restart_file
if (ierr < 0) then
call ESMF_LogWrite(trim(subname)//' rpointer file read returns error', ESMF_LOGMSG_INFO)
diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90
deleted file mode 100644
index 8a05c367..00000000
--- a/mediator/med_time_mod.F90
+++ /dev/null
@@ -1,302 +0,0 @@
-module med_time_mod
-
- use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8
- use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_GridCompSet
- use ESMF , only : ESMF_Clock, ESMF_ClockCreate, ESMF_ClockGet, ESMF_ClockSet
- use ESMF , only : ESMF_ClockAdvance
- use ESMF , only : ESMF_Alarm, ESMF_AlarmCreate, ESMF_AlarmGet, ESMF_AlarmSet
- use ESMF , only : ESMF_Calendar, ESMF_CalKind_Flag, ESMF_CalendarCreate
- use ESMF , only : ESMF_CALKIND_NOLEAP, ESMF_CALKIND_GREGORIAN
- use ESMF , only : ESMF_Time, ESMF_TimeGet, ESMF_TimeSet
- use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet
- use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_FAILURE
- use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast
- use ESMF , only : ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_LOGMSG_ERROR
- use ESMF , only : operator(<), operator(/=), operator(+)
- use ESMF , only : operator(-), operator(*) , operator(>=)
- use ESMF , only : operator(<=), operator(>), operator(==)
- use med_constants_mod , only : dbug_flag => med_constants_dbug_flag
- use med_utils_mod , only : chkerr => med_utils_ChkErr
- use med_internalstate_mod, only : maintask, logunit
-
- implicit none
- private ! default private
-
- public :: med_time_alarmInit ! initialize an alarm
-
- ! Clock and alarm options
- character(len=*), private, parameter :: &
- optNONE = "none" , &
- optNever = "never" , &
- optNSteps = "nstep" , &
- optNSeconds = "nsecond" , &
- optNMinutes = "nminute" , &
- optNHours = "nhour" , &
- optNDays = "nday" , &
- optNMonths = "nmonth" , &
- optNYears = "nyear" , &
- optMonthly = "monthly" , &
- optYearly = "yearly" , &
- optDate = "date" , &
- optEnd = "end" , &
- optGLCCouplingPeriod = "glc_coupling_period"
-
- ! Module data
- integer, parameter :: SecPerDay = 86400 ! Seconds per day
- character(len=*), parameter :: u_FILE_u = &
- __FILE__
-
-!===============================================================================
-contains
-!===============================================================================
-
- subroutine med_time_alarmInit( clock, alarm, option, &
- opt_n, opt_ymd, opt_tod, reftime, alarmname, advance_clock, rc)
-
- ! Setup an alarm in a clock
- ! Notes: The ringtime sent to AlarmCreate MUST be the next alarm
- ! time. If you send an arbitrary but proper ringtime from the
- ! past and the ring interval, the alarm will always go off on the
- ! next clock advance and this will cause serious problems. Even
- ! if it makes sense to initialize an alarm with some reference
- ! time and the alarm interval, that reference time has to be
- ! advance forward to be >= the current time. In the logic below
- ! we set an appropriate "NextAlarm" and then we make sure to
- ! advance it properly based on the ring interval.
-
- ! input/output variables
- type(ESMF_Clock) , intent(inout) :: clock ! clock
- type(ESMF_Alarm) , intent(inout) :: alarm ! alarm
- character(len=*) , intent(in) :: option ! alarm option
- integer , optional , intent(in) :: opt_n ! alarm freq
- integer , optional , intent(in) :: opt_ymd ! alarm ymd
- integer , optional , intent(in) :: opt_tod ! alarm tod (sec)
- type(ESMF_Time) , optional , intent(in) :: reftime ! reference time
- character(len=*) , optional , intent(in) :: alarmname ! alarm name
- logical , optional , intent(in) :: advance_clock ! advance clock to trigger alarm
- integer , intent(out) :: rc ! Return code
-
- ! local variables
- type(ESMF_Calendar) :: cal ! calendar
- integer :: lymd ! local ymd
- integer :: ltod ! local tod
- integer :: cyy,cmm,cdd,csec ! time info
- character(len=64) :: lalarmname ! local alarm name
- logical :: update_nextalarm ! update next alarm
- type(ESMF_Time) :: CurrTime ! Current Time
- type(ESMF_Time) :: NextAlarm ! Next alarm time
- type(ESMF_TimeInterval) :: AlarmInterval ! Alarm interval
- character(len=*), parameter :: subname = '(med_time_alarmInit): '
- !-------------------------------------------------------------------------------
-
- rc = ESMF_SUCCESS
-
- lalarmname = 'alarm_unknown'
- if (present(alarmname)) lalarmname = trim(alarmname)
- ltod = 0
- if (present(opt_tod)) ltod = opt_tod
- lymd = -1
- if (present(opt_ymd)) lymd = opt_ymd
-
- call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- call ESMF_TimeGet(CurrTime, yy=cyy, mm=cmm, dd=cdd, s=csec, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- ! initial guess of next alarm, this will be updated below
- if (present(RefTime)) then
- NextAlarm = RefTime
- else
- NextAlarm = CurrTime
- endif
-
- ! Get calendar from clock
- call ESMF_ClockGet(clock, calendar=cal)
-
- ! Error checks
- if (trim(option) == optdate) then
- if (.not. present(opt_ymd)) then
- call ESMF_LogWrite(trim(subname)//trim(option)//' requires opt_ymd', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- if (lymd < 0 .or. ltod < 0) then
- call ESMF_LogWrite(subname//trim(option)//'opt_ymd, opt_tod invalid', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- else if (&
- trim(option) == optNSteps .or. trim(option) == trim(optNSteps)//'s' .or. &
- trim(option) == optNSeconds .or. trim(option) == trim(optNSeconds)//'s' .or. &
- trim(option) == optNMinutes .or. trim(option) == trim(optNMinutes)//'s' .or. &
- trim(option) == optNHours .or. trim(option) == trim(optNHours)//'s' .or. &
- trim(option) == optNDays .or. trim(option) == trim(optNDays)//'s' .or. &
- trim(option) == optNMonths .or. trim(option) == trim(optNMonths)//'s' .or. &
- trim(option) == optNYears .or. trim(option) == trim(optNYears)//'s' ) then
- if (.not.present(opt_n)) then
- call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- if (opt_n <= 0) then
- call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
- end if
- end if
-
- ! Determine inputs for call to create alarm
- selectcase (trim(option))
-
- case (optNONE)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optNever)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optEnd)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optDate)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call med_time_date2ymd(opt_ymd, cyy, cmm, cdd)
-
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=cdd, s=ltod, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .false.
-
- case (optNSteps,trim(optNSteps)//'s')
- call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNSeconds,trim(optNSeconds)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMinutes,trim(optNMinutes)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc)
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNHours,trim(optNHours)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNDays,trim(optNDays)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optNMonths,trim(optNMonths)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optMonthly)
- call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .true.
-
- case (optNYears, trim(optNYears)//'s')
- call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- AlarmInterval = AlarmInterval * opt_n
- update_nextalarm = .true.
-
- case (optYearly)
- call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_TimeSet( NextAlarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc )
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- update_nextalarm = .true.
- case default
- call ESMF_LogWrite(subname//'unknown option '//trim(option), ESMF_LOGMSG_ERROR)
- rc = ESMF_FAILURE
- return
-
- end select
-
- ! --------------------------------------------------------------------------------
- ! --- AlarmInterval and NextAlarm should be set ---
- ! --------------------------------------------------------------------------------
-
- ! --- advance Next Alarm so it won't ring on first timestep for
- ! --- most options above. go back one alarminterval just to be careful
-
- if (update_nextalarm) then
- NextAlarm = NextAlarm - AlarmInterval
- do while (NextAlarm <= CurrTime)
- NextAlarm = NextAlarm + AlarmInterval
- enddo
- endif
-
- if (maintask) then
- write(logunit,*)
- write(logunit,'(a)') trim(subname) //' creating alarm '// trim(lalarmname)
- end if
-
- alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, &
- ringInterval=AlarmInterval, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
-
- ! Advance model clock to trigger alarm then reset model clock back to currtime
- if (present(advance_clock)) then
- if (advance_clock) then
- call ESMF_AlarmSet(alarm, clock=clock, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_ClockGet(clock, currTime=CurrTime, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_ClockAdvance(clock,rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- call ESMF_ClockSet(clock, currTime=currtime, rc=rc)
- if (ChkErr(rc,__LINE__,u_FILE_u)) return
- end if
- end if
-
- end subroutine med_time_alarmInit
-
- !===============================================================================
- subroutine med_time_date2ymd (date, year, month, day)
-
- ! input/output variables
- integer, intent(in) :: date ! coded-date (yyyymmdd)
- integer, intent(out) :: year,month,day ! calendar year,month,day
-
- ! local variables
- integer :: tdate ! temporary date
- character(*),parameter :: subName = "(med_time_date2ymd)"
- !-------------------------------------------------------------------------------
- tdate = abs(date)
- year = int(tdate/10000)
- if (date < 0) then
- year = -year
- end if
- month = int( mod(tdate,10000)/ 100)
- day = mod(tdate, 100)
- end subroutine med_time_date2ymd
-
-end module med_time_mod