wrf_SST_ESMF.F

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