!WRF:DRIVER_LAYER:MAIN ! ! ! Stand-alone ESMF Application Wrapper for WRF model. This file contains the ! main program and creates a top level ESMF Gridded Component. ! ! This source file is only built when ESMF coupling is used. ! ! PROGRAM wrf_ESMFApp ! ! Stand-alone ESMF Application Wrapper for WRF model. This is the main ! program that creates a top level ESMF Gridded Component. ! ! ! WRF registration routine USE module_wrf_setservices, ONLY: WRF_register ! ESMF module, defines all ESMF data types and procedures USE ESMF_Mod ! Not-yet-implemented ESMF features USE module_esmf_extensions ! Component-independent utilities USE module_metadatautils, ONLY: GetTimesFromStates IMPLICIT NONE ! Local variables ! Components TYPE(ESMF_GridComp) :: WRFcompGridded ! WRF ! State, Virtual Machine, and DELayout TYPE(ESMF_VM) :: vm TYPE(ESMF_State) :: importState, exportState ! A clock, some times, and a time step TYPE(ESMF_Clock) :: driverClock TYPE(ESMF_Time) :: startTime TYPE(ESMF_Time) :: stopTime TYPE(ESMF_TimeInterval) :: couplingInterval ! Return codes for error checks INTEGER :: rc ! Warn users that this is not yet ready for general use. PRINT *, ' W A R N I N G ' PRINT *, ' ESMF COUPLING CAPABILITY IS EXPERIMENTAL AND UNSUPPORTED ' PRINT *, ' IN THIS VERSION OF WRF ' PRINT *, ' U S E A T Y O U R O W N R I S K ' ! This call includes everything that must be done before ESMF_Initialize() ! is called. CALL init_modules(1) ! Phase 1 returns after MPI_INIT() (if it is called) ! Initialize ESMF, get the default Global VM, and set ! the default calendar to be Gregorian. CALL ESMF_Initialize( vm=vm, defaultCalendar=ESMF_CAL_GREGORIAN, rc=rc ) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_Initialize failed' ) ENDIF CALL ESMF_SetInitialized() ! eliminate this once ESMF does it internally !TBH: these cause hangs on bluesky, PET* files never get written... !TBH: CALL ESMF_LogSet( maxElements=1, verbose=ESMF_TRUE, flush=ESMF_TRUE, rc=rc ) !TBH: CALL ESMF_LogSet( maxElements=1, rc=rc ) !TBH: IF ( rc /= ESMF_SUCCESS ) THEN !TBH: CALL wrf_error_fatal( 'ESMF_LogSet failed' ) !TBH: ENDIF ! Create the top level Gridded Component, passing in the default VM. WRFcompGridded = ESMF_GridCompCreate(vm, "WRF Model", rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_GridCompCreate failed' ) ENDIF ! Create empty import and export states importState = ESMF_StateCreate("WRF Import State", statetype=ESMF_STATE_IMPORT, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_StateCreate(importState) failed' ) ENDIF exportState = ESMF_StateCreate("WRF Export State", statetype=ESMF_STATE_EXPORT, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_StateCreate(exportState) failed' ) ENDIF ! Create top-level clock. There is no way to create an "empty" clock, so ! stuff in bogus values for start time, stop time, and time step and fix ! them after "WRF Init" returns. CALL ESMF_TimeSet(startTime, yy=2000, mm=1, dd=1, & h=0, m=0, s=0, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_TimeSet(startTime) failed' ) ENDIF CALL ESMF_TimeSet(stopTime, yy=2000, mm=1, dd=1, & h=12, m=0, s=0, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_TimeSet(stopTime) failed' ) ENDIF CALL ESMF_TimeIntervalSet(couplingInterval, s=2, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_TimeIntervalSet(couplingInterval) failed' ) ENDIF driverClock = ESMF_ClockCreate(timeStep=couplingInterval, startTime=startTime, & stopTime=stopTime, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_ClockCreate failed' ) ENDIF ! Register the top level Gridded Component CALL ESMF_GridCompSetServices(WRFcompGridded, WRF_register, rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_GridCompSetServices(WRFcompGridded) failed' ) ENDIF ! Init, Run, and Finalize section ! Phase 1 init returns WRF time and decomposition information as ! exportState metadata. CALL ESMF_GridCompInitialize(WRFcompGridded, importState, exportState, & driverClock, phase=1, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_GridCompInitialize(WRFcompGridded phase 1) failed' ) ENDIF ! For now, use settings from WRF component intialization to set up ! top-level clock. Per suggestion from ESMF Core team, these are passed ! back from "WRF init" as attributes on exportState. CALL GetTimesFromStates( exportState, startTime, stopTime, couplingInterval ) ! update driver clock CALL ESMF_ClockDestroy(driverClock, rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_ClockDestroy failed' ) ENDIF driverClock = ESMF_ClockCreate(timeStep=couplingInterval, startTime=startTime, & stopTime=stopTime, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_ClockCreate(driverClock) failed' ) ENDIF CALL wrf_clockprint ( 150, driverClock, 'driverClock before phase 2 WRF init' ) ! Phase 2 init sets up WRF importState and exportState. CALL ESMF_GridCompInitialize(WRFcompGridded, importState, exportState, & driverClock, phase=2, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_GridCompInitialize(WRFcompGridded phase 2) failed' ) ENDIF CALL wrf_debug ( 150, 'wrf_ESMFApp: begin time stepping...' ) ! main time-stepping loop DO WHILE ( .NOT. ESMF_ClockIsStopTime(driverClock, rc) ) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_ClockIsStopTime failed' ) ENDIF ! Run WRF CALL wrf_debug ( 150, 'wrf_ESMFApp: calling ESMF_GridCompRun(WRFcompGridded)...' ) CALL ESMF_GridCompRun(WRFcompGridded, importState, exportState, & driverClock, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_GridCompRun failed' ) ENDIF CALL wrf_debug ( 150, 'wrf_ESMFApp: back from ESMF_GridCompRun(WRFcompGridded)...' ) ! advance clock to next coupling time step CALL ESMF_ClockAdvance( driverClock, rc=rc ) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_ClockAdvance failed' ) ENDIF CALL wrf_clockprint ( 150, driverClock, 'driverClock after ESMF_ClockAdvance' ) ENDDO CALL wrf_debug ( 150, 'wrf_ESMFApp: done time stepping...' ) CALL wrf_debug ( 150, 'wrf_ESMFApp: calling ESMF_GridCompFinalize(WRFcompGridded)...' ) ! clean up WRF CALL ESMF_GridCompFinalize(WRFcompGridded, importState, exportState, & driverClock, rc=rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_GridCompFinalize failed' ) ENDIF CALL wrf_debug ( 150, 'wrf_ESMFApp: back from ESMF_GridCompFinalize(WRFcompGridded)...' ) ! Clean up CALL wrf_debug ( 150, 'wrf_ESMFApp: cleaning up ESMF objects...' ) CALL ESMF_GridCompDestroy(WRFcompGridded, rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_GridCompDestroy failed' ) ENDIF CALL ESMF_StateDestroy(importState, rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_StateDestroy(importState) failed' ) ENDIF CALL ESMF_StateDestroy(exportState, rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_StateDestroy(exportState) failed' ) ENDIF CALL ESMF_ClockDestroy(driverClock, rc) IF ( rc /= ESMF_SUCCESS ) THEN CALL wrf_error_fatal( 'ESMF_Destroy(driverClock) failed' ) ENDIF CALL wrf_debug ( 150, 'wrf_ESMFApp: calling ESMF_Finalize()...' ) CALL ESMF_Finalize( rc=rc ) CALL wrf_debug ( 150, 'wrf_ESMFApp: back from ESMF_Finalize()...' ) END PROGRAM wrf_ESMFApp