Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'valid time' variable using ISO string format #492

Merged
merged 15 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ccpp/physics
6 changes: 4 additions & 2 deletions io/inline_post_stub.F90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module inline_post

contains

subroutine inline_post_run(wrt_int_state,mypei,mpicomp,lead_write, &
subroutine inline_post_run(wrt_int_state,grid_id,mypei,mpicomp,lead_write, &
mynfhr,mynfmin,mynfsec)
!
! revision history:
Expand All @@ -28,6 +28,7 @@ subroutine inline_post_run(wrt_int_state,mypei,mpicomp,lead_write, &
!
type(wrt_internal_state),intent(in) :: wrt_int_state
integer,intent(in) :: mypei
integer,intent(in) :: grid_id
integer,intent(in) :: mpicomp
integer,intent(in) :: lead_write
integer,intent(in) :: mynfhr
Expand All @@ -40,11 +41,12 @@ end subroutine inline_post_run
!
!-----------------------------------------------------------------------
!
subroutine inline_post_getattr(wrt_int_state)
subroutine inline_post_getattr(wrt_int_state,grid_id)
!
implicit none
!
type(wrt_internal_state),intent(inout) :: wrt_int_state
integer,intent(in) :: grid_id
!
!
print *,'in stub inline_post_getattr - not supported on this machine, return'
Expand Down
3 changes: 0 additions & 3 deletions io/module_write_internal_state.F90
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ module write_internal_state
!-------------------------------------
!
type(ESMF_Time) :: io_basetime
type(ESMF_TimeInterval) :: io_currtimediff
real :: nfhour
integer :: idate(7)
integer :: fdate(7)
!
Expand All @@ -89,7 +87,6 @@ module write_internal_state
!-----------------------------------------
!
logical :: output_history
logical :: write_netcdfflag
!
!-----------------------------------------
!*** POST flags and required variables
Expand Down
19 changes: 16 additions & 3 deletions io/module_write_netcdf.F90
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ subroutine write_netcdf(wrtfb, filename, &
integer :: ncerr,ierr
integer :: ncid
integer :: oldMode
integer :: im_dimid, jm_dimid, tile_dimid, pfull_dimid, phalf_dimid, time_dimid
integer :: im_varid, jm_varid, tile_varid, lon_varid, lat_varid
integer :: im_dimid, jm_dimid, tile_dimid, pfull_dimid, phalf_dimid, time_dimid, ch_dimid
integer :: im_varid, jm_varid, tile_varid, lon_varid, lat_varid, timeiso_varid
integer, dimension(:), allocatable :: dimids_2d, dimids_3d
integer, dimension(:), allocatable :: varids
logical shuffle
Expand Down Expand Up @@ -213,6 +213,7 @@ subroutine write_netcdf(wrtfb, filename, &
! define dimensions [grid_xt, grid_yta ,(pfull/phalf), (tile), time]
ncerr = nf90_def_dim(ncid, "grid_xt", im, im_dimid); NC_ERR_STOP(ncerr)
ncerr = nf90_def_dim(ncid, "grid_yt", jm, jm_dimid); NC_ERR_STOP(ncerr)
ncerr = nf90_def_dim(ncid, "nchars", 20, ch_dimid); NC_ERR_STOP(ncerr)
if (lm > 1) then
call add_dim(ncid, "pfull", pfull_dimid, wrtgrid, rc)
call add_dim(ncid, "phalf", phalf_dimid, wrtgrid, rc)
Expand All @@ -229,9 +230,13 @@ subroutine write_netcdf(wrtfb, filename, &
ncerr = nf90_put_att(ncid, jm_varid, "cartesian_axis", "Y"); NC_ERR_STOP(ncerr)
if (is_cubed_sphere) then
ncerr = nf90_def_var(ncid, "tile", NF90_INT, tile_dimid, tile_varid); NC_ERR_STOP(ncerr)
ncerr = nf90_put_att(ncid, tile_varid, "long_name", "cubed-spehere face"); NC_ERR_STOP(ncerr)
ncerr = nf90_put_att(ncid, tile_varid, "long_name", "cubed-sphere face"); NC_ERR_STOP(ncerr)
end if

ncerr = nf90_def_var(ncid, "time_iso", NF90_CHAR, [ch_dimid,time_dimid], timeiso_varid); NC_ERR_STOP(ncerr)
ncerr = nf90_put_att(ncid, timeiso_varid, "long_name", "valid time"); NC_ERR_STOP(ncerr)
ncerr = nf90_put_att(ncid, timeiso_varid, "description", "ISO 8601 datetime string"); NC_ERR_STOP(ncerr)

! coordinate variable attributes based on output_grid type
if (trim(output_grid(grid_id)) == 'gaussian_grid' .or. &
trim(output_grid(grid_id)) == 'global_latlon' .or. &
Expand Down Expand Up @@ -275,6 +280,7 @@ subroutine write_netcdf(wrtfb, filename, &
ncerr = nf90_var_par_access(ncid, lon_varid, NF90_INDEPENDENT); NC_ERR_STOP(ncerr)
ncerr = nf90_var_par_access(ncid, jm_varid, NF90_INDEPENDENT); NC_ERR_STOP(ncerr)
ncerr = nf90_var_par_access(ncid, lat_varid, NF90_INDEPENDENT); NC_ERR_STOP(ncerr)
ncerr = nf90_var_par_access(ncid, timeiso_varid, NF90_INDEPENDENT); NC_ERR_STOP(ncerr)
if (is_cubed_sphere) then
ncerr = nf90_var_par_access(ncid, tile_varid, NF90_INDEPENDENT); NC_ERR_STOP(ncerr)
end if
Expand Down Expand Up @@ -560,6 +566,13 @@ subroutine write_netcdf(wrtfb, filename, &
ncerr = nf90_put_var(ncid, tile_varid, values=[1,2,3,4,5,6]); NC_ERR_STOP(ncerr)
end if

! write time_iso (timeiso_varid)
if (do_io) then
call ESMF_AttributeGet(wrtgrid, convention="NetCDF", purpose="FV3", &
name="time_iso", value=varcval, rc=rc); ESMF_ERR_RETURN(rc)
ncerr = nf90_put_var(ncid, timeiso_varid, values=[trim(varcval)]); NC_ERR_STOP(ncerr)
end if

! write variables (fields)
do i=1, fieldCount

Expand Down
76 changes: 24 additions & 52 deletions io/module_wrt_grid_comp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1368,12 +1368,6 @@ subroutine wrt_initialize(wrt_comp, imp_state_write, exp_state_write, clock, rc)
deallocate(attNameList, attNameList2, typekindList)
!
!-----------------------------------------------------------------------
!*** SET THE FIRST HISTORY FILE'S TIME INDEX.
!-----------------------------------------------------------------------
!
wrt_int_state%NFHOUR = 0
!
!-----------------------------------------------------------------------
!*** Initialize for POST
!-----------------------------------------------------------------------
!
Expand Down Expand Up @@ -1410,6 +1404,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
TYPE(ESMF_VM) :: VM
type(ESMF_FieldBundle) :: file_bundle
type(ESMF_Time) :: currtime
type(ESMF_TimeInterval) :: io_currtimediff
type(ESMF_Grid) :: fbgrid, wrtGrid
type(ESMF_State),save :: stateGridFB
type(optimizeT), save :: optimize(4)
Expand All @@ -1420,8 +1415,8 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
!
integer :: i,j,n,mype,nolog, grid_id
!
integer :: nf_hours,nf_seconds, nf_minutes, &
nseconds,nseconds_num,nseconds_den
integer :: nf_hours,nf_seconds,nf_minutes
real(ESMF_KIND_R8) :: nfhour
!
integer :: nbdl, date(6), ndig, nnnn
integer :: step=1
Expand All @@ -1431,7 +1426,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
!
character(esmf_maxstr) :: filename,compname
character(40) :: cfhour, cform
real(ESMF_KIND_R8) :: time
character(20) :: time_iso
!
real(kind=8) :: MPI_Wtime
real(kind=8) :: tbeg
Expand Down Expand Up @@ -1475,67 +1470,39 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
!*** get current time and elapsed forecast time

call ESMF_ClockGet(clock=CLOCK, currTime=CURRTIME, rc=rc)

if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

call ESMF_TimeGet(time=currTime,yy=date(1),mm=date(2),dd=date(3),h=date(4), &
m=date(5),s=date(6),rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

wrt_int_state%fdate(7) = 1
wrt_int_state%fdate(1:6) = date(1:6)
write(time_iso,'(I4,"-",I2.2,"-",I2.2,"T",I2.2,":",I2.2,":",I2.2,"Z")') date(1:6)

if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
! if(mype == lead_write_task) print *,'in wrt run, curr time=',date
!
call ESMF_TimeGet(time=wrt_int_state%IO_BASETIME,yy=date(1),mm=date(2),dd=date(3),h=date(4), &
m=date(5),s=date(6),rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

io_currtimediff = currtime - wrt_int_state%IO_BASETIME

call ESMF_TimeIntervalGet(timeinterval=io_currtimediff &
,h_r8=nfhour,h=nf_hours,m=nf_minutes,s=nf_seconds,rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
! print *,'in wrt run, io_baseline time=',date
!
wrt_int_state%IO_CURRTIMEDIFF = CURRTIME-wrt_int_state%IO_BASETIME
!
call ESMF_TimeIntervalGet(timeinterval=wrt_int_state%IO_CURRTIMEDIFF &
,h =nf_hours & !<-- Hours of elapsed time
,m =nf_minutes & !<-- Minutes of elapsed time
,s =nseconds & !<-- Seconds of elapsed time
,sN =nseconds_num & !<-- Numerator of fractional elapsed seconds
,sD =nseconds_den & !<-- denominator of fractional elapsed seconds
,rc =RC)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
! if (lprnt) print *,'in wrt run, nf_hours=',nf_hours,nf_minutes,nseconds, &
! 'nseconds_num=',nseconds_num,nseconds_den,'mype=',mype
!
nf_seconds = nf_hours*3600+nf_minuteS*60+nseconds+real(nseconds_num)/real(nseconds_den)
wrt_int_state%nfhour = nf_seconds/3600.
nf_hours = int(nf_seconds/3600.)
if(lprnt) print *,'in write grid comp, nf_hours=',nf_hours
! if iau_offset > nf_hours, don't write out anything
if (nf_hours < 0) return

nf_minutes = int((nf_seconds-nf_hours*3600.)/60.)
nseconds = int(nf_seconds-nf_hours*3600.-nf_minutes*60.)
if (nsout > 0 .or. lflname_fulltime) then
ndig = max(log10(nf_hours+0.5)+1., 3.)
write(cform, '("(I",I1,".",I1,",A1,I2.2,A1,I2.2)")') ndig, ndig
write(cfhour, cform) nf_hours,'-',nf_minutes,'-',nseconds
write(cfhour, cform) nf_hours,'-',nf_minutes,'-',nf_seconds
else
ndig = max(log10(nf_hours+0.5)+1., 3.)
write(cform, '("(I",I1,".",I1,")")') ndig, ndig
write(cfhour, cform) nf_hours
endif
!
if(lprnt) print *,'in wrt run, nf_hours=',nf_hours,nf_minutes,nseconds, &
'nseconds_num=',nseconds_num,nseconds_den,' FBCount=',FBCount,' cfhour=',trim(cfhour)

! if(lprnt) print *,'in wrt run, cfhour=',cfhour, &
! print *,'in wrt run, cfhour=',cfhour, &
! ' nf_seconds=',nf_seconds,wrt_int_state%nfhour

! access the time Attribute which is updated by the driver each time
call ESMF_AttributeGet(imp_state_write, convention="NetCDF", purpose="FV3", &
name="time", value=time, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

if(lprnt) print *,'in wrt run, nfhour=',nfhour,' cfhour=',trim(cfhour)
!
!-----------------------------------------------------------------------
!*** loop on the files that need to write out
Expand Down Expand Up @@ -1570,7 +1537,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
endif

call inline_post_run(wrt_int_state, 1, mype, wrt_mpi_comm, lead_write_task, &
nf_hours, nf_minutes,nseconds)
nf_hours, nf_minutes, nf_seconds)
wend = MPI_Wtime()
if (lprnt) then
write(*,'(A,F10.5,A,I4.2,A,I2.2)')' actual inline post Time is ',wend-wbeg &
Expand Down Expand Up @@ -1649,7 +1616,12 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

call ESMF_AttributeSet(fbgrid, convention="NetCDF", purpose="FV3", &
name="time", value=real(wrt_int_state%nfhour,ESMF_KIND_R8), rc=rc)
name="time", value=nfhour, rc=rc)

if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

call ESMF_AttributeSet(fbgrid, convention="NetCDF", purpose="FV3", &
name="time_iso", value=trim(time_iso), rc=rc)

if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

Expand Down Expand Up @@ -1765,7 +1737,7 @@ subroutine wrt_run(wrt_comp, imp_state_write, exp_state_write,clock,rc)
enddo
!
open(nolog,file='logf'//trim(cfhour),form='FORMATTED')
write(nolog,100)wrt_int_state%nfhour,idate(1:6)
write(nolog,100)nfhour,idate(1:6)
100 format(' completed fv3gfs fhour=',f10.3,2x,6(i4,2x))
close(nolog)
endif
Expand Down
32 changes: 20 additions & 12 deletions module_fcst_grid_comp.F90
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,6 @@ subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc)

integer,dimension(6) :: date, date_end
!
character(len=9) :: month
integer :: initClock, unit, total_inttime
integer :: mype
character(4) dateSY
Expand Down Expand Up @@ -590,17 +589,7 @@ subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc)
! if there is restart writing during integration
intrm_rst = 0
if (frestart(1)>0) intrm_rst = 1
!
!----- write time stamps (for start time and end time) ------

call mpp_open( unit, 'time_stamp.out', nohdrs=.TRUE. )
month = month_name(date(2))
if ( mpp_pe() == mpp_root_pe() ) write (unit,20) date, month(1:3)
month = month_name(date_end(2))
if ( mpp_pe() == mpp_root_pe() ) write (unit,20) date_end, month(1:3)
call mpp_close (unit)
20 format (6i4,2x,a3)
!
!------ initialize component models ------

call atmos_model_init (Atmos, Time_init, Time, Time_step)
Expand Down Expand Up @@ -829,7 +818,26 @@ subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc)
call ESMF_AttributeSet(exportState, convention="NetCDF", purpose="FV3", &
name="time:calendar", value=uppercase(trim(calendar)), rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
!

! Add time_iso Attribute to the exportState
call ESMF_AttributeAdd(exportState, convention="NetCDF", purpose="FV3", &
attrList=(/ "time_iso ", &
"time_iso:long_name ", &
"time_iso:description " /), rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

call ESMF_AttributeSet(exportState, convention="NetCDF", purpose="FV3", &
name="time_iso", value="yyyy-mm-ddThh:mm:ssZ", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

call ESMF_AttributeSet(exportState, convention="NetCDF", purpose="FV3", &
name="time_iso:description", value="ISO 8601 Date String", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

call ESMF_AttributeSet(exportState, convention="NetCDF", purpose="FV3", &
name="time_iso:long_name", value="valid time", rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

! Create FieldBundle for Fields that need to be regridded bilinear
if( quilting ) then

Expand Down