wrf svn trunk commit r4103
[wrffire.git] / wrfv2_fire / main / wrf_SST_ESMF.F
bloba847643d8d6a4210d48609414e68a6080dd7ee2f
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    USE ESMF_Mod
32    USE module_esmf_extensions
33    USE module_metadatautils, ONLY: AttachTimesToState
36    IMPLICIT NONE
38    ! everything is private by default
39    PRIVATE
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
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)
79 CONTAINS
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.
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>
104 #ifdef DM_PARALLEL
105      INCLUDE 'mpif.h'
106 #endif
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
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'
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) )
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 )
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) )
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"
207      rc = ESMF_SUCCESS
209    END SUBROUTINE sst_component_init1
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>
222      #include <wrf_status_codes.h>
223      #include <wrf_io_flags.h>
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
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.  
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
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 !jm the dimensions have already been reduced to the non-staggered WRF grid when
295 !   they were stored in this module..  Just use as is.
296               ids , ide , jds , jde , 1 , 1 , &
297               ims , ime , jms , jme , 1 , 1         , &
298               ips , ipe , jps , jpe , 1 , 1 , &
299               ierr )
300        IF (ierr /= 0) THEN
301          CALL wrf_error_fatal ( TRIM(errormsg) )
302        ENDIF
303      ENDDO
305      ! stuff fields into exportState
306 !TODO:  change this to Bundles, eventually
307      CALL ESMF_StateGet( exportState, TRIM(datanames(SST_INDX)), &
308                               out_sst_field, rc=rc )
309      IF (rc /= ESMF_SUCCESS) THEN
310        CALL wrf_error_fatal ( &
311          'could not find sea_surface_temperature field in exportState' )
312      ENDIF
313      CALL ESMF_StateGet( exportState, TRIM(datanames(LANDMASK_INDX)), &
314                               out_landmask_field, rc=rc )
315      IF (rc /= ESMF_SUCCESS) THEN
316        CALL wrf_error_fatal ( &
317          'could not find land_binary_mask field in exportState' )
318      ENDIF
319 !     CALL ESMF_FieldGetDataPointer( out_sst_field, out_sst_ptr, rc=rc )
320      CALL ESMF_FieldGet( out_sst_field, 0, out_sst_ptr, rc=rc )
321      IF (rc /= ESMF_SUCCESS) THEN
322        CALL wrf_error_fatal ( &
323          'could not find sea_surface_temperature data in sea_surface_temperature field' )
324      ENDIF
325 !     CALL ESMF_FieldGetDataPointer( out_landmask_field, out_landmask_ptr, rc=rc )
326      CALL ESMF_FieldGet( out_landmask_field, 0, out_landmask_ptr, rc=rc )
327      IF (rc /= ESMF_SUCCESS) THEN
328        CALL wrf_error_fatal ( &
329          'could not find land_binary_mask data in land_binary_mask field' )
330      ENDIF
331      ! staggered starts/ends
332      DO j= jps , jpe
333        DO i= ips , ipe
334          out_sst_ptr(i,j) = file_sst_data(i,j)
335          out_landmask_ptr(i,j) = file_landmask_data(i,j)
336        ENDDO
337      ENDDO
339    END SUBROUTINE read_data
344    SUBROUTINE compare_data( importState, clock )
345      TYPE(ESMF_State), INTENT(INOUT) :: importState
346 !TODO:  remove clock after debugging is finished
347      TYPE(ESMF_Clock), INTENT(INOUT) :: clock
348 !<DESCRIPTION>
349 !     Gets data from coupler via importState 
350 !     and compares with data read from file and 
351 !     error-exits if they differ.  
353 !     The arguments are:
354 !       importState     Importstate
355 !</DESCRIPTION>
357      ! Local variables
358      TYPE(ESMF_Field) :: in_sst_field, in_landmask_field
359      REAL(ESMF_KIND_R4), POINTER :: in_sst_ptr(:,:), in_landmask_ptr(:,:)
360      REAL, POINTER :: in_sst_ptr_real(:,:), in_landmask_ptr_real(:,:)
361      INTEGER :: i, j
362      INTEGER :: rc
363      LOGICAL :: landmask_ok, sst_ok
364      ! use these for debug prints
365      TYPE(ESMF_Time) :: currentTime
366      INTEGER, SAVE :: numtimes=0   ! track number of calls
367      CHARACTER(LEN=256) :: timestamp
369      ! count calls for debug prints...
370      CALL ESMF_ClockGet( clock, CurrTime=currentTime, rc=rc )
371      IF (rc /= ESMF_SUCCESS) THEN
372        CALL wrf_error_fatal ( 'compare_data:  ESMF_ClockGet() failed' )
373      ENDIF
374      CALL wrf_timetoa ( currentTime, timestamp )
375      numtimes = numtimes + 1
376      WRITE(str,*) 'SST compare_data:  begin, numtimes = ',numtimes,' time = ',TRIM(timestamp)
377      CALL wrf_debug ( 100 , TRIM(str) )
379      ! extract data from the importState and compare with data from file
380 !TODO:  change this to Bundles, eventually
381      CALL ESMF_StateGet( importState, TRIM(datanames(SST_INDX)), &
382                               in_sst_field, rc=rc )
383      IF (rc /= ESMF_SUCCESS) THEN
384        CALL wrf_error_fatal ( &
385          'could not extract sea_surface_temperature field from importState' )
386      ENDIF
387      CALL ESMF_StateGet( importState, TRIM(datanames(LANDMASK_INDX)), &
388                               in_landmask_field, rc=rc )
389      IF (rc /= ESMF_SUCCESS) THEN
390        CALL wrf_error_fatal ( &
391          'could not extract land_binary_mask field from importState' )
392      ENDIF
393 !     CALL ESMF_FieldGetDataPointer( in_sst_field, in_sst_ptr, rc=rc )
394      CALL ESMF_FieldGet( in_sst_field, 0, in_sst_ptr, rc=rc )
395      IF (rc /= ESMF_SUCCESS) THEN
396        CALL wrf_error_fatal ( &
397          'could not extract sea_surface_temperature data from sea_surface_temperature field' )
398      ENDIF
399      ALLOCATE( in_sst_ptr_real(ims:ime,jms:jme) )
400      WRITE( str,* ) 'compare_data, ips:ipe,jps:jpe = ',           &
401        ips,':',ipe,',',jps,':',jpe,                               &
402        ', in_sst_ptr(BOUNDS) = ',                                 &
403        LBOUND(in_sst_ptr,1),':',UBOUND(in_sst_ptr,1),',',         &
404        LBOUND(in_sst_ptr,2),':',UBOUND(in_sst_ptr,2)
405      CALL wrf_debug ( 100 , TRIM(str) )
406      DO j= jms, jme
407        DO i= ims, ime
408          in_sst_ptr_real(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
409        ENDDO
410      ENDDO
411      in_sst_ptr_real(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe)) = &
412           in_sst_ptr(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe))
413 !     CALL ESMF_FieldGetDataPointer( in_landmask_field, in_landmask_ptr, rc=rc )
414      CALL ESMF_FieldGet( in_landmask_field, 0, in_landmask_ptr, rc=rc )
415      IF (rc /= ESMF_SUCCESS) THEN
416        CALL wrf_error_fatal ( &
417          'could not extract land_binary_mask data from land_binary_mask field' )
418      ENDIF
419      ALLOCATE( in_landmask_ptr_real(ims:ime,jms:jme) )
420      WRITE( str,* ) 'compare_data, ips:ipe,jps:jpe = ',             &
421        ips,':',ipe,',',jps,':',jpe,                                 &
422        ', in_landmask_ptr(BOUNDS) = ',                              &
423        LBOUND(in_landmask_ptr,1),':',UBOUND(in_landmask_ptr,1),',', &
424        LBOUND(in_landmask_ptr,2),':',UBOUND(in_landmask_ptr,2)
425      CALL wrf_debug ( 100 , TRIM(str) )
426      DO j= jms, jme
427        DO i= ims, ime
428          in_landmask_ptr_real(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
429        ENDDO
430      ENDDO
431      in_landmask_ptr_real(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe)) = &
432           in_landmask_ptr(ips:MIN((ide-1),ipe),jps:MIN((jde-1),jpe))
434      ! compare LANDMASK...  
435      landmask_ok = .TRUE.
436      ! staggered starts/ends
437      LANDMASK_COMPARE : DO j= jps , MIN( (jde-1), jpe )
438        DO i= ips , MIN( (ide-1), ipe )
439          IF ( file_landmask_data(i,j) /= in_landmask_ptr_real(i,j) ) THEN
440            landmask_ok = .FALSE.
441            WRITE( str , * ) 'error landmask mismatch at (i,j) = (',i,',',j, &
442                             '), values are',file_landmask_data(i,j),' and ',     &
443                             in_landmask_ptr_real(i,j) 
444            EXIT LANDMASK_COMPARE
445          ENDIF
446        ENDDO
447      ENDDO LANDMASK_COMPARE
448      IF ( landmask_ok ) THEN
449        WRITE(str,*) 'compare_data: LANDMASK compares OK'
450        CALL wrf_debug ( 100 , TRIM(str) )
451      ELSE
452        CALL wrf_error_fatal ( TRIM(str) )
453      ENDIF
455      ! compare SST...  
456      sst_ok = .TRUE.
457      ! staggered starts/ends
458      SST_COMPARE : DO j= jps , MIN( (jde-1), jpe )
459        DO i= ips , MIN( (ide-1), ipe )
460          IF ( file_sst_data(i,j) /= in_sst_ptr_real(i,j) ) THEN
461            sst_ok = .FALSE.
462            WRITE( str , * ) 'error sst mismatch at (i,j) = (',i,',',j, &
463                             '), values are',file_sst_data(i,j),' and ',     &
464                             in_sst_ptr_real(i,j) 
465            EXIT SST_COMPARE
466          ENDIF
467        ENDDO
468      ENDDO SST_COMPARE
469      IF ( sst_ok ) THEN
470        WRITE(str,*) 'compare_data: SST compares OK'
471        CALL wrf_debug ( 100 , TRIM(str) )
472      ELSE
473        CALL wrf_error_fatal ( TRIM(str) )
474      ENDIF
476      DEALLOCATE( in_sst_ptr_real, in_landmask_ptr_real )
478      WRITE(str,*) 'compare_data:  end, numtimes = ',numtimes
479      CALL wrf_debug ( 100 , TRIM(str) )
481    END SUBROUTINE compare_data
483    ! Second-phase "init" gets decomposition information from 
484    ! importState.  
485    SUBROUTINE sst_component_init2( gcomp, importState, exportState, clock, rc )
486      USE module_metadatautils, ONLY: GetDecompFromState
487      USE module_io
488      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
489      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState
490      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: exportState
491      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
492      INTEGER,                     INTENT(  OUT) :: rc
493 !<DESCRIPTION>
494 !     SST component init routine, phase 2.
496 !     The arguments are:
497 !       gcomp           Component
498 !       importState     Importstate
499 !       exportState     Exportstate
500 !       clock           External clock
501 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
502 !                       otherwise ESMF_FAILURE.
503 !</DESCRIPTION>
505      ! Local variables
506      TYPE(ESMF_Field) :: out_sst_field, out_landmask_field
507      TYPE(ESMF_Field) :: in_sst_field, in_landmask_field
508      INTEGER, PARAMETER :: NUMDIMS=2
509      INTEGER :: DomainStart(NUMDIMS)
510      INTEGER :: DomainEnd(NUMDIMS)
511      INTEGER :: MemoryStart(NUMDIMS)
512      INTEGER :: MemoryEnd(NUMDIMS)
513      INTEGER :: PatchStart(NUMDIMS)
514      INTEGER :: PatchEnd(NUMDIMS)
515      INTEGER :: rc, i, j
516      INTEGER :: ierr
518     ! Get decomposition information from importState.  Note that index 
519     ! values are for staggered dimensions, following the WRF convention.  
520 !TODO:  Note that this will only work for SPMD serial operation.  For 
521 !TODO:  concurrent operation (SPMD or MPMD), we will need to create a new 
522 !TODO:  "domdesc" suitable for the task layout of the SST component.  For
523 !TODO:  MPMD serial operation, we will need to extract serialized domdesc 
524 !TODO:  from export state metadata and de-serialize it.  Similar arguments 
525 !TODO:  apply to [ij][mp][se] and bdy_mask.  
526      write(str,*) 'sst_component_init2: calling GetDecompFromState'
527      CALL wrf_debug ( 100 , TRIM(str) )
528      CALL GetDecompFromState( importState,                  &
529                               ids, ide, jds, jde, kds, kde, &
530                               ims, ime, jms, jme, kms, kme, &
531                               ips, ipe, jps, jpe, kps, kpe, &
532                               domdesc, bdy_mask )
533      write(str,*) 'sst_component_init2: back from GetDecompFromState'
534      CALL wrf_debug ( 100 , TRIM(str) )
535      write(str,*) 'sst_component_init2: ids, ide, jds, jde, kds, kde = ', ids, ide, jds, jde, kds, kde
536      CALL wrf_debug ( 100 , TRIM(str) )
537      write(str,*) 'sst_component_init2: ims, ime, jms, jme, kms, kme = ', ims, ime, jms, jme, kms, kme
538      CALL wrf_debug ( 100 , TRIM(str) )
539      write(str,*) 'sst_component_init2: ips, ipe, jps, jpe, kps, kpe = ', ips, ipe, jps, jpe, kps, kpe
540      CALL wrf_debug ( 100 , TRIM(str) )
542      ! allocate space for data read from disk
543      ALLOCATE( file_sst_data     (ims:ime,jms:jme) )
544      DO j= jms, jme
545        DO i= ims, ime
546          file_sst_data(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
547        ENDDO
548      ENDDO
549 !TODO:  Hmmm...  really need to load these pointers here?  Check...  
550      this_data(SST_INDX)%r2d => file_sst_data
551      ALLOCATE( file_landmask_data(ims:ime,jms:jme) )
552      DO j= jms, jme
553        DO i= ims, ime
554          file_landmask_data(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
555        ENDDO
556      ENDDO
557      this_data(LANDMASK_INDX)%r2d => file_landmask_data
559      ! Create ESMF_Fields in importState and exportState
560      ! Create ESMF_Grid.  Use exactly the same method as WRF so WRFIO will 
561      ! work.  
562      DomainStart(1) = ids; DomainEnd(1) = ide;
563      DomainStart(2) = jds; DomainEnd(2) = jde;
564      MemoryStart(1) = ims; MemoryEnd(1) = ime;
565      MemoryStart(2) = jms; MemoryEnd(2) = jme;
566      PatchStart(1)  = ips; PatchEnd(1)  = ipe;
567      PatchStart(2)  = jps; PatchEnd(2)  = jpe
568 !write(0,*)__FILE__,__LINE__,'DomainStart ',DomainStart(1:2)
569 !write(0,*)__FILE__,__LINE__,'DomainEnd ',DomainEnd(1:2)
570 !write(0,*)__FILE__,__LINE__,'MemoryStart ',MemoryStart(1:2)
571 !write(0,*)__FILE__,__LINE__,'MemoryEnd ',MemoryEnd(1:2)
572 !write(0,*)__FILE__,__LINE__,'PatchStart ',PatchStart(1:2)
573 !write(0,*)__FILE__,__LINE__,'PatchEnd ',PatchEnd(1:2)
574      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  Calling ioesmf_create_grid_int()' )
575      CALL ioesmf_create_grid_int( esmfgrid, NUMDIMS,      &
576                                   DomainStart, DomainEnd, &
577                                   MemoryStart, MemoryEnd, &
578                                   PatchStart, PatchEnd )
579 !write(0,*)__FILE__,__LINE__
580      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  back from ioesmf_create_grid_int()' )
581      ! create ESMF_Fields
582      ! Note use of patch dimension for POINTERs allocated by ESMF.  
583      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  Calling ESMF_GridValidate(esmfgrid)' )
584      CALL ESMF_GridValidate( esmfgrid, rc=rc )
585 !write(0,*)__FILE__,__LINE__
586      IF ( rc /= ESMF_SUCCESS ) THEN
587        WRITE( str,* ) 'Error in ESMF_GridValidate ',   &
588                       __FILE__ ,                       &
589                       ', line ',                       &
590                       __LINE__ ,                       &
591                       ', error code = ',rc
592        CALL wrf_error_fatal ( TRIM(str) )
593      ENDIF
594      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  back OK from ESMF_GridValidate(esmfgrid)' )
595 !TODO:  Once new ESMF 3.0 interfaces have settled down, eliminate "tmp_data_" 
596 !TODO:  arrays and let ESMF allocate/deallocate them.  Assuming of course that 
597 !TODO:  we can convince ESMF to deallocate safely...  
598 !write(0,*)__FILE__,__LINE__
599      ALLOCATE( tmp_data_out_sst(ips:ipe,jps:jpe) )
600 !write(0,*)__FILE__,__LINE__
601      write(str,*) 'sst_component_init2: tmp_data_out_sst(', &
602        LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',',LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2),')'
603      CALL wrf_debug ( 100 , TRIM(str) )
604      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_sst_field)' )
605 !write(0,*)__FILE__,__LINE__,trim(datanames(sst_indx))
606 !write(0,*)__FILE__,__LINE__,ips,jps,ipe,jpe
607      out_sst_field = ESMF_FieldCreate(                 &
608                        esmfgrid, tmp_data_out_sst,     &
609                        copyflag=ESMF_DATA_REF,         &
610                        staggerloc=ESMF_STAGGERLOC_CENTER,          &
611                        name=TRIM(datanames(SST_INDX)), &
612                        rc=rc )
613 !write(0,*)__FILE__,__LINE__,'Creating out_sst_field for exportState of SST component name ',TRIM(datanames(SST_INDX))
614      IF ( rc /= ESMF_SUCCESS ) THEN
615        WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) failed ', &
616                       __FILE__ ,                                 &
617                       ', line ',                                 &
618                       __LINE__ ,                                 &
619                       ', error code = ',rc
620        CALL wrf_error_fatal ( TRIM(str) )
621      ENDIF
622      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_sst_field)' )
623      write(str,*) 'sst_component_init2: ips:ipe,jps:jpe = ', &
624        ips,':',ipe,',',jps,':',jpe
625      CALL wrf_debug ( 100 , TRIM(str) )
626 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
627      ! validate ESMF allocation
628      IF ( ( ips /= LBOUND(tmp_data_out_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_sst,1) ) .OR. &
629           ( jps /= LBOUND(tmp_data_out_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_sst,2) ) ) THEN
630        WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) allocation failed ', &
631                       __FILE__ ,                                            &
632                       ', line ',                                            &
633                       __LINE__ ,                                            &
634                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
635                       ', tmp_data_out_sst(BOUNDS) = ',LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',', &
636                                               LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2)
637        CALL wrf_error_fatal ( TRIM(str) )
638      ENDIF
639      ALLOCATE( tmp_data_out_landmask(ips:ipe,jps:jpe) )
640      write(str,*) 'sst_component_init2: tmp_data_out_landmask(', &
641        LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',',LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2),')'
642      CALL wrf_debug ( 100 , TRIM(str) )
643      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_landmask_field)' )
644      out_landmask_field = ESMF_FieldCreate(                      &
645                             esmfgrid, tmp_data_out_landmask,     &
646                             copyflag=ESMF_DATA_REF,              &
647                             staggerloc=ESMF_STAGGERLOC_CENTER,          &
648                             name=TRIM(datanames(LANDMASK_INDX)), &
649 !                            lbounds=(/ips,jps/),                 &
650 !                            ubounds=(/ipe,jpe/),                 &
651                             rc=rc )
652      IF ( rc /= ESMF_SUCCESS ) THEN
653        CALL wrf_error_fatal ( 'ESMF_FieldCreate(out_landmask_field) failed' )
654      ENDIF
655      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_landmask_field)' )
656 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
657      ! validate ESMF allocation
658      IF ( ( ips /= LBOUND(tmp_data_out_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_landmask,1) ) .OR. &
659           ( jps /= LBOUND(tmp_data_out_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_landmask,2) ) ) THEN
660        WRITE( str,* ) 'ESMF_FieldCreate(out_landmask_field) allocation failed ', &
661                       __FILE__ ,                                            &
662                       ', line ',                                            &
663                       __LINE__ ,                                            &
664                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
665                       ', tmp_data_out_landmask(BOUNDS) = ',LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',', &
666                                               LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2)
667        CALL wrf_error_fatal ( TRIM(str) )
668      ENDIF
669      ALLOCATE( tmp_data_in_sst(ips:ipe,jps:jpe) )
670      write(str,*) 'sst_component_init2: tmp_data_in_sst(', &
671        LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',',LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2),')'
672      CALL wrf_debug ( 100 , TRIM(str) )
673      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_sst_field)' )
674      in_sst_field = ESMF_FieldCreate(                 &
675                       esmfgrid, tmp_data_in_sst,      &
676                       copyflag=ESMF_DATA_REF,         &
677                       staggerloc=ESMF_STAGGERLOC_CENTER,          &
678                       name=TRIM(datanames(SST_INDX)), &
679 !                      lbounds=(/ips,jps/),            &
680 !                      ubounds=(/ipe,jpe/),            &
681                       rc=rc )
682      IF ( rc /= ESMF_SUCCESS ) THEN
683        CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_sst_field) failed' )
684      ENDIF
685      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_sst_field)' )
686 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
687      ! validate ESMF allocation
688      IF ( ( ips /= LBOUND(tmp_data_in_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_sst,1) ) .OR. &
689           ( jps /= LBOUND(tmp_data_in_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_sst,2) ) ) THEN
690        WRITE( str,* ) 'ESMF_FieldCreate(in_sst_field) allocation failed ', &
691                       __FILE__ ,                                            &
692                       ', line ',                                            &
693                       __LINE__ ,                                            &
694                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
695                       ', tmp_data_in_sst(BOUNDS) = ',LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',', &
696                                               LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2)
697        CALL wrf_error_fatal ( TRIM(str) )
698      ENDIF
699      ALLOCATE( tmp_data_in_landmask(ips:ipe,jps:jpe) )
700      write(str,*) 'sst_component_init2: tmp_data_in_landmask(', &
701        LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',',LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2),')'
702      CALL wrf_debug ( 100 , TRIM(str) )
703      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_landmask_field)' )
704      in_landmask_field = ESMF_FieldCreate(                      &
705                            esmfgrid, tmp_data_in_landmask,      &
706                            copyflag=ESMF_DATA_REF,              &
707                            staggerloc=ESMF_STAGGERLOC_CENTER,          &
708                            name=TRIM(datanames(LANDMASK_INDX)), &
709 !                           lbounds=(/ips,jps/),                 &
710 !                           ubounds=(/ipe,jpe/),                 &
711                            rc=rc )
712      IF ( rc /= ESMF_SUCCESS ) THEN
713        CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_landmask_field) failed' )
714      ENDIF
715      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_landmask_field)' )
716 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
717      ! validate ESMF allocation
718      IF ( ( ips /= LBOUND(tmp_data_in_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_landmask,1) ) .OR. &
719           ( jps /= LBOUND(tmp_data_in_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_landmask,2) ) ) THEN
720        WRITE( str,* ) 'ESMF_FieldCreate(in_landmask_field) allocation failed ', &
721                       __FILE__ ,                                            &
722                       ', line ',                                            &
723                       __LINE__ ,                                            &
724                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
725                       ', tmp_data_in_landmask(BOUNDS) = ',LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',', &
726                                               LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2)
727        CALL wrf_error_fatal ( TRIM(str) )
728      ENDIF
730      ! attach ESMF_Field to importState
731      CALL ESMF_StateAdd( importState, in_sst_field, rc=rc )
732      IF ( rc /= ESMF_SUCCESS ) THEN
733        CALL wrf_error_fatal ( 'ESMF_StateAdd(in_sst_field) failed' )
734      ENDIF
735      CALL ESMF_StateAdd( importState, in_landmask_field, rc=rc )
736      IF ( rc /= ESMF_SUCCESS ) THEN
737        CALL wrf_error_fatal ( 'ESMF_StateAdd(in_landmask_field) failed' )
738      ENDIF
739      ! attach ESMF_Field to exportState
740      CALL ESMF_StateAdd( exportState, out_sst_field, rc=rc )
741      IF ( rc /= ESMF_SUCCESS ) THEN
742        CALL wrf_error_fatal ( 'ESMF_StateAdd(out_sst_field) failed' )
743      ENDIF
744      CALL ESMF_StateAdd( exportState, out_landmask_field, rc=rc )
745      IF ( rc /= ESMF_SUCCESS ) THEN
746        CALL wrf_error_fatal ( 'ESMF_StateAdd(out_landmask_field) failed' )
747      ENDIF
749      !  Open the "SST" input data file for reading.
750      write(str,'(A,A)') 'sst_component_init2: Opening data file ', &
751        TRIM(sstinfilename)
752      CALL wrf_message ( TRIM(str) )
753      CALL wrf_open_for_read ( TRIM(sstinfilename) , &
754                               mpicom ,              &
755                               mpicom ,              &
756                               "DATASET=INPUT" ,     &
757                               fid ,                 &
758                               ierr )
759      IF ( ierr .NE. 0 ) THEN
760        WRITE( str , FMT='(A,A,A,I8)' )  &
761          'sst_component_init2: error opening ', &
762          TRIM(sstinfilename),' for reading ierr=',ierr
763        CALL wrf_error_fatal ( TRIM(str) )
764      ENDIF
765      WRITE( str , FMT='(A,A,A,I8)' ) &
766        'subroutine sst_component_init2: opened file ', &
767        TRIM(sstinfilename),' for reading fid=',fid
768      CALL wrf_debug ( 100, TRIM(str) )
770      write(str,'(A)') 'sst_component_init2: returning rc=ESMF_SUCCESS'
771      CALL wrf_debug ( 100 , TRIM(str) )
773      rc = ESMF_SUCCESS
775    END SUBROUTINE sst_component_init2
779    SUBROUTINE sst_component_run1( gcomp, importState, exportState, clock, rc )
780      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
781      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
782      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
783      INTEGER,                     INTENT(  OUT) :: rc
784 !<DESCRIPTION>
785 !     SST component run routine, phase 1.
786 !     Read "SST" data from file and stuff into exportState.  
788 !     The arguments are:
789 !       gcomp           Component
790 !       importState     Importstate
791 !       exportState     Exportstate
792 !       clock           External clock
793 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
794 !                       otherwise ESMF_FAILURE.
795 !</DESCRIPTION>
797      rc = ESMF_SUCCESS
799      ! Get "SST" data from file and stuff it into exportState.  
800      CALL read_data( exportState, clock )
802    END SUBROUTINE sst_component_run1
806    SUBROUTINE sst_component_run2( gcomp, importState, exportState, clock, rc )
807      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
808      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
809      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
810      INTEGER,                     INTENT(  OUT) :: rc
811 !<DESCRIPTION>
812 !     SST component run routine, phase 2.
813 !     Get from importState, compare with file data, and error-exit 
814 !     if they differ...  If they are the same, then 
815 !     stuff the file data into the exportState.  
817 !     The arguments are:
818 !       gcomp           Component
819 !       importState     Importstate
820 !       exportState     Exportstate
821 !       clock           External clock
822 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
823 !                       otherwise ESMF_FAILURE.
824 !</DESCRIPTION>
826      rc = ESMF_SUCCESS
828      ! Get from importState, compare with file data, and error_exit 
829      ! if they differ...  
830 !TODO:  change this once WRF can load exportState after integrating
831      ! This works because WRF loads its exportState BEFORE integrating.  
832      CALL wrf_clockprint ( 50, clock, 'sst_component_run2:  clock before call to compare_data()' )
833      CALL compare_data( importState, clock )
834      CALL wrf_clockprint ( 50, clock, 'sst_component_run2:  clock after call to compare_data()' )
836    END SUBROUTINE sst_component_run2
840    SUBROUTINE sst_component_finalize( gcomp, importState, exportState, clock, rc )
841      USE module_io
842      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
843      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
844      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
845      INTEGER,                     INTENT(  OUT) :: rc
846 !<DESCRIPTION>
847 !     SST component finalize routine.
849 !     The arguments are:
850 !       gcomp           Component
851 !       importState     Importstate
852 !       exportState     Exportstate
853 !       clock           External clock
854 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
855 !                       otherwise ESMF_FAILURE.
856 !</DESCRIPTION>
858      ! Local variables
859      TYPE(ESMF_Field) :: tmp_field
860      INTEGER :: i, ierr
862      rc = ESMF_SUCCESS
864      ! destroy ESMF_Fields and other "deep" objects created by this component
865      ! note that this component relied on ESMF to allocate data pointers during 
866      ! calls to ESMF_FieldCreate() so it also expects ESMF to free these pointers 
867      DO i=1, datacount
868        ! destroy field in importState
869        CALL ESMF_StateGet( importState, TRIM(datanames(i)), tmp_field, &
870                                 rc=rc )
871        IF (rc /= ESMF_SUCCESS) THEN
872          WRITE( str , * )                                               &
873            'sst_component_finalize:  ESMF_StateGet( importState,', &
874            TRIM(datanames(i)),') failed'
875          CALL wrf_error_fatal ( TRIM(str) )
876        ENDIF
877        CALL ESMF_FieldDestroy( tmp_field, rc=rc )
878        IF (rc /= ESMF_SUCCESS) THEN
879          WRITE( str , * )                                              &
880            'sst_component_finalize:  ESMF_FieldDestroy( importState,', &
881            TRIM(datanames(i)),') failed'
882          CALL wrf_error_fatal ( TRIM(str) )
883        ENDIF
884        ! destroy field in exportState
885        CALL ESMF_StateGet( exportState, TRIM(datanames(i)), tmp_field, &
886                                 rc=rc )
887        IF (rc /= ESMF_SUCCESS) THEN
888          WRITE( str , * )                                               &
889            'sst_component_finalize:  ESMF_StateGet( exportState,', &
890            TRIM(datanames(i)),') failed'
891          CALL wrf_error_fatal ( TRIM(str) )
892        ENDIF
893        CALL ESMF_FieldDestroy( tmp_field, rc=rc )
894        IF (rc /= ESMF_SUCCESS) THEN
895          WRITE( str , * )                                              &
896            'sst_component_finalize:  ESMF_FieldDestroy( exportState,', &
897            TRIM(datanames(i)),') failed'
898          CALL wrf_error_fatal ( TRIM(str) )
899        ENDIF
900      ENDDO
902      ! deallocate space for data read from disk
903      DEALLOCATE( file_sst_data, file_landmask_data )
905      ! close SST data file
906      WRITE( str , FMT='(A,I8)' ) &
907        'subroutine sst_component_finalize: closing file fid=',fid
908      CALL wrf_debug ( 100, TRIM(str) )
909      CALL wrf_ioclose( fid , ierr )
910      IF ( ierr .NE. 0 ) THEN
911        CALL wrf_error_fatal ( 'sst_component_finalize:  wrf_ioclose failed' )
912      ENDIF
914    END SUBROUTINE sst_component_finalize
917 END MODULE module_sst_component_top
922 MODULE module_sst_setservices
923 !<DESCRIPTION>
924 ! This module defines SST "Set Services" method sst_register() 
925 ! used for ESMF coupling.  
926 !</DESCRIPTION>
928    USE module_sst_component_top, ONLY: sst_component_init1,  &
929                                        sst_component_init2,  &
930                                        sst_component_run1,   &
931                                        sst_component_run2,   &
932                                        sst_component_finalize
933    USE ESMF_Mod
935    IMPLICIT NONE
937    ! everything is private by default
938    PRIVATE
940    ! Public entry point for ESMF_GridCompSetServices()
941    PUBLIC SST_register
943    ! private stuff
944    CHARACTER (ESMF_MAXSTR) :: str
946 CONTAINS
949    SUBROUTINE sst_register(gcomp, rc)
950      TYPE(ESMF_GridComp), INTENT(INOUT) :: gcomp
951      INTEGER, INTENT(OUT) :: rc
952      INTEGER :: finalrc
954 !<DESCRIPTION>
955 !     SST_register - Externally visible registration routine
957 !     User-supplied SetServices routine.
958 !     The Register routine sets the subroutines to be called
959 !     as the init, run, and finalize routines.  Note that these are
960 !     private to the module.
962 !     The arguments are:
963 !       gcomp           Component
964 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
965 !                       otherwise ESMF_FAILURE.
966 !</DESCRIPTION>
968      finalrc = ESMF_SUCCESS
969      ! Register the callback routines.
970      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
971                                      sst_component_init1, 1, rc)
972      IF ( rc /= ESMF_SUCCESS) THEN
973         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init1) failed with rc = ', rc
974         CALL wrf_error_fatal ( TRIM(str) )
975      ENDIF
976      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
977                                      sst_component_init2, 2, rc)
978      IF ( rc /= ESMF_SUCCESS) THEN
979         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init2) failed with rc = ', rc
980         CALL wrf_error_fatal ( TRIM(str) )
981      ENDIF
982      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETRUN, &
983                                      sst_component_run1, 1, rc)
984      IF ( rc /= ESMF_SUCCESS) THEN
985         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run1) failed with rc = ', rc
986         CALL wrf_error_fatal ( TRIM(str) )
987      ENDIF
988      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETRUN, &
989                                      sst_component_run2, 2, rc)
990      IF ( rc /= ESMF_SUCCESS) THEN
991         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run2) failed with rc = ', rc
992         CALL wrf_error_fatal ( TRIM(str) )
993      ENDIF
994      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETFINAL, &
995                                      sst_component_finalize, ESMF_SINGLEPHASE, rc)
996      IF ( rc /= ESMF_SUCCESS) THEN
997         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_finalize) failed with rc = ', rc
998         CALL wrf_error_fatal ( TRIM(str) )
999      ENDIF
1001      PRINT *,'SST:  Registered Initialize, Run, and Finalize routines'
1003      rc = finalrc
1005    END SUBROUTINE sst_register
1007 END MODULE module_sst_setservices
1011 !<DESCRIPTION>
1012 ! Module module_wrfsst_coupler defines the 
1013 ! "WRF-SST" coupler component.  It provides two-way coupling between 
1014 ! the "SST" and "WRF" components.  
1015 ! In its run routine it transfers data directly from the 
1016 ! SST Component's export state to the WRF Component's import state.  
1017 ! It also transfers data directly from the 
1018 ! WRF Component's export state to the SST Component's import state.  
1020 ! This is derived from src/demo/coupled_flow/src/CouplerMod.F90
1021 ! created by Nancy Collins and others on the ESMF Core Team.  
1023 !</DESCRIPTION>
1025 MODULE module_wrfsst_coupler
1027     USE ESMF_Mod
1029     IMPLICIT NONE
1030     
1031     ! everything is private by default
1032     PRIVATE
1034     ! Public entry point 
1035     PUBLIC WRFSSTCpl_register
1037     ! private data members
1038     ! route handles and flags
1039     TYPE(ESMF_RouteHandle), SAVE :: fromWRF_rh, fromSST_rh
1040     LOGICAL, SAVE :: fromWRF_rh_ready = .FALSE.
1041     LOGICAL, SAVE :: fromSST_rh_ready = .FALSE.
1042     ! field names
1043     INTEGER, PARAMETER :: datacount = 2
1044     INTEGER, PARAMETER :: SST_INDX = 1
1045     INTEGER, PARAMETER :: LANDMASK_INDX = 2
1046     CHARACTER(LEN=ESMF_MAXSTR), SAVE :: datanames(datacount)
1047     CHARACTER(LEN=ESMF_MAXSTR) :: str
1050 CONTAINS
1053    SUBROUTINE WRFSSTCpl_register(comp, rc)
1054      TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1055      INTEGER, INTENT(OUT) :: rc
1057 !<DESCRIPTION>
1058 !     WRFSSTCpl_register - Externally visible registration routine
1060 !     User-supplied SetServices routine.
1061 !     The Register routine sets the subroutines to be called
1062 !     as the init, run, and finalize routines.  Note that these are
1063 !     private to the module.
1065 !     The arguments are:
1066 !       comp            Component
1067 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1068 !                       otherwise ESMF_FAILURE.
1069 !</DESCRIPTION>
1071       ! guilty until proven innocent
1072       rc = ESMF_FAILURE
1074       ! Register the callback routines.
1076       call ESMF_CplCompSetEntryPoint(comp, ESMF_SETINIT, WRFSSTCpl_init, &
1077                                      ESMF_SINGLEPHASE, rc)
1078       IF ( rc /= ESMF_SUCCESS ) THEN
1079         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_init) failed' )
1080       ENDIF
1081       call ESMF_CplCompSetEntryPoint(comp, ESMF_SETRUN, WRFSSTCpl_run, &
1082                                      ESMF_SINGLEPHASE, rc)
1083       IF ( rc /= ESMF_SUCCESS ) THEN
1084         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_run) failed' )
1085       ENDIF
1086       call ESMF_CplCompSetEntryPoint(comp, ESMF_SETFINAL, WRFSSTCpl_final, &
1087                                      ESMF_SINGLEPHASE, rc)
1088       IF ( rc /= ESMF_SUCCESS ) THEN
1089         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_final) failed' )
1090       ENDIF
1092       print *, "module_wrfsst_coupler: Registered Initialize, Run, and Finalize routines"
1094     END SUBROUTINE WRFSSTCpl_register
1097     SUBROUTINE WRFSSTCpl_init(comp, importState, exportState, clock, rc)
1098       USE module_metadatautils, ONLY: AttachDecompToState, GetDecompFromState
1099       TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1100       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1101       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1102       INTEGER, INTENT(OUT) :: rc
1103 !<DESCRIPTION>
1104 !     WRF-SST coupler component init routine.  This simply passes needed 
1105 !     metadata from WRF to SST.  Initialization of ESMF_RouteHandle objects 
1106 !     is handled later via lazy evaluation.  
1108 !     The arguments are:
1109 !       comp            Component
1110 !       importState     Importstate
1111 !       exportState     Exportstate
1112 !       clock           External clock
1113 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1114 !                       otherwise ESMF_FAILURE.
1115 !</DESCRIPTION>
1117       ! Local variables
1118       CHARACTER(ESMF_MAXSTR) :: importstatename
1119       ! decomposition information
1120       INTEGER :: ids, ide, jds, jde, kds, kde
1121       INTEGER :: ims, ime, jms, jme, kms, kme
1122       INTEGER :: ips, ipe, jps, jpe, kps, kpe
1123       INTEGER :: domdesc
1124       LOGICAL :: bdy_mask(4)
1126       PRINT *, "DEBUG:  Coupler Init starting"
1128       ! guilty until proven innocent
1129       rc = ESMF_FAILURE
1131       CALL ESMF_StateGet(importState, name=importstatename, rc=rc)
1132       IF ( rc /= ESMF_SUCCESS ) THEN
1133         CALL wrf_error_fatal ( 'WRFSSTCpl_init:  ESMF_StateGet failed' )
1134       ENDIF
1136       IF ( TRIM(importstatename) .EQ. "WRF Export State" ) THEN
1137         ! get metadata from WRF export state
1138         CALL GetDecompFromState( importState,                  &
1139                                  ids, ide, jds, jde, kds, kde, &
1140                                  ims, ime, jms, jme, kms, kme, &
1141                                  ips, ipe, jps, jpe, kps, kpe, &
1142                                  domdesc, bdy_mask )
1143         ! put metadata from in SST import state
1144         CALL AttachDecompToState( exportState,                  &
1145                                   ids, ide, jds, jde, kds, kde, &
1146                                   ims, ime, jms, jme, kms, kme, &
1147                                   ips, ipe, jps, jpe, kps, kpe, &
1148                                   domdesc, bdy_mask )
1151       ELSE
1152         CALL wrf_error_fatal ( 'WRFSSTCpl_init:  invalid importState name' )
1153       ENDIF
1155       ! set up field names
1156 !TODO:  use CF conventions for "standard_name" once WRF Registry supports them
1157 !TODO:      datanames(SST_INDX) = "sea_surface_temperature"
1158 !TODO:      datanames(LANDMASK_INDX) = "land_binary_mask"
1159       datanames(SST_INDX) = "SST"
1160       datanames(LANDMASK_INDX) = "LANDMASK"
1162       PRINT *, "DEBUG:  Coupler Init returning"
1163    
1164     END SUBROUTINE WRFSSTCpl_init
1168     SUBROUTINE WRFSSTCpl_run(comp, importState, exportState, clock, rc)
1169       TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1170       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1171       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1172       INTEGER, INTENT(OUT) :: rc
1173 !<DESCRIPTION>
1174 !     WRF-SST coupler component run routine.
1176 !     The arguments are:
1177 !       comp            Component
1178 !       importState     Importstate
1179 !       exportState     Exportstate
1180 !       clock           External clock
1181 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1182 !                       otherwise ESMF_FAILURE.
1183 !</DESCRIPTION>
1185 ! Note that comments in this code are preserved from the sample coupler 
1186 ! provided by the ESMF core team.  
1188       ! Local variables
1189 character*256 :: mename
1190 character*256 :: melist(100)
1191 integer :: mecount
1192 TYPE(ESMF_StateItemType) :: metypelist(100)
1193       TYPE(ESMF_Field) :: src_field, dst_field
1194       TYPE(ESMF_Array) :: src_array, dst_array
1195       TYPE(ESMF_RouteHandle) :: routehandle
1196       TYPE(ESMF_VM) :: vm
1197       LOGICAL :: build_fromWRF_rh, build_fromSST_rh, fromWRF
1198       CHARACTER(LEN=ESMF_MAXSTR) :: importStatename
1199       CHARACTER(LEN=ESMF_MAXSTR) :: SST_exportStatename, WRF_exportStatename
1200       INTEGER :: i
1201       CHARACTER(LEN=256) :: directionString
1203       WRITE(str,*) 'WRFSSTCpl_run: begin'
1204       CALL wrf_debug ( 100 , TRIM(str) )
1206       ! guilty until proven innocent
1207       rc = ESMF_FAILURE
1209       ! Which way is this coupling going?  
1210       WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateGet(importState,name,...)'
1211       CALL wrf_debug ( 100 , TRIM(str) )
1212       CALL ESMF_StateGet( importState, name=importStatename, rc=rc )
1213 !write(0,*)__FILE__,__LINE__, 'importStatename ', trim(importStatename), 'rc = ', rc
1214       IF ( rc /= ESMF_SUCCESS ) THEN
1215         CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(importState,name,...) failed' )
1216       ENDIF
1217       WRITE(str,*) 'WRFSSTCpl_run: back from ESMF_StateGet, importStatename = <',TRIM(importStatename),'>'
1218       CALL wrf_debug ( 100 , TRIM(str) )
1220       ! first time through in each direction:  create route handle and 
1221       ! associated objects
1222       WRF_exportStatename = "WRF Export State"
1223       SST_exportStatename = "SST Export State"
1224       IF ( TRIM(importStatename) .EQ. TRIM(WRF_exportStatename) ) THEN
1225         fromWRF = .TRUE.
1226         directionString = 'WRFtoSST'
1227       ELSE IF ( TRIM(importStatename) .EQ. TRIM(SST_exportStatename) ) THEN
1228         fromWRF = .FALSE.
1229         directionString = 'SSTtoWRF'
1230       ELSE
1231         CALL wrf_error_fatal ( 'WRFSSTCpl_run:  invalid importState name' )
1232       ENDIF
1233       WRITE(str,*) 'WRFSSTCpl_run: fromWRF = ',fromWRF
1234       CALL wrf_debug ( 100 , TRIM(str) )
1235       build_fromWRF_rh =         fromWRF   .AND. ( .NOT. fromWRF_rh_ready )
1236       build_fromSST_rh = ( .NOT. fromWRF ) .AND. ( .NOT. fromSST_rh_ready )
1237       WRITE(str,*) 'WRFSSTCpl_run: build_fromWRF_rh = ',build_fromWRF_rh
1238       CALL wrf_debug ( 100 , TRIM(str) )
1239       WRITE(str,*) 'WRFSSTCpl_run: build_fromSST_rh = ',build_fromSST_rh
1240       CALL wrf_debug ( 100 , TRIM(str) )
1241       IF ( build_fromWRF_rh .OR. build_fromSST_rh ) THEN
1242         CALL ESMF_CplCompGet( comp, vm=vm, rc=rc )
1243         IF ( rc /= ESMF_SUCCESS ) THEN
1244           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_CplCompGet failed' )
1245         ENDIF
1246         ! The use of literal index "1" here indicates that we don't care which 
1247         ! ESMF_Field we get so we might as well get the first one.  
1248         WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1249                      '> from import state'
1250         CALL wrf_debug ( 100 , TRIM(str) )
1252 CALL ESMF_StateGet( importState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1253 !write(0,*)'importState mename ',trim(mename)
1254 !write(0,*)'importState mecount ',mecount
1255 !do i = 1,mecount
1256 !write(0,*)i,trim(melist(i))
1257 !enddo
1258 !do i = 1,mecount
1259 !write(0,*)i,metypelist(i)
1260 !enddo
1262         CALL ESMF_StateGet( importState, TRIM(datanames(1)), src_field, &
1263                                  rc=rc )
1264 !write(0,*)__FILE__,__LINE__, 'from importState: datanames(1) ', TRIM(datanames(1)), ' 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 !write(0,*)__FILE__,__LINE__, 'from fieldget:  rc = ', rc
1271         IF ( rc /= ESMF_SUCCESS ) THEN
1272           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldGet src_array failed' )
1273         ENDIF
1274         WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1275                      '> from export state'
1276         CALL wrf_debug ( 100 , TRIM(str) )
1278 CALL ESMF_StateGet( exportState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1279 !write(0,*)'Exportstate mename ',trim(mename)
1280 !write(0,*)'Exportstate mecount ',mecount
1281 !do i = 1,mecount
1282 !write(0,*)i,trim(melist(i))
1283 !enddo
1284 !do i = 1,mecount
1285 !write(0,*)i,metypelist(i)
1286 !enddo
1288         CALL ESMF_StateGet( exportState, TRIM(datanames(1)), dst_field, &
1289                                  rc=rc )
1290         IF ( rc /= ESMF_SUCCESS ) THEN
1291           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(exportState) failed' )
1292         ENDIF
1293         CALL ESMF_FieldGet( dst_field, array=dst_array, &
1294                                  rc=rc )
1295         IF ( rc /= ESMF_SUCCESS ) THEN
1296           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldGet dst_array failed' )
1297         ENDIF
1301         IF ( build_fromWRF_rh ) THEN
1302           WRITE(str,*) 'WRFSSTCpl_run: creating fromWRF_rh'
1303           CALL wrf_debug ( 100 , TRIM(str) )
1304           fromWRF_rh = ESMF_RouteHandleCreate( rc )
1305           IF ( rc /= ESMF_SUCCESS ) THEN
1306             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_RouteHandleCreate(fromWRF_rh) failed' )
1307           ENDIF
1308           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromWRF_rh)'
1309           CALL wrf_debug ( 100 , TRIM(str) )
1310           CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1311                                       routehandle=fromWRF_rh, rc=rc )
1312           IF ( rc /= ESMF_SUCCESS ) THEN
1313             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedistStore(fromWRF_rh) failed' )
1314           ENDIF
1315           fromWRF_rh_ready = .TRUE.
1316         ENDIF
1317         IF ( build_fromSST_rh ) THEN
1318           WRITE(str,*) 'WRFSSTCpl_run: creating fromSST_rh'
1319           CALL wrf_debug ( 100 , TRIM(str) )
1320           fromSST_rh = ESMF_RouteHandleCreate( rc )
1321           IF ( rc /= ESMF_SUCCESS ) THEN
1322             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_RouteHandleCreate(fromSST_rh) failed' )
1323           ENDIF
1324           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromSST_rh)'
1325           CALL wrf_debug ( 100 , TRIM(str) )
1326           CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1327                                       routehandle=fromSST_rh, rc=rc )
1328 !write(0,*)__FILE__,__LINE__,'rc = ',rc
1329           IF ( rc /= ESMF_SUCCESS ) THEN
1330             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedistStore(fromSST_rh) failed' )
1331           ENDIF
1332           fromSST_rh_ready = .TRUE.
1333         ENDIF
1334         DO i=1, datacount
1335           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateSetNeeded(importState, ',TRIM(datanames(i)),')'
1336           CALL wrf_debug ( 100 , TRIM(str) )
1337           CALL ESMF_StateSetNeeded( importState, TRIM(datanames(i)), &
1338                                     ESMF_NEEDED, rc=rc )
1339           IF ( rc /= ESMF_SUCCESS ) THEN
1340             WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateSetNeeded(',TRIM(datanames(i)),') failed'
1341             CALL wrf_error_fatal ( str )
1342           ENDIF
1343         ENDDO
1344       ENDIF
1346       ! In this case, the coupling is symmetric - you call redist going
1347       ! both ways - so we only care about the coupling direction in order 
1348       ! to get the right routehandle selected.
1349       IF ( fromWRF ) THEN
1350         WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromWRF_rh'
1351         CALL wrf_debug ( 100 , TRIM(str) )
1352         routehandle = fromWRF_rh 
1353       ELSE
1354         WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromSST_rh'
1355         CALL wrf_debug ( 100 , TRIM(str) )
1356         routehandle = fromSST_rh 
1357       ENDIF
1359       DO i=1, datacount
1360         WRITE(str,*) 'WRFSSTCpl_run: grabbing field <',TRIM(datanames(i)),'>'
1361         CALL wrf_debug ( 100 , TRIM(str) )
1362         ! check isneeded flag here
1363         IF ( .NOT. ESMF_StateIsNeeded( importState, TRIM(datanames(i)), rc=rc ) ) THEN 
1364           IF ( rc /= ESMF_SUCCESS ) THEN
1365             WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateIsNeeded(',TRIM(datanames(i)),') failed'
1366             CALL wrf_error_fatal ( str )
1367           ENDIF
1368           WRITE(str,*) 'WRFSSTCpl_run: skipping field <',TRIM(datanames(i)),'>'
1369           CALL wrf_debug ( 100 , TRIM(str) )
1370           CYCLE
1371         ENDIF
1373         WRITE(str,*) 'WRFSSTCpl_run: processing field <',TRIM(datanames(i)),'>'
1374         CALL wrf_debug ( 100 , TRIM(str) )
1376 !   The following piece of code provides an example of calling the data
1377 !   redistribution routine  between two Fields in the Coupler Component.  
1378 !   Unlike regrid, which translates between
1379 !   different Grids, redist translates between different DELayouts on
1380 !   the same Grid.   The first two lines get the Fields from the 
1381 !   States, each corresponding to a different subcomponent.  One is
1382 !   an Export State and the other is an Import State.
1384         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_StateGet(importState,', &
1385                      TRIM(datanames(i)),')...'
1386         CALL wrf_debug ( 100 , TRIM(str) )
1387         CALL ESMF_StateGet( importState, TRIM(datanames(i)), src_field, &
1388                                  rc=rc )
1389         IF ( rc /= ESMF_SUCCESS ) THEN
1390           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateGet(importState,', &
1391                        TRIM(datanames(i)),') failed'
1392           CALL wrf_error_fatal ( str )
1393         ENDIF
1394         CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1395         IF ( rc /= ESMF_SUCCESS ) THEN
1396           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_FieldGet(src_field,src_array,rc) failed'
1397           CALL wrf_error_fatal ( str )
1398         ENDIF
1400         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_StateGet(exportState,', &
1401                      TRIM(datanames(i)),')...'
1402         CALL wrf_debug ( 100 , TRIM(str) )
1403         CALL ESMF_StateGet( exportState, TRIM(datanames(i)), dst_field, &
1404                                  rc=rc )
1405         IF ( rc /= ESMF_SUCCESS ) THEN
1406           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateGet(exportState,', &
1407                        TRIM(datanames(i)),') failed'
1408           CALL wrf_error_fatal ( str )
1409         ENDIF
1410         CALL ESMF_FieldGet( dst_field, array=dst_array, rc=rc )
1411         IF ( rc /= ESMF_SUCCESS ) THEN
1412           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_FieldGet(dst_field,dst_array,rc) failed'
1413           CALL wrf_error_fatal ( str )
1414         ENDIF
1416 !   The redist routine uses information contained in the Fields and the
1417 !   Coupler VM object to call the communication routines to move the data.
1418 !   Because many Fields may share the same Grid association, the same
1419 !   routing information may be needed repeatedly.  Route information is 
1420 !   saved so the precomputed information can be retained.  The following 
1421 !   is an example of a Field redist call:
1422         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_FieldRedist for <', &
1423                      TRIM(datanames(i)),'>...'
1424         CALL wrf_debug ( 100 , TRIM(str) )
1425         CALL ESMF_ArrayRedist( src_array, dst_array, routehandle, rc=rc )
1426         IF ( rc /= ESMF_SUCCESS ) THEN
1427           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedist failed' )
1428         ENDIF
1429         WRITE(str,*) 'WRFSSTCpl_run:  back from ESMF_FieldRedist for <', &
1430                      TRIM(datanames(i)),'>...'
1431         CALL wrf_debug ( 100 , TRIM(str) )
1433       ENDDO
1435       WRITE(str,*) 'WRFSSTCpl_run: end'
1436       CALL wrf_debug ( 100 , TRIM(str) )
1438     END SUBROUTINE WRFSSTCpl_run
1442     SUBROUTINE WRFSSTCpl_final(comp, importState, exportState, clock, rc)
1443       TYPE(ESMF_CplComp) :: comp
1444       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1445       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1446       INTEGER, INTENT(OUT) :: rc
1447 !<DESCRIPTION>
1448 !     WRF-SST coupler component finalize routine.
1450 !     The arguments are:
1451 !       comp            Component
1452 !       importState     Importstate
1453 !       exportState     Exportstate
1454 !       clock           External clock
1455 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1456 !                       otherwise ESMF_FAILURE.
1457 !</DESCRIPTION>
1459       PRINT *, "DEBUG:  Coupler Final starting"
1460    
1461       ! guilty until proven innocent
1462       rc = ESMF_FAILURE
1464       ! Only thing to do here is release redist and route handles
1465       IF ( fromWRF_rh_ready ) THEN
1466         CALL ESMF_RouteHandleDestroy(fromWRF_rh, rc)
1467         IF ( rc /= ESMF_SUCCESS ) THEN
1468           CALL wrf_error_fatal ( 'WRFSSTCpl_final:  ESMF_RouteHandleDestroy(fromWRF_rh) failed' )
1469         ENDIF
1470       ENDIF
1471       IF ( fromSST_rh_ready ) THEN
1472         CALL ESMF_RouteHandleDestroy(fromSST_rh, rc)
1473         IF ( rc /= ESMF_SUCCESS ) THEN
1474           CALL wrf_error_fatal ( 'WRFSSTCpl_final:  ESMF_RouteHandleDestroy(fromSST_rh) failed' )
1475         ENDIF
1476       ENDIF
1478       PRINT *, "DEBUG:  Coupler Final returning"
1479    
1480     END SUBROUTINE WRFSSTCpl_final
1483 END MODULE module_wrfsst_coupler
1484     
1485     
1488 PROGRAM wrf_SST_ESMF
1490 !<DESCRIPTION>
1491 ! ESMF Application Wrapper for coupling WRF with a "dummy" component 
1492 ! that simply reads SSTs from a file and sends them to WRF (one-way 
1493 ! coupling).  Fields are returned from WRF to SST via the coupler for 
1494 ! self-test only.  
1496 ! Note that, like other WRF coupling methods (MCEL, MCT), ESMF coupling is 
1497 ! supported only via auxiliary input and history streams.  
1499 ! This is the main program that creates the ESMF Gridded and Coupler 
1500 ! Component.  
1502 ! "init" looks like this:  
1503 !   1. Init phase 1 for WRF, sets WRF exportState metadata for "time" 
1504 !      and "domain" information needed by WRF IOAPI (which is called from 
1505 !      the SST component).  It also sets up all WRF and WSF modules.  Note 
1506 !      that this must be called before SST phase-1 init because SST uses 
1507 !      WRF IOAPI.  
1508 !   2. Init phase 1 for SST, sets "time" metadata in SST exportState.  
1509 !   3. Initialize coupler, passing decomposition metadata from WRF exportState 
1510 !      to SST importState.  
1511 !   4. Resolve any "time" metadata inconsistencies and create top-level clock.  
1512 !   5. Init phase 2 for SST, gets "domain" information from importState, 
1513 !      creates an ESMF_Grid based on "domain" information using the exact same 
1514 !      method as WRF (so WRF IOAPI calls will work), and sets up SST 
1515 !      importState and exportState.  
1516 !   6. Init phase 2 for WRF, runs up to the end of the head_grid I/O "training" 
1517 !      phase (done in med_before_solve_io()).  This initializes WRF 
1518 !      importState and exportState prior to the first coupling step during the 
1519 !      "run" loop.  Note that this only works for head_grid at present because 
1520 !      recursion in WRF traversal of subdomains is not dealt with yet and 
1521 !      because the code that populates the WRF importState and exportState is 
1522 !      not yet sophisticated enough to handle creating and destroying nested 
1523 !      domains at any time during the model run.  
1524 !TODO:  ESMF auxio must begin at the start of the run.  Remove this 
1525 !TODO:  restriction later, if needed.  
1527 !TODO:  Note that coupling is currently limited to one auxin plus one auxout 
1528 !TODO:  streams.  Extension to multiple pairs of auxio streams requires 
1529 !TODO:  nested states (one for each auxio stream pair).  
1530 !TODO:  For now, only support one input and/or one output stream via 
1531 !TODO:  io_esmf.  This condition is asserted in 
1532 !TODO:  ext_esmf_open_for_read_begin() and 
1533 !TODO:  ext_esmf_open_for_write_begin().  
1535 ! "run" loop looks like this:  
1536 !   1. Run SST phase 1, reads SST from file and writes it to SST exportState 
1537 !      for coupling to WRF.  
1538 !   2. Couple SST exportState -> WRF importState.  First iteration:  set up 
1539 !      SST->WRF routeHandle via lazy evaluation.  
1540 !   3. Run WRF.  First iteration:  head_grid resumes after I/O "training" 
1541 !      phase.  Other iterations and domains:  run normally.  
1542 !      Read WRF importState and write WRF exportState (via med_before_solve_io()).  
1543 !      Note that WRF assigns sst -> tsk for sea points in 
1544 !      share/module_soil_pre.F.  
1545 !   4. Couple WRF exportState -> SST importState.  First iteration:  set up
1546 !      WRF->SST routeHandle via lazy evaluation.
1547 !   5. Run SST phase 2, compare SST from file with SST from WRF (via 
1548 !      SST importState) and error-exit if they differ.  
1549 !   6. Advance clock and goto step 1
1551 ! "finalize" is trivial, except for destruction of ESMF objects which is 
1552 ! quite non-trivial at the moment.  
1554 !</DESCRIPTION>
1556    ! WRF registration routine
1557    USE module_wrf_setservices, ONLY: WRF_register
1558    ! SST registration routine
1559    USE module_sst_setservices, ONLY: SST_register
1560    ! WRF-SST coupler registration routine
1561    USE module_wrfsst_coupler, ONLY: WRFSSTCpl_register
1562    ! ESMF module, defines all ESMF data types and procedures
1563    USE ESMF_Mod
1564    ! Not-yet-implemented ESMF features
1565    USE module_esmf_extensions
1566    ! Component-independent utilities
1567    USE module_metadatautils, ONLY: GetTimesFromStates
1569    IMPLICIT NONE
1571    ! Local variables
1573    ! Components
1574    TYPE(ESMF_GridComp) :: compGriddedWRF   ! WRF
1575    TYPE(ESMF_GridComp) :: compGriddedSST   ! SST reader
1576    TYPE(ESMF_CplComp) :: compCplWRFSST     ! WRF-SST coupler
1578    ! State, Virtual Machine, and DELayout
1579    TYPE(ESMF_VM) :: vm
1580    TYPE(ESMF_State) :: importStateWRF, exportStateWRF
1581    TYPE(ESMF_State) :: importStateSST, exportStateSST
1583    ! A clock, some times, and a time step
1584    TYPE(ESMF_Clock) :: driverClock
1585    TYPE(ESMF_Time) :: startTime
1586    TYPE(ESMF_Time) :: stopTime
1587    TYPE(ESMF_TimeInterval) :: couplingInterval
1589    ! other misc stuff
1590    TYPE(ESMF_State) :: tmpState
1591    INTEGER :: timestepdebug
1592    INTEGER :: thecount  ! ah ah ah
1594    ! Return codes for error checks
1595    INTEGER :: rc
1596    CHARACTER (ESMF_MAXSTR) :: str
1598    ! debugging
1599    CHARACTER(LEN=256) :: couplingIntervalString
1600 integer(ESMF_KIND_I4) :: timevals(6)
1602         
1603    ! Warn users that this is not yet ready for general use.  
1604    PRINT *, '                      W A R N I N G                          '
1605    PRINT *, '  ESMF COUPLING CAPABILITY IS EXPERIMENTAL AND UNSUPPORTED   '
1606    PRINT *, '               IN THIS VERSION OF WRF-CPL-SST                '
1607    PRINT *, '          U S E   A T   Y O U R   O W N   R I S K            '
1609    ! Initialize ESMF, get the default Global VM, and set
1610    ! the default calendar to be Gregorian.
1611    CALL ESMF_Initialize( vm=vm, defaultCalendar=ESMF_CAL_GREGORIAN, defaultlogtype=ESMF_LOG_MULTI,rc=rc )
1612    IF ( rc /= ESMF_SUCCESS ) THEN
1613      PRINT *, 'wrf_SST_ESMF:  ESMF_Initialize failed'
1614    ENDIF
1615    ! Note:  wrf_debug and wrf_error_fatal are not initialized yet
1616    PRINT *, 'DEBUG wrf_SST_ESMF:  returned from ESMF_Initialize'
1617    CALL ESMF_SetInitialized()   ! eliminate this once ESMF does it internally
1619    ! Create the WRF Gridded Component, passing in the default VM.
1620    compGriddedWRF = ESMF_GridCompCreate( name="WRF Model", rc=rc)
1621    IF ( rc /= ESMF_SUCCESS ) THEN
1622      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompCreate(WRF Model) failed'
1623    ENDIF
1625    ! Create the SST Gridded Component, passing in the default VM.
1626    compGriddedSST = ESMF_GridCompCreate( name="SST Dummy Model", rc=rc)
1627    IF ( rc /= ESMF_SUCCESS ) THEN
1628      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompCreate(WRF Dummy Model) failed'
1629    ENDIF
1631    ! Create the WRF-SST Coupler Component, passing in the default VM.
1632    compCplWRFSST = ESMF_CplCompCreate( name="WRF-SST Coupler", rc=rc)
1633    IF ( rc /= ESMF_SUCCESS ) THEN
1634      PRINT *, 'wrf_SST_ESMF:  ESMF_CplCompCreate failed'
1635    ENDIF
1637    ! Create empty import and export states for WRF
1638    importStateWRF = ESMF_StateCreate(stateName="WRF Import State", statetype=ESMF_STATE_IMPORT, rc=rc)
1639    IF ( rc /= ESMF_SUCCESS ) THEN
1640      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(WRF Import State) failed'
1641    ENDIF
1642    exportStateWRF = ESMF_StateCreate(stateName="WRF Export State", statetype=ESMF_STATE_EXPORT, rc=rc)
1643    IF ( rc /= ESMF_SUCCESS ) THEN
1644      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(WRF Export State) failed'
1645    ENDIF
1647    ! Create empty import and export states for SST
1648    importStateSST = ESMF_StateCreate(stateName="SST Import State", statetype=ESMF_STATE_IMPORT, rc=rc)
1649    IF ( rc /= ESMF_SUCCESS ) THEN
1650      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(SST Import State) failed'
1651    ENDIF
1652    exportStateSST = ESMF_StateCreate(stateName="SST Export State", statetype=ESMF_STATE_EXPORT, rc=rc)
1653    IF ( rc /= ESMF_SUCCESS ) THEN
1654      PRINT *, 'wrf_SST_ESMF:  ESMF_StateCreate(SST Export State) failed'
1655    ENDIF
1657    ! Register the WRF Gridded Component
1658    CALL ESMF_GridCompSetServices(compGriddedWRF, WRF_register, rc)
1659    IF ( rc /= ESMF_SUCCESS ) THEN
1660      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompSetServices(compGriddedWRF) failed'
1661    ENDIF
1663    ! Register the SST Gridded Component
1664    CALL ESMF_GridCompSetServices(compGriddedSST, SST_register, rc)
1665    IF ( rc /= ESMF_SUCCESS ) THEN
1666      PRINT *, 'wrf_SST_ESMF:  ESMF_GridCompSetServices(compGriddedSST) failed'
1667    ENDIF
1669    ! Register the WRF-SST Coupler Component
1670    CALL ESMF_CplCompSetServices(compCplWRFSST, WRFSSTCpl_register, rc)
1671    IF ( rc /= ESMF_SUCCESS ) THEN
1672      PRINT *, 'wrf_SST_ESMF:  ESMF_CplCompSetServices failed'
1673    ENDIF
1675    ! Create top-level clock.  There is no way to create an "empty" clock, so 
1676    ! stuff in bogus values for start time, stop time, and time step and fix 
1677    ! them after gridded component "init" phases return.  
1678    CALL ESMF_TimeSet(startTime, yy=2000, mm=1, dd=1, &
1679                      h=0, m=0, s=0, rc=rc)
1680    IF ( rc /= ESMF_SUCCESS ) THEN
1681      PRINT *, 'wrf_SST_ESMF:  ESMF_TimeSet(startTime) failed'
1682    ENDIF
1683    CALL ESMF_TimeSet(stopTime, yy=2000, mm=1, dd=1, &
1684                      h=12, m=0, s=0, rc=rc)
1685    IF ( rc /= ESMF_SUCCESS ) THEN
1686      PRINT *, 'wrf_SST_ESMF:  ESMF_TimeSet(stopTime) failed'
1687    ENDIF
1688    CALL ESMF_TimeIntervalSet(couplingInterval, s=2, rc=rc)
1689    IF ( rc /= ESMF_SUCCESS ) THEN
1690      PRINT *, 'wrf_SST_ESMF:  ESMF_TimeIntervalSet failed'
1691    ENDIF
1692    driverClock = ESMF_ClockCreate(timeStep=couplingInterval, &
1693                                   startTime=startTime,       &
1694                                   stopTime=stopTime, rc=rc)
1695    IF ( rc /= ESMF_SUCCESS ) THEN
1696      PRINT *, 'wrf_SST_ESMF:  ESMF_ClockCreate failed'
1697    ENDIF
1699    ! Init, Run, and Finalize section
1701    ! Init...
1702    ! initialize WRF, phase 1
1703    ! Phase 1 init returns WRF time and decomposition information as
1704    ! exportState metadata.
1705    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 WRF init (wrf_component_init1)'
1706    CALL ESMF_GridCompInitialize(compGriddedWRF, importStateWRF, &
1707                                 exportStateWRF, driverClock, phase=1, rc=rc)
1708 thecount = size(timevals)
1709 call esmf_attributeget(exportstatewrf,'ComponentCouplingInterval',timevals,itemcount=thecount,rc=rc)
1710 !write(0,*) 'exportStateWRF year ',timevals(1),__LINE__
1711 !write(0,*) 'exportStateWRF month ',timevals(2),__LINE__
1712 !write(0,*) 'exportStateWRF day ',timevals(3),__LINE__
1713 !write(0,*) 'exportStateWRF hour ',timevals(4),__LINE__
1714 !write(0,*) 'exportStateWRF minute ',timevals(5),__LINE__
1715 !write(0,*) 'exportStateWRF second ',timevals(6),__LINE__
1716    ! Note:  wrf_debug and wrf_error_fatal are now initialized
1717    IF ( rc /= ESMF_SUCCESS ) THEN
1718      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(WRF phase 1) failed' )
1719    ENDIF
1721    ! initialize SST, phase 1
1722    ! Phase 1 init returns SST time information as
1723    ! exportState metadata.
1724    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 SST init (sst_component_init1)'
1725    CALL ESMF_GridCompInitialize(compGriddedSST, importStateSST, &
1726                                 exportStateSST, driverClock, phase=1, rc=rc)
1727 thecount = size(timevals)
1728 call esmf_attributeget(exportstatesst,'ComponentCouplingInterval',timevals,itemcount=thecount,rc=rc)
1729 !write(0,*) 'exportStateSST year ',timevals(1),__LINE__
1730 !write(0,*) 'exportStateSST month ',timevals(2),__LINE__
1731 !write(0,*) 'exportStateSST day ',timevals(3),__LINE__
1732 !write(0,*) 'exportStateSST hour ',timevals(4),__LINE__
1733 !write(0,*) 'exportStateSST minute ',timevals(5),__LINE__
1734 !write(0,*) 'exportStateSST second ',timevals(6),__LINE__
1735    IF ( rc /= ESMF_SUCCESS ) THEN
1736      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(SST phase 1) failed' )
1737    ENDIF
1739    ! Reconcile clock settings from WRF and SST components to set up 
1740    ! top-level clock.  These are passed back from each "init" as attributes 
1741    ! on exportState*.  
1742    ! Stuff both States into a single State to pass into GetTimesFromStates() 
1743    ! which is smart enough to deal with a Composite.  
1744    PRINT *, 'DEBUG wrf_SST_ESMF:  reconciling clock from WRF and SST components'
1745    tmpState = ESMF_StateCreate( rc=rc )
1746    IF ( rc /= ESMF_SUCCESS ) THEN
1747      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateCreate(tmpState) failed' )
1748    ENDIF
1749    CALL ESMF_StateAdd( tmpState, exportStateWRF, rc )
1750    IF ( rc /= ESMF_SUCCESS ) THEN
1751      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateAdd(exportStateWRF) failed' )
1752    ENDIF
1753    CALL ESMF_StateAdd( tmpState, exportStateSST, rc )
1754    IF ( rc /= ESMF_SUCCESS ) THEN
1755      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateAdd(exportStateSST) failed' )
1756    ENDIF
1757    CALL GetTimesFromStates( tmpState, startTime, stopTime, couplingInterval )
1758    CALL ESMF_TimeIntervalGet( couplingInterval, TimeString=couplingIntervalString, &
1759                               rc=rc )
1760    IF ( rc /= ESMF_SUCCESS ) THEN
1761      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_TimeIntervalGet failed' )
1762    ENDIF
1763    CALL wrf_debug( 100, 'wrf_SST_ESMF:  couplingInterval = '//TRIM(couplingIntervalString) )
1764    CALL ESMF_StateDestroy( tmpState, rc )
1765    IF ( rc /= ESMF_SUCCESS ) THEN
1766      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(tmpState) failed' )
1767    ENDIF
1768    ! update driver clock
1769    CALL ESMF_ClockDestroy(driverClock, rc)
1770    IF ( rc /= ESMF_SUCCESS ) THEN
1771      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockDestroy failed' )
1772    ENDIF
1773    driverClock = ESMF_ClockCreate(timeStep=couplingInterval, &
1774                                   startTime=startTime,       &
1775                                   stopTime=stopTime, rc=rc)
1776    IF ( rc /= ESMF_SUCCESS ) THEN
1777      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockCreate(driverClock) failed' )
1778    ENDIF
1779    PRINT *, 'DEBUG wrf_SST_ESMF:  done reconciling clock from WRF and SST components'
1780    CALL wrf_clockprint(50, driverClock, &
1781           'DEBUG wrf_SST_ESMF:  driverClock after creation,')
1783    ! initialize WRF-SST Coupler
1784    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 CPL init (WRFSSTCpl_init)'
1785    CALL ESMF_CplCompInitialize(compCplWRFSST, exportStateWRF, &
1786                                importStateSST, driverClock, rc=rc)
1787    IF ( rc /= ESMF_SUCCESS ) THEN
1788      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompInitialize(WRF -> SST) failed' )
1789    ENDIF
1791 ! TBH:  this bit is not needed, but would be in general
1792 !   CALL ESMF_CplCompInitialize(compCplWRFSST, exportStateSST, &
1793 !                               importStateWRF, driverClock, rc=rc)
1794 !   IF ( rc /= ESMF_SUCCESS ) THEN
1795 !     CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompInitialize(SST -> WRF) failed' )
1796 !   ENDIF
1798    ! initialize SST, phase 2
1799    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for SST (sst_component_init2)'
1800    CALL wrf_debug ( 100 , TRIM(str) )
1801    CALL ESMF_GridCompInitialize(compGriddedSST, importStateSST, &
1802                                 exportStateSST, driverClock, phase=2, rc=rc)
1803    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for SST'
1804    CALL wrf_debug ( 100 , TRIM(str) )
1805    IF ( rc /= ESMF_SUCCESS ) THEN
1806      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(SST phase 2) failed' )
1807    ENDIF
1809    ! initialize WRF, phase 2
1810    ! Phase 2 init sets up WRF importState and exportState.
1811    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for WRF (wrf_component_init2)'
1812    CALL wrf_debug ( 100 , TRIM(str) )
1813    CALL ESMF_GridCompInitialize(compGriddedWRF, importStateWRF, &
1814                                 exportStateWRF, driverClock, phase=2, rc=rc)
1815    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for WRF'
1816    CALL wrf_debug ( 100 , TRIM(str) )
1817    IF ( rc /= ESMF_SUCCESS ) THEN
1818      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(WRF phase 2) failed' )
1819    ENDIF
1821    CALL wrf_clockprint(50, driverClock, &
1822           'DEBUG wrf_SST_ESMF:  driverClock before main time-stepping loop,')
1823    ! Run...
1824    ! main time-stepping loop
1825    timestepdebug = 0
1826    DO WHILE ( .NOT. ESMF_ClockIsStopTime(driverClock, rc) )
1828      timestepdebug = timestepdebug + 1
1829      WRITE(str,'(A,I8)') 'PROGRAM wrf_SST_ESMF: Top of time-stepping loop, timestepdebug = ',timestepdebug
1830      CALL wrf_debug ( 100 , TRIM(str) )
1831      CALL wrf_clockprint(50, driverClock, &
1832             'DEBUG wrf_SST_ESMF:  driverClock at top of time-stepping loop,')
1834      ! Run SST phase 1
1835      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-1 run for SST (sst_component_run1)'
1836      CALL wrf_debug ( 100 , TRIM(str) )
1837      CALL ESMF_GridCompRun(compGriddedSST, importStateSST, exportStateSST, &
1838                            driverClock, phase=1, rc=rc)
1839      IF ( rc /= ESMF_SUCCESS ) THEN
1840        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(SST phase 1) failed' )
1841      ENDIF
1842      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-1 run for SST (sst_component_run1)'
1843      CALL wrf_debug ( 100 , TRIM(str) )
1845      ! couple SST export -> WRF import
1846      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL SST->WRF (WRFSSTCpl_run)'
1847      CALL wrf_debug ( 100 , TRIM(str) )
1848      CALL ESMF_CplCompRun(compCplWRFSST, exportStateSST, &
1849                           importStateWRF, driverClock, rc=rc)
1850      IF ( rc /= ESMF_SUCCESS ) THEN
1851        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompRun(SST -> WRF) failed' )
1852      ENDIF
1853      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL SST->WRF (WRFSSTCpl_run)'
1854      CALL wrf_debug ( 100 , TRIM(str) )
1856      ! Run WRF
1857      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for WRF (wrf_component_run)'
1858      CALL wrf_debug ( 100 , TRIM(str) )
1859      CALL ESMF_GridCompRun(compGriddedWRF, importStateWRF, exportStateWRF, &
1860                            driverClock, rc=rc)
1861      IF ( rc /= ESMF_SUCCESS ) THEN
1862        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(WRF) failed' )
1863      ENDIF
1864      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for WRF (wrf_component_run)'
1865      CALL wrf_debug ( 100 , TRIM(str) )
1867      ! couple WRF export -> SST import
1868      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL WRF->SST (WRFSSTCpl_run)'
1869      CALL wrf_debug ( 100 , TRIM(str) )
1870      CALL ESMF_CplCompRun(compCplWRFSST, exportStateWRF, &
1871                           importStateSST, driverClock, rc=rc)
1872      IF ( rc /= ESMF_SUCCESS ) THEN
1873        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompRun(WRF -> SST) failed' )
1874      ENDIF
1875      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL WRF->SST (WRFSSTCpl_run)'
1876      CALL wrf_debug ( 100 , TRIM(str) )
1878      ! Run SST phase 2
1879      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 run for SST (sst_component_run2)'
1880      CALL wrf_debug ( 100 , TRIM(str) )
1881      CALL ESMF_GridCompRun(compGriddedSST, importStateSST, exportStateSST, &
1882                            driverClock, phase=2, rc=rc)
1883      IF ( rc /= ESMF_SUCCESS ) THEN
1884        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(SST phase 2) failed' )
1885      ENDIF
1886      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 run for SST (sst_component_run2)'
1887      CALL wrf_debug ( 100 , TRIM(str) )
1889      ! advance clock to next coupling time step
1890      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: advancing clock'
1891      CALL wrf_debug ( 100 , TRIM(str) )
1892      CALL ESMF_ClockAdvance( driverClock, rc=rc )
1893      IF ( rc /= ESMF_SUCCESS ) THEN
1894        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockAdvance failed' )
1895      ENDIF
1896      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done advancing clock'
1897      CALL wrf_debug ( 100 , TRIM(str) )
1899      CALL wrf_clockprint(50, driverClock, &
1900             'DEBUG wrf_SST_ESMF:  driverClock at end of time-stepping loop,')
1902    ENDDO
1904    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done with time-stepping loop'
1905    CALL wrf_debug ( 100 , TRIM(str) )
1907    ! clean up SST
1908    CALL ESMF_GridCompFinalize(compGriddedSST, importStateSST, exportStateSST, &
1909                               driverClock, rc=rc)
1910    IF ( rc /= ESMF_SUCCESS ) THEN
1911      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompFinalize(compGriddedSST) failed' )
1912    ENDIF
1914    ! clean up compCplWRFSST
1915    CALL ESMF_CplCompFinalize( compCplWRFSST, exportStateWRF, importStateSST, &
1916                               driverClock, rc=rc)
1917    IF ( rc /= ESMF_SUCCESS ) THEN
1918      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompFinalize(compCplWRFSST) failed' )
1919    ENDIF
1921    ! clean up WRF
1922    ! must do this AFTER clean up of SST since SST uses WRF IOAPI
1923    CALL ESMF_GridCompFinalize(compGriddedWRF, importStateWRF, exportStateWRF, &
1924                               driverClock, rc=rc)
1925    IF ( rc /= ESMF_SUCCESS ) THEN
1926      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompFinalize(compGriddedWRF) failed' )
1927    ENDIF
1929    ! Clean up
1931    CALL ESMF_GridCompDestroy(compGriddedWRF, rc)
1932    IF ( rc /= ESMF_SUCCESS ) THEN
1933      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompDestroy(compGriddedWRF) failed' )
1934    ENDIF
1935    CALL ESMF_StateDestroy(importStateWRF, rc)
1936    IF ( rc /= ESMF_SUCCESS ) THEN
1937      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(importStateWRF) failed' )
1938    ENDIF
1939    CALL ESMF_StateDestroy(exportStateWRF, rc)
1940    IF ( rc /= ESMF_SUCCESS ) THEN
1941      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(exportStateWRF) failed' )
1942    ENDIF
1943    CALL ESMF_StateDestroy(importStateSST, rc)
1944    IF ( rc /= ESMF_SUCCESS ) THEN
1945      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(importStateSST) failed' )
1946    ENDIF
1947    CALL ESMF_StateDestroy(exportStateSST, rc)
1948    IF ( rc /= ESMF_SUCCESS ) THEN
1949      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(exportStateSST) failed' )
1950    ENDIF
1951    CALL ESMF_ClockDestroy(driverClock, rc)
1952    IF ( rc /= ESMF_SUCCESS ) THEN
1953      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockDestroy(driverClock) failed' )
1954    ENDIF
1956    CALL ESMF_Finalize( rc=rc )
1957    IF ( rc /= ESMF_SUCCESS ) THEN
1958      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_Finalize failed' )
1959    ENDIF
1961 END PROGRAM wrf_SST_ESMF