From 4e2565382e52eab5e75846f1a05b668ee3b08604 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 10 Sep 2024 08:31:19 -0600 Subject: [PATCH 1/3] add timestamp to rpointer files --- src/control/cam_comp.F90 | 14 +++++++++++--- src/control/cam_initfiles.F90 | 27 +++++++++++++++++---------- src/control/cam_restart.F90 | 32 +++++++++++++++++++------------- src/control/runtime_opts.F90 | 6 +++--- src/cpl/nuopc/atm_comp_nuopc.F90 | 3 +++ 5 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/control/cam_comp.F90 b/src/control/cam_comp.F90 index a040762067..561129c3db 100644 --- a/src/control/cam_comp.F90 +++ b/src/control/cam_comp.F90 @@ -16,7 +16,7 @@ module cam_comp use spmd_utils, only: masterproc, mpicom use cam_control_mod, only: cam_ctrl_init, cam_ctrl_set_orbit use runtime_opts, only: read_namelist -use time_manager, only: timemgr_init, get_nstep +use time_manager, only: timemgr_init, get_nstep, get_curr_date use camsrfexch, only: cam_out_t, cam_in_t use ppgrid, only: begchunk, endchunk use physics_types, only: physics_state, physics_tend @@ -122,11 +122,11 @@ subroutine cam_init( & integer, intent(in) :: stop_tod ! Stop time of day (sec) integer, intent(in) :: ref_ymd ! Reference date (YYYYMMDD) integer, intent(in) :: ref_tod ! Reference time of day (sec) - type(cam_out_t), pointer :: cam_out(:) ! Output from CAM to surface type(cam_in_t) , pointer :: cam_in(:) ! Merged input state to CAM ! Local variables + integer :: yr, mon, day, tod character(len=cs) :: filein ! Input namelist filename !----------------------------------------------------------------------- @@ -152,7 +152,15 @@ subroutine cam_init( & ! Read CAM namelists. filein = "atm_in" // trim(inst_suffix) - call read_namelist(filein, single_column, scmlat, scmlon) + call get_curr_date(yr, mon, day, tod) + if(len_trim(inst_suffix) > 0) then + restart_pointer_file = interpret_filename_spec("rpointer.cam."//trim(inst_suffix)//".%y-%m-%d-%s", & + yr=yr_spec, mon=mon_spec, day=day_spec, tod= sec_spec ) + else + restart_pointer_file = interpret_filename_spec("rpointer.cam.%y-%m-%d-%s", & + yr=yr_spec, mon=mon_spec, day=day_spec, tod= sec_spec ) + endif + call read_namelist(filein, single_column, scmlat, scmlon, restart_pointer_file=restart_pointer_file) ! Open initial or restart file, and topo file if specified. call cam_initfiles_open() diff --git a/src/control/cam_initfiles.F90 b/src/control/cam_initfiles.F90 index 3b48f1ab0e..6c67125c8d 100644 --- a/src/control/cam_initfiles.F90 +++ b/src/control/cam_initfiles.F90 @@ -42,10 +42,6 @@ module cam_initfiles real(r8), public, protected :: scale_dry_air_mass = 0.0_r8 ! Toggle and target avg air mass for MPAS dycore -! The restart pointer file contains name of most recently written primary restart file. -! The contents of this file are updated by cam_write_restart as new restart files are written. -character(len=cl), public, protected :: rest_pfile - ! Filename for initial restart file. character(len=cl) :: restart_file = ' ' @@ -61,7 +57,7 @@ module cam_initfiles contains !======================================================================================== -subroutine cam_initfiles_readnl(nlfile) +subroutine cam_initfiles_readnl(nlfile, restart_pointer_file) use namelist_utils, only: find_group_name use units, only: getunit, freeunit @@ -70,7 +66,7 @@ subroutine cam_initfiles_readnl(nlfile) use cam_instance, only: inst_suffix character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input - + character(len=*), optional, intent(in) :: restart_pointer_file ! Local variables integer :: unitn, ierr @@ -78,6 +74,10 @@ subroutine cam_initfiles_readnl(nlfile) logical :: filefound integer :: xtype integer(pio_offset_kind) :: slen + logical :: found + + ! The restart pointer file contains name of most recently written primary restart file. + character(len=cl) :: rest_pfile character(len=*), parameter :: sub = 'cam_initfiles_readnl' @@ -112,18 +112,25 @@ subroutine cam_initfiles_readnl(nlfile) call mpi_bcast(scale_dry_air_mass, 1, mpir8, mstrid, mpicom, ierr) if (ierr /= 0) call endrun(sub//": ERROR: mpi_bcast: scale_dry_air_mass") - ! Set pointer file name based on instance suffix - rest_pfile = './rpointer.atm' // trim(inst_suffix) - + if(present(restart_pointer_file)) then + rest_pfile = restart_pointer_file + else + ! Set pointer file name based on instance suffix + rest_pfile = './rpointer.atm' // trim(inst_suffix) + endif ! Set name of primary restart file if (restart_run) then ! Read name of restart file from pointer file if (masterproc) then + inquire(file=trim(rest_pfile),exist=found) + if(.not. found) then + call endrun(sub // ': ERROR: rpointer file: '//trim(rest_pfile) // ' not found') + endif unitn = getunit() call opnfil(rest_pfile, unitn, 'f', status="old") read (unitn, '(a)', iostat=ierr) restart_file if (ierr /= 0) then - call endrun(sub // ': ERROR: reading rpointer file') + call endrun(sub // ': ERROR: reading rpointer file: '//trim(rest_pfile)) end if close(unitn) call freeunit(unitn) diff --git a/src/control/cam_restart.F90 b/src/control/cam_restart.F90 index 124cf3b4b5..41463c71f9 100644 --- a/src/control/cam_restart.F90 +++ b/src/control/cam_restart.F90 @@ -132,38 +132,44 @@ subroutine cam_write_restart(cam_in, cam_out, dyn_out, pbuf2d, & call ionosphere_write_restart(fh) call write_restart_physics(fh, cam_in, cam_out, pbuf2d) - if (present(yr_spec).and.present(mon_spec).and.& - present(day_spec).and.present(sec_spec)) then - call write_restart_history(fh, yr_spec=yr_spec, mon_spec=mon_spec, & - day_spec=day_spec, sec_spec= sec_spec ) - else - call write_restart_history(fh) - end if + call write_restart_history(fh, yr_spec=yr_spec, mon_spec=mon_spec, & + day_spec=day_spec, sec_spec= sec_spec ) ! Close the primary restart file call pio_closefile(fh) ! Update the restart pointer file - call write_rest_pfile(fname) + call write_rest_pfile(fname, yr_spec=yr_spec, mon_spec=mon_spec, & + day_spec=day_spec, sec_spec= sec_spec ) end subroutine cam_write_restart !======================================================================================== -subroutine write_rest_pfile(restart_file) +subroutine write_rest_pfile(restart_file, yr_spec, mon_spec, day_spec, sec_spec) ! Write the restart pointer file - - use cam_initfiles, only: rest_pfile - + use cam_instance, only: inst_suffix + use filenames, only: interpret_filename_spec character(len=*), intent(in) :: restart_file + integer, optional, intent(in) :: yr_spec ! Simulation year + integer, optional, intent(in) :: mon_spec ! Simulation month + integer, optional, intent(in) :: day_spec ! Simulation day + integer, optional, intent(in) :: sec_spec ! Seconds into current simulation day integer :: nsds, ierr + character(len=CL) :: rest_pfile character(len=*), parameter :: sub='write_rest_pfile' !--------------------------------------------------------------------------- if (masterproc) then - + if(inst_suffix .ne. "") then + rest_pfile = interpret_filename_spec('rpointer.cpl.%y-%m-%d-%s',& + yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) + else + rest_pfile = interpret_filename_spec('rpointer.cpl.'//trim(inst_suffix)//'.'//'%y-%m-%d-%s',& + yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) + endif nsds = getunit() call opnfil(rest_pfile, nsds, 'f') rewind nsds diff --git a/src/control/runtime_opts.F90 b/src/control/runtime_opts.F90 index 915664cdb9..0a8c48b509 100644 --- a/src/control/runtime_opts.F90 +++ b/src/control/runtime_opts.F90 @@ -19,7 +19,7 @@ module runtime_opts contains !======================================================================= -subroutine read_namelist(nlfilename, single_column, scmlat, scmlon) +subroutine read_namelist(nlfilename, single_column, scmlat, scmlon, restart_pointer_file) use cam_initfiles, only: cam_initfiles_readnl use constituents, only: cnst_readnl @@ -109,7 +109,7 @@ subroutine read_namelist(nlfilename, single_column, scmlat, scmlon) logical, intent(in) :: single_column real(r8), intent(in) :: scmlat real(r8), intent(in) :: scmlon - + character(len=*), optional, intent(in) :: restart_pointer_file !---------------------------Local variables----------------------------- character(len=*), parameter :: subname = "read_namelist" @@ -133,7 +133,7 @@ subroutine read_namelist(nlfilename, single_column, scmlat, scmlon) !++bee 13 Oct 2015, need to fix the pbuf_global_allocate functionality, then ! can uncomment the pbuf_readnl line ! call pbuf_readnl(nlfilename) - call cam_initfiles_readnl(nlfilename) + call cam_initfiles_readnl(nlfilename, restart_pointer_file=restart_pointer_file) call cnst_readnl(nlfilename) call history_readnl(nlfilename) call chem_surfvals_readnl(nlfilename) diff --git a/src/cpl/nuopc/atm_comp_nuopc.F90 b/src/cpl/nuopc/atm_comp_nuopc.F90 index 8b2ba903d0..927a300bae 100644 --- a/src/cpl/nuopc/atm_comp_nuopc.F90 +++ b/src/cpl/nuopc/atm_comp_nuopc.F90 @@ -1976,6 +1976,9 @@ subroutine cam_write_clockrest( clock, yr_spec, mon_spec, day_spec, sec_spec, rc yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) if (masterproc) then + restart_pfile = interpret_filename_spec('rpointer.cpl.%y-%m-%d-%s',& + yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) + write(iulog,*) " In this configuration, there is no mediator" write(iulog,*) " Normally, the mediator restart file provides the restart time info" write(iulog,*) " In this case, CAM will create the rpointer.cpl and cpl restart file" From 2cae3268f93b0f9673d0de976b40aab6b912fed9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Tue, 10 Sep 2024 15:23:27 -0600 Subject: [PATCH 2/3] add rpointer timestamp to cam --- src/control/cam_comp.F90 | 13 ++++++++----- src/control/cam_restart.F90 | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/control/cam_comp.F90 b/src/control/cam_comp.F90 index 561129c3db..66adf3b614 100644 --- a/src/control/cam_comp.F90 +++ b/src/control/cam_comp.F90 @@ -16,7 +16,7 @@ module cam_comp use spmd_utils, only: masterproc, mpicom use cam_control_mod, only: cam_ctrl_init, cam_ctrl_set_orbit use runtime_opts, only: read_namelist -use time_manager, only: timemgr_init, get_nstep, get_curr_date +use time_manager, only: timemgr_init, get_nstep, get_prev_date use camsrfexch, only: cam_out_t, cam_in_t use ppgrid, only: begchunk, endchunk use physics_types, only: physics_state, physics_tend @@ -87,7 +87,7 @@ subroutine cam_init( & use cam_snapshot_common, only: cam_snapshot_deactivate use air_composition, only: air_composition_init use phys_grid_ctem, only: phys_grid_ctem_reg - + use filenames, only: interpret_filename_spec ! Arguments character(len=cl), intent(in) :: caseid ! case ID character(len=cl), intent(in) :: ctitle ! case title @@ -126,6 +126,7 @@ subroutine cam_init( & type(cam_in_t) , pointer :: cam_in(:) ! Merged input state to CAM ! Local variables + character(len=cl) :: restart_pointer_file integer :: yr, mon, day, tod character(len=cs) :: filein ! Input namelist filename !----------------------------------------------------------------------- @@ -152,14 +153,16 @@ subroutine cam_init( & ! Read CAM namelists. filein = "atm_in" // trim(inst_suffix) - call get_curr_date(yr, mon, day, tod) + call get_prev_date(yr, mon, day, tod) if(len_trim(inst_suffix) > 0) then restart_pointer_file = interpret_filename_spec("rpointer.cam."//trim(inst_suffix)//".%y-%m-%d-%s", & - yr=yr_spec, mon=mon_spec, day=day_spec, tod= sec_spec ) + yr_spec=yr, mon_spec=mon, day_spec=day, sec_spec=tod ) else restart_pointer_file = interpret_filename_spec("rpointer.cam.%y-%m-%d-%s", & - yr=yr_spec, mon=mon_spec, day=day_spec, tod= sec_spec ) + yr_spec=yr, mon_spec=mon, day_spec=day, sec_spec=tod ) + endif + print *,__FILE__,__LINE__,trim(restart_pointer_file) call read_namelist(filein, single_column, scmlat, scmlon, restart_pointer_file=restart_pointer_file) ! Open initial or restart file, and topo file if specified. diff --git a/src/control/cam_restart.F90 b/src/control/cam_restart.F90 index 41463c71f9..02cb97b8c5 100644 --- a/src/control/cam_restart.F90 +++ b/src/control/cam_restart.F90 @@ -163,11 +163,11 @@ subroutine write_rest_pfile(restart_file, yr_spec, mon_spec, day_spec, sec_spec) !--------------------------------------------------------------------------- if (masterproc) then - if(inst_suffix .ne. "") then - rest_pfile = interpret_filename_spec('rpointer.cpl.%y-%m-%d-%s',& + if(len_trim(inst_suffix) > 0) then + rest_pfile = interpret_filename_spec('rpointer.cam.'//trim(inst_suffix)//'.'//'%y-%m-%d-%s',& yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) else - rest_pfile = interpret_filename_spec('rpointer.cpl.'//trim(inst_suffix)//'.'//'%y-%m-%d-%s',& + rest_pfile = interpret_filename_spec('rpointer.cam.%y-%m-%d-%s',& yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) endif nsds = getunit() From 2187227d08983d081291d9b9f6959962b96765e9 Mon Sep 17 00:00:00 2001 From: Jim Edwards Date: Thu, 12 Sep 2024 07:27:50 -0600 Subject: [PATCH 3/3] simplify rpointer naming --- src/control/cam_comp.F90 | 15 ++------------- src/control/cam_initfiles.F90 | 22 +++++++++++----------- src/control/cam_restart.F90 | 17 ++++------------- src/control/runtime_opts.F90 | 5 ++--- 4 files changed, 19 insertions(+), 40 deletions(-) diff --git a/src/control/cam_comp.F90 b/src/control/cam_comp.F90 index 66adf3b614..3eb94f041a 100644 --- a/src/control/cam_comp.F90 +++ b/src/control/cam_comp.F90 @@ -16,7 +16,7 @@ module cam_comp use spmd_utils, only: masterproc, mpicom use cam_control_mod, only: cam_ctrl_init, cam_ctrl_set_orbit use runtime_opts, only: read_namelist -use time_manager, only: timemgr_init, get_nstep, get_prev_date +use time_manager, only: timemgr_init, get_nstep use camsrfexch, only: cam_out_t, cam_in_t use ppgrid, only: begchunk, endchunk use physics_types, only: physics_state, physics_tend @@ -126,8 +126,6 @@ subroutine cam_init( & type(cam_in_t) , pointer :: cam_in(:) ! Merged input state to CAM ! Local variables - character(len=cl) :: restart_pointer_file - integer :: yr, mon, day, tod character(len=cs) :: filein ! Input namelist filename !----------------------------------------------------------------------- @@ -153,17 +151,8 @@ subroutine cam_init( & ! Read CAM namelists. filein = "atm_in" // trim(inst_suffix) - call get_prev_date(yr, mon, day, tod) - if(len_trim(inst_suffix) > 0) then - restart_pointer_file = interpret_filename_spec("rpointer.cam."//trim(inst_suffix)//".%y-%m-%d-%s", & - yr_spec=yr, mon_spec=mon, day_spec=day, sec_spec=tod ) - else - restart_pointer_file = interpret_filename_spec("rpointer.cam.%y-%m-%d-%s", & - yr_spec=yr, mon_spec=mon, day_spec=day, sec_spec=tod ) - endif - print *,__FILE__,__LINE__,trim(restart_pointer_file) - call read_namelist(filein, single_column, scmlat, scmlon, restart_pointer_file=restart_pointer_file) + call read_namelist(filein, single_column, scmlat, scmlon) ! Open initial or restart file, and topo file if specified. call cam_initfiles_open() diff --git a/src/control/cam_initfiles.F90 b/src/control/cam_initfiles.F90 index 6c67125c8d..d44d5030e1 100644 --- a/src/control/cam_initfiles.F90 +++ b/src/control/cam_initfiles.F90 @@ -57,19 +57,19 @@ module cam_initfiles contains !======================================================================================== -subroutine cam_initfiles_readnl(nlfile, restart_pointer_file) +subroutine cam_initfiles_readnl(nlfile) use namelist_utils, only: find_group_name use units, only: getunit, freeunit use spmd_utils, only: mpicom, mstrid=>masterprocid, mpir8=>mpi_real8, & mpichar=>mpi_character, mpi_logical use cam_instance, only: inst_suffix - + use filenames, only: interpret_filename_spec + character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input - character(len=*), optional, intent(in) :: restart_pointer_file + ! Local variables integer :: unitn, ierr - character(len=cl) :: locfn logical :: filefound integer :: xtype @@ -112,19 +112,19 @@ subroutine cam_initfiles_readnl(nlfile, restart_pointer_file) call mpi_bcast(scale_dry_air_mass, 1, mpir8, mstrid, mpicom, ierr) if (ierr /= 0) call endrun(sub//": ERROR: mpi_bcast: scale_dry_air_mass") - if(present(restart_pointer_file)) then - rest_pfile = restart_pointer_file - else - ! Set pointer file name based on instance suffix - rest_pfile = './rpointer.atm' // trim(inst_suffix) - endif ! Set name of primary restart file if (restart_run) then ! Read name of restart file from pointer file if (masterproc) then + rest_pfile = interpret_filename_spec("rpointer.cam"//trim(inst_suffix)//".%y-%m-%d-%s", prev=.true.) inquire(file=trim(rest_pfile),exist=found) if(.not. found) then - call endrun(sub // ': ERROR: rpointer file: '//trim(rest_pfile) // ' not found') + write(iulog, "Warning : rpointer file "//trim(rest_pfile)//" not found.") + rest_pfile = "rpointer.cam"//trim(inst_suffix) + inquire(file=trim(rest_pfile),exist=found) + if(.not. found) then + call endrun(sub // ': ERROR: rpointer file: '//trim(rest_pfile) // ' not found') + endif endif unitn = getunit() call opnfil(rest_pfile, unitn, 'f', status="old") diff --git a/src/control/cam_restart.F90 b/src/control/cam_restart.F90 index 02cb97b8c5..35087aa89b 100644 --- a/src/control/cam_restart.F90 +++ b/src/control/cam_restart.F90 @@ -106,12 +106,8 @@ subroutine cam_write_restart(cam_in, cam_out, dyn_out, pbuf2d, & ! (%c = caseid, $y = year, $m = month, $d = day, $s = seconds in day, %t = number) rfilename_spec = '%c.cam' // trim(inst_suffix) //'.r.%y-%m-%d-%s.nc' - if (present(yr_spec).and.present(mon_spec).and.present(day_spec).and.present(sec_spec)) then - fname = interpret_filename_spec( rfilename_spec, & - yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) - else - fname = interpret_filename_spec( rfilename_spec ) - end if + fname = interpret_filename_spec( rfilename_spec, & + yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) call cam_pio_createfile(fh, trim(fname), 0) ierr = cam_pio_set_fill(fh) @@ -163,13 +159,8 @@ subroutine write_rest_pfile(restart_file, yr_spec, mon_spec, day_spec, sec_spec) !--------------------------------------------------------------------------- if (masterproc) then - if(len_trim(inst_suffix) > 0) then - rest_pfile = interpret_filename_spec('rpointer.cam.'//trim(inst_suffix)//'.'//'%y-%m-%d-%s',& - yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) - else - rest_pfile = interpret_filename_spec('rpointer.cam.%y-%m-%d-%s',& - yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) - endif + rest_pfile = interpret_filename_spec('rpointer.cam'//trim(inst_suffix)//'.'//'%y-%m-%d-%s',& + yr_spec=yr_spec, mon_spec=mon_spec, day_spec=day_spec, sec_spec= sec_spec ) nsds = getunit() call opnfil(rest_pfile, nsds, 'f') rewind nsds diff --git a/src/control/runtime_opts.F90 b/src/control/runtime_opts.F90 index 0a8c48b509..19cff5c884 100644 --- a/src/control/runtime_opts.F90 +++ b/src/control/runtime_opts.F90 @@ -19,7 +19,7 @@ module runtime_opts contains !======================================================================= -subroutine read_namelist(nlfilename, single_column, scmlat, scmlon, restart_pointer_file) +subroutine read_namelist(nlfilename, single_column, scmlat, scmlon) use cam_initfiles, only: cam_initfiles_readnl use constituents, only: cnst_readnl @@ -109,7 +109,6 @@ subroutine read_namelist(nlfilename, single_column, scmlat, scmlon, restart_poin logical, intent(in) :: single_column real(r8), intent(in) :: scmlat real(r8), intent(in) :: scmlon - character(len=*), optional, intent(in) :: restart_pointer_file !---------------------------Local variables----------------------------- character(len=*), parameter :: subname = "read_namelist" @@ -133,7 +132,7 @@ subroutine read_namelist(nlfilename, single_column, scmlat, scmlon, restart_poin !++bee 13 Oct 2015, need to fix the pbuf_global_allocate functionality, then ! can uncomment the pbuf_readnl line ! call pbuf_readnl(nlfilename) - call cam_initfiles_readnl(nlfilename, restart_pointer_file=restart_pointer_file) + call cam_initfiles_readnl(nlfilename) call cnst_readnl(nlfilename) call history_readnl(nlfilename) call chem_surfvals_readnl(nlfilename)