From 546b39b7ba4062f1c27e7cdbaf0af9e39324e429 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 29 Mar 2024 14:10:42 -0600 Subject: [PATCH 01/14] now its working --- cesm/driver/esm_time_mod.F90 | 58 +----- cesm/nuopc_cap_share/nuopc_shr_methods.F90 | 223 +++++++++------------ mediator/med.F90 | 12 +- mediator/med_phases_history_mod.F90 | 22 +- mediator/med_phases_restart_mod.F90 | 13 +- mediator/med_time_mod.F90 | 34 +++- 6 files changed, 170 insertions(+), 192 deletions(-) diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90 index 3b56bb95..a08eb258 100644 --- a/cesm/driver/esm_time_mod.F90 +++ b/cesm/driver/esm_time_mod.F90 @@ -18,7 +18,7 @@ module esm_time_mod use ESMF , only : operator(<=), operator(>), operator(==) use NUOPC , only : NUOPC_CompAttributeGet use esm_utils_mod , only : chkerr - + implicit none private ! default private @@ -54,7 +54,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 +81,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 +113,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 +236,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 @@ -292,7 +252,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas ! Create the clock clock = ESMF_ClockCreate(TimeStep, StartTime, refTime=RefTime, name='ESMF Driver Clock', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! Advance the clock to the current time (in case of a restart) call ESMF_ClockGet(clock, currTime=clocktime, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/cesm/nuopc_cap_share/nuopc_shr_methods.F90 b/cesm/nuopc_cap_share/nuopc_shr_methods.F90 index 9062b27f..7c251cfa 100644 --- a/cesm/nuopc_cap_share/nuopc_shr_methods.F90 +++ b/cesm/nuopc_cap_share/nuopc_shr_methods.F90 @@ -35,36 +35,35 @@ module nuopc_shr_methods public :: state_setscalar public :: state_diagnose public :: alarmInit + public :: get_minimum_timestep 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" , & + ! Module data + + ! Clock and alarm options shared with esm_time_mod along with dtime_driver which is initialized there. + ! Dtime_driver is needed here for setting alarm options which use the nstep option and is a module variable + ! to avoid requiring a change in all model caps. + character(len=*), public, 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" , & - optDate = "date" - + optGLCCouplingPeriod = "glc_coupling_period" - ! Module data + integer, public :: dtime_drv ! initialized in esm_time_mod.F90 + integer, parameter :: SecPerDay = 86400 ! Seconds per day integer, parameter :: memdebug_level=1 character(len=1024) :: msgString @@ -566,21 +565,7 @@ subroutine alarmInit( clock, alarm, option, & ! 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) + case (optNONE, optNever, 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 ) @@ -600,39 +585,15 @@ subroutine alarmInit( clock, alarm, option, & 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) + case (optNSteps, trim(optNSteps)//'s') 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 + ! variable dtime_drv is the smallest component timestep, set in esm_time_mod.F90 + call ESMF_TimeIntervalSet(AlarmInterval, s=dtime_drv, rc=rc ) + AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. - case (optNSecond) + case (optNSeconds, trim(optNSeconds)//'s') if (.not.present(opt_n)) then call shr_sys_abort(subname//trim(option)//' requires opt_n') end if @@ -644,7 +605,7 @@ subroutine alarmInit( clock, alarm, option, & AlarmInterval = AlarmInterval * opt_n update_nextalarm = .true. - case (optNMinutes) + case (optNMinutes, trim(optNMinutes)//'s') call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc) if (.not.present(opt_n)) then call shr_sys_abort(subname//trim(option)//' requires opt_n') @@ -655,19 +616,7 @@ subroutine alarmInit( clock, alarm, option, & 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) + case (optNHours, trim(optNHours)//'s') if (.not.present(opt_n)) then call shr_sys_abort(subname//trim(option)//' requires opt_n') end if @@ -679,31 +628,7 @@ subroutine alarmInit( clock, alarm, option, & 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) + case (optNDays, trim(optNDays)//'s') if (.not.present(opt_n)) then call shr_sys_abort(subname//trim(option)//' requires opt_n') end if @@ -715,19 +640,7 @@ subroutine alarmInit( clock, alarm, option, & 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) + case (optNMonths, trim(optNMonths)//'s') if (.not.present(opt_n)) then call shr_sys_abort(subname//trim(option)//' requires opt_n') end if @@ -746,19 +659,7 @@ subroutine alarmInit( clock, alarm, option, & 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) + case (optNYears, trim(optNYears)//'s') if (.not.present(opt_n)) then call shr_sys_abort(subname//trim(option)//' requires opt_n') end if @@ -839,6 +740,64 @@ subroutine timeInit( Time, ymd, cal, tod, rc) end subroutine timeInit +!=============================================================================== + + integer function get_minimum_timestep(gcomp, rc) + type(ESMF_GridComp), intent(in) :: gcomp + integer, intent(out) :: rc + + character(len=CS) :: cvalue + 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 + + !--------------------------------------------------------------------------- + ! Determine driver clock timestep + !--------------------------------------------------------------------------- + + call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) atm_cpl_dt + + call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) lnd_cpl_dt + + call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ice_cpl_dt + + call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ocn_cpl_dt + + 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 NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) rof_cpl_dt + + call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) wav_cpl_dt + + get_minimum_timestep = minval((/atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt/)) + if(get_minimum_timestep <= 0) then + print *,__FILE__,__LINE__,atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt + call ESMF_LogWrite('minimum_timestep_error ERROR ', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + end function get_minimum_timestep + !=============================================================================== logical function chkerr(rc, line, file) diff --git a/mediator/med.F90 b/mediator/med.F90 index dc0f68cf..e8a3e440 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -2256,7 +2256,8 @@ subroutine SetRunClock(gcomp, rc) use ESMF , only : ESMF_ClockGetAlarmList use NUOPC , only : NUOPC_CompCheckSetClock, NUOPC_CompAttributeGet use NUOPC_Mediator , only : NUOPC_MediatorGet - + use nuopc_shr_methods, only : get_minimum_timestep + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -2271,6 +2272,8 @@ subroutine SetRunClock(gcomp, rc) character(len=CL) :: stop_option integer :: stop_n, stop_ymd logical, save :: stopalarmcreated=.false. + integer :: min_timestep = 0 ! used for nsteps option + character(len=*), parameter :: optNsteps = "nstep" character(len=*), parameter :: subname = '('//__FILE__//':SetRunClock)' !----------------------------------------------------------- @@ -2313,8 +2316,13 @@ 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 + + if (stop_option(1:len(optnsteps)) .eq. optNSteps) then + min_timestep = get_minimum_timestep(gcomp, rc) + endif + call med_time_alarmInit(mclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, & - alarmname='alarm_stop', rc=rc) + alarmname='alarm_stop', min_timestep=min_timestep, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return stopalarmcreated = .true. end if diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index 52b20c03..f1157805 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -21,10 +21,10 @@ 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 + use nuopc_shr_methods, only : get_minimum_timestep implicit none private @@ -128,6 +128,7 @@ module med_phases_history_mod character(CL) :: case_name = 'unset' ! case name character(CS) :: inst_tag = 'unset' ! instance tag logical :: debug_alarms = .true. + character(len=*), parameter :: optNsteps = "nstep" character(*), parameter :: u_FILE_u = & __FILE__ @@ -153,7 +154,8 @@ 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 med_time_mod , only : med_time_alarmInit + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -184,6 +186,7 @@ subroutine med_phases_history_write(gcomp, rc) type(ESMF_TimeInterval) :: ringInterval integer :: ringInterval_length logical :: first_time = .true. + integer :: min_timestep = 0 ! used for nsteps option character(len=*), parameter :: subname='(med_phases_history_write)' !--------------------------------------- @@ -221,8 +224,12 @@ 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 + + if (hist_option_all_inst(1:len(optnsteps)) == optnsteps) then + min_timestep = get_minimum_timestep(gcomp, rc=rc) + endif call med_time_alarmInit(mclock, alarm, option=hist_option_all_inst, opt_n=hist_n_all_inst, & - reftime=starttime, alarmname=alarmname, rc=rc) + reftime=starttime, alarmname=alarmname, min_timestep=min_timestep, rc=rc) call ESMF_AlarmSet(alarm, clock=mclock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1530,6 +1537,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: get_minimum_timestep ! input/output variables type(ESMF_GridComp) , intent(in) :: gcomp @@ -1539,12 +1547,13 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi character(len=*) , intent(in) :: hist_option ! freq_option setting (ndays, nsteps, etc) integer , intent(in) :: hist_n ! freq_n setting relative to freq_option integer , intent(out) :: rc - + ! local variables type(ESMF_Clock) :: mclock, dclock type(ESMF_Time) :: StartTime type(ESMF_TimeInterval) :: mtimestep, dtimestep integer :: msec, dsec + integer :: min_timestep character(len=*), parameter :: subname='(med_phases_history_init_histclock) ' !--------------------------------------- @@ -1574,8 +1583,11 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi ! Initialize history alarm and advance history clock to trigger ! alarms then reset history clock back to mcurrtime + if (hist_option(1:len(optnsteps)) == optnsteps) then + min_timestep = get_minimum_timestep(gcomp, rc=rc) + endif call med_time_alarmInit(hclock, alarm, option=hist_option, opt_n=hist_n, & - reftime=StartTime, alarmname=trim(alarmname), advance_clock=.true., rc=rc) + reftime=StartTime, alarmname=trim(alarmname), advance_clock=.true., min_timestep=min_timestep, rc=rc) ! Write diagnostic info if (maintask) then diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index 1bbbb0fb..724be366 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -48,6 +48,7 @@ subroutine med_phases_restart_alarm_init(gcomp, rc) use NUOPC , only : NUOPC_CompAttributeGet use NUOPC_Model , only : NUOPC_ModelGet use med_time_mod , only : med_time_AlarmInit + use nuopc_shr_methods, only : get_minimum_timestep ! input/output variables type(ESMF_GridComp) :: gcomp @@ -64,6 +65,8 @@ subroutine med_phases_restart_alarm_init(gcomp, rc) integer :: restart_n ! freq_n setting relative to freq_option logical :: isPresent logical :: isSet + integer :: min_timestep = 0 ! used for nsteps option + character(len=*), parameter :: optNsteps = "nstep" character(len=*), parameter :: subname='(med_phases_restart_alarm_init)' !--------------------------------------- @@ -83,8 +86,16 @@ 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 + print *,__FILE__,__LINE__,trim(restart_option), trim(optNsteps) + if (restart_option(1:len(optNsteps)) .eq. optNSteps) then + min_timestep = get_minimum_timestep(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + print *,__FILE__,__LINE__,min_timestep + endif + call med_time_alarmInit(mclock, alarm, option=restart_option, opt_n=restart_n, & - reftime=mcurrTime, alarmname='alarm_restart', rc=rc) + reftime=mcurrTime, alarmname='alarm_restart', min_timestep=min_timestep, rc=rc) + call ESMF_AlarmSet(alarm, clock=mclock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 index 8a05c367..1eac92f8 100644 --- a/mediator/med_time_mod.F90 +++ b/mediator/med_time_mod.F90 @@ -12,7 +12,7 @@ module med_time_mod 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(+), mod use ESMF , only : operator(-), operator(*) , operator(>=) use ESMF , only : operator(<=), operator(>), operator(==) use med_constants_mod , only : dbug_flag => med_constants_dbug_flag @@ -51,7 +51,7 @@ module med_time_mod !=============================================================================== subroutine med_time_alarmInit( clock, alarm, option, & - opt_n, opt_ymd, opt_tod, reftime, alarmname, advance_clock, rc) + opt_n, opt_ymd, opt_tod, reftime, alarmname, advance_clock, min_timestep, rc) ! Setup an alarm in a clock ! Notes: The ringtime sent to AlarmCreate MUST be the next alarm @@ -74,6 +74,7 @@ subroutine med_time_alarmInit( clock, alarm, option, & 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 , optional , intent(in) :: min_timestep ! used for nsteps option only integer , intent(out) :: rc ! Return code ! local variables @@ -85,6 +86,7 @@ subroutine med_time_alarmInit( clock, alarm, option, & logical :: update_nextalarm ! update next alarm type(ESMF_Time) :: CurrTime ! Current Time type(ESMF_Time) :: NextAlarm ! Next alarm time + type(ESMF_TimeInterval) :: TimeStepInterval ! Timestep interval type(ESMF_TimeInterval) :: AlarmInterval ! Alarm interval character(len=*), parameter :: subname = '(med_time_alarmInit): ' !------------------------------------------------------------------------------- @@ -139,11 +141,25 @@ subroutine med_time_alarmInit( clock, alarm, option, & rc = ESMF_FAILURE return end if + if(trim(option) == optNSteps .or. trim(option) == trim(optNSteps)//'s') then + if(present(min_timestep)) then + if(min_timestep <= 0) then + call ESMF_LogWrite(subname//trim(option)//' min_timestep <= 0', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif + else + call ESMF_LogWrite(subname//trim(option)//' requires min_timestep', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + end if + endif 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 @@ -180,9 +196,16 @@ subroutine med_time_alarmInit( clock, alarm, option, & update_nextalarm = .false. case (optNSteps,trim(optNSteps)//'s') - call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc) + call ESMF_ClockGet(clock, TimeStep=TimestepInterval, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeIntervalSet(AlarmInterval, s=min_timestep, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n + if (mod(AlarmInterval, TimestepInterval) /= (timestepinterval*0)) then + call ESMF_LogWrite(subname//'illegal Alarm setting for '//trim(alarmname), ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif update_nextalarm = .true. case (optNSeconds,trim(optNSeconds)//'s') @@ -249,6 +272,11 @@ subroutine med_time_alarmInit( clock, alarm, option, & if (update_nextalarm) then NextAlarm = NextAlarm - AlarmInterval + if (AlarmInterval <= AlarmInterval*0) then + call ESMF_LogWrite(subname//'AlarmInterval ERROR ', ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + endif do while (NextAlarm <= CurrTime) NextAlarm = NextAlarm + AlarmInterval enddo From 545fd9fd98f9db35ff8ea7efe2193eea3064924c Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Fri, 29 Mar 2024 14:26:22 -0600 Subject: [PATCH 02/14] clean up buildnml --- cime_config/buildnml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index ff2553be..f95b2012 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -305,7 +305,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 +608,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 +621,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): From 44cb9019a00ff02191802be5bcccc7d9d4087d38 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Mon, 1 Apr 2024 16:02:32 -0600 Subject: [PATCH 03/14] fix issue with REST_OPTION=end --- cesm/driver/esm_time_mod.F90 | 12 +- cesm/nuopc_cap_share/nuopc_shr_methods.F90 | 818 --------------------- mediator/med.F90 | 1 + mediator/med_phases_restart_mod.F90 | 2 - mediator/med_time_mod.F90 | 8 +- 5 files changed, 18 insertions(+), 823 deletions(-) delete mode 100644 cesm/nuopc_cap_share/nuopc_shr_methods.F90 diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90 index a08eb258..6650a4ab 100644 --- a/cesm/driver/esm_time_mod.F90 +++ b/cesm/driver/esm_time_mod.F90 @@ -11,7 +11,7 @@ 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(>=) @@ -42,6 +42,7 @@ module esm_time_mod optMonthly = "monthly" , & optYearly = "yearly" , & optDate = "date" , & + optEnd = "end" , & optGLCCouplingPeriod = "glc_coupling_period" ! Module data @@ -505,6 +506,15 @@ subroutine esm_time_alarmInit( clock, alarm, option, & if (ChkErr(rc,__LINE__,u_FILE_u)) return update_nextalarm = .true. + case (optEnd) + call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGetAlarm(clock, "alarm_stop", alarm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_AlarmGet(alarm, ringTime=NextAlarm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + update_nextalarm = .false. + case default call ESMF_LogWrite(subname//'unknown option '//trim(option), ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE 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 7c251cfa..00000000 --- a/cesm/nuopc_cap_share/nuopc_shr_methods.F90 +++ /dev/null @@ -1,818 +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 :: get_minimum_timestep - public :: chkerr - - private :: timeInit - private :: field_getfldptr - - ! Module data - - ! Clock and alarm options shared with esm_time_mod along with dtime_driver which is initialized there. - ! Dtime_driver is needed here for setting alarm options which use the nstep option and is a module variable - ! to avoid requiring a change in all model caps. - character(len=*), public, 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" - - integer, public :: dtime_drv ! initialized in esm_time_mod.F90 - - 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, optNever, 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, trim(optNSteps)//'s') - 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') - ! variable dtime_drv is the smallest component timestep, set in esm_time_mod.F90 - call ESMF_TimeIntervalSet(AlarmInterval, s=dtime_drv, rc=rc ) - AlarmInterval = AlarmInterval * opt_n - update_nextalarm = .true. - - case (optNSeconds, trim(optNSeconds)//'s') - 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, trim(optNMinutes)//'s') - 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 (optNHours, trim(optNHours)//'s') - 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, trim(optNDays)//'s') - 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, trim(optNMonths)//'s') - 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, trim(optNYears)//'s') - 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 - -!=============================================================================== - - integer function get_minimum_timestep(gcomp, rc) - type(ESMF_GridComp), intent(in) :: gcomp - integer, intent(out) :: rc - - character(len=CS) :: cvalue - 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 - - !--------------------------------------------------------------------------- - ! Determine driver clock timestep - !--------------------------------------------------------------------------- - - call NUOPC_CompAttributeGet(gcomp, name="atm_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) atm_cpl_dt - - call NUOPC_CompAttributeGet(gcomp, name="lnd_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) lnd_cpl_dt - - call NUOPC_CompAttributeGet(gcomp, name="ice_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ice_cpl_dt - - call NUOPC_CompAttributeGet(gcomp, name="ocn_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) ocn_cpl_dt - - 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 NUOPC_CompAttributeGet(gcomp, name="rof_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) rof_cpl_dt - - call NUOPC_CompAttributeGet(gcomp, name="wav_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) wav_cpl_dt - - get_minimum_timestep = minval((/atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt/)) - if(get_minimum_timestep <= 0) then - print *,__FILE__,__LINE__,atm_cpl_dt, lnd_cpl_dt, ocn_cpl_dt, ice_cpl_dt, glc_cpl_dt, rof_cpl_dt, wav_cpl_dt - call ESMF_LogWrite('minimum_timestep_error ERROR ', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - end function get_minimum_timestep - -!=============================================================================== - - 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/mediator/med.F90 b/mediator/med.F90 index e8a3e440..c9f1328c 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -2256,6 +2256,7 @@ 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 : get_minimum_timestep ! input/output variables diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index 724be366..70d80f7e 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -86,11 +86,9 @@ 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 - print *,__FILE__,__LINE__,trim(restart_option), trim(optNsteps) if (restart_option(1:len(optNsteps)) .eq. optNSteps) then min_timestep = get_minimum_timestep(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - print *,__FILE__,__LINE__,min_timestep endif call med_time_alarmInit(mclock, alarm, option=restart_option, opt_n=restart_n, & diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 index 1eac92f8..6e513155 100644 --- a/mediator/med_time_mod.F90 +++ b/mediator/med_time_mod.F90 @@ -10,7 +10,7 @@ module med_time_mod 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_VM, ESMF_VMGet, ESMF_VMBroadcast, ESMF_ClockGetAlarm use ESMF , only : ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_LOGMSG_ERROR use ESMF , only : operator(<), operator(/=), operator(+), mod use ESMF , only : operator(-), operator(*) , operator(>=) @@ -182,7 +182,9 @@ subroutine med_time_alarmInit( clock, alarm, option, & 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 ) + call ESMF_ClockGetAlarm(clock, "alarm_stop", alarm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_AlarmGet(alarm, ringTime=NextAlarm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return update_nextalarm = .false. @@ -201,6 +203,7 @@ subroutine med_time_alarmInit( clock, alarm, option, & call ESMF_TimeIntervalSet(AlarmInterval, s=min_timestep, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return AlarmInterval = AlarmInterval * opt_n + ! timestepinterval*0 is 0 of kind ESMF_TimeStepInterval if (mod(AlarmInterval, TimestepInterval) /= (timestepinterval*0)) then call ESMF_LogWrite(subname//'illegal Alarm setting for '//trim(alarmname), ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE @@ -272,6 +275,7 @@ subroutine med_time_alarmInit( clock, alarm, option, & if (update_nextalarm) then NextAlarm = NextAlarm - AlarmInterval + ! AlarmInterval*0 is 0 of kind ESMF_TimeStepInterval if (AlarmInterval <= AlarmInterval*0) then call ESMF_LogWrite(subname//'AlarmInterval ERROR ', ESMF_LOGMSG_ERROR) rc = ESMF_FAILURE From bcaac2a6326630507153d565817169d3882e0ce6 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 4 Apr 2024 15:38:36 -0600 Subject: [PATCH 04/14] move all alarminit to nuopc_shr_methods in share code --- cesm/driver/esm_time_mod.F90 | 266 +-------------------- mediator/CMakeLists.txt | 2 +- mediator/Makefile | 7 +- mediator/med.F90 | 7 +- mediator/med_diag_mod.F90 | 1 - mediator/med_phases_history_mod.F90 | 22 +- mediator/med_phases_prep_glc_mod.F90 | 6 +- mediator/med_phases_profile_mod.F90 | 2 +- mediator/med_phases_restart_mod.F90 | 15 +- mediator/med_time_mod.F90 | 334 --------------------------- 10 files changed, 26 insertions(+), 636 deletions(-) delete mode 100644 mediator/med_time_mod.F90 diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90 index 6650a4ab..d4d0e81c 100644 --- a/cesm/driver/esm_time_mod.F90 +++ b/cesm/driver/esm_time_mod.F90 @@ -18,6 +18,7 @@ module esm_time_mod 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 @@ -25,7 +26,7 @@ module esm_time_mod public :: esm_time_clockInit ! initialize driver clock (assumes default calendar) ! private :: esm_time_timeInit - private :: esm_time_alarmInit +! private :: esm_time_alarmInit private :: esm_time_date2ymd ! Clock and alarm options @@ -296,7 +297,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, & @@ -329,267 +330,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 (optEnd) - call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockGetAlarm(clock, "alarm_stop", alarm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_AlarmGet(alarm, ringTime=NextAlarm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .false. - - 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/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 c9f1328c..f11a34fd 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 @@ -2257,7 +2256,7 @@ subroutine SetRunClock(gcomp, rc) 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 : get_minimum_timestep + use nuopc_shr_methods, only : get_minimum_timestep, AlarmInit ! input/output variables type(ESMF_GridComp) :: gcomp @@ -2322,8 +2321,8 @@ subroutine SetRunClock(gcomp, rc) min_timestep = get_minimum_timestep(gcomp, rc) endif - call med_time_alarmInit(mclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, & - alarmname='alarm_stop', min_timestep=min_timestep, rc=rc) + 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. end if diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 8ea6651e..0416e469 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_history_mod.F90 b/mediator/med_phases_history_mod.F90 index f1157805..2da08cc6 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -154,8 +154,8 @@ 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 med_time_mod , only : med_time_alarmInit - + use nuopc_shr_methods , only : alarmInit + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -228,8 +228,8 @@ subroutine med_phases_history_write(gcomp, rc) if (hist_option_all_inst(1:len(optnsteps)) == optnsteps) then min_timestep = get_minimum_timestep(gcomp, rc=rc) endif - call med_time_alarmInit(mclock, alarm, option=hist_option_all_inst, opt_n=hist_n_all_inst, & - reftime=starttime, alarmname=alarmname, min_timestep=min_timestep, rc=rc) + 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 @@ -1536,8 +1536,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: get_minimum_timestep + use nuopc_shr_methods, only: AlarmInit ! input/output variables type(ESMF_GridComp) , intent(in) :: gcomp @@ -1547,7 +1546,7 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi character(len=*) , intent(in) :: hist_option ! freq_option setting (ndays, nsteps, etc) integer , intent(in) :: hist_n ! freq_n setting relative to freq_option integer , intent(out) :: rc - + ! local variables type(ESMF_Clock) :: mclock, dclock type(ESMF_Time) :: StartTime @@ -1581,13 +1580,8 @@ 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 - if (hist_option(1:len(optnsteps)) == optnsteps) then - min_timestep = get_minimum_timestep(gcomp, rc=rc) - endif - call med_time_alarmInit(hclock, alarm, option=hist_option, opt_n=hist_n, & - reftime=StartTime, alarmname=trim(alarmname), advance_clock=.true., min_timestep=min_timestep, rc=rc) + call alarmInit(hclock, alarm, option=hist_option, opt_n=hist_n, & + reftime=StartTime, alarmname=trim(alarmname), advance_clock=.true., rc=rc) ! Write diagnostic info if (maintask) then diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 920fb415..19ac47e7 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -38,7 +38,7 @@ module med_phases_prep_glc_mod use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d 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 @@ -545,7 +545,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)//& @@ -555,7 +555,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 5c28eca3..76a630cb 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 diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index 70d80f7e..54684cf8 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -47,8 +47,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 : get_minimum_timestep + use nuopc_shr_methods, only : AlarmInit ! input/output variables type(ESMF_GridComp) :: gcomp @@ -65,8 +64,6 @@ subroutine med_phases_restart_alarm_init(gcomp, rc) integer :: restart_n ! freq_n setting relative to freq_option logical :: isPresent logical :: isSet - integer :: min_timestep = 0 ! used for nsteps option - character(len=*), parameter :: optNsteps = "nstep" character(len=*), parameter :: subname='(med_phases_restart_alarm_init)' !--------------------------------------- @@ -86,13 +83,9 @@ 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 - if (restart_option(1:len(optNsteps)) .eq. optNSteps) then - min_timestep = get_minimum_timestep(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - - call med_time_alarmInit(mclock, alarm, option=restart_option, opt_n=restart_n, & - reftime=mcurrTime, alarmname='alarm_restart', min_timestep=min_timestep, rc=rc) + + 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 diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 deleted file mode 100644 index 6e513155..00000000 --- a/mediator/med_time_mod.F90 +++ /dev/null @@ -1,334 +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, ESMF_ClockGetAlarm - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_LOGMSG_ERROR - use ESMF , only : operator(<), operator(/=), operator(+), mod - 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, min_timestep, 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 , optional , intent(in) :: min_timestep ! used for nsteps option only - 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) :: TimeStepInterval ! Timestep interval - 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(trim(option) == optNSteps .or. trim(option) == trim(optNSteps)//'s') then - if(present(min_timestep)) then - if(min_timestep <= 0) then - call ESMF_LogWrite(subname//trim(option)//' min_timestep <= 0', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - else - call ESMF_LogWrite(subname//trim(option)//' requires min_timestep', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - end if - endif - 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_ClockGetAlarm(clock, "alarm_stop", alarm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_AlarmGet(alarm, ringTime=NextAlarm, 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=TimestepInterval, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeIntervalSet(AlarmInterval, s=min_timestep, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - ! timestepinterval*0 is 0 of kind ESMF_TimeStepInterval - if (mod(AlarmInterval, TimestepInterval) /= (timestepinterval*0)) then - call ESMF_LogWrite(subname//'illegal Alarm setting for '//trim(alarmname), ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - 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 - ! AlarmInterval*0 is 0 of kind ESMF_TimeStepInterval - if (AlarmInterval <= AlarmInterval*0) then - call ESMF_LogWrite(subname//'AlarmInterval ERROR ', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - 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 From b2b2d465d6d8dc6f598caae51a5a8d362f1eb8f3 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Sat, 6 Apr 2024 08:38:58 -0600 Subject: [PATCH 05/14] fixes restart at end of run --- cime_config/buildnml | 2 + cime_config/namelist_definition_drv.xml | 13 +- mediator/fd_cesm.yaml | 867 +++++++++++++----------- mediator/med_phases_profile_mod.F90 | 12 +- 4 files changed, 496 insertions(+), 398 deletions(-) diff --git a/cime_config/buildnml b/cime_config/buildnml index f95b2012..5e09595a 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -51,6 +51,8 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): 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") + + config["comp_ocn"] = case.get_value("COMP_OCN") atm_grid = case.get_value("ATM_GRID") diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 3e4d6bf6..8cf085b9 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -233,17 +233,14 @@ - - - - logical nuopc ALLCOMP_attributes - .false. - .true. + .true. + .false. + .false. @@ -256,6 +253,10 @@ + + + + char orbital diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index f5a6abce..88b4a515 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -3,852 +3,938 @@ institution: National ESPC, CSC & MCL Working Groups description: Community-based dictionary for shared coupling fields entries: - # - #----------------------------------- - # section: mediator export for atm/ocn flux calculation - #----------------------------------- - # + # + #----------------------------------- + # Current the following sections are below + # section: fields computed in med + # section: lnd import to med + # section: lnd export from med (computed in med) + # section: atm import to med + # section: atm export from med (computed in med) + # section: glc import to med + # section: glc export from med (computed in med) + # section: ice import to med + # section: ocn import to med + # section: ocn export from med (computed in med) + # section: river import to med + # section: river export from med (computed in med) + # section: wav import to med + #----------------------------------- + # + #----------------------------------- + # section: fields computed in med + #----------------------------------- + # + - standard_name: cpl_scalars + canonical_units: unitless + # + - standard_name: frac + canonical_units: 1 + # + - standard_name: mask + canonical_units: 1 + # + - standard_name: area + canonical_units: radians**2 + description: med area for component + # - standard_name: Faox_evap alias: mean_evap_rate_atm_into_ocn canonical_units: kg m-2 s-1 - description: mediator export - atm/ocn evaporation water flux + description: med export - atm/ocn evaporation water flux computed in medidator # - standard_name: Faox_evap_wiso canonical_units: kg m-2 s-1 - description: mediator export - atm/ocn evaporation water flux 16O, 18O, HDO + description: med export - atm/ocn evaporation water flux 16O, 18O, HDO computed in medidator # - standard_name: Faox_lat alias: mean_laten_heat_flx_atm_into_ocn canonical_units: W m-2 - description: mediator export - atm/ocn surface latent heat flux + description: med export - atm/ocn surface latent heat flux computed in medidator # - standard_name: Faox_sen alias: mean_sensi_heat_flx_atm_into_ocn canonical_units: W m-2 - description: mediator export - atm/ocn surface sensible heat flux + description: med export - atm/ocn surface sensible heat flux computed in medidator # - standard_name: Faox_lwup alias: mean_up_lw_flx_ocn canonical_units: W m-2 - description: mediator export - long wave radiation flux over the ocean + description: med export - ocn long wave radiation flux over the ocean computed in medidator # - standard_name: Faox_taux alias: stress_on_air_ocn_zonal canonical_units: N m-2 - description: mediator export + description: med export - atm/ocn zonal surface stress computed in medidator # - standard_name: Faox_tauy alias: stress_on_air_ocn_merid canonical_units: N m-2 - description: mediator export + description: med export - atm/ocn meridional surface stress computed in medidator # - - standard_name: area - canonical_units: radians**2 - description: mediator area for component + - standard_name: Fwxx_taux + alias: mean_zonal_moment_flx + canonical_units: N m-2 + description: wave import to med - zonal surface stress + # + - standard_name: Fwxx_tauy + alias: mean_merid_moment_flx + canonical_units: N m-2 + description: wave import to med - meridional surface stress # #----------------------------------- - # section: land export + # section: lnd import to med #----------------------------------- # - standard_name: Fall_evap canonical_units: kg m-2 s-1 - description: land export + description: lnd import to med # - standard_name: Fall_evap_wiso canonical_units: kg m-2 s-1 - description: land export + description: lnd import to med # - standard_name: Fall_fco2_lnd canonical_units: moles m-2 s-1 - description: land export + description: lnd import to med # - standard_name: Fall_fire canonical_units: kg/m2/sec - description: land export - wild fire emission fluxes (1->10) + description: lnd import to med - wild fire emission fluxes (1->10) # - standard_name: Fall_flxdst canonical_units: kg m-2 s-1 - description: land export - dust fluxes from land (sizes 1->4) + description: lnd import to med - dust fluxes from lnd (sizes 1->4) # - standard_name: Fall_lat canonical_units: W m-2 - description: land export + description: lnd import to med # - standard_name: Fall_lwup canonical_units: W m-2 - description: land export + description: lnd import to med # - standard_name: Fall_sen canonical_units: W m-2 - description: land export + description: lnd import to med # - standard_name: Fall_swnet canonical_units: W m-2 - description: land export + description: lnd import to med # - standard_name: Fall_taux canonical_units: N m-2 - description: land export + description: lnd import to med # - standard_name: Fall_tauy canonical_units: N m-2 - description: land export + description: lnd import to med # - standard_name: Fall_voc canonical_units: molecules/m2/sec - description: land export - MEGAN voc emission fluxes from land (1->20) + description: lnd import to med - MEGAN voc emission fluxes from lnd (1->20) # - standard_name: Sl_anidf canonical_units: 1 - description: land export + description: lnd import to med # - standard_name: Sl_anidr canonical_units: 1 - description: land export + description: lnd import to med # - standard_name: Sl_avsdf canonical_units: 1 - description: land export + description: lnd import to med # - standard_name: Sl_avsdr canonical_units: 1 - description: land export + description: lnd import to med # - standard_name: Sl_ddvel canonical_units: cm/sec - description: land export - dry deposition velocities from (1->80) + description: lnd import to med - dry deposition velocities from (1->80) # - standard_name: Sl_fv canonical_units: m s-1 - description: land export + description: lnd import to med # - standard_name: Sl_fztop canonical_units: m - description: land export + description: lnd import to med # - standard_name: Sl_lfrac canonical_units: 1 - description: land export + description: lnd import to med # - standard_name: Sl_lfrin canonical_units: 1 - description: land export + description: lnd import to med # - standard_name: Sl_qref canonical_units: kg kg-1 - description: land export + description: lnd import to med # - standard_name: Sl_qref_wiso canonical_units: kg kg-1 - description: land export + description: lnd import to med # - standard_name: Sl_ram1 canonical_units: s/m - description: land export + description: lnd import to med # - standard_name: Sl_snowh canonical_units: m - description: land export + description: lnd import to med # - standard_name: Sl_snowh_wiso canonical_units: m - description: land export + description: lnd import to med # - standard_name: Sl_soilw canonical_units: m3/m3 - description: land export + description: lnd import to med # - standard_name: Sl_t canonical_units: K - description: land export + description: lnd import to med # - - standard_name: Sl_topo_elev - canonical_units: m - description: land export to mediator in elevation classes (1->glc_nec) + - standard_name: Flrl_irrig + canonical_units: kg m-2 s-1 + description: lnd export to river # - - standard_name: Sl_topo + - standard_name: Flrl_rofdto + canonical_units: kg m-2 s-1 + description: lnd export to river + # + - standard_name: Flrl_rofgwl + canonical_units: kg m-2 s-1 + description: lnd export to river + # + - standard_name: Flrl_rofi + canonical_units: kg m-2 s-1 + description: lnd export to river + # + - standard_name: Flrl_rofsub + canonical_units: kg m-2 s-1 + description: lnd export to river + # + - standard_name: Flrl_rofsur + canonical_units: kg m-2 s-1 + description: lnd export to river + # + - standard_name: Sl_topo_elev canonical_units: m - description: mediator export to glc - no levation classes + description: lnd import to med with elevation classes (1->glc_nec) # - standard_name: Sl_tsrf_elev canonical_units: deg C - description: land export to mediator in elevation classes (1->glc_nec) + description: lnd import to med with elevation classes (1->glc_nec) + # + - standard_name: Flgl_qice_elev + canonical_units: kg m-2 s-1 + description: lnd import to med in elevation classes (1->glc_nec) + # + #----------------------------------- + # section: lnd export from med (computed in med) + #----------------------------------- + # + - standard_name: Sl_topo + canonical_units: m + description: lnd export from med with no elevation classes (computed in med) # - standard_name: Sl_tsrf canonical_units: deg C - description: mediator export to gcl with no elevation classes + description: lnd export from med with no elevation classes (computed in med) # - standard_name: Sl_tref canonical_units: K - description: mediator export to glc - no levation classes + description: lnd export from med with no elevation classes (computed in med) # - standard_name: Sl_u10 canonical_units: m - description: land export + description: lnd import to med with no elevation classes (computed in med) + # + - standard_name: Flgl_qice + canonical_units: kg m-2 s-1 + description: lnd export to med no elevation classes (computed in med) # #----------------------------------- - # section: atmosphere export + # section: atm import to med #----------------------------------- # - standard_name: Faxa_nhx canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_noy canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_bcph canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_ocph canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_dstdry canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_dstwet canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_swdn alias: mean_down_sw_flx canonical_units: W m-2 - description: atmosphere export + description: atm import to med mean downward SW heat flux # - standard_name: Faxa_lwdn alias: mean_down_lw_flx canonical_units: W m-2 - description: atmosphere export + description: atm import to med mean downward SW heat flux # - standard_name: Faxa_ndep canonical_units: kg(N)/m2/sec - description: atmosphere export to land and ocean - currently nhx and noy + description: atm import to med - currently nhx and noy # - standard_name: Faxa_prec_wiso canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_rain alias: mean_prec_rate canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_rain_wiso alias: mean_prec_rate_wiso canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_rainc canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_rainc_wiso canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_rainl canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_rainl_wiso canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_snow alias: mean_fprec_rate canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_snow_wiso canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_snowc canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_snowc_wiso canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_snowl canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_snowl_wiso canonical_units: kg m-2 s-1 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_swnet canonical_units: W m-2 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_lwnet canonical_units: W m-2 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_swndf alias: mean_down_sw_ir_dif_flx canonical_units: W m-2 - description: atmosphere export - mean surface downward nir diffuse flux + description: atm import to med - mean surface downward nir diffuse flux # - standard_name: Faxa_swndr alias: mean_down_sw_ir_dir_flx canonical_units: W m-2 - description: atmosphere export - mean surface downward nir direct flux + description: atm import to med - mean surface downward nir direct flux # - standard_name: Faxa_swvdf alias: mean_down_sw_vis_dif_flx canonical_units: W m-2 - description: atmosphere export - mean surface downward uv+vis diffuse flux + description: atm import to med - mean surface downward uv+vis diffuse flux # - standard_name: Faxa_swvdr alias: mean_down_sw_vis_dir_flx canonical_units: W m-2 - description: atmosphere export - mean surface downward uv+visvdirect flux + description: atm import to med - mean surface downward uv+visvdirect flux # - standard_name: Sa_co2diag canonical_units: 1e-6 mol/mol - description: atmosphere export - diagnostic CO2 at the lowest model level + description: atm import to med - diagnostic CO2 at the lowest model level # - standard_name: Sa_co2prog canonical_units: 1e-6 mol/mol - description: atmosphere export - prognostic CO2 at the lowest model level + description: atm import to med - prognostic CO2 at the lowest model level # - standard_name: Sa_o3 canonical_units: mol/mol - description: atmosphere export - O3 in the lowest model layer (prognosed or prescribed) + description: atm import to med - O3 in the lowest model layer (prognosed or prescribed) # - standard_name: Sa_lightning canonical_units: /min - description: atmosphere export - lightning flash freqency + description: atm import to med - lightning flash freqency # - standard_name: Sa_topo alias: inst_surface_height canonical_units: m - description: atmosphere export - topographic height + description: atm import to med - topographic height # - standard_name: Sa_dens alias: air_density_height_lowest canonical_units: kg m-3 - description: atmosphere export - density at the lowest model layer + description: atm import to med - density at the lowest model layer # - standard_name: Sa_pbot alias: inst_pres_height_lowest canonical_units: Pa - description: atmosphere export - pressure at lowest model layer + description: atm import to med - pressure at lowest model layer # - standard_name: Sa_pslv alias: inst_pres_height_surface canonical_units: Pa - description: atmosphere export + description: atm import to med # - standard_name: Sa_ptem canonical_units: K - description: atmosphere export - bottom layer potential temperature + description: atm import to med - bottom layer potential temperature # - standard_name: Sa_shum alias: inst_spec_humid_height_lowest canonical_units: kg kg-1 - description: atmosphere export - bottom layer specific humidity + description: atm import to med - bottom layer specific humidiaty # - standard_name: Sa_shum_wiso alias: inst_spec_humid_height_lowest_wiso canonical_units: kg kg-1 - description: atmosphere export - bottom layer specific humidity 16O, 18O, HDO + description: atm import to med - bottom layer specific humidity 16O, 18O, HDO # - standard_name: Sa_tbot alias: inst_temp_height_lowest canonical_units: K - description: atmosphere export - bottom layer temperature + description: atm import to med - bottom layer temperature # - standard_name: Sa_tskn alias: inst_temp_skin_temperature canonical_units: K - description: atmosphere export - sea surface skin temperature + description: atm import to med - sea surface skin temperature # - standard_name: Sa_u alias: inst_zonal_wind_height_lowest canonical_units: m s-1 - description: atmosphere export - bottom layer zonal wind + description: atm import to med - bottom layer zonal wind # - standard_name: Sa_v alias: inst_merid_wind_height_lowest canonical_units: m s-1 - description: atmosphere export - bottom layer meridional wind + description: atm import to med - bottom layer meridional wind + # + - standard_name: Sa_u10m + canonical_units: m s-1 + description: atm import to med - 10m zonal wind + # + - standard_name: Sa_v10m + canonical_units: m s-1 + description: atm import to med- 10m meridional wind # - standard_name: Sa_wspd alias: inst_wind_speed_height_lowest canonical_units: m s-1 - description: atmosphere export - bottom layer wind speed + description: atm import to med - bottom layer wind speed # - standard_name: Sa_z alias: inst_height_lowest canonical_units: m - description: atmosphere export - bottom layer height + description: atm import to med - bottom layer height # - standard_name: Faxa_taux alias: mean_zonal_moment_flx_atm canonical_units: N m-2 - description: atmosphere export - zonal component of momentum flux + description: atm import to med - zonal component of momentum flux # - standard_name: Faxa_tauy alias: mean_merid_moment_flx_atm canonical_units: N m-2 - description: atmosphere export - meridional component of momentum flux + description: atm import to med - meridional component of momentum flux # - standard_name: Faxa_lat alias: mean_laten_heat_flx_atm canonical_units: W m-2 - description: atmosphere export + description: atm import to med # - standard_name: Faxa_sen alias: mean_sensi_heat_flx_atm canonical_units: W m-2 - description: atmosphere export + description: atm import to med # #----------------------------------- - # section: atmosphere import + # section: atm export from med (computed in med) #----------------------------------- # - standard_name: Faxx_evap canonical_units: kg m-2 s-1 - description: to atm merged water evaporation flux + description: atm export from meditor - merged water evaporation flux # - standard_name: Faxx_evap_wiso canonical_units: kg m-2 s-1 - description: to atm merged water evaporation flux for 16O, 18O and HDO + description: atm export from med - merged water evaporation flux for 16O, 18O and HDO # - standard_name: Faxx_lat alias: mean_laten_heat_flx canonical_units: W m-2 - description: to to atm merged latent heat flux + description: atm export from med - merged latent heat flux # - standard_name: Faxx_lwup canonical_units: W m-2 - description: to atm merged outgoing longwave radiation + description: atm export from med - merged outgoing longwave radiation # - standard_name: Faxx_sen alias: mean_sensi_heat_flx canonical_units: W m-2 - description: to atm merged sensible heat flux + description: atm export from med - merged sensible heat flux # - standard_name: Faxx_taux alias: mean_zonal_moment_flx canonical_units: N m-2 - description: to atm merged zonal surface stress + description: atm export from med - merged zonal surface stress # - standard_name: Faxx_tauy alias: mean_merid_moment_flx canonical_units: N m-2 - description: to atm merged meridional surface stress + description: atm export from med - merged meridional surface stress # - standard_name: Sx_anidf canonical_units: 1 - description: atmosphere import - description: to atm merged surface diffuse albedo (near-infrared radiation) + description: atm export from med - merged surface diffuse albedo (near-infrared radiation) # - standard_name: Sx_anidr canonical_units: 1 - description: to atm merged direct surface albedo (near-infrared radiation) + description: atm export from med - merged direct surface albedo (near-infrared radiation) # - standard_name: Sx_avsdf canonical_units: 1 - description: to atm merged surface diffuse albedo (visible radation) + description: atm export from med - merged surface diffuse albedo (visible radation) # - standard_name: Sx_avsdr canonical_units: 1 - description: to atm merged direct surface albedo (visible radiation) + description: atm export from med - merged direct surface albedo (visible radiation) # - standard_name: Sx_qref canonical_units: kg kg-1 - description: atmosphere import + description: atm export from med # - standard_name: Sx_qref_wiso canonical_units: kg kg-1 - description: atmosphere import + description: atm export from med # - standard_name: Sx_t alias: surface_temperature canonical_units: K - description: atmosphere import + description: atm export from med # - standard_name: Sx_tref canonical_units: K - description: atmosphere import + description: atm export from med # - standard_name: Sx_u10 canonical_units: m - description: atmosphere import + description: atm export from med # - standard_name: So_ugustOut canonical_units: m/s - description: atmosphere import + description: atm export from med # - standard_name: So_u10withGust canonical_units: m/s - description: atmosphere import + description: atm export from med # - standard_name: So_u10res canonical_units: m/s - description: atmosphere import + description: atm export from med # #----------------------------------- - # section: land-ice export + # section: glc import to med + #----------------------------------- + # # Note that the fields sent from glc->med do NOT have elevation classes, # but the fields from med->lnd are broken into multiple elevation classes - #----------------------------------- # - standard_name: Figg_rofi canonical_units: kg m-2 s-1 - description: land-ice export - glc frozen runoff_iceberg flux to ice + description: glc import to med - glc frozen runoff_iceberg flux to ice # - standard_name: Figg_rofi_wiso canonical_units: kg m-2 s-1 - description: land-ice export - glc frozen runoff_iceberg flux to ice for 16O, 18O, HDO + description: glc import to med - glc frozen runoff_iceberg flux to ice for 16O, 18O, HDO # - standard_name: Flgg_hflx canonical_units: W m-2 - description: land-ice export to mediator (no elevation classes) - Downward heat flux from glacier interior, from mediator, elev class 0 - # - - standard_name: Flgg_hflx_elev - canonical_units: W m-2 - description: mediator land-ice export to lnd (elevation classes 1->glc_nec) - Downward heat flux from glacier interior, from mediator, elev class 1->glc_nec + description: glc import to med to med (no elevation classes) + Downward heat flux from glacier interior, from med, elev class 0 # - standard_name: Sg_area canonical_units: area internal to the CISM grid in radians**2 - description: land-ice export to mediator (no elevation classes) + description: glc import to med to med (no elevation classes) # - standard_name: Sg_ice_covered canonical_units: 1 - description: land-ice export to mediator (no elevation classes) - # - - standard_name: Sg_ice_covered_elev - canonical_units: 1 - description: mediator land-ice export to lnd (elevation classes 1->glc_nec) + description: glc import to med (no elevation classes) # - standard_name: Sg_icemask canonical_units: 1 - description: land-ice export + description: glc import to med # - standard_name: Sg_icemask_coupled_fluxes canonical_units: 1 - description: land-ice export + description: glc import to med # - standard_name: Sg_topo canonical_units: m - description: land-ice export to mediator (no elevation classes) + description: glc import to med (no elevation classes) + # + #----------------------------------- + # section: glc export from med (computed in med) + #----------------------------------- + # + - standard_name: Flgg_hflx_elev + canonical_units: W m-2 + description: glc export from med (elevation classes 1->glc_nec) + Downward heat flux from glacier interior, from med, elev class 1->glc_nec + # + - standard_name: Sg_ice_covered_elev + canonical_units: 1 + description: glc export from med (elevation classes 1->glc_nec) # - standard_name: Sg_topo_elev canonical_units: m - description: mediator land-ice export to lnd (elevation classes 1->glc_nec) + description: glc export from med (elevation classes 1->glc_nec) # - standard_name: Fogg_rofi canonical_units: kg m-2 s-1 - description: land-ice export - glacier_frozen_runoff_flux_to_ocean + description: glc export from med - glacier_frozen_runoff_flux_to_ocean # - standard_name: Fogg_rofi_wiso canonical_units: kg m-2 s-1 - description: land-ice export - glacier_frozen_runoff_flux_to_ocean for 16O, 18O, HDO + description: glc export from med - glacier_frozen_runoff_flux_to_ocean for 16O, 18O, HDO # - standard_name: Fogg_rofl canonical_units: kg m-2 s-1 - description: land-ice export - glacier liquid runoff flux to ocean + description: glc export from med - glacier liquid runoff flux to ocean # - standard_name: Fogg_rofl_wiso canonical_units: kg m-2 s-1 - description: land-ice export - glacier_frozen_runoff_flux_to_ocean for 16O, 18O, HDO + description: glc export from med - glacier_frozen_runoff_flux_to_ocean for 16O, 18O, HDO # #----------------------------------- - # section: sea-ice export + # section: ice import to med #----------------------------------- # - standard_name: Faii_evap alias: mean_evap_rate_atm_into_ice canonical_units: kg m-2 s-1 - description: sea-ice export + description: ice import to med # - standard_name: Faii_evap_wiso canonical_units: kg m-2 s-1 - description: sea-ice export for 16O, 18O, HDO + description: ice import to med for 16O, 18O, HDO # - standard_name: Faii_lat alias: mean_laten_heat_flx_atm_into_ice canonical_units: W m-2 - description: sea-ice export to atm - atm/ice latent heat flux + description: ice import to med - atm/ice latent heat flux # - standard_name: Faii_sen alias: mean_sensi_heat_flx_atm_into_ice canonical_units: W m-2 - description: sea-ice export to atm - atm/ice sensible heat flux + description: ice import to med - atm/ice sensible heat flux # - standard_name: Faii_lwup alias: mean_up_lw_flx_ice canonical_units: W m-2 - description: sea-ice export -outgoing logwave radiation + description: ice import to med -outgoing logwave radiation # - standard_name: Faii_swnet canonical_units: W m-2 - description: sea-ice export to atm + description: ice import to med to atm # - standard_name: Faii_taux alias: stress_on_air_ice_zonal canonical_units: N m-2 - description: sea-ice export to atm - air ice zonal stress + description: ice import to med - air ice zonal stress # - standard_name: Faii_tauy alias: stress_on_air_ice_merid canonical_units: N m-2 - description: sea-ice export - air ice meridional stress + description: ice import to med - air ice meridional stress # - standard_name: Fioi_bcphi canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - hydrophilic black carbon flux to ocean + description: ice import to med to ocean - hydrophilic black carbon flux to ocean # - standard_name: Fioi_bcpho canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - hydrophobic black carbon flux to ocean + description: ice import to med to ocean - hydrophobic black carbon flux to ocean # - standard_name: Fioi_flxdst canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - dust aerosol flux to ocean + description: ice import to med to ocean - dust aerosol flux to ocean # - standard_name: Fioi_melth alias: net_heat_flx_to_ocn canonical_units: W m-2 - description: sea-ice export to ocean - net heat flux to ocean + description: ice import to med to ocean - net heat flux to ocean # - standard_name: Fioi_melth_wiso canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - isotope head flux to ocean for 16O, 18O, HDO + description: ice import to med to ocean - isotope head flux to ocean for 16O, 18O, HDO # - standard_name: Fioi_melth_HDO canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - isotope head flux to ocean + description: ice import to med to ocean - isotope head flux to ocean # - standard_name: Fioi_meltw alias: mean_fresh_water_to_ocean_rate canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - fresh water to ocean (h2o flux from melting) + description: ice import to med to ocean - fresh water to ocean (h2o flux from melting) # - standard_name: Fioi_meltw_wiso alias: mean_fresh_water_to_ocean_rate_wiso canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - fresh water to ocean (h2o flux from melting) for 16O, 18O, HDO + description: ice import to med to ocean - fresh water to ocean (h2o flux from melting) for 16O, 18O, HDO # - standard_name: Fioi_salt alias: mean_salt_rate canonical_units: kg m-2 s-1 - description: sea-ice export to ocean - salt to ocean (salt flux from melting) + description: ice import to med - salt to ocean (salt flux from melting) # - standard_name: Fioi_swpen alias: mean_sw_pen_to_ocn canonical_units: W m-2 - description: sea-ice export to ocean - flux of shortwave through ice to ocean + description: ice import to med - flux of shortwave through ice to ocean # - standard_name: Fioi_swpen_vdr alias: mean_sw_pen_to_ocn_vis_dir_flx canonical_units: W m-2 - description: sea-ice export to ocean - flux of vis dir shortwave through ice to ocean + description: ice import to med - flux of vis dir shortwave through ice to ocean # - standard_name: Fioi_swpen_vdf alias: mean_sw_pen_to_ocn_vis_dif_flx canonical_units: W m-2 - description: sea-ice export to ocean - flux of vif dir shortwave through ice to ocean + description: ice import to med - flux of vif dir shortwave through ice to ocean # - standard_name: Fioi_swpen_idr alias: mean_sw_pen_to_ocn_ir_dir_flx canonical_units: W m-2 - description: sea-ice export to ocean - flux of ir dir shortwave through ice to ocean + description: ice import to med - flux of ir dir shortwave through ice to ocean # - standard_name: Fioi_swpen_idf alias: mean_sw_pen_to_ocn_ir_dif_flx canonical_units: W m-2 - description: sea-ice export to ocean - flux of ir dif shortwave through ice to ocean + description: ice import to med - flux of ir dif shortwave through ice to ocean # - standard_name: Fioi_taux alias: stress_on_ocn_ice_zonal canonical_units: N m-2 - description: sea-ice export to ocean - ice ocean zonal stress + description: ice import to med - ice ocean zonal stress # - standard_name: Fioi_tauy alias: stress_on_ocn_ice_merid canonical_units: N m-2 - description: sea-ice export to ocean - ice ocean meridional stress + description: ice import to med - ice ocean meridional stress # - standard_name: Si_anidf alias: inst_ice_ir_dif_albedo canonical_units: 1 - description: sea-ice export to atm + description: ice import to med # - standard_name: Si_anidr alias: inst_ice_ir_dir_albedo canonical_units: 1 - description: sea-ice export to atm + description: ice import to med # - standard_name: Si_avsdf alias: inst_ice_vis_dif_albedo canonical_units: 1 - description: sea-ice export to atm + description: ice import to med # - standard_name: Si_avsdr alias: inst_ice_vis_dir_albedo canonical_units: 1 - description: sea-ice export to atm + description: ice import to med # - standard_name: Si_ifrac alias: ice_fraction canonical_units: 1 - description: sea-ice export to atm - ice fraction (varies with time) + description: ice import to med - ice fraction (varies with time) # - standard_name: Si_ifrac_n alias: ice_fraction_n canonical_units: 1 - description: sea-ice export - ice fraction per category (varies with time) + description: ice import to med - ice fraction per category (varies with time) # - standard_name: Si_imask alias: ice_mask canonical_units: 1 - description: sea-ice export - ice mask + description: ice import to med - ice mask # - standard_name: Si_qref canonical_units: kg kg-1 - description: sea-ice export to atm + description: ice import to med # - standard_name: Si_qref_wiso canonical_units: kg kg-1 - description: sea-ice export to atm + description: ice import to med # - standard_name: Si_t alias: sea_ice_surface_temperature canonical_units: K - description: sea-ice export + description: ice import to med # - standard_name: Si_tref canonical_units: K - description: sea-ice export + description: ice import to med # - standard_name: Si_u10 canonical_units: m - description: sea-ice export + description: ice import to med # - standard_name: Si_vice alias: mean_ice_volume canonical_units: m - description: sea-ice export - volume of ice per unit area + description: ice import to med - volume of ice per unit area # - standard_name: Si_snowh canonical_units: m - description: sea-ice export - surface_snow_water_equivalent + description: ice import to med - surface_snow_water_equivalent # - standard_name: Si_vsno alias: mean_snow_volume canonical_units: m - description: sea-ice export - volume of snow per unit area + description: ice import to med - volume of snow per unit area # - standard_name: Si_thick canonical_units: m - description: sea-ice export - ice thickness + description: ice import to med - ice thickness # - standard_name: Si_floediam canonical_units: m - description: sea-ice export - ice floe diameter + description: ice import to med - ice floe diameter # #----------------------------------- - # section: ocean export to mediator + # section: ocn import to med #----------------------------------- # - standard_name: Fioo_q alias: freezing_melting_potential canonical_units: W m-2 - description: ocean export + description: ocn import to med # - standard_name: Faoo_fco2_ocn canonical_units: moles m-2 s-1 - description: ocean export + description: ocn import to med + # + - standard_name: Faoo_dms_ocn + canonical_units: moles m-2 s-1 + description: ocn import to med - surface flux of DMS (downward positive) # - standard_name: So_anidf canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_anidr canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_avsdf canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_avsdr canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_bldepth alias: mixed_layer_depth canonical_units: m - description: ocean export + description: ocn import to med # - standard_name: So_dhdx alias: sea_surface_slope_zonal canonical_units: m m-1 - description: ocean export + description: ocn import to med # - standard_name: So_dhdy alias: sea_surface_slope_merid canonical_units: m m-1 - description: ocean export + description: ocn import to med # - standard_name: So_duu10n canonical_units: m2 s-2 - description: ocean export + description: ocn import to med # - standard_name: So_fswpen canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_ofrac canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_omask alias: ocean_mask canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_qref canonical_units: kg kg-1 - description: ocean export + description: ocn import to med # - standard_name: So_qref_wiso canonical_units: kg kg-1 - description: ocean export + description: ocn import to med # - standard_name: So_re canonical_units: 1 - description: ocean export + description: ocn import to med # - standard_name: So_qref_wiso canonical_units: kg kg-1 - description: ocean export + description: ocn import to med # - standard_name: So_roce_wiso canonical_units: unitless - description: ocean export + description: ocn import to med # - standard_name: So_s alias: s_surf canonical_units: g kg-1 - description: ocean export + description: ocn import to med # - standard_name: So_s_depth alias: s_surf_depths @@ -857,12 +943,12 @@ # - standard_name: So_ssq canonical_units: kg kg-1 - description: ocean export + description: ocn import to med # - standard_name: So_t alias: sea_surface_temperature canonical_units: K - description: ocean export + description: ocn import to med # - standard_name: So_t_depth alias: sea_surface_temperature_depths @@ -871,292 +957,256 @@ # - standard_name: So_tref canonical_units: K - description: ocean export + description: ocn import to med # - standard_name: So_u alias: ocn_current_zonal canonical_units: m s-1 - description: ocean export + description: ocn import to med # - standard_name: So_u10 canonical_units: m - description: ocean export + description: ocn import to med # - standard_name: So_ustar canonical_units: m s-1 - description: ocean export + description: ocn import to med # - standard_name: So_v alias: ocn_current_merid canonical_units: m s-1 - description: ocean export - # - #----------------------------------- - # section: river export - #----------------------------------- - # - - standard_name: Firr_rofi - canonical_units: kg m-2 s-1 - description: river export - water flux into sea ice due to runoff (frozen) - # - - standard_name: Firr_rofi_wiso - canonical_units: kg m-2 s-1 - description: river export - water flux into sea ice due to runoff (frozen) for 16O, 18O, HDO - # - - standard_name: Fixx_rofi - canonical_units: kg m-2 s-1 - description: frozen runoff to ice from river and land-ice - # - - standard_name: Fixx_rofi_wiso - canonical_units: kg m-2 s-1 - description: frozen runoff to ice from river and land-ice for 16O, 18O, HDO - # - #----------------------------------- - # section: lnd export to glc - #----------------------------------- - # - - standard_name: Flgl_qice - canonical_units: kg m-2 s-1 - description: mediator export to glc no elevation classes - # - - standard_name: Flgl_qice_elev - canonical_units: kg m-2 s-1 - description: land export to mediator in elevation classes (1->glc_nec) - # - #----------------------------------- - # section: lnd export to river - #----------------------------------- - # - - standard_name: Flrl_irrig - canonical_units: kg m-2 s-1 - description: land export to river - # - - standard_name: Flrl_rofdto - canonical_units: kg m-2 s-1 - description: land export to river - # - - standard_name: Flrl_rofgwl - canonical_units: kg m-2 s-1 - description: land export to river - # - - standard_name: Flrl_rofi - canonical_units: kg m-2 s-1 - description: land export to river - # - - standard_name: Flrl_rofsub - canonical_units: kg m-2 s-1 - description: land export to river - # - - standard_name: Flrl_rofsur - canonical_units: kg m-2 s-1 - description: land export to river - # - #----------------------------------- - # section: river export - #----------------------------------- - # - - standard_name: Flrr_flood - canonical_units: kg m-2 s-1 - description: river export to land - water flux due to flooding - # - - standard_name: Flrr_flood_wiso - canonical_units: kg m-2 s-1 - description: river export to land - water flux due to flooding for 16O, 18O, HDO - # - - standard_name: Flrr_volr - canonical_units: m - description: river export to land - river channel total water volume - # - - standard_name: Flrr_volr_wiso - canonical_units: m - description: river export to land - river channel total water volume from 16O, 18O, HDO - # - - standard_name: Flrr_volrmch - canonical_units: m - description: river export to land - river channel main channel water volume - # - - standard_name: Flrr_volrmch_wiso - canonical_units: m - description: river export to land - river channel main channel water volume from 16O, 18O, HDO - # - - standard_name: Sr_tdepth - canonical_units: m - description: river export to land - tributary channel water depth - # - - standard_name: Sr_tdepth_max - canonical_units: m - description: river export to land - tributary channel bankfull depth - # - - standard_name: Forr_rofi - canonical_units: kg m-2 s-1 - description: river export to ocean - water flux due to runoff (frozen) - # - - standard_name: Forr_rofi_wiso - canonical_units: kg m-2 s-1 - description: river export to ocean - water flux due to runoff (frozen) for 16O, 18O, HDO - # - - standard_name: Forr_rofl - canonical_units: kg m-2 s-1 - description: river export to ocean - water flux due to runoff (liquid) - # - - standard_name: Forr_rofl_wiso - canonical_units: kg m-2 s-1 - description: river export to ocean - water flux due to runoff (frozen) for 16O, 18O, HDO + description: ocn import to med # #----------------------------------- - # section: ocean import + # section: ocn export from med (computed in med) #----------------------------------- # - standard_name: Foxx_hrain alias: heat_content_lprec canonical_units: W m-2 - description: to ocn heat content of rain + description: med export to ocn heat content of rain # - standard_name: Foxx_hsnow alias: heat_content_fprec canonical_units: W m-2 - description: to ocn heat content of snow + description: med export to ocn heat content of snow # - standard_name: Foxx_hevap alias: heat_content_evap canonical_units: W m-2 - description: to ocn heat content of evaporation + description: med export to ocn heat content of evaporation # - standard_name: Foxx_hcond alias: heat_content_cond canonical_units: W m-2 - description: to ocn heat content of condensation + description: med export to ocn heat content of condensation # - standard_name: Foxx_hrofl alias: heat_content_rofl canonical_units: W m-2 - description: to ocn heat content of liquid runoff + description: med export to ocn heat content of liquid runoff # - standard_name: Foxx_hrofi alias: heat_content_rofi canonical_units: W m-2 - description: to ocn heat content of ice runoff + description: med export to ocn heat content of ice runoff # - standard_name: Foxx_evap alias: mean_evap_rate canonical_units: kg m-2 s-1 - description: ocean import - specific humidity flux + description: med export to ocn - specific humidity flux # - standard_name: Foxx_evap_wiso alias: mean_evap_rate_wiso canonical_units: kg m-2 s-1 - description: ocean import - specific humidity flux 16O, 18O, HDO + description: med export to ocn - specific humidity flux 16O, 18O, HDO # - standard_name: Foxx_lat canonical_units: W m-2 - description: ocean import - latent heat flux into ocean + description: med export to ocn - latent heat flux into ocean # - standard_name: Foxx_lat_wiso canonical_units: W m-2 - description: ocean import - latent heat flux into ocean for 16O, 18O, HDO + description: med export to ocn - latent heat flux into ocean for 16O, 18O, HDO # - standard_name: Foxx_lat canonical_units: W m-2 - description: ocean import - latent heat flux into ocean for HDO + description: med export to ocn - latent heat flux into ocean for HDO # - standard_name: Foxx_sen alias: mean_sensi_heat_flx canonical_units: W m-2 - description: ocean import - sensible heat flux into ocean + description: med export to ocn - sensible heat flux into ocean # - standard_name: Foxx_lwup canonical_units: W m-2 - description: ocean import - surface upward longwave heat flux + description: med export to ocn - surface upward longwave heat flux # - standard_name: Foxx_lwnet alias: mean_net_lw_flx canonical_units: W m-2 - description: ocean import - mean NET long wave radiation flux to ocean + description: med export to ocn - mean NET long wave radiation flux to ocean # - standard_name: mean_runoff_rate canonical_units: kg m-2 s-1 - description: ocean import - total runoff to ocean + description: med export to ocn - total runoff to ocean # - standard_name: mean_runoff_heat_flux canonical_units: kg m-2 s-1 - description: ocean import - heat content of runoff + description: med export to ocn - heat content of runoff # - standard_name: mean_calving_rate canonical_units: kg m-2 s-1 - description: ocean import - total calving to ocean + description: med export to ocn - total calving to ocean # - standard_name: mean_calving_heat_flux canonical_units: kg m-2 s-1 - description: ocean import - heat content of calving + description: med export to ocn - heat content of calving # - standard_name: Foxx_rofi canonical_units: kg m-2 s-1 - description: ocean import - water flux due to runoff (frozen) + description: med export to ocn - water flux due to runoff (frozen) # - standard_name: Foxx_rofi_wiso canonical_units: kg m-2 s-1 - description: ocean import - water flux due to runoff (frozen) for 16O, 18O, HDO + description: med export to ocn - water flux due to runoff (frozen) for 16O, 18O, HDO # - standard_name: Foxx_rofl alias: mean_runoff_rate canonical_units: kg m-2 s-1 - description: ocean import - water flux due to runoff (liquid) + description: med export to ocn - water flux due to runoff (liquid) # - standard_name: Foxx_rofl_wiso canonical_units: kg m-2 s-1 - description: ocean import - water flux due to runoff (liquid) for 16O, 18O, HDO + description: med export to ocn - water flux due to runoff (liquid) for 16O, 18O, HDO # - standard_name: Foxx_swnet alias: mean_net_sw_flx canonical_units: W m-2 - description: ocean import - net shortwave radiation to ocean + description: med export to ocn - net shortwave radiation to ocean # - standard_name: Foxx_swnet_vdr alias: mean_net_sw_vis_dir_flx canonical_units: W m-2 - description: ocean import - net shortwave visible direct radiation to ocean + description: med export to ocn - net shortwave visible direct radiation to ocean # - standard_name: Foxx_swnet_vdf alias: mean_net_sw_vis_dif_flx canonical_units: W m-2 - description: ocean import - net shortwave visible diffuse radiation to ocean + description: med export to ocn - net shortwave visible diffuse radiation to ocean # - standard_name: Foxx_swnet_idr alias: mean_net_sw_ir_dir_flx canonical_units: W m-2 - description: ocean import - net shortwave ir direct radiation to ocean + description: med export to ocn - net shortwave ir direct radiation to ocean # - standard_name: Foxx_swnet_idf alias: mean_net_sw_ir_dif_flx canonical_units: W m-2 - description: ocean import - net shortwave ir diffuse radiation to ocean + description: med export to ocn - net shortwave ir diffuse radiation to ocean # - standard_name: Foxx_swnet_afracr canonical_units: W m-2 - description: ocean import - net shortwave radiation times atmosphere fraction + description: med export to ocn - net shortwave radiation times atmosphere fraction # - standard_name: Foxx_taux alias: mean_zonal_moment_flx canonical_units: N m-2 - description: ocean import - zonal surface stress + description: med export to ocn - zonal surface stress # - standard_name: Foxx_tauy alias: mean_merid_moment_flx canonical_units: N m-2 - description: ocean import - meridional surface stress + description: med export to ocn - meridional surface stress # - standard_name: Fioi_swpen_ifrac_n alias: mean_sw_pen_to_ocn_ifrac_n canonical_units: W m-2 - description: ocean import - net shortwave radiation penetrating into ice and ocean times ice fraction for thickness category 1 + description: med export to ocn - net shortwave radiation penetrating into ice and ocean times ice fraction for thickness category 1 # - standard_name: Sf_afrac canonical_units: 1 - description: ocean import - fractional atmosphere coverage wrt ocean + description: med export to ocn - fractional atmosphere coverage wrt ocean # - standard_name: Sf_afracr canonical_units: 1 - description: ocean import - fractional atmosphere coverage used in radiation computations wrt ocean + description: med export to ocn - fractional atmosphere coverage used in radiation computations wrt ocean + # + #----------------------------------- + # section: river import to med + #----------------------------------- + # + - standard_name: Flrr_flood + canonical_units: kg m-2 s-1 + description: river import to med - water flux due to flooding + # + - standard_name: Flrr_flood_wiso + canonical_units: kg m-2 s-1 + description: river import to med - water flux due to flooding for 16O, 18O, HDO + # + - standard_name: Flrr_volr + canonical_units: m + description: river import to med - river channel total water volume + # + - standard_name: Flrr_volr_wiso + canonical_units: m + description: river import to med - river channel total water volume from 16O, 18O, HDO + # + - standard_name: Flrr_volrmch + canonical_units: m + description: river import to med - river channel main channel water volume + # + - standard_name: Flrr_volrmch_wiso + canonical_units: m + description: river import to med - river channel main channel water volume from 16O, 18O, HDO + # + - standard_name: Sr_tdepth + canonical_units: m + description: river import to med - tributary channel water depth + # + - standard_name: Sr_tdepth_max + canonical_units: m + description: river import to med - tributary channel bankfull depth + # + - standard_name: Forr_rofi + canonical_units: kg m-2 s-1 + description: river export to ocean - water flux due to runoff (frozen) + # + - standard_name: Forr_rofi_wiso + canonical_units: kg m-2 s-1 + description: river import to med - water flux due to runoff (frozen) for 16O, 18O, HDO + # + - standard_name: Forr_rofl + canonical_units: kg m-2 s-1 + description: river import to med - water flux due to runoff (liquid) + # + - standard_name: Forr_rofl_wiso + canonical_units: kg m-2 s-1 + description: river import to med - water flux due to runoff (frozen) for 16O, 18O, HDO + # + - standard_name: Firr_rofi + canonical_units: kg m-2 s-1 + description: river export - water flux into sea ice due to runoff (frozen) + # + - standard_name: Firr_rofi_wiso + canonical_units: kg m-2 s-1 + description: river export - water flux into sea ice due to runoff (frozen) for 16O, 18O, HDO + # + #----------------------------------- + # section: river export from med (computed in med) + #----------------------------------- + # + - standard_name: Fixx_rofi + canonical_units: kg m-2 s-1 + description: frozen runoff to ice from river and lnd-ice + # + - standard_name: Fixx_rofi_wiso + canonical_units: kg m-2 s-1 + description: frozen runoff to ice from river and lnd-ice for 16O, 18O, HDO + # + #----------------------------------- + # section: wav import to med + #----------------------------------- # - standard_name: Sw_hstokes canonical_units: m @@ -1181,37 +1231,76 @@ - standard_name: Sw_pstokes_y canonical_units: m/s description: Northward partitioned stokes drift components - # - standard_name: Sw_elevation_spectrum alias: wave_elevation_spectrum canonical_units: m2/s description: wave elevation spectrum - # - #----------------------------------- - # section: wave import - #----------------------------------- + - standard_name: Sw_ustokes_avg + canonical_units: m/s + description: Daily averaged stokes drift u component (only needed for med history output) # - - standard_name: Fwxx_taux - alias: mean_zonal_moment_flx - canonical_units: N m-2 - description: wave import - zonal surface stress + - standard_name: Sw_vstokes_avg + canonical_units: m/s + description: Daily averaged stokes drift v component (only needed for med history output) # - - standard_name: Fwxx_tauy - alias: mean_merid_moment_flx - canonical_units: N m-2 - description: wave import - meridional surface stress - - #----------------------------------- - # mediator fields - #----------------------------------- + - standard_name: Sw_hs_avg + canonical_units: m + description: Daily averaged significant wave hight (only needed for med history output) # - - standard_name: cpl_scalars - canonical_units: unitless + - standard_name: Sw_phs0_avg + canonical_units: m + description: Daily averaged averaged wind sea swh (only needed for med history output) # - - standard_name: frac - canonical_units: 1 + - standard_name: Sw_phs1_avg + canonical_units: m + description: Daily averaged swell swh (only needed for med history output) # - - standard_name: mask - canonical_units: 1 + - standard_name: Sw_pdir0_avg + canonical_units: degrees + description: Daily averaged wind sea swh (only needed for med history output) + # + - standard_name: Sw_pdir1_avg + canonical_units: degrees + description: Daily averaged swell swh (only needed for med history output) + # + - standard_name: Sw_pTm10_avg + canonical_units: s + description: Daily averaged wind sea mean wave Tm1 period (only needed for med history output) + # + - standard_name: Sw_pTm11_avg + canonical_units: s + description: Daily average swell mean wave Tm1 period (only needed for med history output) + # + - standard_name: Sw_Tm1_avg + canonical_units: s + description: Daily averaged mean wave period of the first moment (only needed for med history output) + # + - standard_name: Sw_thm_avg + canonical_units: degrees + description: Daily averaged mean wave direction (only needed for med history output) + # + - standard_name: Sw_thp0_avg + canonical_units: degrees + description: Daily averaged peak wave direction (only needed for med history output) + # + - standard_name: Sw_fp0_avg + canonical_units: 1/s + description: Daily averaged peak wave frequency (only needed for med history output) + # + - standard_name: Sw_u_avg + canonical_units: m/s + description: Daily averaged surface wind zonal (only needed for med history output) + # + - standard_name: Sw_v_avg + canonical_units: m/s + description: Daily averaged surface wind meridional (only needed for med history output) + # + - standard_name: Sw_tusx_avg + canonical_units: m2/s + description: Daily averaged stokes zonal transport vector (only needed for med history output) + # + - standard_name: Sw_tusy_avg + canonical_units: m2/s + description: Daily averaged stokes meridional transport vector (only needed for med history output) diff --git a/mediator/med_phases_profile_mod.F90 b/mediator/med_phases_profile_mod.F90 index 76a630cb..1fb13d6f 100644 --- a/mediator/med_phases_profile_mod.F90 +++ b/mediator/med_phases_profile_mod.F90 @@ -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,8 +177,7 @@ 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 - call ESMF_TimeSet(wallclockTime, calkindflag=ESMF_CALKIND_GREGORIAN, 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 From a7b782f69d7e53a297b95835e54cb3ed4ff68c6b Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 10 Apr 2024 14:22:39 -0500 Subject: [PATCH 06/14] allow for ufs which does not use the gust code --- mediator/med_phases_aofluxes_mod.F90 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 33bc0aba..7afe15dc 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -1714,11 +1714,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_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 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) @@ -1750,8 +1745,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 From 27e647ed5c2fa363c89046c2a2b7d8ea7516329c Mon Sep 17 00:00:00 2001 From: James Edwards Date: Wed, 10 Apr 2024 16:09:38 -0500 Subject: [PATCH 07/14] improve description for START_TOD variable --- cime_config/config_component.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 938e0e31..772d069d 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. From 57290e24f83c468959a01d055828100aa8abeff1 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 26 Jun 2024 07:15:37 -0600 Subject: [PATCH 08/14] merge to main, add timestamp to rpointer file name --- mediator/med_phases_restart_mod.F90 | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index f2ffb911..c85e703e 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -5,7 +5,7 @@ module med_phases_restart_mod !----------------------------------------------------------------------------- use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag +! 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, InternalState use med_internalstate_mod , only : ncomps, compname, compocn, complnd, compwav @@ -25,7 +25,7 @@ module med_phases_restart_mod logical :: write_restart_at_endofrun = .false. logical :: whead(2) = (/.true. , .false./) logical :: wdata(2) = (/.false., .true. /) - + integer, parameter:: dbug_flag = 2 character(*), parameter :: u_FILE_u = & __FILE__ @@ -302,7 +302,7 @@ subroutine med_phases_restart_write(gcomp, rc) trim(nexttimestr),'.nc' if (maintask) then - restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag) + restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag)//'.'//trim(nexttimestr) call ESMF_LogWrite(trim(subname)//" write rpointer file = "//trim(restart_pfile), ESMF_LOGMSG_INFO) open(newunit=unitn, file=restart_pfile, form='FORMATTED') write(unitn,'(a)') trim(restart_file) @@ -547,14 +547,21 @@ subroutine med_phases_restart_read(gcomp, rc) endif ! Get the restart file name from the pointer file - restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag) + restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag)//'.'//trim(currtimestr) 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 + ! try without currtimestr + restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag) + 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 end if read (unitn,'(a)', iostat=ierr) restart_file if (ierr < 0) then From 0b6518d0c5d0942a2daa0476f16808110670c1c7 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 21 Aug 2024 07:22:23 -0600 Subject: [PATCH 09/14] cleanup work --- cesm/driver/esm_time_mod.F90 | 5 +---- cime_config/buildnml | 2 -- mediator/med_phases_restart_mod.F90 | 17 +---------------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90 index d4d0e81c..a1a39a78 100644 --- a/cesm/driver/esm_time_mod.F90 +++ b/cesm/driver/esm_time_mod.F90 @@ -25,15 +25,12 @@ module esm_time_mod 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" , & @@ -254,7 +251,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas ! Create the clock clock = ESMF_ClockCreate(TimeStep, StartTime, refTime=RefTime, name='ESMF Driver Clock', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - + ! Advance the clock to the current time (in case of a restart) call ESMF_ClockGet(clock, currTime=clocktime, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/cime_config/buildnml b/cime_config/buildnml index e02ca307..44116d98 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -190,8 +190,6 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): # determine coupling intervals comps = case.get_values("COMP_CLASSES") mindt = basedt - - coupling_times = {} for comp in comps: ncpl = case.get_value(comp.upper() + "_NCPL") diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index eeaf50e1..887aab8d 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -5,7 +5,7 @@ module med_phases_restart_mod !----------------------------------------------------------------------------- use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 -! use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + 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, InternalState use med_internalstate_mod , only : ncomps, compname, compocn, complnd, compwav @@ -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. /) - integer, parameter:: dbug_flag = 2 character(*), parameter :: u_FILE_u = & __FILE__ @@ -302,7 +301,6 @@ subroutine med_phases_restart_write(gcomp, rc) trim(nexttimestr),'.nc' if (maintask) then -! restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag)//'.'//trim(nexttimestr) restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag) call ESMF_LogWrite(trim(subname)//" write rpointer file = "//trim(restart_pfile), ESMF_LOGMSG_INFO) open(newunit=unitn, file=restart_pfile, form='FORMATTED') @@ -548,23 +546,10 @@ subroutine med_phases_restart_read(gcomp, rc) endif ! Get the restart file name from the pointer file -! restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag)//'.'//trim(currtimestr) restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag) 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 - ! try without currtimestr - restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag) - 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 - 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) From ee628d11ed412ea98e81e3823343a2f21fc4db01 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 21 Aug 2024 13:12:56 -0600 Subject: [PATCH 10/14] fix dglc setting and remove end run alarm for the moment --- cime_config/namelist_definition_drv.xml | 3 ++- cime_config/runseq/driver_config.py | 12 ++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 4482506c..0d72779b 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -233,12 +233,13 @@ + logical nuopc ALLCOMP_attributes - .true. + .false. .false. .false. 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 From 59b0c10da06f1681cc3163d4e36f554714ce538d Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Wed, 21 Aug 2024 14:45:24 -0600 Subject: [PATCH 11/14] remove unused code --- mediator/med.F90 | 9 +-------- mediator/med_phases_history_mod.F90 | 8 +------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/mediator/med.F90 b/mediator/med.F90 index 98b98534..914e35ad 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -2261,7 +2261,7 @@ subroutine SetRunClock(gcomp, rc) 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 : get_minimum_timestep, AlarmInit + use nuopc_shr_methods, only : AlarmInit ! input/output variables type(ESMF_GridComp) :: gcomp @@ -2277,8 +2277,6 @@ subroutine SetRunClock(gcomp, rc) character(len=CL) :: stop_option integer :: stop_n, stop_ymd logical, save :: stopalarmcreated=.false. - integer :: min_timestep = 0 ! used for nsteps option - character(len=*), parameter :: optNsteps = "nstep" character(len=*), parameter :: subname = '('//__FILE__//':SetRunClock)' !----------------------------------------------------------- @@ -2321,11 +2319,6 @@ 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 - - if (stop_option(1:len(optnsteps)) .eq. optNSteps) then - min_timestep = get_minimum_timestep(gcomp, rc) - endif - 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 diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index 51068340..b1e0f896 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -24,7 +24,6 @@ module med_phases_history_mod 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 - use nuopc_shr_methods, only : get_minimum_timestep implicit none private @@ -128,7 +127,6 @@ module med_phases_history_mod character(CL) :: case_name = 'unset' ! case name character(CS) :: inst_tag = 'unset' ! instance tag logical :: debug_alarms = .true. - character(len=*), parameter :: optNsteps = "nstep" character(*), parameter :: u_FILE_u = & __FILE__ @@ -186,7 +184,7 @@ subroutine med_phases_history_write(gcomp, rc) type(ESMF_TimeInterval) :: ringInterval integer :: ringInterval_length logical :: first_time = .true. - integer :: min_timestep = 0 ! used for nsteps option + character(len=*), parameter :: subname='(med_phases_history_write)' !--------------------------------------- @@ -224,10 +222,6 @@ 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 - - if (hist_option_all_inst(1:len(optnsteps)) == optnsteps) then - min_timestep = get_minimum_timestep(gcomp, rc=rc) - endif 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) From bfb0c28f6b209c05511db4ae1e8f83efaf67645c Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Aug 2024 07:40:01 -0600 Subject: [PATCH 12/14] update github workflow --- .github/workflows/extbuild.yml | 4 ++-- .github/workflows/srt.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) 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..48855281 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 }} From 086762bf3d138014e3198b70b2d6a925883857a2 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Aug 2024 07:44:44 -0600 Subject: [PATCH 13/14] remove unused variable --- mediator/med_phases_history_mod.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index b1e0f896..6859a6c9 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -1567,7 +1567,6 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi type(ESMF_Time) :: StartTime type(ESMF_TimeInterval) :: mtimestep, dtimestep integer :: msec, dsec - integer :: min_timestep character(len=*), parameter :: subname='(med_phases_history_init_histclock) ' !--------------------------------------- From 0db155415d08d49244a892c1bab04878f0d2d24f Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 22 Aug 2024 08:03:34 -0600 Subject: [PATCH 14/14] update github workflow --- .github/workflows/srt.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/srt.yml b/.github/workflows/srt.yml index 48855281..5a45a82a 100644 --- a/.github/workflows/srt.yml +++ b/.github/workflows/srt.yml @@ -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