Merge branch 'master' into devel
[wrffire.git] / wrfv2_fire / main / wrf_SST_ESMF.F
blobcff9bc3634b78cf6d0adefd29a9199a490bd081a
1 !WRF:DRIVER_LAYER:MAIN
4 !<DESCRIPTION>
5 ! ESMF Application Wrapper for coupling WRF with a "dummy" component 
6 ! that simply reads SSTs from a file, sends to WRF, receives SST from 
7 ! WRF (two-way coupling). and checks that the SSTs match.  
9 ! This file contains the main program and associated modules for the 
10 ! SST "dummy" component and a simple coupler.  It creates ESMF Gridded 
11 ! and Coupler Components.  
13 ! This source file is only built when ESMF coupling is used.  
15 !</DESCRIPTION>
19 !<DESCRIPTION>
20 ! Modules module_sst_component_top and module_sst_setservices define the 
21 ! "SST" dummy component.  
22 !</DESCRIPTION>
24 MODULE module_sst_component_top
25 !<DESCRIPTION>
26 ! This module defines sst_component_init1(), sst_component_init2(), 
27 ! sst_component_run1(), sst_component_run2(), and sst_component_finalize() 
28 ! routines that are called when SST is run as an ESMF component.  
29 !</DESCRIPTION>
31 ! Updated for ESMF 5.2.0r  -- see:
32 !  http://www.earthsystemmodeling.org/esmf_releases/public/ESMF_5_2_0r/InterfaceChanges520to520r.pdf
33 !   USE ESMF_Mod  
34    USE ESMF
35    USE module_esmf_extensions
36    USE module_metadatautils, ONLY: AttachTimesToState
39    IMPLICIT NONE
41    ! everything is private by default
42    PRIVATE
44    ! Public entry points
45    PUBLIC sst_component_init1
46    PUBLIC sst_component_init2
47    PUBLIC sst_component_run1
48    PUBLIC sst_component_run2
49    PUBLIC sst_component_finalize
51    ! private stuff
52    TYPE(ESMF_Grid), SAVE :: esmfgrid  ! grid used in fields
53    CHARACTER (4096) :: str
54    INTEGER, SAVE :: fid               ! file handle
55    ! decomposition information
56    INTEGER, SAVE :: ids, ide, jds, jde, kds, kde
57    INTEGER, SAVE :: ims, ime, jms, jme, kms, kme
58    INTEGER, SAVE :: ips, ipe, jps, jpe, kps, kpe
59    REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_out_sst(:,:)
60    REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_out_landmask(:,:)
61    REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_in_sst(:,:)
62    REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_in_landmask(:,:)
63    INTEGER, SAVE :: domdesc
64    LOGICAL, SAVE :: bdy_mask(4)
65    ! MPI communicator, if needed
66    INTEGER, SAVE :: mpicom
67    ! field data
68    REAL, POINTER, SAVE :: file_landmask_data(:,:), file_sst_data(:,:)
69    ! input data file name
70    CHARACTER ( ESMF_MAXSTR ), SAVE :: sstinfilename
71    ! field names
72    INTEGER, PARAMETER :: datacount = 2
73    INTEGER, PARAMETER :: SST_INDX = 1
74    INTEGER, PARAMETER :: LANDMASK_INDX = 2
75    CHARACTER(LEN=ESMF_MAXSTR), SAVE :: datanames(datacount)
76    TYPE real2d
77      REAL, POINTER :: r2d(:,:)
78    END TYPE real2d
79    TYPE(real2d) :: this_data(datacount)
82 CONTAINS
86    ! First-phase "init" reads "SST" data file and returns "time" metadata in 
87    ! exportState.  
88    SUBROUTINE sst_component_init1( gcomp, importState, exportState, clock, rc )
89      USE module_io
90      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
91      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState
92      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: exportState
93      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
94      INTEGER,                     INTENT(  OUT) :: rc
95 !<DESCRIPTION>
96 !     SST component init routine, phase 1.
98 !     The arguments are:
99 !       gcomp           Component
100 !       importState     Importstate
101 !       exportState     Exportstate
102 !       clock           External clock
103 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
104 !                       otherwise ESMF_FAILURE.
105 !</DESCRIPTION>
107 #ifdef DM_PARALLEL
108      INCLUDE 'mpif.h'
109 #endif
111      ! Local variables
112      CHARACTER (LEN=19) :: date_string
113 #ifdef DM_PARALLEL
114      TYPE(ESMF_VM) :: vm
115      INTEGER :: mpicomtmp
116 #endif
117      TYPE(ESMF_Time) :: startTime, stopTime, currentTime, dataTime
118      TYPE(ESMF_TimeInterval) :: timeStep
119      INTEGER :: ierr, num_steps, time_loop_max
120      INTEGER :: status_next_var
122 !TODO:  For now, sstinfilename is hard-coded
123 !TODO:  Upgrade to use a variant of construct_filename() via startTime 
124 !TODO:  extracted from clock.  
125      sstinfilename = 'sstin_d01_000000'
127      ! get MPI communicator out of current VM and duplicate (if needed)
128 #ifdef DM_PARALLEL
129      CALL ESMF_VMGetCurrent(vm, rc=rc)
130      IF ( rc /= ESMF_SUCCESS ) THEN
131        CALL wrf_error_fatal ( 'sst_component_init1:  ESMF_VMGetCurrent failed' )
132      ENDIF
133      CALL ESMF_VMGet(vm, mpiCommunicator=mpicomtmp, rc=rc)
134      IF ( rc /= ESMF_SUCCESS ) THEN
135        CALL wrf_error_fatal ( 'sst_component_init1:  ESMF_VMGet failed' )
136      ENDIF
137      CALL MPI_Comm_dup( mpicomtmp, mpicom, ierr )
138 #else
139      mpicom = 0
140 #endif
141      !  Open the "SST" input data file for reading.
142      write(str,'(A,A)') 'Subroutine sst_component_init1: Opening data file ', &
143        TRIM(sstinfilename)
144      CALL wrf_message ( TRIM(str) )
145      CALL wrf_open_for_read ( TRIM(sstinfilename) , &
146                               mpicom ,              &
147                               mpicom ,              &
148                               "DATASET=INPUT" ,     &
149                               fid ,                 &
150                               ierr )
151      IF ( ierr .NE. 0 ) THEN
152         WRITE( str , FMT='(A,A,A,I8)' ) &
153           'subroutine sst_component_init1: error opening ', &
154           TRIM(sstinfilename),' for reading ierr=',ierr
155         CALL wrf_error_fatal ( TRIM(str) )
156      ENDIF
157      WRITE( str , FMT='(A,A,A,I8)' ) &
158        'subroutine sst_component_init1: opened file ', &
159        TRIM(sstinfilename),' for reading fid=',fid
160      CALL wrf_debug ( 100, TRIM(str) )
162      ! How many data time levels are in the SST input file?  
163      num_steps = -1
164      time_loop_max = 0
165      CALL wrf_debug    ( 100, 'subroutine sst_component_init1: find time_loop_max' )
166      ! compute SST start time, time step, and end time here
167      get_the_right_time : DO
168         CALL wrf_get_next_time ( fid, date_string, status_next_var )
169         write(str,'(A,A)') 'Subroutine sst_component_init1: SST data startTime: ', &
170           date_string
171         CALL wrf_debug ( 100 , TRIM(str) )
172         IF ( status_next_var == 0 ) THEN
173            IF ( time_loop_max == 0 ) THEN
174              CALL wrf_atotime( date_string, startTime )
175            ELSEIF ( time_loop_max == 1 ) THEN
176              ! assumes fixed time step!
177              CALL wrf_atotime( date_string, dataTime )
178              timeStep = dataTime - startTime
179            ENDIF
180            time_loop_max = time_loop_max + 1
181            CALL wrf_atotime( date_string, stopTime )
182         ELSE
183            EXIT get_the_right_time
184         ENDIF
185      END DO get_the_right_time
186      CALL wrf_timetoa ( stopTime, date_string )
187      write(str,'(A,A)') 'Subroutine sst_component_init1: SST data stopTime: ', &
188        date_string
189      CALL wrf_debug ( 100 , TRIM(str) )
190      ! attach times to exportState for use by driver
191      CALL AttachTimesToState( exportState, startTime, stopTime, timeStep )
193      ! There should be a more elegant way to get to the beginning of the 
194      ! file, but this will do.
195      CALL wrf_ioclose( fid , ierr )
196      IF ( ierr .NE. 0 ) THEN
197         CALL wrf_error_fatal ( 'sst_component_init1:  wrf_ioclose failed' )
198      ENDIF
199      WRITE( str , FMT='(A,I8)' ) &
200        'subroutine sst_component_init1: closed file fid=',fid
201      CALL wrf_debug ( 100, TRIM(str) )
203      ! set up field names
204 !TODO:  use CF conventions for "standard_name" once WRF Registry supports them
205 !TODO:      datanames(SST_INDX) = "sea_surface_temperature"
206 !TODO:      datanames(LANDMASK_INDX) = "land_binary_mask"
207      datanames(SST_INDX) = "SST"
208      datanames(LANDMASK_INDX) = "LANDMASK"
210      rc = ESMF_SUCCESS
212    END SUBROUTINE sst_component_init1
216    SUBROUTINE read_data( exportState, clock )
217      USE module_io
218      TYPE(ESMF_State), INTENT(INOUT) :: exportState
219      TYPE(ESMF_Clock), INTENT(IN   ) :: clock
220 !<DESCRIPTION>
221 !     Reads data from file and stores.  Then 
222 !     stuffs the file data into the SST exportState.  
223 !</DESCRIPTION>
225 #include <wrf_status_codes.h>
226 #include <wrf_io_flags.h>
228      ! Local variables
229      CHARACTER (LEN=19) :: date_string
230      TYPE(ESMF_Time) :: currentTime, dataTime
231      REAL(ESMF_KIND_R4), POINTER :: out_sst_ptr(:,:), out_landmask_ptr(:,:)
232      TYPE(ESMF_Field) :: out_sst_field, out_landmask_field
233      TYPE(ESMF_Field) :: in_sst_field, in_landmask_field
234      INTEGER :: i, j
235      CHARACTER(LEN=ESMF_MAXSTR) :: fieldname, debugmsg, errormsg, timestr
236      INTEGER :: ierr
237      INTEGER :: rc
239      ! This call to wrf_get_next_time will position the dataset over the next 
240      ! time-frame in the file and return the date_string, which is used as an 
241      ! argument to the read_field routines in the blocks of code included 
242      ! below.  
244      CALL wrf_get_next_time( fid, date_string , ierr )
245      WRITE(str,'(A,A)') 'Subroutine read_data: SST data time: ', &
246        date_string
247      CALL wrf_debug ( 100 , TRIM(str) )
248      IF ( ierr .NE. 0 .AND. ierr .NE. WRF_WARN_NOTSUPPORTED .AND.  &
249           ierr .NE. WRF_WARN_DRYRUN_READ ) THEN
250        CALL wrf_error_fatal ( "... May have run out of valid SST data ..." )
251      ELSE IF ( ierr .NE. WRF_WARN_NOTSUPPORTED .AND. &
252                ierr .NE. WRF_WARN_DRYRUN_READ) THEN
253        ! check input time against current time (which will be start time at 
254        ! beginning)
255        CALL wrf_atotime( date_string, dataTime )
256        CALL ESMF_ClockGet( clock, CurrTime=currentTime, rc=rc )
257        IF (rc /= ESMF_SUCCESS) THEN
258          CALL wrf_error_fatal ( 'read_data:  ESMF_ClockGet() failed' )
259        ENDIF
260        CALL wrf_clockprint(150, clock, &
261               'DEBUG read_data():  get currentTime from clock,')
262        IF ( dataTime .NE. currentTime ) THEN
263            CALL wrf_timetoa ( dataTime, timestr )
264            WRITE( errormsg , * )'Time in file: ',trim( timestr )
265            CALL wrf_message ( trim(errormsg) )
266            CALL wrf_timetoa ( currentTime, timestr )
267            WRITE( errormsg , * )'Time on domain: ',trim( timestr )
268            CALL wrf_message ( trim(errormsg) )
269            CALL wrf_error_fatal( &
270              "**ERROR** Time in input file not equal to time on domain **ERROR**" )
271        ENDIF
272      ENDIF
274      ! doing this in a loop only works if staggering is the same for all fields
275      this_data(SST_INDX)%r2d => file_sst_data
276      this_data(LANDMASK_INDX)%r2d => file_landmask_data
277      DO i=1, datacount
278        fieldname = TRIM(datanames(i))
279        debugmsg  = 'ext_read_field '//TRIM(fieldname)//' memorder XY'
280        errormsg  = 'could not read '//TRIM(fieldname)//' data from file'
281        CALL wrf_ext_read_field (    &
282               fid                 , &  ! DataHandle
283               date_string         , &  ! DateStr
284               TRIM(fieldname)     , &  ! Data Name
285               this_data(i)%r2d    , &  ! Field
286               WRF_REAL            , &  ! FieldType
287               mpicom              , &  ! Comm
288               mpicom              , &  ! I/O Comm
289               domdesc             , &  ! Domain descriptor
290               bdy_mask            , &  ! bdy_mask
291               'XY'                , &  ! MemoryOrder
292               ''                  , &  ! Stagger
293               TRIM(debugmsg)      , &  ! Debug message
294 #if 1
295               ids , (ide-1) , jds , (jde-1) , 1 , 1 , &
296               ims , ime , jms , jme , 1 , 1         , &
297               ips , MIN( (ide-1), ipe ) , jps , MIN( (jde-1), jpe ) , 1 , 1 , &
298 #else
299 !jm the dimensions have already been reduced to the non-staggered WRF grid when
300 !   they were stored in this module..  Just use as is.
301               ids , ide , jds , jde , 1 , 1 , &
302               ims , ime , jms , jme , 1 , 1         , &
303               ips , ipe , jps , jpe , 1 , 1 , &
304 #endif
305               ierr )
306        IF (ierr /= 0) THEN
307          CALL wrf_error_fatal ( TRIM(errormsg) )
308        ENDIF
309      ENDDO
311      ! stuff fields into exportState
312 !TODO:  change this to Bundles, eventually
313      CALL ESMF_StateGet( exportState, TRIM(datanames(SST_INDX)), &
314                               out_sst_field, rc=rc )
315      IF (rc /= ESMF_SUCCESS) THEN
316        CALL wrf_error_fatal ( &
317          'could not find sea_surface_temperature field in exportState' )
318      ENDIF
319      CALL ESMF_StateGet( exportState, TRIM(datanames(LANDMASK_INDX)), &
320                               out_landmask_field, rc=rc )
321      IF (rc /= ESMF_SUCCESS) THEN
322        CALL wrf_error_fatal ( &
323          'could not find land_binary_mask field in exportState' )
324      ENDIF
325 !     CALL ESMF_FieldGetDataPointer( out_sst_field, out_sst_ptr, rc=rc )
326      CALL ESMF_FieldGet( out_sst_field, 0, out_sst_ptr, rc=rc )
327      IF (rc /= ESMF_SUCCESS) THEN
328        CALL wrf_error_fatal ( &
329          'could not find sea_surface_temperature data in sea_surface_temperature field' )
330      ENDIF
331 !     CALL ESMF_FieldGetDataPointer( out_landmask_field, out_landmask_ptr, rc=rc )
332      CALL ESMF_FieldGet( out_landmask_field, 0, out_landmask_ptr, rc=rc )
333      IF (rc /= ESMF_SUCCESS) THEN
334        CALL wrf_error_fatal ( &
335          'could not find land_binary_mask data in land_binary_mask field' )
336      ENDIF
337      ! staggered starts/ends
338      DO j= jps , jpe
339        DO i= ips , ipe
340          out_sst_ptr(i,j) = file_sst_data(i,j)
341          out_landmask_ptr(i,j) = file_landmask_data(i,j)
342        ENDDO
343      ENDDO
345    END SUBROUTINE read_data
350    SUBROUTINE compare_data( importState, clock )
351      TYPE(ESMF_State), INTENT(INOUT) :: importState
352 !TODO:  remove clock after debugging is finished
353      TYPE(ESMF_Clock), INTENT(INOUT) :: clock
354 !<DESCRIPTION>
355 !     Gets data from coupler via importState 
356 !     and compares with data read from file and 
357 !     error-exits if they differ.  
359 !     The arguments are:
360 !       importState     Importstate
361 !</DESCRIPTION>
363      ! Local variables
364      TYPE(ESMF_Field) :: in_sst_field, in_landmask_field
365      REAL(ESMF_KIND_R4), POINTER :: in_sst_ptr(:,:), in_landmask_ptr(:,:)
366      REAL, POINTER :: in_sst_ptr_real(:,:), in_landmask_ptr_real(:,:)
367      INTEGER :: i, j
368      INTEGER :: rc
369      LOGICAL :: landmask_ok, sst_ok
370      ! use these for debug prints
371      TYPE(ESMF_Time) :: currentTime
372      INTEGER, SAVE :: numtimes=0   ! track number of calls
373      CHARACTER(LEN=256) :: timestamp
375      ! count calls for debug prints...
376      CALL ESMF_ClockGet( clock, CurrTime=currentTime, rc=rc )
377      IF (rc /= ESMF_SUCCESS) THEN
378        CALL wrf_error_fatal ( 'compare_data:  ESMF_ClockGet() failed' )
379      ENDIF
380      CALL wrf_timetoa ( currentTime, timestamp )
381      numtimes = numtimes + 1
382      WRITE(str,*) 'SST compare_data:  begin, numtimes = ',numtimes,' time = ',TRIM(timestamp)
383      CALL wrf_debug ( 100 , TRIM(str) )
385      ! extract data from the importState and compare with data from file
386 !TODO:  change this to Bundles, eventually
387      CALL ESMF_StateGet( importState, TRIM(datanames(SST_INDX)), &
388                               in_sst_field, rc=rc )
389      IF (rc /= ESMF_SUCCESS) THEN
390        CALL wrf_error_fatal ( &
391          'could not extract sea_surface_temperature field from importState' )
392      ENDIF
393      CALL ESMF_StateGet( importState, TRIM(datanames(LANDMASK_INDX)), &
394                               in_landmask_field, rc=rc )
395      IF (rc /= ESMF_SUCCESS) THEN
396        CALL wrf_error_fatal ( &
397          'could not extract land_binary_mask field from importState' )
398      ENDIF
399 !     CALL ESMF_FieldGetDataPointer( in_sst_field, in_sst_ptr, rc=rc )
400      CALL ESMF_FieldGet( in_sst_field, 0, in_sst_ptr, rc=rc )
401      IF (rc /= ESMF_SUCCESS) THEN
402        CALL wrf_error_fatal ( &
403          'could not extract sea_surface_temperature data from sea_surface_temperature field' )
404      ENDIF
405      ALLOCATE( in_sst_ptr_real(ims:ime,jms:jme) )
406      WRITE( str,* ) 'compare_data, ips:ipe,jps:jpe = ',           &
407        ips,':',ipe,',',jps,':',jpe,                               &
408        ', in_sst_ptr(BOUNDS) = ',                                 &
409        LBOUND(in_sst_ptr,1),':',UBOUND(in_sst_ptr,1),',',         &
410        LBOUND(in_sst_ptr,2),':',UBOUND(in_sst_ptr,2)
411      CALL wrf_debug ( 100 , TRIM(str) )
412      DO j= jms, jme
413        DO i= ims, ime
414          in_sst_ptr_real(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
415        ENDDO
416      ENDDO
417      in_sst_ptr_real(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe)) = &
418           in_sst_ptr(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe))
419 !     CALL ESMF_FieldGetDataPointer( in_landmask_field, in_landmask_ptr, rc=rc )
420      CALL ESMF_FieldGet( in_landmask_field, 0, in_landmask_ptr, rc=rc )
421      IF (rc /= ESMF_SUCCESS) THEN
422        CALL wrf_error_fatal ( &
423          'could not extract land_binary_mask data from land_binary_mask field' )
424      ENDIF
425      ALLOCATE( in_landmask_ptr_real(ims:ime,jms:jme) )
426      WRITE( str,* ) 'compare_data, ips:ipe,jps:jpe = ',             &
427        ips,':',ipe,',',jps,':',jpe,                                 &
428        ', in_landmask_ptr(BOUNDS) = ',                              &
429        LBOUND(in_landmask_ptr,1),':',UBOUND(in_landmask_ptr,1),',', &
430        LBOUND(in_landmask_ptr,2),':',UBOUND(in_landmask_ptr,2)
431      CALL wrf_debug ( 100 , TRIM(str) )
432      DO j= jms, jme
433        DO i= ims, ime
434          in_landmask_ptr_real(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
435        ENDDO
436      ENDDO
437      in_landmask_ptr_real(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe)) = &
438           in_landmask_ptr(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe))
440      ! compare LANDMASK...  
441      landmask_ok = .TRUE.
442      ! staggered starts/ends
443      LANDMASK_COMPARE : DO j= jps , MIN( (jde-1), jpe )
444        DO i= ips , MIN( (ide-1), ipe )
445          IF ( file_landmask_data(i,j) /= in_landmask_ptr_real(i,j) ) THEN
446            landmask_ok = .FALSE.
447            WRITE( str , * ) 'error landmask mismatch at (i,j) = (',i,',',j, &
448                             '), values are',file_landmask_data(i,j),' and ',     &
449                             in_landmask_ptr_real(i,j) 
450            EXIT LANDMASK_COMPARE
451          ENDIF
452        ENDDO
453      ENDDO LANDMASK_COMPARE
454      IF ( landmask_ok ) THEN
455        WRITE(str,*) 'TESTING data returned from WRF through ESMF: LANDMASK compares OK'
456        CALL wrf_debug ( 0 , TRIM(str) )
457      ELSE
458        CALL wrf_error_fatal ( TRIM(str) )
459      ENDIF
461      ! compare SST...  
462      sst_ok = .TRUE.
463      ! staggered starts/ends
464      SST_COMPARE : DO j= jps , MIN( (jde-1), jpe )
465        DO i= ips , MIN( (ide-1), ipe )
466          IF ( file_sst_data(i,j) /= in_sst_ptr_real(i,j) ) THEN
467            sst_ok = .FALSE.
468            WRITE( str , * ) 'error sst mismatch at (i,j) = (',i,',',j, &
469                             '), values are',file_sst_data(i,j),' and ',     &
470                             in_sst_ptr_real(i,j) 
471            EXIT SST_COMPARE
472          ENDIF
473        ENDDO
474      ENDDO SST_COMPARE
475      IF ( sst_ok ) THEN
476        WRITE(str,*) 'TESTING data returned from WRF through ESMF: SST compares OK'
477        CALL wrf_debug ( 0 , TRIM(str) )
478      ELSE
479        CALL wrf_error_fatal ( TRIM(str) )
480      ENDIF
482      DEALLOCATE( in_sst_ptr_real, in_landmask_ptr_real )
484      WRITE(str,*) 'compare_data:  end, numtimes = ',numtimes
485      CALL wrf_debug ( 100 , TRIM(str) )
487    END SUBROUTINE compare_data
489    ! Second-phase "init" gets decomposition information from 
490    ! importState.  
491    SUBROUTINE sst_component_init2( gcomp, importState, exportState, clock, rc )
492      USE module_metadatautils, ONLY: GetDecompFromState
493      USE module_io
494      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
495      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState
496      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: exportState
497      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
498      INTEGER,                     INTENT(  OUT) :: rc
499 !<DESCRIPTION>
500 !     SST component init routine, phase 2.
502 !     The arguments are:
503 !       gcomp           Component
504 !       importState     Importstate
505 !       exportState     Exportstate
506 !       clock           External clock
507 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
508 !                       otherwise ESMF_FAILURE.
509 !</DESCRIPTION>
511      ! Local variables
512      TYPE(ESMF_Field) :: out_sst_field, out_landmask_field
513      TYPE(ESMF_Field) :: in_sst_field, in_landmask_field
514      INTEGER, PARAMETER :: NUMDIMS=2
515      INTEGER :: DomainStart(NUMDIMS)
516      INTEGER :: DomainEnd(NUMDIMS)
517      INTEGER :: MemoryStart(NUMDIMS)
518      INTEGER :: MemoryEnd(NUMDIMS)
519      INTEGER :: PatchStart(NUMDIMS)
520      INTEGER :: PatchEnd(NUMDIMS)
521      INTEGER :: rc, i, j
522      INTEGER :: ierr
524     ! Get decomposition information from importState.  Note that index 
525     ! values are for staggered dimensions, following the WRF convention.  
526 !TODO:  Note that this will only work for SPMD serial operation.  For 
527 !TODO:  concurrent operation (SPMD or MPMD), we will need to create a new 
528 !TODO:  "domdesc" suitable for the task layout of the SST component.  For
529 !TODO:  MPMD serial operation, we will need to extract serialized domdesc 
530 !TODO:  from export state metadata and de-serialize it.  Similar arguments 
531 !TODO:  apply to [ij][mp][se] and bdy_mask.  
532      write(str,*) 'sst_component_init2: calling GetDecompFromState'
533      CALL wrf_debug ( 100 , TRIM(str) )
534      CALL GetDecompFromState( importState,                  &
535                               ids, ide, jds, jde, kds, kde, &
536                               ims, ime, jms, jme, kms, kme, &
537                               ips, ipe, jps, jpe, kps, kpe, &
538                               domdesc, bdy_mask )
539      write(str,*) 'sst_component_init2: back from GetDecompFromState'
540      CALL wrf_debug ( 100 , TRIM(str) )
541      write(str,*) 'sst_component_init2: ids, ide, jds, jde, kds, kde = ', ids, ide, jds, jde, kds, kde
542      CALL wrf_debug ( 100 , TRIM(str) )
543      write(str,*) 'sst_component_init2: ims, ime, jms, jme, kms, kme = ', ims, ime, jms, jme, kms, kme
544      CALL wrf_debug ( 100 , TRIM(str) )
545      write(str,*) 'sst_component_init2: ips, ipe, jps, jpe, kps, kpe = ', ips, ipe, jps, jpe, kps, kpe
546      CALL wrf_debug ( 100 , TRIM(str) )
548      ! allocate space for data read from disk
549      ALLOCATE( file_sst_data     (ims:ime,jms:jme) )
550      DO j= jms, jme
551        DO i= ims, ime
552          file_sst_data(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
553        ENDDO
554      ENDDO
555 !TODO:  Hmmm...  really need to load these pointers here?  Check...  
556      this_data(SST_INDX)%r2d => file_sst_data
557      ALLOCATE( file_landmask_data(ims:ime,jms:jme) )
558      DO j= jms, jme
559        DO i= ims, ime
560          file_landmask_data(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
561        ENDDO
562      ENDDO
563      this_data(LANDMASK_INDX)%r2d => file_landmask_data
565      ! Create ESMF_Fields in importState and exportState
566      ! Create ESMF_Grid.  Use exactly the same method as WRF so WRFIO will 
567      ! work.  
568      DomainStart(1) = ids; DomainEnd(1) = ide;
569      DomainStart(2) = jds; DomainEnd(2) = jde;
570      MemoryStart(1) = ims; MemoryEnd(1) = ime;
571      MemoryStart(2) = jms; MemoryEnd(2) = jme;
572      PatchStart(1)  = ips; PatchEnd(1)  = ipe;
573      PatchStart(2)  = jps; PatchEnd(2)  = jpe
574 !write(0,*)__FILE__,__LINE__,'DomainStart ',DomainStart(1:2)
575 !write(0,*)__FILE__,__LINE__,'DomainEnd ',DomainEnd(1:2)
576 !write(0,*)__FILE__,__LINE__,'MemoryStart ',MemoryStart(1:2)
577 !write(0,*)__FILE__,__LINE__,'MemoryEnd ',MemoryEnd(1:2)
578 !write(0,*)__FILE__,__LINE__,'PatchStart ',PatchStart(1:2)
579 !write(0,*)__FILE__,__LINE__,'PatchEnd ',PatchEnd(1:2)
580      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  Calling ioesmf_create_grid_int()' )
581      CALL ioesmf_create_grid_int( esmfgrid, NUMDIMS,      &
582                                   DomainStart, DomainEnd, &
583                                   MemoryStart, MemoryEnd, &
584                                   PatchStart, PatchEnd )
585 !write(0,*)__FILE__,__LINE__
586      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  back from ioesmf_create_grid_int()' )
587      ! create ESMF_Fields
588      ! Note use of patch dimension for POINTERs allocated by ESMF.  
589      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  Calling ESMF_GridValidate(esmfgrid)' )
590      CALL ESMF_GridValidate( esmfgrid, rc=rc )
591 !write(0,*)__FILE__,__LINE__
592      IF ( rc /= ESMF_SUCCESS ) THEN
593        WRITE( str,* ) 'Error in ESMF_GridValidate ',   &
594                       __FILE__ ,                       &
595                       ', line ',                       &
596                       __LINE__ ,                       &
597                       ', error code = ',rc
598        CALL wrf_error_fatal ( TRIM(str) )
599      ENDIF
600      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  back OK from ESMF_GridValidate(esmfgrid)' )
601 !TODO:  Once new ESMF 3.0 interfaces have settled down, eliminate "tmp_data_" 
602 !TODO:  arrays and let ESMF allocate/deallocate them.  Assuming of course that 
603 !TODO:  we can convince ESMF to deallocate safely...  
604 !write(0,*)__FILE__,__LINE__
605      ALLOCATE( tmp_data_out_sst(ips:ipe,jps:jpe) )
606 !write(0,*)__FILE__,__LINE__
607      write(str,*) 'sst_component_init2: tmp_data_out_sst(', &
608        LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',',LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2),')'
609      CALL wrf_debug ( 100 , TRIM(str) )
610      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_sst_field)' )
611 !write(0,*)__FILE__,__LINE__,trim(datanames(sst_indx))
612 !write(0,*)__FILE__,__LINE__,ips,jps,ipe,jpe
613      out_sst_field = ESMF_FieldCreate(                 &
614                        esmfgrid, tmp_data_out_sst,     &
615                        datacopyflag=ESMF_DATACOPY_REFERENCE,         &
616                        staggerloc=ESMF_STAGGERLOC_CENTER,          &
617                        name=TRIM(datanames(SST_INDX)), &
618                        rc=rc )
619 !write(0,*)__FILE__,__LINE__,'Creating out_sst_field for exportState of SST component name ',TRIM(datanames(SST_INDX))
620      IF ( rc /= ESMF_SUCCESS ) THEN
621        WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) failed ', &
622                       __FILE__ ,                                 &
623                       ', line ',                                 &
624                       __LINE__ ,                                 &
625                       ', error code = ',rc
626        CALL wrf_error_fatal ( TRIM(str) )
627      ENDIF
628      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_sst_field)' )
629      write(str,*) 'sst_component_init2: ips:ipe,jps:jpe = ', &
630        ips,':',ipe,',',jps,':',jpe
631      CALL wrf_debug ( 100 , TRIM(str) )
632 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
633      ! validate ESMF allocation
634      IF ( ( ips /= LBOUND(tmp_data_out_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_sst,1) ) .OR. &
635           ( jps /= LBOUND(tmp_data_out_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_sst,2) ) ) THEN
636        WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) allocation failed ', &
637                       __FILE__ ,                                            &
638                       ', line ',                                            &
639                       __LINE__ ,                                            &
640                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
641                       ', tmp_data_out_sst(BOUNDS) = ',LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',', &
642                                               LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2)
643        CALL wrf_error_fatal ( TRIM(str) )
644      ENDIF
645      ALLOCATE( tmp_data_out_landmask(ips:ipe,jps:jpe) )
646      write(str,*) 'sst_component_init2: tmp_data_out_landmask(', &
647        LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',',LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2),')'
648      CALL wrf_debug ( 100 , TRIM(str) )
649      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_landmask_field)' )
650      out_landmask_field = ESMF_FieldCreate(                      &
651                             esmfgrid, tmp_data_out_landmask,     &
652                             datacopyflag=ESMF_DATACOPY_REFERENCE,              &
653                             staggerloc=ESMF_STAGGERLOC_CENTER,          &
654                             name=TRIM(datanames(LANDMASK_INDX)), &
655 !                            lbounds=(/ips,jps/),                 &
656 !                            ubounds=(/ipe,jpe/),                 &
657                             rc=rc )
658      IF ( rc /= ESMF_SUCCESS ) THEN
659        CALL wrf_error_fatal ( 'ESMF_FieldCreate(out_landmask_field) failed' )
660      ENDIF
661      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_landmask_field)' )
662 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
663      ! validate ESMF allocation
664      IF ( ( ips /= LBOUND(tmp_data_out_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_landmask,1) ) .OR. &
665           ( jps /= LBOUND(tmp_data_out_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_landmask,2) ) ) THEN
666        WRITE( str,* ) 'ESMF_FieldCreate(out_landmask_field) allocation failed ', &
667                       __FILE__ ,                                            &
668                       ', line ',                                            &
669                       __LINE__ ,                                            &
670                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
671                       ', tmp_data_out_landmask(BOUNDS) = ',LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',', &
672                                               LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2)
673        CALL wrf_error_fatal ( TRIM(str) )
674      ENDIF
675      ALLOCATE( tmp_data_in_sst(ips:ipe,jps:jpe) )
676      write(str,*) 'sst_component_init2: tmp_data_in_sst(', &
677        LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',',LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2),')'
678      CALL wrf_debug ( 100 , TRIM(str) )
679      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_sst_field)' )
680      in_sst_field = ESMF_FieldCreate(                 &
681                       esmfgrid, tmp_data_in_sst,      &
682                       datacopyflag=ESMF_DATACOPY_REFERENCE,         &
683                       staggerloc=ESMF_STAGGERLOC_CENTER,          &
684                       name=TRIM(datanames(SST_INDX)), &
685 !                      lbounds=(/ips,jps/),            &
686 !                      ubounds=(/ipe,jpe/),            &
687                       rc=rc )
688      IF ( rc /= ESMF_SUCCESS ) THEN
689        CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_sst_field) failed' )
690      ENDIF
691      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_sst_field)' )
692 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
693      ! validate ESMF allocation
694      IF ( ( ips /= LBOUND(tmp_data_in_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_sst,1) ) .OR. &
695           ( jps /= LBOUND(tmp_data_in_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_sst,2) ) ) THEN
696        WRITE( str,* ) 'ESMF_FieldCreate(in_sst_field) allocation failed ', &
697                       __FILE__ ,                                            &
698                       ', line ',                                            &
699                       __LINE__ ,                                            &
700                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
701                       ', tmp_data_in_sst(BOUNDS) = ',LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',', &
702                                               LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2)
703        CALL wrf_error_fatal ( TRIM(str) )
704      ENDIF
705      ALLOCATE( tmp_data_in_landmask(ips:ipe,jps:jpe) )
706      write(str,*) 'sst_component_init2: tmp_data_in_landmask(', &
707        LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',',LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2),')'
708      CALL wrf_debug ( 100 , TRIM(str) )
709      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_landmask_field)' )
710      in_landmask_field = ESMF_FieldCreate(                      &
711                            esmfgrid, tmp_data_in_landmask,      &
712                            datacopyflag=ESMF_DATACOPY_REFERENCE,              &
713                            staggerloc=ESMF_STAGGERLOC_CENTER,          &
714                            name=TRIM(datanames(LANDMASK_INDX)), &
715 !                           lbounds=(/ips,jps/),                 &
716 !                           ubounds=(/ipe,jpe/),                 &
717                            rc=rc )
718      IF ( rc /= ESMF_SUCCESS ) THEN
719        CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_landmask_field) failed' )
720      ENDIF
721      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_landmask_field)' )
722 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
723      ! validate ESMF allocation
724      IF ( ( ips /= LBOUND(tmp_data_in_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_landmask,1) ) .OR. &
725           ( jps /= LBOUND(tmp_data_in_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_landmask,2) ) ) THEN
726        WRITE( str,* ) 'ESMF_FieldCreate(in_landmask_field) allocation failed ', &
727                       __FILE__ ,                                            &
728                       ', line ',                                            &
729                       __LINE__ ,                                            &
730                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
731                       ', tmp_data_in_landmask(BOUNDS) = ',LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',', &
732                                               LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2)
733        CALL wrf_error_fatal ( TRIM(str) )
734      ENDIF
736      ! attach ESMF_Field to importState
737      CALL ESMF_StateAdd( importState, fieldList=(/in_sst_field/), rc=rc )
738      IF ( rc /= ESMF_SUCCESS ) THEN
739        CALL wrf_error_fatal ( 'ESMF_StateAdd(in_sst_field) failed' )
740      ENDIF
741      CALL ESMF_StateAdd( importState, fieldList=(/in_landmask_field/), rc=rc )
742      IF ( rc /= ESMF_SUCCESS ) THEN
743        CALL wrf_error_fatal ( 'ESMF_StateAdd(in_landmask_field) failed' )
744      ENDIF
745      ! attach ESMF_Field to exportState
746      CALL ESMF_StateAdd( exportState, fieldList=(/out_sst_field/), rc=rc )
747      IF ( rc /= ESMF_SUCCESS ) THEN
748        CALL wrf_error_fatal ( 'ESMF_StateAdd(out_sst_field) failed' )
749      ENDIF
750      CALL ESMF_StateAdd( exportState, fieldList=(/out_landmask_field/), rc=rc )
751      IF ( rc /= ESMF_SUCCESS ) THEN
752        CALL wrf_error_fatal ( 'ESMF_StateAdd(out_landmask_field) failed' )
753      ENDIF
755      !  Open the "SST" input data file for reading.
756      write(str,'(A,A)') 'sst_component_init2: Opening data file ', &
757        TRIM(sstinfilename)
758      CALL wrf_message ( TRIM(str) )
759      CALL wrf_open_for_read ( TRIM(sstinfilename) , &
760                               mpicom ,              &
761                               mpicom ,              &
762                               "DATASET=INPUT" ,     &
763                               fid ,                 &
764                               ierr )
765      IF ( ierr .NE. 0 ) THEN
766        WRITE( str , FMT='(A,A,A,I8)' )  &
767          'sst_component_init2: error opening ', &
768          TRIM(sstinfilename),' for reading ierr=',ierr
769        CALL wrf_error_fatal ( TRIM(str) )
770      ENDIF
771      WRITE( str , FMT='(A,A,A,I8)' ) &
772        'subroutine sst_component_init2: opened file ', &
773        TRIM(sstinfilename),' for reading fid=',fid
774      CALL wrf_debug ( 100, TRIM(str) )
776      write(str,'(A)') 'sst_component_init2: returning rc=ESMF_SUCCESS'
777      CALL wrf_debug ( 100 , TRIM(str) )
779      rc = ESMF_SUCCESS
781    END SUBROUTINE sst_component_init2
785    SUBROUTINE sst_component_run1( gcomp, importState, exportState, clock, rc )
786      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
787      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
788      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
789      INTEGER,                     INTENT(  OUT) :: rc
790 !<DESCRIPTION>
791 !     SST component run routine, phase 1.
792 !     Read "SST" data from file and stuff into exportState.  
794 !     The arguments are:
795 !       gcomp           Component
796 !       importState     Importstate
797 !       exportState     Exportstate
798 !       clock           External clock
799 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
800 !                       otherwise ESMF_FAILURE.
801 !</DESCRIPTION>
803      rc = ESMF_SUCCESS
805      ! Get "SST" data from file and stuff it into exportState.  
806      CALL read_data( exportState, clock )
808    END SUBROUTINE sst_component_run1
812    SUBROUTINE sst_component_run2( gcomp, importState, exportState, clock, rc )
813      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
814      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
815      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
816      INTEGER,                     INTENT(  OUT) :: rc
817 !<DESCRIPTION>
818 !     SST component run routine, phase 2.
819 !     Get from importState, compare with file data, and error-exit 
820 !     if they differ...  If they are the same, then 
821 !     stuff the file data into the exportState.  
823 !     The arguments are:
824 !       gcomp           Component
825 !       importState     Importstate
826 !       exportState     Exportstate
827 !       clock           External clock
828 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
829 !                       otherwise ESMF_FAILURE.
830 !</DESCRIPTION>
832      rc = ESMF_SUCCESS
834      ! Get from importState, compare with file data, and error_exit 
835      ! if they differ...  
836 !TODO:  change this once WRF can load exportState after integrating
837      ! This works because WRF loads its exportState BEFORE integrating.  
838      CALL wrf_clockprint ( 50, clock, 'sst_component_run2:  clock before call to compare_data()' )
839      CALL compare_data( importState, clock )
840      CALL wrf_clockprint ( 50, clock, 'sst_component_run2:  clock after call to compare_data()' )
842    END SUBROUTINE sst_component_run2
846    SUBROUTINE sst_component_finalize( gcomp, importState, exportState, clock, rc )
847      USE module_io
848      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
849      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
850      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
851      INTEGER,                     INTENT(  OUT) :: rc
852 !<DESCRIPTION>
853 !     SST component finalize routine.
855 !     The arguments are:
856 !       gcomp           Component
857 !       importState     Importstate
858 !       exportState     Exportstate
859 !       clock           External clock
860 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
861 !                       otherwise ESMF_FAILURE.
862 !</DESCRIPTION>
864      ! Local variables
865      TYPE(ESMF_Field) :: tmp_field
866      INTEGER :: i, ierr
868      rc = ESMF_SUCCESS
870      ! destroy ESMF_Fields and other "deep" objects created by this component
871      ! note that this component relied on ESMF to allocate data pointers during 
872      ! calls to ESMF_FieldCreate() so it also expects ESMF to free these pointers 
873      DO i=1, datacount
874        ! destroy field in importState
875        CALL ESMF_StateGet( importState, TRIM(datanames(i)), tmp_field, &
876                                 rc=rc )
877        IF (rc /= ESMF_SUCCESS) THEN
878          WRITE( str , * )                                               &
879            'sst_component_finalize:  ESMF_StateGet( importState,', &
880            TRIM(datanames(i)),') failed'
881          CALL wrf_error_fatal ( TRIM(str) )
882        ENDIF
883        CALL ESMF_FieldDestroy( tmp_field, rc=rc )
884        IF (rc /= ESMF_SUCCESS) THEN
885          WRITE( str , * )                                              &
886            'sst_component_finalize:  ESMF_FieldDestroy( importState,', &
887            TRIM(datanames(i)),') failed'
888          CALL wrf_error_fatal ( TRIM(str) )
889        ENDIF
890        ! destroy field in exportState
891        CALL ESMF_StateGet( exportState, TRIM(datanames(i)), tmp_field, &
892                                 rc=rc )
893        IF (rc /= ESMF_SUCCESS) THEN
894          WRITE( str , * )                                               &
895            'sst_component_finalize:  ESMF_StateGet( exportState,', &
896            TRIM(datanames(i)),') failed'
897          CALL wrf_error_fatal ( TRIM(str) )
898        ENDIF
899        CALL ESMF_FieldDestroy( tmp_field, rc=rc )
900        IF (rc /= ESMF_SUCCESS) THEN
901          WRITE( str , * )                                              &
902            'sst_component_finalize:  ESMF_FieldDestroy( exportState,', &
903            TRIM(datanames(i)),') failed'
904          CALL wrf_error_fatal ( TRIM(str) )
905        ENDIF
906      ENDDO
908      ! deallocate space for data read from disk
909      DEALLOCATE( file_sst_data, file_landmask_data )
911      ! close SST data file
912      WRITE( str , FMT='(A,I8)' ) &
913        'subroutine sst_component_finalize: closing file fid=',fid
914      CALL wrf_debug ( 100, TRIM(str) )
915      CALL wrf_ioclose( fid , ierr )
916      IF ( ierr .NE. 0 ) THEN
917        CALL wrf_error_fatal ( 'sst_component_finalize:  wrf_ioclose failed' )
918      ENDIF
920    END SUBROUTINE sst_component_finalize
923 END MODULE module_sst_component_top
928 MODULE module_sst_setservices
929 !<DESCRIPTION>
930 ! This module defines SST "Set Services" method sst_register() 
931 ! used for ESMF coupling.  
932 !</DESCRIPTION>
934    USE module_sst_component_top, ONLY: sst_component_init1,  &
935                                        sst_component_init2,  &
936                                        sst_component_run1,   &
937                                        sst_component_run2,   &
938                                        sst_component_finalize
939 !  Updated for ESMF 5.2.0r 
940 !   USE ESMF_Mod
941    USE ESMF
943    IMPLICIT NONE
945    ! everything is private by default
946    PRIVATE
948    ! Public entry point for ESMF_GridCompSetServices()
949    PUBLIC SST_register
951    ! private stuff
952    CHARACTER (ESMF_MAXSTR) :: str
954 CONTAINS
957    SUBROUTINE sst_register(gcomp, rc)
958      TYPE(ESMF_GridComp), INTENT(INOUT) :: gcomp
959      INTEGER, INTENT(OUT) :: rc
960      INTEGER :: finalrc
962 !<DESCRIPTION>
963 !     SST_register - Externally visible registration routine
965 !     User-supplied SetServices routine.
966 !     The Register routine sets the subroutines to be called
967 !     as the init, run, and finalize routines.  Note that these are
968 !     private to the module.
970 !     The arguments are:
971 !       gcomp           Component
972 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
973 !                       otherwise ESMF_FAILURE.
974 !</DESCRIPTION>
976      finalrc = ESMF_SUCCESS
977      ! Register the callback routines.
978      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
979                                      sst_component_init1, phase=1, rc=rc)
980      IF ( rc /= ESMF_SUCCESS) THEN
981         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init1) failed with rc = ', rc
982         CALL wrf_error_fatal ( TRIM(str) )
983      ENDIF
984      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_INITIALIZE, &
985                                      sst_component_init2, phase=2, rc=rc)
986      IF ( rc /= ESMF_SUCCESS) THEN
987         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init2) failed with rc = ', rc
988         CALL wrf_error_fatal ( TRIM(str) )
989      ENDIF
990      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_RUN, &
991                                      sst_component_run1, phase=1, rc=rc)
992      IF ( rc /= ESMF_SUCCESS) THEN
993         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run1) failed with rc = ', rc
994         CALL wrf_error_fatal ( TRIM(str) )
995      ENDIF
996      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_RUN, &
997                                      sst_component_run2, phase=2, rc=rc)
998      IF ( rc /= ESMF_SUCCESS) THEN
999         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run2) failed with rc = ', rc
1000         CALL wrf_error_fatal ( TRIM(str) )
1001      ENDIF
1002      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_METHOD_FINALIZE, &
1003                                      sst_component_finalize, rc=rc)
1004      IF ( rc /= ESMF_SUCCESS) THEN
1005         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_finalize) failed with rc = ', rc
1006         CALL wrf_error_fatal ( TRIM(str) )
1007      ENDIF
1009      PRINT *,'SST:  Registered Initialize, Run, and Finalize routines'
1011      rc = finalrc
1013    END SUBROUTINE sst_register
1015 END MODULE module_sst_setservices
1019 !<DESCRIPTION>
1020 ! Module module_wrfsst_coupler defines the 
1021 ! "WRF-SST" coupler component.  It provides two-way coupling between 
1022 ! the "SST" and "WRF" components.  
1023 ! In its run routine it transfers data directly from the 
1024 ! SST Component's export state to the WRF Component's import state.  
1025 ! It also transfers data directly from the 
1026 ! WRF Component's export state to the SST Component's import state.  
1028 ! This is derived from src/demo/coupled_flow/src/CouplerMod.F90
1029 ! created by Nancy Collins and others on the ESMF Core Team.  
1031 !</DESCRIPTION>
1033 MODULE module_wrfsst_coupler
1035 ! Updated for ESMF 5.2.0r
1036 !    USE ESMF_Mod
1037     USE ESMF
1039     IMPLICIT NONE
1040     
1041     ! everything is private by default
1042     PRIVATE
1044     ! Public entry point 
1045     PUBLIC WRFSSTCpl_register
1047     ! private data members
1048     ! route handles and flags
1049     TYPE(ESMF_RouteHandle), SAVE :: fromWRF_rh, fromSST_rh
1050     LOGICAL, SAVE :: fromWRF_rh_ready = .FALSE.
1051     LOGICAL, SAVE :: fromSST_rh_ready = .FALSE.
1052     ! field names
1053     INTEGER, PARAMETER :: datacount = 2
1054     INTEGER, PARAMETER :: SST_INDX = 1
1055     INTEGER, PARAMETER :: LANDMASK_INDX = 2
1056     CHARACTER(LEN=ESMF_MAXSTR), SAVE :: datanames(datacount)
1057     CHARACTER(LEN=ESMF_MAXSTR) :: str
1060 CONTAINS
1063    SUBROUTINE WRFSSTCpl_register(comp, rc)
1064      TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1065      INTEGER, INTENT(OUT) :: rc
1067 !<DESCRIPTION>
1068 !     WRFSSTCpl_register - Externally visible registration routine
1070 !     User-supplied SetServices routine.
1071 !     The Register routine sets the subroutines to be called
1072 !     as the init, run, and finalize routines.  Note that these are
1073 !     private to the module.
1075 !     The arguments are:
1076 !       comp            Component
1077 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1078 !                       otherwise ESMF_FAILURE.
1079 !</DESCRIPTION>
1081       ! guilty until proven innocent
1082       rc = ESMF_FAILURE
1084       ! Register the callback routines.
1086       call ESMF_CplCompSetEntryPoint(comp, ESMF_METHOD_INITIALIZE, WRFSSTCpl_init, &
1087                                      rc=rc)
1088       IF ( rc /= ESMF_SUCCESS ) THEN
1089         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_init) failed' )
1090       ENDIF
1091       call ESMF_CplCompSetEntryPoint(comp, ESMF_METHOD_RUN, WRFSSTCpl_run, &
1092                                      rc=rc)
1093       IF ( rc /= ESMF_SUCCESS ) THEN
1094         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_run) failed' )
1095       ENDIF
1096       call ESMF_CplCompSetEntryPoint(comp, ESMF_METHOD_FINALIZE, WRFSSTCpl_final, &
1097                                      rc=rc)
1098       IF ( rc /= ESMF_SUCCESS ) THEN
1099         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_final) failed' )
1100       ENDIF
1102       print *, "module_wrfsst_coupler: Registered Initialize, Run, and Finalize routines"
1104     END SUBROUTINE WRFSSTCpl_register
1107     SUBROUTINE WRFSSTCpl_init(comp, importState, exportState, clock, rc)
1108       USE module_metadatautils, ONLY: AttachDecompToState, GetDecompFromState
1109       TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1110       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1111       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1112       INTEGER, INTENT(OUT) :: rc
1113 !<DESCRIPTION>
1114 !     WRF-SST coupler component init routine.  This simply passes needed 
1115 !     metadata from WRF to SST.  Initialization of ESMF_RouteHandle objects 
1116 !     is handled later via lazy evaluation.  
1118 !     The arguments are:
1119 !       comp            Component
1120 !       importState     Importstate
1121 !       exportState     Exportstate
1122 !       clock           External clock
1123 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1124 !                       otherwise ESMF_FAILURE.
1125 !</DESCRIPTION>
1127       ! Local variables
1128       CHARACTER(ESMF_MAXSTR) :: importstatename
1129       ! decomposition information
1130       INTEGER :: ids, ide, jds, jde, kds, kde
1131       INTEGER :: ims, ime, jms, jme, kms, kme
1132       INTEGER :: ips, ipe, jps, jpe, kps, kpe
1133       INTEGER :: domdesc
1134       LOGICAL :: bdy_mask(4)
1136       PRINT *, "DEBUG:  Coupler Init starting"
1138       ! guilty until proven innocent
1139       rc = ESMF_FAILURE
1141       CALL ESMF_StateGet(importState, name=importstatename, rc=rc)
1142       IF ( rc /= ESMF_SUCCESS ) THEN
1143         CALL wrf_error_fatal ( 'WRFSSTCpl_init:  ESMF_StateGet failed' )
1144       ENDIF
1146       IF ( TRIM(importstatename) .EQ. "WRF Export State" ) THEN
1147         ! get metadata from WRF export state
1148         CALL GetDecompFromState( importState,                  &
1149                                  ids, ide, jds, jde, kds, kde, &
1150                                  ims, ime, jms, jme, kms, kme, &
1151                                  ips, ipe, jps, jpe, kps, kpe, &
1152                                  domdesc, bdy_mask )
1153         ! put metadata from in SST import state
1154         CALL AttachDecompToState( exportState,                  &
1155                                   ids, ide, jds, jde, kds, kde, &
1156                                   ims, ime, jms, jme, kms, kme, &
1157                                   ips, ipe, jps, jpe, kps, kpe, &
1158                                   domdesc, bdy_mask )
1161       ELSE
1162         WRITE(str,*)'WRFSSTCpl_init:  invalid importState name: ',TRIM(importstatename)
1163         CALL wrf_error_fatal ( TRIM(str) )
1164       ENDIF
1166       ! set up field names
1167 !TODO:  use CF conventions for "standard_name" once WRF Registry supports them
1168 !TODO:      datanames(SST_INDX) = "sea_surface_temperature"
1169 !TODO:      datanames(LANDMASK_INDX) = "land_binary_mask"
1170       datanames(SST_INDX) = "SST"
1171       datanames(LANDMASK_INDX) = "LANDMASK"
1173       PRINT *, "DEBUG:  Coupler Init returning"
1174    
1175     END SUBROUTINE WRFSSTCpl_init
1179     SUBROUTINE WRFSSTCpl_run(comp, importState, exportState, clock, rc)
1180       USE ESMF
1181       TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1182       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1183       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1184       INTEGER, INTENT(OUT) :: rc
1185 !<DESCRIPTION>
1186 !     WRF-SST coupler component run routine.
1188 !     The arguments are:
1189 !       comp            Component
1190 !       importState     Importstate
1191 !       exportState     Exportstate
1192 !       clock           External clock
1193 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1194 !                       otherwise ESMF_FAILURE.
1195 !</DESCRIPTION>
1197 ! Note that comments in this code are preserved from the sample coupler 
1198 ! provided by the ESMF core team.  
1200       ! Local variables
1201       TYPE(ESMF_Field) :: src_field, dst_field
1202       TYPE(ESMF_Array) :: src_array, dst_array
1203       TYPE(ESMF_RouteHandle) :: routehandle
1204       TYPE(ESMF_VM) :: vm
1205       LOGICAL :: build_fromWRF_rh, build_fromSST_rh, fromWRF
1206       CHARACTER(LEN=ESMF_MAXSTR) :: importStatename
1207       CHARACTER(LEN=ESMF_MAXSTR) :: SST_exportStatename, WRF_exportStatename
1208       INTEGER :: i
1209       CHARACTER(LEN=256) :: directionString
1210       LOGICAL :: neededFlag(1)
1212       WRITE(str,*) 'WRFSSTCpl_run: begin'
1213       CALL wrf_debug ( 100 , TRIM(str) )
1215       ! guilty until proven innocent
1216       rc = ESMF_FAILURE
1218       ! Which way is this coupling going?  
1219       WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateGet(importState,name,...)'
1220       CALL wrf_debug ( 100 , TRIM(str) )
1221       CALL ESMF_StateGet( importState, name=importStatename, rc=rc )
1222       WRITE(str,*) 'WRFSSTCpl_run: importStatename ', trim(importStatename), 'rc = ', rc
1223       CALL wrf_debug ( 100, TRIM(str) )
1224       IF ( rc /= ESMF_SUCCESS ) THEN
1225         CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(importState,name,...) failed' )
1226       ENDIF
1227       WRITE(str,*) 'WRFSSTCpl_run: back from ESMF_StateGet, importStatename = <',TRIM(importStatename),'>'
1228       CALL wrf_debug ( 100 , TRIM(str) )
1230       ! first time through in each direction:  create route handle and 
1231       ! associated objects
1232       WRF_exportStatename = "WRF Export State"
1233       SST_exportStatename = "SST Export State"
1234       IF ( TRIM(importStatename) .EQ. TRIM(WRF_exportStatename) ) THEN
1235         fromWRF = .TRUE.
1236         directionString = 'WRFtoSST'
1237       ELSE IF ( TRIM(importStatename) .EQ. TRIM(SST_exportStatename) ) THEN
1238         fromWRF = .FALSE.
1239         directionString = 'SSTtoWRF'
1240       ELSE
1241         WRITE(str,*)'WRFSSTCpl_run:  invalid importState name: ',TRIM(importstatename)
1242         CALL wrf_error_fatal ( TRIM(str) )
1243       ENDIF
1244       WRITE(str,*) 'WRFSSTCpl_run: fromWRF = ',fromWRF
1245       CALL wrf_debug ( 100 , TRIM(str) )
1246       build_fromWRF_rh =         fromWRF   .AND. ( .NOT. fromWRF_rh_ready )
1247       build_fromSST_rh = ( .NOT. fromWRF ) .AND. ( .NOT. fromSST_rh_ready )
1248       WRITE(str,*) 'WRFSSTCpl_run: build_fromWRF_rh = ',build_fromWRF_rh
1249       CALL wrf_debug ( 100 , TRIM(str) )
1250       WRITE(str,*) 'WRFSSTCpl_run: build_fromSST_rh = ',build_fromSST_rh
1251       CALL wrf_debug ( 100 , TRIM(str) )
1252       IF ( build_fromWRF_rh .OR. build_fromSST_rh ) THEN
1253         CALL ESMF_CplCompGet( comp, vm=vm, rc=rc )
1254         IF ( rc /= ESMF_SUCCESS ) THEN
1255           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_CplCompGet failed' )
1256         ENDIF
1257         ! The use of literal index "1" here indicates that we don't care which 
1258         ! ESMF_Field we get so we might as well get the first one.  
1259         WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1260                      '> from import state'
1261         CALL wrf_debug ( 100 , TRIM(str) )
1263         CALL ESMF_StateGet( importState, TRIM(datanames(1)), src_field, &
1264                                  rc=rc )
1265         IF ( rc /= ESMF_SUCCESS ) THEN
1266           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(importState) failed' )
1267         ENDIF
1269         CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1270         IF ( rc /= ESMF_SUCCESS ) THEN
1271           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldGet src_array failed' )
1272         ENDIF
1273         WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1274                      '> from export state'
1275         CALL wrf_debug ( 100 , TRIM(str) )
1277         CALL ESMF_StateGet( exportState, TRIM(datanames(1)), dst_field, &
1278                                  rc=rc )
1279         IF ( rc /= ESMF_SUCCESS ) THEN
1280           WRITE(str,*)'WRFSSTCpl_run: datanames(1) ',TRIM(datanames(1)),' rc ',rc
1281           CALL wrf_message(TRIM(str))
1282           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(exportState) failed' )
1283         ENDIF
1284         CALL ESMF_FieldGet( dst_field, array=dst_array, &
1285                                  rc=rc )
1286         IF ( rc /= ESMF_SUCCESS ) THEN
1287           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldGet dst_array failed' )
1288         ENDIF
1291         IF ( build_fromWRF_rh ) THEN
1292           WRITE(str,*) 'WRFSSTCpl_run: creating fromWRF_rh'
1293           CALL wrf_debug ( 100 , TRIM(str) )
1294           fromWRF_rh = ESMF_RouteHandleCreate( rc )
1295           IF ( rc /= ESMF_SUCCESS ) THEN
1296             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_RouteHandleCreate(fromWRF_rh) failed' )
1297           ENDIF
1298           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromWRF_rh)'
1299           CALL wrf_debug ( 100 , TRIM(str) )
1300           CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1301                                       routehandle=fromWRF_rh, rc=rc )
1302           IF ( rc /= ESMF_SUCCESS ) THEN
1303             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedistStore(fromWRF_rh) failed' )
1304           ENDIF
1305           fromWRF_rh_ready = .TRUE.
1306         ENDIF
1307         IF ( build_fromSST_rh ) THEN
1308           WRITE(str,*) 'WRFSSTCpl_run: creating fromSST_rh'
1309           CALL wrf_debug ( 100 , TRIM(str) )
1310           fromSST_rh = ESMF_RouteHandleCreate( rc )
1311           IF ( rc /= ESMF_SUCCESS ) THEN
1312             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_RouteHandleCreate(fromSST_rh) failed' )
1313           ENDIF
1314           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromSST_rh)'
1315           CALL wrf_debug ( 100 , TRIM(str) )
1316           CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1317                                       routehandle=fromSST_rh, rc=rc )
1318 !write(0,*)__FILE__,__LINE__,'rc = ',rc
1319           IF ( rc /= ESMF_SUCCESS ) THEN
1320             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedistStore(fromSST_rh) failed' )
1321           ENDIF
1322           fromSST_rh_ready = .TRUE.
1323         ENDIF
1324         DO i=1, datacount
1325           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_AttributeSet(importState, ',TRIM(datanames(i))//':needed',')'
1326           CALL wrf_debug ( 100 , TRIM(str) )
1327 !5.2.0r          CALL ESMF_StateSetNeeded( importState, TRIM(datanames(i)), &
1328 !5.2.0r                                    ESMF_NEEDED, rc=rc )
1329           CALL ESMF_AttributeSet( importState, name=TRIM(datanames(i))//':needed',value=.true.,rc=rc)
1330           IF ( rc /= ESMF_SUCCESS ) THEN
1331             WRITE(str,*) 'WRFSSTCpl_run:  ESMF_AttributeSet(',TRIM(datanames(i))//':needed',') failed'
1332             CALL wrf_error_fatal ( str )
1333           ENDIF
1334         ENDDO
1335       ENDIF
1337       ! In this case, the coupling is symmetric - you call redist going
1338       ! both ways - so we only care about the coupling direction in order 
1339       ! to get the right routehandle selected.
1340       IF ( fromWRF ) THEN
1341         WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromWRF_rh'
1342         CALL wrf_debug ( 100 , TRIM(str) )
1343         routehandle = fromWRF_rh 
1344       ELSE
1345         WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromSST_rh'
1346         CALL wrf_debug ( 100 , TRIM(str) )
1347         routehandle = fromSST_rh 
1348       ENDIF
1350       DO i=1, datacount
1351         WRITE(str,*) 'WRFSSTCpl_run: grabbing field <',TRIM(datanames(i)),'>'
1352         CALL wrf_debug ( 100 , TRIM(str) )
1353         ! check isneeded flag here
1354 !5.2.0r        IF ( .NOT. ESMF_StateIsNeeded( importState, TRIM(datanames(i)), rc=rc ) ) THEN 
1355 !5.2.0r         IF ( rc /= ESMF_SUCCESS ) THEN
1356 !5.2.0r            WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateIsNeeded(',TRIM(datanames(i)),') failed'
1357 !5.2.0r            CALL wrf_error_fatal ( str )
1358 !5.2.0r          ENDIF
1359 !5.2.0r          WRITE(str,*) 'WRFSSTCpl_run: skipping field <',TRIM(datanames(i)),'>'
1360 !5.2.0r          CALL wrf_debug ( 100 , TRIM(str) )
1361 !5.2.0r          CYCLE
1362 !5.2.0r        ENDIF
1363         CALL ESMF_AttributeGet(importState,name=TRIM(datanames(i))//':needed',valueList=neededFlag,rc=rc)
1364         IF ( rc == ESMF_SUCCESS ) THEN
1365           IF ( .NOT. neededFlag(1) ) THEN
1366             WRITE(str,*) 'WRFSSTCpl_run: skipping field <',TRIM(datanames(i)),'>'
1367             CALL wrf_debug ( 100 , TRIM(str) )
1368             CYCLE
1369           ENDIF
1370         ELSE
1371           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_AttributeGet(',TRIM(datanames(i))//':needed',') failed'
1372           CALL wrf_error_fatal ( str )
1373         ENDIF
1375         WRITE(str,*) 'WRFSSTCpl_run: processing field <',TRIM(datanames(i)),'>'
1376         CALL wrf_debug ( 100 , TRIM(str) )
1378 !   The following piece of code provides an example of calling the data
1379 !   redistribution routine  between two Fields in the Coupler Component.  
1380 !   Unlike regrid, which translates between
1381 !   different Grids, redist translates between different DELayouts on
1382 !   the same Grid.   The first two lines get the Fields from the 
1383 !   States, each corresponding to a different subcomponent.  One is
1384 !   an Export State and the other is an Import State.
1386         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_StateGet(importState,', &
1387                      TRIM(datanames(i)),')...'
1388         CALL wrf_debug ( 100 , TRIM(str) )
1389         CALL ESMF_StateGet( importState, TRIM(datanames(i)), src_field, &
1390                                  rc=rc )
1391         IF ( rc /= ESMF_SUCCESS ) THEN
1392           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateGet(importState,', &
1393                        TRIM(datanames(i)),') failed'
1394           CALL wrf_error_fatal ( str )
1395         ENDIF
1396         CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1397         IF ( rc /= ESMF_SUCCESS ) THEN
1398           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_FieldGet(src_field,src_array,rc) failed'
1399           CALL wrf_error_fatal ( str )
1400         ENDIF
1402         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_StateGet(exportState,', &
1403                      TRIM(datanames(i)),')...'
1404         CALL wrf_debug ( 100 , TRIM(str) )
1405         CALL ESMF_StateGet( exportState, TRIM(datanames(i)), dst_field, &
1406                                  rc=rc )
1407         IF ( rc /= ESMF_SUCCESS ) THEN
1408           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateGet(exportState,', &
1409                        TRIM(datanames(i)),') failed'
1410           CALL wrf_error_fatal ( str )
1411         ENDIF
1412         CALL ESMF_FieldGet( dst_field, array=dst_array, rc=rc )
1413         IF ( rc /= ESMF_SUCCESS ) THEN
1414           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_FieldGet(dst_field,dst_array,rc) failed'
1415           CALL wrf_error_fatal ( str )
1416         ENDIF
1418 !   The redist routine uses information contained in the Fields and the
1419 !   Coupler VM object to call the communication routines to move the data.
1420 !   Because many Fields may share the same Grid association, the same
1421 !   routing information may be needed repeatedly.  Route information is 
1422 !   saved so the precomputed information can be retained.  The following 
1423 !   is an example of a Field redist call:
1424         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_FieldRedist for <', &
1425                      TRIM(datanames(i)),'>...'
1426         CALL wrf_debug ( 100 , TRIM(str) )
1427         CALL ESMF_ArrayRedist( src_array, dst_array, routehandle, rc=rc )
1428         IF ( rc /= ESMF_SUCCESS ) THEN
1429           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedist failed' )
1430         ENDIF
1431         WRITE(str,*) 'WRFSSTCpl_run:  back from ESMF_FieldRedist for <', &
1432                      TRIM(datanames(i)),'>...'
1433         CALL wrf_debug ( 100 , TRIM(str) )
1435       ENDDO
1437       WRITE(str,*) 'WRFSSTCpl_run: end'
1438       CALL wrf_debug ( 100 , TRIM(str) )
1440     END SUBROUTINE WRFSSTCpl_run
1444     SUBROUTINE WRFSSTCpl_final(comp, importState, exportState, clock, rc)
1445       TYPE(ESMF_CplComp) :: comp
1446       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1447       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1448       INTEGER, INTENT(OUT) :: rc
1449 !<DESCRIPTION>
1450 !     WRF-SST coupler component finalize routine.
1452 !     The arguments are:
1453 !       comp            Component
1454 !       importState     Importstate
1455 !       exportState     Exportstate
1456 !       clock           External clock
1457 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1458 !                       otherwise ESMF_FAILURE.
1459 !</DESCRIPTION>
1461       PRINT *, "DEBUG:  Coupler Final starting"
1462    
1463       ! guilty until proven innocent
1464       rc = ESMF_FAILURE
1466       ! Only thing to do here is release redist and route handles
1467       IF ( fromWRF_rh_ready ) THEN
1468         CALL ESMF_RouteHandleDestroy(fromWRF_rh, rc)
1469         IF ( rc /= ESMF_SUCCESS ) THEN
1470           CALL wrf_error_fatal ( 'WRFSSTCpl_final:  ESMF_RouteHandleDestroy(fromWRF_rh) failed' )
1471         ENDIF
1472       ENDIF
1473       IF ( fromSST_rh_ready ) THEN
1474         CALL ESMF_RouteHandleDestroy(fromSST_rh, rc)
1475         IF ( rc /= ESMF_SUCCESS ) THEN
1476           CALL wrf_error_fatal ( 'WRFSSTCpl_final:  ESMF_RouteHandleDestroy(fromSST_rh) failed' )
1477         ENDIF
1478       ENDIF
1480       PRINT *, "DEBUG:  Coupler Final returning"
1481    
1482     END SUBROUTINE WRFSSTCpl_final
1485 END MODULE module_wrfsst_coupler
1486     
1487     
1490 PROGRAM wrf_SST_ESMF
1492 !<DESCRIPTION>
1493 ! ESMF Application Wrapper for coupling WRF with a "dummy" component 
1494 ! that simply reads SSTs from a file and sends them to WRF (one-way 
1495 ! coupling).  Fields are returned from WRF to SST via the coupler for 
1496 ! self-test only.  
1498 ! Note that, like other WRF coupling methods (MCEL, MCT), ESMF coupling is 
1499 ! supported only via auxiliary input and history streams.  
1501 ! This is the main program that creates the ESMF Gridded and Coupler 
1502 ! Component.  
1504 ! "init" looks like this:  
1505 !   1. Init phase 1 for WRF, sets WRF exportState metadata for "time" 
1506 !      and "domain" information needed by WRF IOAPI (which is called from 
1507 !      the SST component).  It also sets up all WRF and WSF modules.  Note 
1508 !      that this must be called before SST phase-1 init because SST uses 
1509 !      WRF IOAPI.  
1510 !   2. Init phase 1 for SST, sets "time" metadata in SST exportState.  
1511 !   3. Initialize coupler, passing decomposition metadata from WRF exportState 
1512 !      to SST importState.  
1513 !   4. Resolve any "time" metadata inconsistencies and create top-level clock.  
1514 !   5. Init phase 2 for SST, gets "domain" information from importState, 
1515 !      creates an ESMF_Grid based on "domain" information using the exact same 
1516 !      method as WRF (so WRF IOAPI calls will work), and sets up SST 
1517 !      importState and exportState.  
1518 !   6. Init phase 2 for WRF, runs up to the end of the head_grid I/O "training" 
1519 !      phase (done in med_before_solve_io()).  This initializes WRF 
1520 !      importState and exportState prior to the first coupling step during the 
1521 !      "run" loop.  Note that this only works for head_grid at present because 
1522 !      recursion in WRF traversal of subdomains is not dealt with yet and 
1523 !      because the code that populates the WRF importState and exportState is 
1524 !      not yet sophisticated enough to handle creating and destroying nested 
1525 !      domains at any time during the model run.  
1526 !TODO:  ESMF auxio must begin at the start of the run.  Remove this 
1527 !TODO:  restriction later, if needed.  
1529 !TODO:  Note that coupling is currently limited to one auxin plus one auxout 
1530 !TODO:  streams.  Extension to multiple pairs of auxio streams requires 
1531 !TODO:  nested states (one for each auxio stream pair).  
1532 !TODO:  For now, only support one input and/or one output stream via 
1533 !TODO:  io_esmf.  This condition is asserted in 
1534 !TODO:  ext_esmf_open_for_read_begin() and 
1535 !TODO:  ext_esmf_open_for_write_begin().  
1537 ! "run" loop looks like this:  
1538 !   1. Run SST phase 1, reads SST from file and writes it to SST exportState 
1539 !      for coupling to WRF.  
1540 !   2. Couple SST exportState -> WRF importState.  First iteration:  set up 
1541 !      SST->WRF routeHandle via lazy evaluation.  
1542 !   3. Run WRF.  First iteration:  head_grid resumes after I/O "training" 
1543 !      phase.  Other iterations and domains:  run normally.  
1544 !      Read WRF importState and write WRF exportState (via med_before_solve_io()).  
1545 !      Note that WRF assigns sst -> tsk for sea points in 
1546 !      share/module_soil_pre.F.  
1547 !   4. Couple WRF exportState -> SST importState.  First iteration:  set up
1548 !      WRF->SST routeHandle via lazy evaluation.
1549 !   5. Run SST phase 2, compare SST from file with SST from WRF (via 
1550 !      SST importState) and error-exit if they differ.  
1551 !   6. Advance clock and goto step 1
1553 ! "finalize" is trivial, except for destruction of ESMF objects which is 
1554 ! quite non-trivial at the moment.  
1556 !</DESCRIPTION>
1558    ! WRF registration routine
1559    USE module_wrf_setservices, ONLY: WRF_register
1560    ! SST registration routine
1561    USE module_sst_setservices, ONLY: SST_register
1562    ! WRF-SST coupler registration routine
1563    USE module_wrfsst_coupler, ONLY: WRFSSTCpl_register
1564    ! ESMF module, defines all ESMF data types and procedures
1565 ! Updated for ESMF 5.2.0r
1566 !   USE ESMF_Mod
1567    USE ESMF
1568    ! Not-yet-implemented ESMF features
1569    USE module_esmf_extensions
1570    ! Component-independent utilities
1571    USE module_metadatautils, ONLY: GetTimesFromStates
1573    IMPLICIT NONE
1575    ! Local variables
1577    ! Components
1578    TYPE(ESMF_GridComp) :: compGriddedWRF   ! WRF
1579    TYPE(ESMF_GridComp) :: compGriddedSST   ! SST reader
1580    TYPE(ESMF_CplComp) :: compCplWRFSST     ! WRF-SST coupler
1582    ! State, Virtual Machine, and DELayout
1583    TYPE(ESMF_VM) :: vm
1584    TYPE(ESMF_State) :: importStateWRF, exportStateWRF
1585    TYPE(ESMF_State) :: importStateSST, exportStateSST
1587    ! A clock, some times, and a time step
1588    TYPE(ESMF_Clock) :: driverClock
1589    TYPE(ESMF_Time) :: startTime
1590    TYPE(ESMF_Time) :: stopTime
1591    TYPE(ESMF_TimeInterval) :: couplingInterval
1593    ! other misc stuff
1594    TYPE(ESMF_State) :: tmpState
1595    INTEGER :: timestepdebug
1596    INTEGER :: thecount  ! ah ah ah
1598    ! Return codes for error checks
1599    INTEGER :: rc
1600    CHARACTER (ESMF_MAXSTR) :: str
1602    ! debugging
1603    CHARACTER(LEN=256) :: couplingIntervalString
1604 integer(ESMF_KIND_I4) :: timevals(6)
1606         
1607    ! Warn users that this is not yet ready for general use.  
1608    PRINT *, '                      W A R N I N G                          '
1609    PRINT *, '  ESMF COUPLING CAPABILITY IS EXPERIMENTAL AND UNSUPPORTED   '
1610    PRINT *, '               IN THIS VERSION OF WRF-CPL-SST                '
1611    PRINT *, '          U S E   A T   Y O U R   O W N   R I S K            '
1613    ! Initialize ESMF, get the default Global VM, and set
1614    ! the default calendar to be Gregorian.
1615 #ifdef NO_LEAP_CALENDAR
1616    CALL ESMF_Initialize( vm=vm, defaultCalKind=ESMF_CALKIND_NOLEAP, logkindflag=ESMF_LOGKIND_MULTI,rc=rc )
1617 #else
1618    CALL ESMF_Initialize( vm=vm, defaultCalKind=ESMF_CALKIND_GREGORIAN, logkindflag=ESMF_LOGKIND_MULTI,rc=rc )
1619 #endif
1620    IF ( rc /= ESMF_SUCCESS ) THEN
1621      PRINT *, 'wrf_SST_ESMF:  ESMF_Initialize failed'
1622    ENDIF
1623    ! Note:  wrf_debug and wrf_error_fatal are not initialized yet
1624    PRINT *, 'DEBUG wrf_SST_ESMF:  returned from ESMF_Initialize'
1625    CALL ESMF_SetInitialized()   ! eliminate this once ESMF does it internally
1627    ! Create the WRF Gridded Component, passing in the default VM.
1628    compGriddedWRF = ESMF_GridCompCreate( name="WRF Model", rc=rc)
1629    IF ( rc /= ESMF_SUCCESS ) THEN
1630      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompCreate(WRF Model) failed'
1631    ENDIF
1633    ! Create the SST Gridded Component, passing in the default VM.
1634    compGriddedSST = ESMF_GridCompCreate( name="SST Dummy Model", rc=rc)
1635    IF ( rc /= ESMF_SUCCESS ) THEN
1636      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompCreate(WRF Dummy Model) failed'
1637    ENDIF
1639    ! Create the WRF-SST Coupler Component, passing in the default VM.
1640    compCplWRFSST = ESMF_CplCompCreate( name="WRF-SST Coupler", rc=rc)
1641    IF ( rc /= ESMF_SUCCESS ) THEN
1642      PRINT *, 'wrf_SST_ESMF:  ESMF_CplCompCreate failed'
1643    ENDIF
1645    ! Create empty import and export states for WRF
1646    importStateWRF = ESMF_StateCreate(name="WRF Import State", stateintent=ESMF_STATEINTENT_IMPORT, rc=rc)
1647    IF ( rc /= ESMF_SUCCESS ) THEN
1648      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(WRF Import State) failed'
1649    ENDIF
1650    exportStateWRF = ESMF_StateCreate(name="WRF Export State", stateintent=ESMF_STATEINTENT_EXPORT, rc=rc)
1651    IF ( rc /= ESMF_SUCCESS ) THEN
1652      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(WRF Export State) failed'
1653    ENDIF
1655    ! Create empty import and export states for SST
1656    importStateSST = ESMF_StateCreate(name="SST Import State", stateintent=ESMF_STATEINTENT_IMPORT, rc=rc)
1657    IF ( rc /= ESMF_SUCCESS ) THEN
1658      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(SST Import State) failed'
1659    ENDIF
1660    exportStateSST = ESMF_StateCreate(name="SST Export State", stateintent=ESMF_STATEINTENT_EXPORT, rc=rc)
1661    IF ( rc /= ESMF_SUCCESS ) THEN
1662      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(SST Export State) failed'
1663    ENDIF
1665    ! Register the WRF Gridded Component
1666    CALL ESMF_GridCompSetServices(compGriddedWRF, WRF_register, rc=rc)
1667    IF ( rc /= ESMF_SUCCESS ) THEN
1668      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompSetServices(compGriddedWRF) failed'
1669    ENDIF
1671    ! Register the SST Gridded Component
1672    CALL ESMF_GridCompSetServices(compGriddedSST, SST_register, rc=rc)
1673    IF ( rc /= ESMF_SUCCESS ) THEN
1674      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompSetServices(compGriddedSST) failed'
1675    ENDIF
1677    ! Register the WRF-SST Coupler Component
1678    CALL ESMF_CplCompSetServices(compCplWRFSST, WRFSSTCpl_register, rc=rc)
1679    IF ( rc /= ESMF_SUCCESS ) THEN
1680      PRINT *, 'wrf_SST_ESMF:  ESMF_CplCompSetServices failed'
1681    ENDIF
1683    ! Create top-level clock.  There is no way to create an "empty" clock, so 
1684    ! stuff in bogus values for start time, stop time, and time step and fix 
1685    ! them after gridded component "init" phases return.  
1686    CALL ESMF_TimeSet(startTime, yy=2000, mm=1, dd=1, &
1687                      h=0, m=0, s=0, rc=rc)
1688    IF ( rc /= ESMF_SUCCESS ) THEN
1689      PRINT *, 'wrf_SST_ESMF:  ESMF_TimeSet(startTime) failed'
1690    ENDIF
1691    CALL ESMF_TimeSet(stopTime, yy=2000, mm=1, dd=1, &
1692                      h=12, m=0, s=0, rc=rc)
1693    IF ( rc /= ESMF_SUCCESS ) THEN
1694      PRINT *, 'wrf_SST_ESMF:  ESMF_TimeSet(stopTime) failed'
1695    ENDIF
1696    CALL ESMF_TimeIntervalSet(couplingInterval, s=2, rc=rc)
1697    IF ( rc /= ESMF_SUCCESS ) THEN
1698      PRINT *, 'wrf_SST_ESMF:  ESMF_TimeIntervalSet failed'
1699    ENDIF
1700    driverClock = ESMF_ClockCreate(timeStep=couplingInterval, &
1701                                   startTime=startTime,       &
1702                                   stopTime=stopTime, rc=rc)
1703    IF ( rc /= ESMF_SUCCESS ) THEN
1704      PRINT *, 'wrf_SST_ESMF:  ESMF_ClockCreate failed'
1705    ENDIF
1707    ! Init, Run, and Finalize section
1709    ! Init...
1710    ! initialize WRF, phase 1
1711    ! Phase 1 init returns WRF time and decomposition information as
1712    ! exportState metadata.
1713    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 WRF init (wrf_component_init1)'
1714    CALL ESMF_GridCompInitialize(compGriddedWRF, importstate=importStateWRF, &
1715                                 exportstate=exportStateWRF, clock=driverClock, phase=1, rc=rc)
1716 thecount = size(timevals)
1717 call esmf_attributeget(exportstatewrf,'ComponentCouplingInterval',timevals,itemcount=thecount,rc=rc)
1718 !write(0,*) 'exportStateWRF year ',timevals(1),__LINE__
1719 !write(0,*) 'exportStateWRF month ',timevals(2),__LINE__
1720 !write(0,*) 'exportStateWRF day ',timevals(3),__LINE__
1721 !write(0,*) 'exportStateWRF hour ',timevals(4),__LINE__
1722 !write(0,*) 'exportStateWRF minute ',timevals(5),__LINE__
1723 !write(0,*) 'exportStateWRF second ',timevals(6),__LINE__
1724    ! Note:  wrf_debug and wrf_error_fatal are now initialized
1725    IF ( rc /= ESMF_SUCCESS ) THEN
1726      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(WRF phase 1) failed' )
1727    ENDIF
1729    ! initialize SST, phase 1
1730    ! Phase 1 init returns SST time information as
1731    ! exportState metadata.
1732    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 SST init (sst_component_init1)'
1733    CALL ESMF_GridCompInitialize(compGriddedSST, importstate=importStateSST, &
1734                                 exportstate=exportStateSST, clock=driverClock, phase=1, rc=rc)
1735 thecount = size(timevals)
1736 call esmf_attributeget(exportstatesst,'ComponentCouplingInterval',timevals,itemcount=thecount,rc=rc)
1737 !write(0,*) 'exportStateSST year ',timevals(1),__LINE__
1738 !write(0,*) 'exportStateSST month ',timevals(2),__LINE__
1739 !write(0,*) 'exportStateSST day ',timevals(3),__LINE__
1740 !write(0,*) 'exportStateSST hour ',timevals(4),__LINE__
1741 !write(0,*) 'exportStateSST minute ',timevals(5),__LINE__
1742 !write(0,*) 'exportStateSST second ',timevals(6),__LINE__
1743    IF ( rc /= ESMF_SUCCESS ) THEN
1744      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(SST phase 1) failed' )
1745    ENDIF
1747    ! Reconcile clock settings from WRF and SST components to set up 
1748    ! top-level clock.  These are passed back from each "init" as attributes 
1749    ! on exportState*.  
1750    ! Stuff both States into a single State to pass into GetTimesFromStates() 
1751    ! which is smart enough to deal with a Composite.  
1752    PRINT *, 'DEBUG wrf_SST_ESMF:  reconciling clock from WRF and SST components'
1753    tmpState = ESMF_StateCreate( rc=rc )
1754    IF ( rc /= ESMF_SUCCESS ) THEN
1755      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateCreate(tmpState) failed' )
1756    ENDIF
1757    CALL ESMF_StateAdd( tmpState, nestedStateList=(/exportStateWRF,exportStateSST/), rc=rc )
1758    IF ( rc /= ESMF_SUCCESS ) THEN
1759      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateAdd(exportStateWRF,exportStateSST) failed' )
1760    ENDIF
1761    CALL GetTimesFromStates( tmpState, startTime, stopTime, couplingInterval )
1762    CALL ESMF_TimeIntervalGet( couplingInterval, TimeString=couplingIntervalString, &
1763                               rc=rc )
1764    IF ( rc /= ESMF_SUCCESS ) THEN
1765      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_TimeIntervalGet failed' )
1766    ENDIF
1767    CALL wrf_debug( 100, 'wrf_SST_ESMF:  couplingInterval = '//TRIM(couplingIntervalString) )
1768    CALL ESMF_StateDestroy( tmpState, rc=rc )
1769    IF ( rc /= ESMF_SUCCESS ) THEN
1770      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(tmpState) failed' )
1771    ENDIF
1772    ! update driver clock
1773    CALL ESMF_ClockDestroy(driverClock, rc=rc)
1774    IF ( rc /= ESMF_SUCCESS ) THEN
1775      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockDestroy failed' )
1776    ENDIF
1777    driverClock = ESMF_ClockCreate(timeStep=couplingInterval, &
1778                                   startTime=startTime,       &
1779                                   stopTime=stopTime, rc=rc)
1780    IF ( rc /= ESMF_SUCCESS ) THEN
1781      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockCreate(driverClock) failed' )
1782    ENDIF
1783    PRINT *, 'DEBUG wrf_SST_ESMF:  done reconciling clock from WRF and SST components'
1784    CALL wrf_clockprint(50, driverClock, &
1785           'DEBUG wrf_SST_ESMF:  driverClock after creation,')
1787    ! initialize WRF-SST Coupler
1788    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 CPL init (WRFSSTCpl_init)'
1789    CALL ESMF_CplCompInitialize(compCplWRFSST, importstate=exportStateWRF, &
1790                                exportstate=importStateSST, clock=driverClock, rc=rc)
1791    IF ( rc /= ESMF_SUCCESS ) THEN
1792      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompInitialize(WRF -> SST) failed' )
1793    ENDIF
1795 ! TBH:  this bit is not needed, but would be in general
1796 !   CALL ESMF_CplCompInitialize(compCplWRFSST, importstate=exportStateSST, &
1797 !                               exportstate=importStateWRF, clock=driverClock, rc=rc)
1798 !   IF ( rc /= ESMF_SUCCESS ) THEN
1799 !     CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompInitialize(SST -> WRF) failed' )
1800 !   ENDIF
1802    ! initialize SST, phase 2
1803    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for SST (sst_component_init2)'
1804    CALL wrf_debug ( 100 , TRIM(str) )
1805    CALL ESMF_GridCompInitialize(compGriddedSST, importstate=importStateSST, &
1806                                 exportstate=exportStateSST, clock=driverClock, phase=2, rc=rc)
1807    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for SST'
1808    CALL wrf_debug ( 100 , TRIM(str) )
1809    IF ( rc /= ESMF_SUCCESS ) THEN
1810      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(SST phase 2) failed' )
1811    ENDIF
1813    ! initialize WRF, phase 2
1814    ! Phase 2 init sets up WRF importState and exportState.
1815    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for WRF (wrf_component_init2)'
1816    CALL wrf_debug ( 100 , TRIM(str) )
1817    CALL ESMF_GridCompInitialize(compGriddedWRF, importstate=importStateWRF, &
1818                                 exportstate=exportStateWRF, clock=driverClock, phase=2, rc=rc)
1819    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for WRF'
1820    CALL wrf_debug ( 100 , TRIM(str) )
1821    IF ( rc /= ESMF_SUCCESS ) THEN
1822      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(WRF phase 2) failed' )
1823    ENDIF
1825    CALL wrf_clockprint(50, driverClock, &
1826           'DEBUG wrf_SST_ESMF:  driverClock before main time-stepping loop,')
1827    ! Run...
1828    ! main time-stepping loop
1829    timestepdebug = 0
1830    DO WHILE ( .NOT. ESMF_ClockIsStopTime(driverClock, rc=rc) )
1832      timestepdebug = timestepdebug + 1
1833      WRITE(str,'(A,I8)') 'PROGRAM wrf_SST_ESMF: Top of time-stepping loop, timestepdebug = ',timestepdebug
1834      CALL wrf_debug ( 100 , TRIM(str) )
1835      CALL wrf_clockprint(50, driverClock, &
1836             'DEBUG wrf_SST_ESMF:  driverClock at top of time-stepping loop,')
1838      ! Run SST phase 1
1839      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-1 run for SST (sst_component_run1)'
1840      CALL wrf_debug ( 100 , TRIM(str) )
1841      CALL ESMF_GridCompRun(compGriddedSST, importstate=importStateSST, exportstate=exportStateSST, &
1842                            clock=driverClock, phase=1, rc=rc)
1843      IF ( rc /= ESMF_SUCCESS ) THEN
1844        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(SST phase 1) failed' )
1845      ENDIF
1846      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-1 run for SST (sst_component_run1)'
1847      CALL wrf_debug ( 100 , TRIM(str) )
1849      ! couple SST export -> WRF import
1850      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL SST->WRF (WRFSSTCpl_run)'
1851      CALL wrf_debug ( 100 , TRIM(str) )
1852      CALL ESMF_CplCompRun(compCplWRFSST, importstate=exportStateSST, &
1853                           exportstate=importStateWRF, clock=driverClock, rc=rc)
1854      IF ( rc /= ESMF_SUCCESS ) THEN
1855        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompRun(SST -> WRF) failed' )
1856      ENDIF
1857      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL SST->WRF (WRFSSTCpl_run)'
1858      CALL wrf_debug ( 100 , TRIM(str) )
1860      ! Run WRF
1861      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for WRF (wrf_component_run)'
1862      CALL wrf_debug ( 100 , TRIM(str) )
1863      CALL ESMF_GridCompRun(compGriddedWRF, importstate=importStateWRF, exportstate=exportStateWRF, &
1864                            clock=driverClock, rc=rc)
1865      IF ( rc /= ESMF_SUCCESS ) THEN
1866        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(WRF) failed' )
1867      ENDIF
1868      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for WRF (wrf_component_run)'
1869      CALL wrf_debug ( 100 , TRIM(str) )
1871      ! couple WRF export -> SST import
1872      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL WRF->SST (WRFSSTCpl_run)'
1873      CALL wrf_debug ( 100 , TRIM(str) )
1874      CALL ESMF_CplCompRun(compCplWRFSST, importstate=exportStateWRF, &
1875                           exportstate=importStateSST, clock=driverClock, rc=rc)
1876      IF ( rc /= ESMF_SUCCESS ) THEN
1877        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompRun(WRF -> SST) failed' )
1878      ENDIF
1879      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL WRF->SST (WRFSSTCpl_run)'
1880      CALL wrf_debug ( 100 , TRIM(str) )
1882      ! Run SST phase 2
1883      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 run for SST (sst_component_run2)'
1884      CALL wrf_debug ( 100 , TRIM(str) )
1885      CALL ESMF_GridCompRun(compGriddedSST, importstate=importStateSST, exportstate=exportStateSST, &
1886                            clock=driverClock, phase=2, rc=rc)
1887      IF ( rc /= ESMF_SUCCESS ) THEN
1888        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(SST phase 2) failed' )
1889      ENDIF
1890      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 run for SST (sst_component_run2)'
1891      CALL wrf_debug ( 100 , TRIM(str) )
1893      ! advance clock to next coupling time step
1894      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: advancing clock'
1895      CALL wrf_debug ( 100 , TRIM(str) )
1896      CALL ESMF_ClockAdvance( driverClock, rc=rc )
1897      IF ( rc /= ESMF_SUCCESS ) THEN
1898        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockAdvance failed' )
1899      ENDIF
1900      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done advancing clock'
1901      CALL wrf_debug ( 100 , TRIM(str) )
1903      CALL wrf_clockprint(50, driverClock, &
1904             'DEBUG wrf_SST_ESMF:  driverClock at end of time-stepping loop,')
1906    ENDDO
1908    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done with time-stepping loop'
1909    CALL wrf_debug ( 100 , TRIM(str) )
1911    ! clean up SST
1912    CALL ESMF_GridCompFinalize(compGriddedSST, importstate=importStateSST, exportstate=exportStateSST, &
1913                               clock=driverClock, rc=rc)
1914    IF ( rc /= ESMF_SUCCESS ) THEN
1915      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompFinalize(compGriddedSST) failed' )
1916    ENDIF
1918    ! clean up compCplWRFSST
1919    CALL ESMF_CplCompFinalize( compCplWRFSST, importstate=exportStateWRF, exportstate=importStateSST, &
1920                               clock=driverClock, rc=rc)
1921    IF ( rc /= ESMF_SUCCESS ) THEN
1922      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompFinalize(compCplWRFSST) failed' )
1923    ENDIF
1925    ! clean up WRF
1926    ! must do this AFTER clean up of SST since SST uses WRF IOAPI
1927    CALL ESMF_GridCompFinalize(compGriddedWRF, importstate=importStateWRF, exportstate=exportStateWRF, &
1928                               clock=driverClock, rc=rc)
1929    IF ( rc /= ESMF_SUCCESS ) THEN
1930      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompFinalize(compGriddedWRF) failed' )
1931    ENDIF
1933    ! Clean up
1935    CALL ESMF_GridCompDestroy(compGriddedWRF, rc=rc)
1936    IF ( rc /= ESMF_SUCCESS ) THEN
1937      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompDestroy(compGriddedWRF) failed' )
1938    ENDIF
1939    CALL ESMF_StateDestroy(importStateWRF, rc=rc)
1940    IF ( rc /= ESMF_SUCCESS ) THEN
1941      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(importStateWRF) failed' )
1942    ENDIF
1943    CALL ESMF_StateDestroy(exportStateWRF, rc=rc)
1944    IF ( rc /= ESMF_SUCCESS ) THEN
1945      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(exportStateWRF) failed' )
1946    ENDIF
1947    CALL ESMF_StateDestroy(importStateSST, rc=rc)
1948    IF ( rc /= ESMF_SUCCESS ) THEN
1949      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(importStateSST) failed' )
1950    ENDIF
1951    CALL ESMF_StateDestroy(exportStateSST, rc=rc)
1952    IF ( rc /= ESMF_SUCCESS ) THEN
1953      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(exportStateSST) failed' )
1954    ENDIF
1955    CALL ESMF_ClockDestroy(driverClock, rc=rc)
1956    IF ( rc /= ESMF_SUCCESS ) THEN
1957      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockDestroy(driverClock) failed' )
1958    ENDIF
1960    CALL ESMF_Finalize( rc=rc )
1961    IF ( rc /= ESMF_SUCCESS ) THEN
1962      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_Finalize failed' )
1963    ENDIF
1965 END PROGRAM wrf_SST_ESMF