diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90 index a1a39a78..b65f467a 100644 --- a/cesm/driver/esm_time_mod.F90 +++ b/cesm/driver/esm_time_mod.F90 @@ -95,6 +95,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas logical :: isPresent logical :: inDriver logical, save :: firsttime=.true. + logical :: exists character(len=*), parameter :: subname = '('//__FILE__//':esm_time_clockInit) ' !------------------------------------------------------------------------------- @@ -130,7 +131,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas if (read_restart) then - call NUOPC_CompAttributeGet(instance_driver, name='drv_restart_pointer', value=restart_file, rc=rc) + call NUOPC_CompAttributeGet(instance_driver, name='drv_restart_pointer', value=restart_pfile, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (trim(restart_file) /= 'none') then @@ -140,13 +141,18 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas if(isPresent) then call NUOPC_CompAttributeGet(instance_driver, name="inst_suffix", value=inst_suffix, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + restart_pfile = replace_text(restart_file, ".cpl", ".cpl."//inst_suffix) else inst_suffix = "" endif - - restart_pfile = trim(restart_file)//inst_suffix - if (maintask) then + inquire( file=trim(restart_pfile), exist=exists) + print *,__FILE__,__LINE__,trim(restart_pfile), exists + if (.not. exists) then + restart_pfile = "rpointer.cpl" + if (inst_suffix .ne. "") restart_pfile = trim(restart_pfile)//'.'//inst_suffix + endif + 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) @@ -323,7 +329,20 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas if (ChkErr(rc,__LINE__,u_FILE_u)) return firsttime = .false. endif - end subroutine esm_time_clockInit + contains + FUNCTION Replace_Text (s,text,rep) RESULT(outs) + CHARACTER(len=*) :: s,text,rep + CHARACTER(LEN(s)+100) :: outs ! provide outs with extra 100 char len + INTEGER :: i, nt, nr + + outs = s ; nt = LEN_TRIM(text) ; nr = LEN_TRIM(rep) + DO + i = INDEX(outs,text(:nt)) ; IF (i == 0) EXIT + outs = outs(:i-1) // rep(:nr) // outs(i+nt:) + END DO + END FUNCTION Replace_Text + + end subroutine esm_time_clockInit !=============================================================================== diff --git a/cime_config/buildnml b/cime_config/buildnml index 44116d98..6cc593b9 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -382,8 +382,6 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): nmlgen.set_value( "component_list", value=valid_comps_string.replace("CPL", "MED") ) - # the driver restart pointer will look like a mediator is present even if it is not - nmlgen.set_value("drv_restart_pointer", value="rpointer.cpl") logger.info("Writing nuopc_runconfig for components {}".format(valid_comps)) nuopc_config_file = os.path.join(confdir, "nuopc.runconfig") diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 63e1b09a..dfdc0279 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -402,6 +402,17 @@ + + char + rpointer.cpl + run_begin_stop_restart + env_run.xml + + Name of the restart pointer file, this can be used to restart from an + intermediate restart by appending the restart date and time in format YYYY-MM-DD-SSSSS + + + char none,never,nsteps,nseconds,nminutes,nhours,ndays,nmonths,nyears diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 0d72779b..a9d3eb78 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -162,7 +162,7 @@ - + char expdef DRIVER_attributes @@ -170,7 +170,7 @@ Driver restart pointer file to initialize time info - rpointer.cpl + $DRV_RESTART_POINTER diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index 887aab8d..d21a3ada 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -138,7 +138,7 @@ subroutine med_phases_restart_write(gcomp, rc) use med_io_mod , only : med_io_close, med_io_date2yyyymmdd, med_io_sec2hms use med_phases_history_mod, only : auxcomp use med_constants_mod , only : SecPerDay => med_constants_SecPerDay - + use nuopc_shr_methods , only : shr_get_rpointer_name ! Input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -172,9 +172,9 @@ subroutine med_phases_restart_write(gcomp, rc) character(ESMF_MAXSTR) :: case_name ! case name character(ESMF_MAXSTR) :: restart_file ! Local path to restart filename character(ESMF_MAXSTR) :: restart_pfile ! Local path to restart pointer filename - character(ESMF_MAXSTR) :: cpl_inst_tag ! instance tag character(ESMF_MAXSTR) :: restart_dir ! Optional restart directory name character(ESMF_MAXSTR) :: cvalue ! attribute string + character(ESMF_MAXSTR) :: cpl_inst_tag ! instance tag logical :: alarmIsOn ! generic alarm flag real(R8) :: tbnds(2) ! CF1.0 time bounds logical :: isPresent @@ -197,14 +197,6 @@ subroutine med_phases_restart_write(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - 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=cpl_inst_tag, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - cpl_inst_tag = "" - endif call NUOPC_CompAttributeGet(gcomp, name='restart_dir', isPresent=isPresent, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if(isPresent) then @@ -296,12 +288,20 @@ subroutine med_phases_restart_write(gcomp, rc) ! Use nexttimestr rather than currtimestr here since that is the time at the end of ! the timestep and is preferred for restart file names !--------------------------------------- + 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=cpl_inst_tag, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + cpl_inst_tag = "" + endif write(restart_file,"(6a)") trim(restart_dir)//trim(case_name),'.cpl', trim(cpl_inst_tag),'.r.',& trim(nexttimestr),'.nc' if (maintask) then - restart_pfile = "rpointer.cpl"//trim(cpl_inst_tag) + call shr_get_rpointer_name(gcomp, 'cpl', next_ymd, next_tod, restart_pfile, 'write', rc) 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) @@ -480,13 +480,14 @@ subroutine med_phases_restart_read(gcomp, rc) ! Read mediator restart - use ESMF , only : ESMF_GridComp, ESMF_VM, ESMF_Clock, ESMF_Time, ESMF_MAXSTR - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_VMBroadCast - use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_ClockPrint - use ESMF , only : ESMF_FieldBundleIsCreated, ESMF_TimeGet - use NUOPC , only : NUOPC_CompAttributeGet - use med_io_mod , only : med_io_read + use ESMF , only : ESMF_GridComp, ESMF_VM, ESMF_Clock, ESMF_Time, ESMF_MAXSTR + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_VMBroadCast + use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_ClockPrint + use ESMF , only : ESMF_FieldBundleIsCreated, ESMF_TimeGet + use NUOPC , only : NUOPC_CompAttributeGet + use med_io_mod , only : med_io_read + use nuopc_shr_methods, only : shr_get_rpointer_name ! Input/output variables type(ESMF_GridComp) :: gcomp @@ -501,10 +502,10 @@ subroutine med_phases_restart_read(gcomp, rc) integer :: n integer :: ierr, unitn integer :: yr,mon,day,sec ! time units + integer :: curr_ymd character(ESMF_MAXSTR) :: case_name ! case name character(ESMF_MAXSTR) :: restart_file ! Local path to restart filename character(ESMF_MAXSTR) :: restart_pfile ! Local path to restart pointer filename - character(ESMF_MAXSTR) :: cpl_inst_tag ! instance tag logical :: isPresent character(len=*), parameter :: subname='(med_phases_restart_read)' !--------------------------------------- @@ -520,14 +521,6 @@ subroutine med_phases_restart_read(gcomp, rc) ! Get case name and inst suffix call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - 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=cpl_inst_tag, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - cpl_inst_tag = "" - endif ! Get the clock info call ESMF_GridCompGet(gcomp, clock=clock) @@ -536,6 +529,8 @@ subroutine med_phases_restart_read(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ymd2date(yr,mon,day,curr_ymd) + write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec if (dbug_flag > 1) then call ESMF_LogWrite(trim(subname)//": currtime = "//trim(currtimestr), ESMF_LOGMSG_INFO) @@ -546,8 +541,8 @@ 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) if (maintask) then + call shr_get_rpointer_name(gcomp, 'cpl', curr_ymd, sec, restart_pfile, 'read', rc) 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) read (unitn,'(a)', iostat=ierr) restart_file