diff --git a/atmos_cubed_sphere b/atmos_cubed_sphere index 452333aff..0e84f88b4 160000 --- a/atmos_cubed_sphere +++ b/atmos_cubed_sphere @@ -1 +1 @@ -Subproject commit 452333aff37f4c4348504bb9d485d98072e984e5 +Subproject commit 0e84f88b494b9e0a4097da50abe6b143330e8a2f diff --git a/atmos_model.F90 b/atmos_model.F90 index 23e30e76c..34e1a6c99 100644 --- a/atmos_model.F90 +++ b/atmos_model.F90 @@ -113,7 +113,8 @@ module atmos_model_mod FV3GFS_diag_register, FV3GFS_diag_output, & DIAG_SIZE use fv_iau_mod, only: iau_external_data_type,getiauforcing,iau_initialize -use module_fv3_config, only: output_1st_tstep_rst, first_kdt, nsout +use module_fv3_config, only: output_1st_tstep_rst, first_kdt, nsout, & + frestart, restart_endfcst !----------------------------------------------------------------------- @@ -221,7 +222,8 @@ module atmos_model_mod logical,parameter :: flip_vc = .true. #endif - real(kind=IPD_kind_phys), parameter :: zero=0.0, one=1.0 + real(kind=IPD_kind_phys), parameter :: zero = 0.0_IPD_kind_phys, & + one = 1.0_IPD_kind_phys contains @@ -944,7 +946,7 @@ end subroutine update_atmos_model_state subroutine atmos_model_end (Atmos) type (atmos_data_type), intent(inout) :: Atmos !---local variables - integer :: idx + integer :: idx, seconds #ifdef CCPP integer :: ierr #endif @@ -952,9 +954,11 @@ subroutine atmos_model_end (Atmos) !----------------------------------------------------------------------- !---- termination routine for atmospheric model ---- - call atmosphere_end (Atmos % Time, Atmos%grid) - call FV3GFS_restart_write (IPD_Data, IPD_Restart, Atm_block, & - IPD_Control, Atmos%domain) + call atmosphere_end (Atmos % Time, Atmos%grid, restart_endfcst) + if(restart_endfcst) then + call FV3GFS_restart_write (IPD_Data, IPD_Restart, Atm_block, & + IPD_Control, Atmos%domain) + endif #ifdef CCPP ! Fast physics (from dynamics) are finalized in atmosphere_end above; @@ -1457,6 +1461,24 @@ subroutine update_atmos_chemistry(state, rc) enddo enddo + ! -- zero out accumulated fields +!$OMP parallel do default (none) & +!$OMP shared (nj, ni, Atm_block, IPD_Control, IPD_Data) & +!$OMP private (j, jb, i, ib, nb, ix) + do j = 1, nj + jb = j + Atm_block%jsc - 1 + do i = 1, ni + ib = i + Atm_block%isc - 1 + nb = Atm_block%blkno(ib,jb) + ix = Atm_block%ixp(ib,jb) + IPD_Data(nb)%coupling%rainc_cpl(ix) = zero + if (.not.IPD_Control%cplflx) then + IPD_Data(nb)%coupling%rain_cpl(ix) = zero + IPD_Data(nb)%coupling%snow_cpl(ix) = zero + end if + enddo + enddo + if (IPD_Control%debug) then ! -- diagnostics write(6,'("update_atmos: prsi - min/max/avg",3g16.6)') minval(prsi), maxval(prsi), sum(prsi)/size(prsi) diff --git a/fv3_cap.F90 b/fv3_cap.F90 index d04abdce2..a099ae32e 100644 --- a/fv3_cap.F90 +++ b/fv3_cap.F90 @@ -30,7 +30,7 @@ module fv3gfs_cap_mod calendar, calendar_type, cpl, & force_date_from_configure, & cplprint_flag,output_1st_tstep_rst, & - first_kdt + first_kdt,num_restart_interval use module_fv3_io_def, only: num_pes_fcst,write_groups,app_domain, & num_files, filename_base, & @@ -278,9 +278,16 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) CALL ESMF_ConfigLoadFile(config=CF ,filename='model_configure' ,rc=RC) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! - CALL ESMF_ConfigGetAttribute(config=CF,value=restart_interval, & - label ='restart_interval:',rc=rc) + num_restart_interval = ESMF_ConfigGetLen(config=CF, label ='restart_interval:',rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return + if(mype == 0) print *,'af nems config,num_restart_interval=',num_restart_interval + if (num_restart_interval<=0) num_restart_interval = 1 + allocate(restart_interval(num_restart_interval)) + restart_interval = 0 + CALL ESMF_ConfigGetAttribute(CF,valueList=restart_interval,label='restart_interval:', & + count=num_restart_interval, rc=RC) + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return + if(mype == 0) print *,'af nems config,restart_interval=',restart_interval ! CALL ESMF_ConfigGetAttribute(config=CF,value=calendar, & label ='calendar:',rc=rc) @@ -326,9 +333,8 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc) label ='app_domain:',rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return - if(mype == 0) print *,'af nems config,restart_interval=',restart_interval, & - 'quilting=',quilting,'write_groups=',write_groups,wrttasks_per_group, & - 'calendar=',trim(calendar),'calendar_type=',calendar_type + if(mype == 0) print *,'af nems config,quilting=',quilting,'write_groups=', & + write_groups,wrttasks_per_group,'calendar=',trim(calendar),'calendar_type=',calendar_type ! CALL ESMF_ConfigGetAttribute(config=CF,value=num_files, & label ='num_files:',rc=rc) diff --git a/gfsphysics/GFS_layer/GFS_driver.F90 b/gfsphysics/GFS_layer/GFS_driver.F90 index 3b6a94336..05f97bde8 100644 --- a/gfsphysics/GFS_layer/GFS_driver.F90 +++ b/gfsphysics/GFS_layer/GFS_driver.F90 @@ -422,7 +422,7 @@ subroutine GFS_initialize (Model, Statein, Stateout, Sfcprop, & call cires_ugwp_init(Model%me, Model%master, Model%nlunit, Init_parm%logunit, & Model%fn_nml, Model%lonr, Model%latr, Model%levs, & Init_parm%ak, Init_parm%bk, p_ref, Model%dtp, & - Model%cdmbgwd, Model%cgwf, Model%prslrd0, Model%ral_ts) + Model%cdmbgwd(1:2), Model%cgwf, Model%prslrd0, Model%ral_ts) endif #endif diff --git a/gfsphysics/GFS_layer/GFS_physics_driver.F90 b/gfsphysics/GFS_layer/GFS_physics_driver.F90 index 5b67f7faa..19c40bf24 100644 --- a/gfsphysics/GFS_layer/GFS_physics_driver.F90 +++ b/gfsphysics/GFS_layer/GFS_physics_driver.F90 @@ -3184,9 +3184,13 @@ subroutine GFS_physics_driver & dtdt(1:im,:) = Stateout%gt0(1:im,:) endif ! end if_ldiag3d/cnvgwd - if (Model%ldiag3d) then + if (Model%ldiag3d .or. Model%cplchm) then dqdt(1:im,:,1) = Stateout%gq0(1:im,:,1) - endif ! end if_ldiag3d + endif ! end if_ldiag3d/cplchm + + if (Model%cplchm) then + Coupling%dqdti(1:im,:) = zero + endif ! end if_cplchm #ifdef GFS_HYDRO call get_phi(im, ix, levs, ntrac, Stateout%gt0, Stateout%gq0, & diff --git a/gfsphysics/GFS_layer/GFS_radiation_driver.F90 b/gfsphysics/GFS_layer/GFS_radiation_driver.F90 index c7323d6bb..5215f1b2b 100644 --- a/gfsphysics/GFS_layer/GFS_radiation_driver.F90 +++ b/gfsphysics/GFS_layer/GFS_radiation_driver.F90 @@ -2116,18 +2116,40 @@ subroutine GFS_radiation_driver & Diag%fluxr(i,11-j) = Diag%fluxr(i,11-j) + tem0d * Statein%prsi(i,itop+kt) Diag%fluxr(i,14-j) = Diag%fluxr(i,14-j) + tem0d * Statein%prsi(i,ibtc+kb) Diag%fluxr(i,17-j) = Diag%fluxr(i,17-j) + tem0d * Statein%tgrs(i,itop) + enddo + enddo ! Anning adds optical depth and emissivity output - tem1 = 0. - tem2 = 0. - do k=ibtc,itop - tem1 = tem1 + cldtausw(i,k) ! approx .55 mu channel - tem2 = tem2 + cldtaulw(i,k) ! approx 10. mu channel + if (Model%lsswr .and. (nday > 0)) then + do j = 1, 3 + do i = 1, IM + tem0d = raddt * cldsa(i,j) + itop = mtopa(i,j) - kd + ibtc = mbota(i,j) - kd + tem1 = 0. + do k=ibtc,itop + tem1 = tem1 + cldtausw(i,k) ! approx .55 um channel + enddo + Diag%fluxr(i,43-j) = Diag%fluxr(i,43-j) + tem0d * tem1 enddo - Diag%fluxr(i,43-j) = Diag%fluxr(i,43-j) + tem0d * tem1 - Diag%fluxr(i,46-j) = Diag%fluxr(i,46-j) + tem0d * (1.0-exp(-tem2)) enddo - enddo + endif + + if (Model%lslwr) then + do j = 1, 3 + do i = 1, IM + tem0d = raddt * cldsa(i,j) + itop = mtopa(i,j) - kd + ibtc = mbota(i,j) - kd + tem2 = 0. + do k=ibtc,itop + tem2 = tem2 + cldtaulw(i,k) ! approx 10. um channel + enddo + Diag%fluxr(i,46-j) = Diag%fluxr(i,46-j) + tem0d * (1.0-exp(-tem2)) + enddo + enddo + endif + endif endif ! end_if_lssav diff --git a/gfsphysics/physics/sflx.f b/gfsphysics/physics/sflx.f index 29467fe37..f84006be9 100644 --- a/gfsphysics/physics/sflx.f +++ b/gfsphysics/physics/sflx.f @@ -251,6 +251,7 @@ subroutine sflx & runoff2 = 0.0 runoff3 = 0.0 snomlt = 0.0 + rc = 0.0 ! --- ... define local variable ice to achieve: ! sea-ice case, ice = 1 diff --git a/gfsphysics/physics/ugwp_driver_v0.f b/gfsphysics/physics/ugwp_driver_v0.f index 804bbac19..0ca37e818 100644 --- a/gfsphysics/physics/ugwp_driver_v0.f +++ b/gfsphysics/physics/ugwp_driver_v0.f @@ -46,7 +46,9 @@ subroutine cires_ugwp_driver_v0(me, master, &, rain real(kind=kind_phys), intent(in), dimension(im,levs) :: ugrs - &, vgrs, tgrs, qgrs, prsi, prsl, prslk, phii, phil, del + &, vgrs, tgrs, qgrs, prsl, prslk, phil, del + real(kind=kind_phys), intent(in), dimension(im,levs+1) :: prsi + &, phii ! real(kind=kind_phys), intent(in) :: oro_stat(im,nmtvr) real(kind=kind_phys), intent(in), dimension(im) :: hprime, oc diff --git a/io/FV3GFS_io.F90 b/io/FV3GFS_io.F90 index 4b2d1e426..e8c980f4d 100644 --- a/io/FV3GFS_io.F90 +++ b/io/FV3GFS_io.F90 @@ -157,10 +157,10 @@ subroutine FV3GFS_restart_write (IPD_Data, IPD_Restart, Atm_block, Model, fv_dom type(domain2d), intent(in) :: fv_domain character(len=32), optional, intent(in) :: timestamp - !--- read in surface data from chgres + !--- write surface data from chgres call sfc_prop_restart_write (IPD_Data%Sfcprop, Atm_block, Model, fv_domain, timestamp) - !--- read in physics restart data + !--- write physics restart data call phys_restart_write (IPD_Restart, Atm_block, Model, fv_domain, timestamp) end subroutine FV3GFS_restart_write diff --git a/io/post_gfs.F90 b/io/post_gfs.F90 index 9f3a0a80f..98d4fef50 100644 --- a/io/post_gfs.F90 +++ b/io/post_gfs.F90 @@ -12,6 +12,7 @@ module post_gfs include 'mpif.h' integer mype, nbdl + logical setvar_atmfile, setvar_sfcfile, read_postcntrl public post_run_gfs, post_getattr_gfs contains @@ -28,9 +29,10 @@ subroutine post_run_gfs(wrt_int_state,mypei,mpicomp,lead_write, & ! use ctlblk_mod, only : komax,ifhr,ifmin,modelname,datapd,fld_info, & npset,grib,gocart_on,icount_calmict, jsta, & - jend,im, nsoil + jend,im, nsoil, filenameflat use gridspec_mod, only : maptype, gridtype use grib2_module, only : gribit2,num_pset,nrecout,first_grbtbl + use xml_perl_data,only : paramset ! !----------------------------------------------------------------------- ! @@ -53,9 +55,8 @@ subroutine post_run_gfs(wrt_int_state,mypei,mpicomp,lead_write, & integer n,nwtpg,ieof,lcntrl,ierr,i,j,k,jts,jte,mynsoil integer,allocatable :: jstagrp(:),jendgrp(:) integer,save :: kpo,kth,kpv + logical,save :: log_postalct=.false. real,dimension(komax),save :: po, th, pv - logical,save :: log_postalct=.false. - logical,save :: setvar_atmfile=.false.,setvar_sfcfile=.false. logical :: Log_runpost character(255) :: post_fname*255 @@ -124,6 +125,7 @@ subroutine post_run_gfs(wrt_int_state,mypei,mpicomp,lead_write, & ! log_postalct = .true. first_grbtbl = .true. + read_postcntrl = .true. ! ENDIF ! @@ -135,6 +137,8 @@ subroutine post_run_gfs(wrt_int_state,mypei,mpicomp,lead_write, & ifmin = mynfmin if (ifhr == 0 ) ifmin = 0 if(mype==0) print *,'bf set_postvars,ifmin=',ifmin,'ifhr=',ifhr + setvar_atmfile=.false. + setvar_sfcfile=.false. call set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & setvar_sfcfile) @@ -145,8 +149,28 @@ subroutine post_run_gfs(wrt_int_state,mypei,mpicomp,lead_write, & ! 20190807 no need to call microinit for GFDLMP ! call MICROINIT ! - if(grib=="grib2" .and. first_grbtbl) then - call read_xml() + if(grib=="grib2" .and. read_postcntrl) then + if (ifhr == 0) then + filenameflat = 'postxconfig-NT_FH00.txt' + call read_xml() + if(mype==0) print *,'af read_xml at fh00,name=',trim(filenameflat) + else if(ifhr > 0) then + filenameflat = 'postxconfig-NT.txt' + if(size(paramset)>0) then + do i=1,size(paramset) + if (size(paramset(i)%param)>0) then + deallocate(paramset(i)%param) + nullify(paramset(i)%param) + endif + enddo + deallocate(paramset) + nullify(paramset) + endif + num_pset = 0 + call read_xml() + if(mype==0) print *,'af read_xml,name=',trim(filenameflat),'ifhr=',ifhr + read_postcntrl = .false. + endif endif ! IEOF = 0 @@ -181,9 +205,6 @@ subroutine post_run_gfs(wrt_int_state,mypei,mpicomp,lead_write, & endif ! enddo -! - setvar_atmfile = .false. - setvar_sfcfile = .false. ! endif @@ -335,7 +356,7 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & avgetrans, avgesnow, avgprec_cont, avgcprate_cont,& avisbeamswin, avisdiffswin, airbeamswin, airdiffswin, & alwoutc, alwtoac, aswoutc, aswtoac, alwinc, aswinc,& - avgpotevp, snoavg, si, cuppt + avgpotevp, snoavg, ti, si, cuppt use soil, only: sldpth, sh2o, smc, stc use masks, only: lmv, lmh, htm, vtm, gdlat, gdlon, dx, dy, hbm2, sm, sice use ctlblk_mod, only: im, jm, lm, lp1, jsta, jend, jsta_2l, jend_2u, jsta_m,jend_m, & @@ -477,6 +498,7 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & qs(i,j) = SPVAL twbs(i,j) = SPVAL qwbs(i,j) = SPVAL + ths(i,j) = SPVAL enddo enddo @@ -1122,9 +1144,30 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & !$omp parallel do private(i,j) do j=jsta,jend do i=ista, iend - sr(i,j) = arrayr42d(i,j) + if (arrayr42d(i,j) /= spval) then + !set range within (0,1) + sr(i,j) = min(1.,max(0.,sr(i,j))) + else + sr(i,j) = spval + endif + enddo + enddo + endif + + ! sea ice skin temperature + if(trim(fieldname)=='tisfc') then + !$omp parallel do private(i,j) + do j=jsta,jend + do i=1,im + if (arrayr42d(i,j) /= spval) then + ti(i,j) = arrayr42d(i,j) + if (sice(i,j) == spval .or. sice(i,j) == 0.) ti(i,j)=spval + else + ti(i,j) = spval + endif enddo enddo +! print *,'in gfs_post, get tisfc=',maxval(ti), minval(ti) endif ! vegetation fraction @@ -1237,7 +1280,8 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & do j=jsta,jend do i=ista, iend stc(i,j,1) = arrayr42d(i,j) - if (sm(i,j) /= 0.0) stc(i,j,1) = spval + !mask open water areas, combine with sea ice tmp + if (sm(i,j) /= 0.0 .and. sice(i,j) ==0.) stc(i,j,1) = spval enddo enddo endif @@ -1248,7 +1292,8 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & do j=jsta,jend do i=ista, iend stc(i,j,2) = arrayr42d(i,j) - if (sm(i,j) /= 0.0) stc(i,j,2) = spval + !mask open water areas, combine with sea ice tmp + if (sm(i,j) /= 0.0 .and. sice(i,j) ==0.) stc(i,j,2) = spval enddo enddo endif @@ -1259,7 +1304,8 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & do j=jsta,jend do i=ista, iend stc(i,j,3) = arrayr42d(i,j) - if (sm(i,j) /= 0.0) stc(i,j,3) = spval + !mask open water areas, combine with sea ice tmp + if (sm(i,j) /= 0.0 .and. sice(i,j) ==0.) stc(i,j,3) = spval enddo enddo endif @@ -1270,7 +1316,8 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & do j=jsta,jend do i=ista, iend stc(i,j,4) = arrayr42d(i,j) - if (sm(i,j) /= 0.0) stc(i,j,4) = spval + !mask open water areas, combine with sea ice tmp + if (sm(i,j) /= 0.0 .and. sice(i,j) ==0.) stc(i,j,4) = spval enddo enddo endif @@ -2313,6 +2360,12 @@ subroutine set_postvars_gfs(wrt_int_state,mpicomp,setvar_atmfile, & !$omp parallel do private(i,j) do j=jsta,jend do i=ista, iend + !assign sst + if (sm(i,j) /= 0.0 .and. ths(i,j) /= spval) then + sst(i,j) = ths(i,j) + else + sst(i,j) = spval + endif if (ths(i,j) /= spval) then ths(i,j) = ths(i,j)* (p1000/pint(i,j,lp1))**capa thz0(i,j) = ths(i,j) diff --git a/module_fcst_grid_comp.F90 b/module_fcst_grid_comp.F90 index 6ff1f39c7..fef9698ab 100644 --- a/module_fcst_grid_comp.F90 +++ b/module_fcst_grid_comp.F90 @@ -22,11 +22,12 @@ module module_fcst_grid_comp ! use time_manager_mod, only: time_type, set_calendar_type, set_time, & set_date, days_in_month, month_name, & - operator(+), operator (<), operator (>), & - operator (/=), operator (/), operator (==),& - operator (*), THIRTY_DAY_MONTHS, JULIAN, & - NOLEAP, NO_CALENDAR, date_to_string, & - get_date + operator(+), operator(-), operator (<), & + operator (>), operator (/=), operator (/), & + operator (==), operator (*), & + THIRTY_DAY_MONTHS, JULIAN, NOLEAP, & + NO_CALENDAR, date_to_string, get_date, & + get_time use atmos_model_mod, only: atmos_model_init, atmos_model_end, & get_atmos_model_ungridded_dim, & @@ -70,7 +71,8 @@ module module_fcst_grid_comp iau_offset use module_fv3_config, only: dt_atmos, calendar, restart_interval, & quilting, calendar_type, cpl, & - cplprint_flag, force_date_from_configure + cplprint_flag, force_date_from_configure, & + num_restart_interval, frestart, restart_endfcst ! !----------------------------------------------------------------------- ! @@ -88,7 +90,8 @@ module module_fcst_grid_comp type(atmos_data_type) :: Atm type(time_type) :: Time_atmos, Time_init, Time_end, & Time_step_atmos, Time_step_ocean, & - Time_restart, Time_step_restart + Time_restart, Time_step_restart, & + Time_atstart integer :: num_atmos_calls, ret, intrm_rst end type @@ -179,12 +182,11 @@ subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc) integer :: Run_length integer,dimension(6) :: date, date_end - integer :: res_intvl integer :: mpi_comm_comp ! logical,save :: first=.true. character(len=9) :: month - integer :: initClock, unit, nfhour + integer :: initClock, unit, nfhour, total_inttime integer :: mype, ntasks character(3) cfhour character(4) dateSY @@ -203,7 +205,8 @@ subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc) real(ESMF_KIND_R8),parameter :: dtor = 180.0_ESMF_KIND_R8 / 3.1415926535897931_ESMF_KIND_R8 integer :: jsc, jec, isc, iec, nlev type(domain2D) :: domain - integer :: n, fcstNpes + integer :: n, fcstNpes, tmpvar + logical :: single_restart integer, allocatable, dimension(:) :: isl, iel, jsl, jel integer, allocatable, dimension(:,:,:) :: deBlockList @@ -271,8 +274,9 @@ subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc) !----------------------------------------------------------------------- ! call ESMF_ClockGet(clock, CurrTime=CurrTime, StartTime=StartTime, & - StopTime=StopTime, RunDuration=RunDuration, rc=rc) + StopTime=StopTime, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return + RunDuration = StopTime - CurrTime date_init = 0 call ESMF_TimeGet (StartTime, & @@ -317,16 +321,46 @@ subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc) ! atm_int_state%Time_step_atmos = set_time (dt_atmos,0) atm_int_state%num_atmos_calls = Run_length / dt_atmos + atm_int_state%Time_atstart = atm_int_state%Time_atmos if (mype == 0) write(0,*)'num_atmos_calls=',atm_int_state%num_atmos_calls,'time_init=', & date_init,'time_atmos=',date,'time_end=',date_end,'dt_atmos=',dt_atmos, & 'Run_length=',Run_length - res_intvl = restart_interval*3600 - atm_int_state%Time_step_restart = set_time (res_intvl, 0) - atm_int_state%Time_restart = atm_int_state%Time_atmos + atm_int_state%Time_step_restart - atm_int_state%intrm_rst = 0 - if (res_intvl>0) atm_int_state%intrm_rst = 1 - atm_int_state%Atm%iau_offset = iau_offset -! + frestart = 0 + single_restart = .false. + call get_time(atm_int_state%Time_end - atm_int_state%Time_atstart,total_inttime) + if(num_restart_interval == 2) then + if(restart_interval(2)== -1) single_restart = .true. + endif + if(single_restart) then + frestart(1) = restart_interval(1) * 3600 + elseif ( num_restart_interval == 1) then + if(restart_interval(1) == 0) then + frestart(1) = total_inttime + else if(restart_interval(1) > 0) then + tmpvar = restart_interval(1) * 3600 + frestart(1) = tmpvar + atm_int_state%Time_step_restart = set_time (tmpvar, 0) + atm_int_state%Time_restart = atm_int_state%Time_atstart + atm_int_state%Time_step_restart + i = 2 + do while ( atm_int_state%Time_restart < atm_int_state%Time_end ) + frestart(i) = frestart(i-1) + tmpvar + atm_int_state%Time_restart = atm_int_state%Time_restart + atm_int_state%Time_step_restart + i = i + 1 + enddo + endif + else if(num_restart_interval > 1) then + do i=1,num_restart_interval + frestart(i) = restart_interval(i) * 3600 + enddo + endif + restart_endfcst = .false. + if ( ANY(frestart(:) == total_inttime) ) restart_endfcst = .true. + if (mype == 0) print *,'frestart=',frestart(1:10)/3600, 'restart_endfcst=',restart_endfcst, & + 'total_inttime=',total_inttime + + atm_int_state%intrm_rst = 0 + if (frestart(1)>0) atm_int_state%intrm_rst = 1 + atm_int_state%Atm%iau_offset = iau_offset ! !----- write time stamps (for start time and end time) ------ @@ -737,9 +771,10 @@ subroutine fcst_run_phase_2(fcst_comp, importState, exportState,clock,rc) !----------------------------------------------------------------------- !*** local variables ! - integer :: i,j, mype, na, date(6) + integer :: i,j, mype, na, date(6), seconds character(20) :: compname - + + type(time_type) :: restart_inctime type(ESMF_Time) :: currtime integer(kind=ESMF_KIND_I8) :: ntimestep_esmf character(len=64) :: timestamp @@ -776,13 +811,16 @@ subroutine fcst_run_phase_2(fcst_comp, importState, exportState,clock,rc) !--- intermediate restart if (atm_int_state%intrm_rst>0) then - if ((na /= atm_int_state%num_atmos_calls) .and. & - (atm_int_state%Time_atmos == atm_int_state%Time_restart)) then - timestamp = date_to_string (atm_int_state%Time_restart) - call atmos_model_restart(atm_int_state%Atm, timestamp) - - call wrt_atmres_timestamp(atm_int_state,timestamp) - atm_int_state%Time_restart = atm_int_state%Time_restart + atm_int_state%Time_step_restart + if (na /= atm_int_state%num_atmos_calls-1) then + call get_time(atm_int_state%Time_atmos - atm_int_state%Time_atstart, seconds) + if (ANY(frestart(:) == seconds)) then + restart_inctime = set_time(seconds, 0) + atm_int_state%Time_restart = atm_int_state%Time_atstart + restart_inctime + timestamp = date_to_string (atm_int_state%Time_restart) + call atmos_model_restart(atm_int_state%Atm, timestamp) + + call wrt_atmres_timestamp(atm_int_state,timestamp) + endif endif endif ! @@ -847,20 +885,21 @@ subroutine fcst_finalize(fcst_comp, importState, exportState,clock,rc) 'final time does not match expected ending time', WARNING) !*** write restart file - - call get_date (atm_int_state%Time_atmos, date(1), date(2), date(3), & + if( restart_endfcst ) then + call get_date (atm_int_state%Time_atmos, date(1), date(2), date(3), & date(4), date(5), date(6)) - call mpp_open( unit, 'RESTART/coupler.res', nohdrs=.TRUE. ) - if (mpp_pe() == mpp_root_pe())then - write( unit, '(i6,8x,a)' )calendar_type, & + call mpp_open( unit, 'RESTART/coupler.res', nohdrs=.TRUE. ) + if (mpp_pe() == mpp_root_pe())then + write( unit, '(i6,8x,a)' )calendar_type, & '(Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4)' - write( unit, '(6i6,8x,a)' )date_init, & + write( unit, '(6i6,8x,a)' )date_init, & 'Model start time: year, month, day, hour, minute, second' - write( unit, '(6i6,8x,a)' )date, & + write( unit, '(6i6,8x,a)' )date, & 'Current model time: year, month, day, hour, minute, second' + endif + call mpp_close(unit) endif - call mpp_close(unit) ! call diag_manager_end(atm_int_state%Time_atmos ) diff --git a/module_fv3_config.F90 b/module_fv3_config.F90 index eb1bb2036..2e0fd8883 100644 --- a/module_fv3_config.F90 +++ b/module_fv3_config.F90 @@ -13,11 +13,10 @@ module module_fv3_config implicit none ! - - integer :: restart_interval -! integer :: nfhout, nfhout_hf, nsout, dt_atmos integer :: nfhmax, nfhmax_hf, first_kdt + integer :: num_restart_interval + integer :: frestart(1000) type(ESMF_Alarm) :: alarm_output_hf, alarm_output type(ESMF_TimeInterval) :: output_hfmax type(ESMF_TimeInterval) :: output_interval,output_interval_hf @@ -25,7 +24,9 @@ module module_fv3_config logical :: cpl, cplprint_flag logical :: quilting, output_1st_tstep_rst logical :: force_date_from_configure + logical :: restart_endfcst ! + integer,dimension(:),allocatable :: restart_interval character(esmf_maxstr),dimension(:),allocatable :: filename_base character(17) :: calendar=' ' integer :: calendar_type = -99