#ifdef __PGI #define ESMF_ERR_ABORT(rc) \ if (rc /= ESMF_SUCCESS) write(0,*) 'rc=',rc,__FILE__,__LINE__; call ESMF_Finalize(endflag=ESMF_END_ABORT) #else #define ESMF_ERR_ABORT(rc) \ if (rc /= ESMF_SUCCESS) write(0,*) 'rc=',rc,__FILE__,__LINE__; if(ESMF_LogFoundError(rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) call ESMF_Finalize(endflag=ESMF_END_ABORT) #endif !----------------------------------------------------------------------- ! module module_fcst_grid_comp ! !----------------------------------------------------------------------- !*** Forecast gridded component. !----------------------------------------------------------------------- !*** !*** HISTORY !*** ! Apr 2017: J. Wang - initial code for forecast grid component ! !--------------------------------------------------------------------------------- ! 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 (==), 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, & update_atmos_model_dynamics, & update_atmos_radiation_physics, & update_atmos_model_state, & atmos_data_type, atmos_model_restart, & atmos_model_exchange_phase_1, & atmos_model_exchange_phase_2, & addLsmask2grid use constants_mod, only: constants_init use fms_mod, only: open_namelist_file, file_exist, check_nml_error, & error_mesg, fms_init, fms_end, close_file, & write_version_number, uppercase use mpp_mod, only: mpp_init, mpp_pe, mpp_root_pe, mpp_npes, mpp_get_current_pelist, & mpp_set_current_pelist, stdlog, mpp_error, NOTE, FATAL, WARNING use mpp_mod, only: mpp_clock_id, mpp_clock_begin, mpp_clock_end, mpp_sync use mpp_io_mod, only: mpp_open, mpp_close, MPP_NATIVE, MPP_RDONLY, MPP_DELETE use mpp_domains_mod, only: mpp_get_global_domain, mpp_global_field, CORNER, domain2d use mpp_domains_mod, only: mpp_get_compute_domains use memutils_mod, only: print_memuse_stats use sat_vapor_pres_mod, only: sat_vapor_pres_init use diag_manager_mod, only: diag_manager_init, diag_manager_end, & get_base_date, diag_manager_set_time_end use data_override_mod, only: data_override_init use fv_nggps_diags_mod, only: fv_dyn_bundle_setup use fv3gfs_io_mod, only: fv_phys_bundle_setup use fms_io_mod, only: field_exist, read_data use atmosphere_mod, only: atmosphere_control_data use esmf ! use module_fv3_io_def, only: num_pes_fcst, num_files, filename_base, nbdlphys, & iau_offset use module_fv3_config, only: dt_atmos, calendar, restart_interval, & quilting, calendar_type, cpl, & cplprint_flag, force_date_from_configure, & num_restart_interval, frestart, restart_endfcst ! !----------------------------------------------------------------------- ! implicit none ! include 'mpif.h' ! !----------------------------------------------------------------------- ! private ! !---- model defined-types ---- type atmos_internalstate_type 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_atstart integer :: num_atmos_calls, ret, intrm_rst end type type atmos_internalstate_wrapper type(atmos_internalstate_type), pointer :: ptr end type type(atmos_internalstate_type),pointer,save :: atm_int_state type(atmos_internalstate_wrapper),save :: wrap type(ESMF_VM),save :: VM type(ESMF_Grid) :: fcstGrid !----- coupled model data ----- integer :: date_init(6) integer :: numLevels = 0 integer :: numSoilLayers = 0 integer :: numTracers = 0 integer :: num_diag_sfc_emis_flux = 0 integer :: num_diag_down_flux = 0 integer :: num_diag_type_down_flux = 0 integer :: num_diag_burn_emis_flux = 0 integer :: num_diag_cmass = 0 ! !----------------------------------------------------------------------- ! public SetServices, fcstGrid public numLevels, numSoilLayers, numTracers, & num_diag_sfc_emis_flux, num_diag_down_flux, & num_diag_type_down_flux, num_diag_burn_emis_flux, num_diag_cmass ! contains ! !----------------------------------------------------------------------- !####################################################################### !----------------------------------------------------------------------- ! subroutine SetServices(fcst_comp, rc) ! type(ESMF_GridComp) :: fcst_comp integer, intent(out) :: rc rc = ESMF_SUCCESS call ESMF_GridCompSetEntryPoint(fcst_comp, ESMF_METHOD_INITIALIZE, & userRoutine=fcst_initialize, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! call ESMF_GridCompSetEntryPoint(fcst_comp, ESMF_METHOD_RUN, & userRoutine=fcst_run_phase_1, phase=1, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return call ESMF_GridCompSetEntryPoint(fcst_comp, ESMF_METHOD_RUN, & userRoutine=fcst_run_phase_2, phase=2, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! call ESMF_GridCompSetEntryPoint(fcst_comp, ESMF_METHOD_FINALIZE, & userRoutine=fcst_finalize, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return end subroutine SetServices ! !----------------------------------------------------------------------- !####################################################################### !----------------------------------------------------------------------- ! subroutine fcst_initialize(fcst_comp, importState, exportState, clock, rc) ! !----------------------------------------------------------------------- !*** INITIALIZE THE WRITE GRIDDED COMPONENT. !----------------------------------------------------------------------- ! type(esmf_GridComp) :: fcst_comp type(ESMF_State) :: importState, exportState type(esmf_Clock) :: clock integer,intent(out) :: rc ! !*** LOCAL VARIABLES ! integer :: tl, i, j integer,dimension(2,6) :: decomptile !define delayout for the 6 cubed-sphere tiles integer,dimension(2) :: regdecomp !define delayout for the nest grid type(ESMF_FieldBundle) :: fieldbundle ! type(ESMF_Time) :: CurrTime, StartTime, StopTime type(ESMF_TimeInterval) :: RunDuration, TimeElapsed type(ESMF_Config) :: cf integer :: Run_length integer,dimension(6) :: date, date_end integer :: mpi_comm_comp ! logical,save :: first=.true. character(len=9) :: month integer :: initClock, unit, nfhour, total_inttime integer :: mype, ntasks character(3) cfhour character(4) dateSY character(2) dateSM,dateSD,dateSH,dateSN,dateSS character(128) name_FB, name_FB1, dateS real, allocatable, dimension(:,:) :: glon_bnd, glat_bnd character(256) :: gridfile type(ESMF_FieldBundle),dimension(:), allocatable :: fieldbundlephys real(8) mpi_wtime, timeis type(ESMF_DELayout) :: delayout type(ESMF_DistGrid) :: distgrid real(ESMF_KIND_R8),dimension(:,:), pointer :: glatPtr, glonPtr 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, tmpvar logical :: single_restart integer, allocatable, dimension(:) :: isl, iel, jsl, jel integer, allocatable, dimension(:,:,:) :: deBlockList integer :: globalTileLayout(2) integer :: nestRootPet, peListSize(1) integer, allocatable :: petMap(:) ! !----------------------------------------------------------------------- !*********************************************************************** !----------------------------------------------------------------------- ! timeis = mpi_wtime() rc = ESMF_SUCCESS ! !----------------------------------------------------------------------- !*** ALLOCATE THE WRITE COMPONENT'S INTERNAL STATE. !----------------------------------------------------------------------- ! allocate(atm_int_state,stat=rc) ! !----------------------------------------------------------------------- !*** ATTACH THE INTERNAL STATE TO THE WRITE COMPONENT. !----------------------------------------------------------------------- ! wrap%ptr => atm_int_state call ESMF_GridCompSetInternalState(fcst_comp, wrap, rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! call ESMF_VMGetCurrent(vm=VM,rc=RC) call ESMF_VMGet(vm=VM, localPet=mype, mpiCommunicator=mpi_comm_comp, & petCount=ntasks, rc=rc) if (mype == 0) write(0,*)'in fcst comp init, ntasks=',ntasks ! call fms_init(mpi_comm_comp) call mpp_init() initClock = mpp_clock_id( 'Initialization' ) call mpp_clock_begin (initClock) !nesting problem call fms_init call constants_init call sat_vapor_pres_init ! if ( force_date_from_configure ) then select case( uppercase(trim(calendar)) ) case( 'JULIAN' ) calendar_type = JULIAN case( 'NOLEAP' ) calendar_type = NOLEAP case( 'THIRTY_DAY' ) calendar_type = THIRTY_DAY_MONTHS case( 'NO_CALENDAR' ) calendar_type = NO_CALENDAR case default call mpp_error ( FATAL, 'COUPLER_MAIN: coupler_nml entry calendar must '// & 'be one of JULIAN|NOLEAP|THIRTY_DAY|NO_CALENDAR.' ) end select endif ! call set_calendar_type (calendar_type ) ! !----------------------------------------------------------------------- !*** set atmos time !----------------------------------------------------------------------- ! call ESMF_ClockGet(clock, CurrTime=CurrTime, StartTime=StartTime, & 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, & YY=date_init(1), MM=date_init(2), DD=date_init(3), & H=date_init(4), M =date_init(5), S =date_init(6), RC=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return if ( date_init(1) == 0 ) date_init = date atm_int_state%Time_init = set_date (date_init(1), date_init(2), date_init(3), & date_init(4), date_init(5), date_init(6)) if(mype==0) write(*,'(A,6I5)') 'StartTime=',date_init date=0 call ESMF_TimeGet (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 if(mype==0) write(*,'(A,6I5)') 'CurrTime =',date atm_int_state%Time_atmos = set_date (date(1), date(2), date(3), & date(4), date(5), date(6)) date_end=0 call ESMF_TimeGet (StopTime, & YY=date_end(1), MM=date_end(2), DD=date_end(3), & H=date_end(4), M =date_end(5), S =date_end(6), RC=rc ) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return if ( date_end(1) == 0 ) date_end = date atm_int_state%Time_end = set_date (date_end(1), date_end(2), date_end(3), & date_end(4), date_end(5), date_end(6)) if(mype==0) write(*,'(A,6I5)') 'StopTime =',date_end ! call diag_manager_set_time_end(atm_int_state%Time_end) ! CALL ESMF_TimeIntervalGet(RunDuration, S=Run_length, RC=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! call diag_manager_init (TIME_INIT=date) call diag_manager_set_time_end(atm_int_state%Time_end) ! 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 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) ------ 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 (atm_int_state%Atm, atm_int_state%Time_init, & atm_int_state%Time_atmos, atm_int_state%Time_step_atmos) ! call data_override_init ( ) ! Atm_domain_in = Atm%domain, & ! Ice_domain_in = Ice%domain, & ! Land_domain_in = Land%domain ) !----------------------------------------------------------------------- !---- open and close dummy file in restart dir to check if dir exists -- if (mpp_pe() == 0 ) then call mpp_open( unit, 'RESTART/file' ) call mpp_close(unit, MPP_DELETE) endif ! ! !----------------------------------------------------------------------- !*** create grid for output fields !*** first try: Create cubed sphere grid from file !----------------------------------------------------------------------- ! if (mype == 0) write(0,*)'be create fcst grid' if( quilting ) then gridfile = "grid_spec.nc" ! default if (field_exist("INPUT/grid_spec.nc", "atm_mosaic_file")) then call read_data("INPUT/grid_spec.nc", "atm_mosaic_file", gridfile) endif if( atm_int_state%Atm%regional ) then call atmosphere_control_data (isc, iec, jsc, jec, nlev) domain = atm_int_state%Atm%domain fcstNpes = atm_int_state%Atm%layout(1)*atm_int_state%Atm%layout(2) allocate(isl(fcstNpes), iel(fcstNpes), jsl(fcstNpes), jel(fcstNpes)) allocate(deBlockList(2,2,fcstNpes)) call mpp_get_compute_domains(domain,xbegin=isl,xend=iel,ybegin=jsl,yend=jel) do n=1,fcstNpes deBlockList(:,1,n) = (/ isl(n),iel(n) /) deBlockList(:,2,n) = (/ jsl(n),jel(n) /) end do delayout = ESMF_DELayoutCreate(petMap=(/(i,i=0,fcstNpes-1)/), rc=rc); ESMF_ERR_ABORT(rc) distgrid = ESMF_DistGridCreate(minIndex=(/1,1/), & maxIndex=(/atm_int_state%Atm%mlon,atm_int_state%Atm%mlat/), & delayout=delayout, & deBlockList=deBlockList, rc=rc); ESMF_ERR_ABORT(rc) fcstGrid = ESMF_GridCreateNoPeriDim(regDecomp=(/atm_int_state%Atm%layout(1),atm_int_state%Atm%layout(2)/), & minIndex=(/1,1/), & maxIndex=(/atm_int_state%Atm%mlon,atm_int_state%Atm%mlat/), & gridEdgeLWidth=(/0,0/), & gridEdgeUWidth=(/0,0/), & name="fcst_grid", & indexflag=ESMF_INDEX_DELOCAL, & rc=rc); ESMF_ERR_ABORT(rc) ! add and define "center" coordinate values call ESMF_GridAddCoord(fcstGrid, staggerLoc=ESMF_STAGGERLOC_CENTER, rc=rc); ESMF_ERR_ABORT(rc) call ESMF_GridGetCoord(fcstGrid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CENTER, & farrayPtr=glonPtr, rc=rc); ESMF_ERR_ABORT(rc) call ESMF_GridGetCoord(fcstGrid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CENTER, & farrayPtr=glatPtr, rc=rc); ESMF_ERR_ABORT(rc) do j = jsc, jec do i = isc, iec glonPtr(i-isc+1,j-jsc+1) = atm_int_state%Atm%lon(i-isc+1,j-jsc+1) * dtor glatPtr(i-isc+1,j-jsc+1) = atm_int_state%Atm%lat(i-isc+1,j-jsc+1) * dtor enddo enddo ! add and define "corner" coordinate values !call ESMF_GridAddCoord(fcstGrid, staggerLoc=ESMF_STAGGERLOC_CORNER, staggerAlign=(/1,1/), rc=rc); ESMF_ERR_ABORT(rc) !call ESMF_GridGetCoord(fcstGrid, coordDim=1, staggerLoc=ESMF_STAGGERLOC_CORNER, farrayPtr=glonPtr, rc=rc); ESMF_ERR_ABORT(rc) !call ESMF_GridGetCoord(fcstGrid, coordDim=2, staggerLoc=ESMF_STAGGERLOC_CORNER, farrayPtr=glatPtr, rc=rc); ESMF_ERR_ABORT(rc) !do j = jsc, jec !do i = isc, iec ! glonPtr(i,j) = atm_int_state%Atm%gridstruct%agrid_64(i,j,1) ! glatPtr(i,j) = atm_int_state%Atm%gridstruct%agrid_64(i,j,2) !enddo !enddo else ! not regional if ( .not. atm_int_state%Atm%nested ) then !! global only do tl=1,6 decomptile(1,tl) = atm_int_state%Atm%layout(1) decomptile(2,tl) = atm_int_state%Atm%layout(2) enddo fcstGrid = ESMF_GridCreateMosaic(filename="INPUT/"//trim(gridfile), & regDecompPTile=decomptile,tileFilePath="INPUT/", & staggerlocList=(/ESMF_STAGGERLOC_CENTER, ESMF_STAGGERLOC_CORNER/), & name='fcst_grid', rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return else !! nesting #if ESMF_VERSION_MAJOR >= 8 if (mype==0) globalTileLayout = atm_int_state%Atm%layout call ESMF_VMBroadcast(vm, bcstData=globalTileLayout, count=2, & rootPet=0, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return nestRootPet = globalTileLayout(1) * globalTileLayout(2) * 6 if (mype == nestRootPet) then if (nestRootPet /= atm_int_state%Atm%pelist(1)) then write(0,*)'error in fcst_initialize: nestRootPet /= atm_int_state%Atm%pelist(1)' write(0,*)'error in fcst_initialize: nestRootPet = ',nestRootPet write(0,*)'error in fcst_initialize: atm_int_state%Atm%pelist(1) = ',atm_int_state%Atm%pelist(1) ESMF_ERR_ABORT(100) endif endif ! nest rootPet shares peList with others if (mype == nestRootPet) peListSize(1) = size(atm_int_state%Atm%pelist) call ESMF_VMBroadcast(vm, bcstData=peListSize, count=1, rootPet=nestRootPet, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! nest rootPet shares layout with others if (mype == nestRootPet) regDecomp = atm_int_state%Atm%layout call ESMF_VMBroadcast(vm, bcstData=regDecomp, count=2, rootPet=nestRootPet, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! prepare petMap variable allocate(petMap(peListSize(1))) if (mype == nestRootPet) petMap = atm_int_state%Atm%pelist ! do the actual broadcast of the petMap call ESMF_VMBroadcast(vm, bcstData=petMap, count=peListSize(1), rootPet=nestRootPet, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! create the DELayout that maps DEs to the PETs in the petMap delayout = ESMF_DELayoutCreate(petMap=petMap, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! create the nest Grid by reading it from file but use DELayout fcstGrid = ESMF_GridCreate(filename='INPUT/grid.nest02.tile7.nc', & fileformat=ESMF_FILEFORMAT_GRIDSPEC, regDecomp=regDecomp, & delayout=delayout, isSphere=.false., indexflag=ESMF_INDEX_DELOCAL, & rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return #else write(0,*)'nest quilting is supported only with ESMF 8' call ESMF_Finalize(endflag=ESMF_END_ABORT) #endif endif endif ! !test to write out vtk file: if( cpl ) then call addLsmask2grid(fcstGrid, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! print *,'call addLsmask2grid after fcstgrid, rc=',rc if( cplprint_flag ) then call ESMF_GridWriteVTK(fcstgrid, staggerloc=ESMF_STAGGERLOC_CENTER, & filename='fv3cap_fv3Grid', rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return endif endif ! ! Add gridfile Attribute to the exportState call ESMF_AttributeAdd(exportState, convention="NetCDF", purpose="FV3", & attrList=(/"gridfile"/), 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="gridfile", value=trim(gridfile), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! Add dimension Attributes to Grid call ESMF_AttributeAdd(fcstgrid, convention="NetCDF", purpose="FV3", & attrList=(/"ESMF:gridded_dim_labels"/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return call ESMF_AttributeSet(fcstGrid, convention="NetCDF", purpose="FV3", & name="ESMF:gridded_dim_labels", valueList=(/"grid_xt", "grid_yt"/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! ! Add time Attribute to the exportState call ESMF_AttributeAdd(exportState, convention="NetCDF", purpose="FV3", & attrList=(/ "time ", & "time:long_name ", & "time:units ", & "time:cartesian_axis", & "time:calendar_type ", & "time:calendar " /), 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", value=real(0,ESMF_KIND_R8), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return write(dateSY,'(I4.4)')date_init(1) write(dateSM,'(I2.2)')date_init(2) write(dateSD,'(I2.2)')date_init(3) write(dateSH,'(I2.2)')date_init(4) write(dateSN,'(I2.2)')date_init(5) write(dateSS,'(I2.2)')date_init(6) dateS="hours since "//dateSY//'-'//dateSM//'-'//dateSD//' '//dateSH//':'// & dateSN//":"//dateSS if (mype == 0) write(0,*)'dateS=',trim(dateS),'date_init=',date_init call ESMF_AttributeSet(exportState, convention="NetCDF", purpose="FV3", & name="time:units", value=trim(dateS), rc=rc) ! name="time:units", value="hours since 2016-10-03 00:00:00", 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:long_name", value="time", 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:cartesian_axis", value="T", 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:calendar_type", value="JULIAN", 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:calendar", value="JULIAN", 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 do i=1,num_files ! name_FB = filename_base(i) ! if( i==1 ) then ! for dyn name_FB1 = trim(name_FB)//'_bilinear' fieldbundle = ESMF_FieldBundleCreate(name=trim(name_FB1),rc=rc) if (mype == 0) write(0,*)'af create fcst fieldbundle, name=',trim(name_FB),'rc=',rc if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return call fv_dyn_bundle_setup(atm_int_state%Atm%axes, & fieldbundle, fcstgrid, quilting, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! Add the field to the importState so parent can connect to it call ESMF_StateAdd(exportState, (/fieldbundle/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return else if( i==2 ) then ! for phys nbdlphys = 2 allocate(fieldbundlephys(nbdlphys)) do j=1, nbdlphys if( j==1 ) then name_FB1 = trim(name_FB)//'_nearest_stod' else name_FB1 = trim(name_FB)//'_bilinear' endif fieldbundlephys(j) = ESMF_FieldBundleCreate(name=trim(name_FB1),rc=rc) if (mype == 0) write(0,*)'af create fcst fieldbundle, name=',trim(name_FB1),'rc=',rc if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return enddo ! call fv_phys_bundle_setup(atm_int_state%Atm%diag, atm_int_state%Atm%axes, & fieldbundlephys, fcstgrid, quilting, nbdlphys) ! ! Add the field to the importState so parent can connect to it do j=1,nbdlphys call ESMF_StateAdd(exportState, (/fieldbundlephys(j)/), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return enddo else write(0,*)' unknown name_FB ', trim(name_FB) ESMF_ERR_ABORT(101) endif ! enddo !end qulting endif call get_atmos_model_ungridded_dim(nlev=numLevels, nsoillev=numSoilLayers, & ntracers=numTracers, & num_diag_burn_emis_flux=num_diag_burn_emis_flux, & num_diag_sfc_emis_flux=num_diag_sfc_emis_flux, & num_diag_down_flux=num_diag_down_flux, & num_diag_type_down_flux=num_diag_type_down_flux, & num_diag_cmass=num_diag_cmass) ! !----------------------------------------------------------------------- ! IF(rc /= ESMF_SUCCESS) THEN WRITE(0,*)"FAIL: Fcst_Initialize." ! ELSE ! WRITE(0,*)"PASS: Fcst_Initialize." ENDIF ! if (mype == 0) write(0,*)'in fcst,init total time: ', mpi_wtime() - timeis ! !----------------------------------------------------------------------- ! end subroutine fcst_initialize ! !----------------------------------------------------------------------- !####################################################################### !----------------------------------------------------------------------- ! subroutine fcst_run_phase_1(fcst_comp, importState, exportState,clock,rc) ! !----------------------------------------------------------------------- !*** the run step for the fcst gridded component. !----------------------------------------------------------------------- ! type(ESMF_GridComp) :: fcst_comp type(ESMF_State) :: importState, exportState type(ESMF_Clock) :: clock integer,intent(out) :: rc ! !----------------------------------------------------------------------- !*** local variables ! integer :: i,j, mype, na, date(6) character(20) :: compname type(ESMF_Time) :: currtime integer(kind=ESMF_KIND_I8) :: ntimestep_esmf character(len=64) :: timestamp ! !----------------------------------------------------------------------- ! real(kind=8) :: mpi_wtime, tbeg1 ! !----------------------------------------------------------------------- !*********************************************************************** !----------------------------------------------------------------------- ! tbeg1 = mpi_wtime() rc = esmf_success ! !----------------------------------------------------------------------- ! call ESMF_GridCompGet(fcst_comp, name=compname, localpet=mype, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! call ESMF_ClockGet(clock, advanceCount=NTIMESTEP_ESMF, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return na = NTIMESTEP_ESMF ! !----------------------------------------------------------------------- ! *** call fcst integration subroutines call get_date (atm_int_state%Time_atmos, date(1), date(2), date(3), & date(4), date(5), date(6)) atm_int_state%Time_atmos = atm_int_state%Time_atmos + atm_int_state%Time_step_atmos call update_atmos_model_dynamics (atm_int_state%Atm) call update_atmos_radiation_physics (atm_int_state%Atm) call atmos_model_exchange_phase_1 (atm_int_state%Atm, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return !----------------------------------------------------------------------- ! ! IF(RC /= ESMF_SUCCESS) THEN ! if(mype==0) WRITE(0,*)"FAIL: fcst_RUN" ! ELSE if(mype==0) WRITE(*,*)"PASS: fcstRUN phase 1, na = ",na, ' time is ', mpi_wtime()-tbeg1 ! ENDIF ! !----------------------------------------------------------------------- ! end subroutine fcst_run_phase_1 ! !----------------------------------------------------------------------- !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& !----------------------------------------------------------------------- ! subroutine fcst_run_phase_2(fcst_comp, importState, exportState,clock,rc) ! !----------------------------------------------------------------------- !*** the run step for the fcst gridded component. !----------------------------------------------------------------------- ! type(ESMF_GridComp) :: fcst_comp type(ESMF_State) :: importState, exportState type(ESMF_Clock) :: clock integer,intent(out) :: rc ! !----------------------------------------------------------------------- !*** local variables ! 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 ! !----------------------------------------------------------------------- ! real(kind=8) :: mpi_wtime, tbeg1 ! !----------------------------------------------------------------------- !*********************************************************************** !----------------------------------------------------------------------- ! tbeg1 = mpi_wtime() rc = esmf_success ! !----------------------------------------------------------------------- ! call ESMF_GridCompGet(fcst_comp, name=compname, localpet=mype, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return ! call ESMF_ClockGet(clock, advanceCount=NTIMESTEP_ESMF, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return na = NTIMESTEP_ESMF if (mype == 0) write(0,*)'in fcst run phase 2, na=',na ! !----------------------------------------------------------------------- ! *** call fcst integration subroutines call atmos_model_exchange_phase_2 (atm_int_state%Atm, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return call update_atmos_model_state (atm_int_state%Atm) !--- intermediate restart if (atm_int_state%intrm_rst>0) then 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 ! call print_memuse_stats('after full step') ! !----------------------------------------------------------------------- ! ! IF(RC /= ESMF_SUCCESS) THEN ! if(mype==0) WRITE(0,*)"FAIL: fcst_RUN" ! ELSE if(mype==0) WRITE(*,*)"PASS: fcstRUN phase 2, na = ",na, ' time is ', mpi_wtime()-tbeg1 ! ENDIF ! !----------------------------------------------------------------------- ! end subroutine fcst_run_phase_2 ! !----------------------------------------------------------------------- !&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& !----------------------------------------------------------------------- ! subroutine fcst_finalize(fcst_comp, importState, exportState,clock,rc) ! !----------------------------------------------------------------------- !*** finalize the forecast grid component. !----------------------------------------------------------------------- ! type(ESMF_GridComp) :: fcst_comp type(ESMF_State) :: importState, exportState type(ESMF_Clock) :: clock integer,intent(out) :: rc ! !*** local variables ! integer :: unit integer,dimension(6) :: date real(8) mpi_wtime, tfs, tfe ! !----------------------------------------------------------------------- !*********************************************************************** !----------------------------------------------------------------------- ! tfs = mpi_wtime() rc = ESMF_SUCCESS ! !----------------------------------------------------------------------- !*** retrieve the fcst component's esmf internal state !----------------------------------------------------------------------- ! call ESMF_GridCompGetInternalState(fcst_comp, wrap, rc) atm_int_state => wrap%ptr ! !----------------------------------------------------------------------- ! call atmos_model_end (atm_int_state%atm) ! !*** check time versus expected ending time if (atm_int_state%Time_atmos /= atm_int_state%Time_end) & call error_mesg ('program coupler', & 'final time does not match expected ending time', WARNING) !*** write restart file 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, & '(Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4)' write( unit, '(6i6,8x,a)' )date_init, & 'Model start time: year, month, day, hour, minute, second' write( unit, '(6i6,8x,a)' )date, & 'Current model time: year, month, day, hour, minute, second' endif call mpp_close(unit) endif ! call diag_manager_end(atm_int_state%Time_atmos ) call fms_end ! !----------------------------------------------------------------------- ! IF(RC /= ESMF_SUCCESS)THEN WRITE(0,*)'FAIL: Write_Finalize.' ! ELSE ! WRITE(0,*)'PASS: Write_Finalize.' ENDIF ! tfe = mpi_wtime() ! print *,'fms end time: ', tfe-tfs !----------------------------------------------------------------------- ! end subroutine fcst_finalize ! !####################################################################### !-- change name from coupler_res to wrt_res_stamp to avoid confusion, !-- here we only write out atmos restart time stamp ! subroutine wrt_atmres_timestamp(atm_int_state,timestamp) type(atmos_internalstate_type), intent(in) :: atm_int_state character(len=32), intent(in) :: timestamp integer :: unit, date(6) !----- compute current date ------ call get_date (atm_int_state%Time_atmos, date(1), date(2), date(3), & date(4), date(5), date(6)) !----- write restart file ------ if (mpp_pe() == mpp_root_pe())then call mpp_open( unit, 'RESTART/'//trim(timestamp)//'.coupler.res', nohdrs=.TRUE. ) 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, & 'Model start time: year, month, day, hour, minute, second' write( unit, '(6i6,8x,a)' )date, & 'Current model time: year, month, day, hour, minute, second' call mpp_close(unit) endif end subroutine wrt_atmres_timestamp ! !---------------------------------------------------------------------------- !---------------------------------------------------------------------------- ! end module module_fcst_grid_comp ! !----------------------------------------------------------------------------