merge standard release WRF/WPS V3.0.1.1 into wrffire
[wrffire.git] / wrfv2_fire / main / wrf_SST_ESMF.F
blob0d67548871da1ecf4f8f1eef59e56ab7ab62b9e8
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(0,*)__FILE__,__LINE__,'entered sst_component_init2 '
527      write(str,*) 'sst_component_init2: calling GetDecompFromState'
528      CALL wrf_debug ( 100 , TRIM(str) )
529      CALL GetDecompFromState( importState,                  &
530                               ids, ide, jds, jde, kds, kde, &
531                               ims, ime, jms, jme, kms, kme, &
532                               ips, ipe, jps, jpe, kps, kpe, &
533                               domdesc, bdy_mask )
534      write(str,*) 'sst_component_init2: back from GetDecompFromState'
535      CALL wrf_debug ( 100 , TRIM(str) )
536      write(str,*) 'sst_component_init2: ids, ide, jds, jde, kds, kde = ', ids, ide, jds, jde, kds, kde
537      CALL wrf_debug ( 100 , TRIM(str) )
538      write(str,*) 'sst_component_init2: ims, ime, jms, jme, kms, kme = ', ims, ime, jms, jme, kms, kme
539      CALL wrf_debug ( 100 , TRIM(str) )
540      write(str,*) 'sst_component_init2: ips, ipe, jps, jpe, kps, kpe = ', ips, ipe, jps, jpe, kps, kpe
541      CALL wrf_debug ( 100 , TRIM(str) )
543      ! allocate space for data read from disk
544      ALLOCATE( file_sst_data     (ims:ime,jms:jme) )
545      DO j= jms, jme
546        DO i= ims, ime
547          file_sst_data(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
548        ENDDO
549      ENDDO
550 !TODO:  Hmmm...  really need to load these pointers here?  Check...  
551      this_data(SST_INDX)%r2d => file_sst_data
552      ALLOCATE( file_landmask_data(ims:ime,jms:jme) )
553      DO j= jms, jme
554        DO i= ims, ime
555          file_landmask_data(i,j) = -(i*1000.0 + j)/100000.0     ! obvious bad value for debugging
556        ENDDO
557      ENDDO
558      this_data(LANDMASK_INDX)%r2d => file_landmask_data
560      ! Create ESMF_Fields in importState and exportState
561      ! Create ESMF_Grid.  Use exactly the same method as WRF so WRFIO will 
562      ! work.  
563      DomainStart(1) = ids; DomainEnd(1) = ide;
564      DomainStart(2) = jds; DomainEnd(2) = jde;
565      MemoryStart(1) = ims; MemoryEnd(1) = ime;
566      MemoryStart(2) = jms; MemoryEnd(2) = jme;
567      PatchStart(1)  = ips; PatchEnd(1)  = ipe;
568      PatchStart(2)  = jps; PatchEnd(2)  = jpe
569 write(0,*)__FILE__,__LINE__,'DomainStart ',DomainStart(1:2)
570 write(0,*)__FILE__,__LINE__,'DomainEnd ',DomainEnd(1:2)
571 write(0,*)__FILE__,__LINE__,'MemoryStart ',MemoryStart(1:2)
572 write(0,*)__FILE__,__LINE__,'MemoryEnd ',MemoryEnd(1:2)
573 write(0,*)__FILE__,__LINE__,'PatchStart ',PatchStart(1:2)
574 write(0,*)__FILE__,__LINE__,'PatchEnd ',PatchEnd(1:2)
575      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  Calling ioesmf_create_grid_int()' )
576      CALL ioesmf_create_grid_int( esmfgrid, NUMDIMS,      &
577                                   DomainStart, DomainEnd, &
578                                   MemoryStart, MemoryEnd, &
579                                   PatchStart, PatchEnd )
580 write(0,*)__FILE__,__LINE__
581      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  back from ioesmf_create_grid_int()' )
582      ! create ESMF_Fields
583      ! Note use of patch dimension for POINTERs allocated by ESMF.  
584      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  Calling ESMF_GridValidate(esmfgrid)' )
585      CALL ESMF_GridValidate( esmfgrid, rc=rc )
586 write(0,*)__FILE__,__LINE__
587      IF ( rc /= ESMF_SUCCESS ) THEN
588        WRITE( str,* ) 'Error in ESMF_GridValidate ',   &
589                       __FILE__ ,                       &
590                       ', line ',                       &
591                       __LINE__ ,                       &
592                       ', error code = ',rc
593        CALL wrf_error_fatal ( TRIM(str) )
594      ENDIF
595      CALL wrf_debug ( 5 , 'DEBUG sst_component_init2:  back OK from ESMF_GridValidate(esmfgrid)' )
596 !TODO:  Once new ESMF 3.0 interfaces have settled down, eliminate "tmp_data_" 
597 !TODO:  arrays and let ESMF allocate/deallocate them.  Assuming of course that 
598 !TODO:  we can convince ESMF to deallocate safely...  
599 write(0,*)__FILE__,__LINE__
600      ALLOCATE( tmp_data_out_sst(ips:ipe,jps:jpe) )
601 write(0,*)__FILE__,__LINE__
602      write(str,*) 'sst_component_init2: tmp_data_out_sst(', &
603        LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',',LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2),')'
604      CALL wrf_debug ( 100 , TRIM(str) )
605      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_sst_field)' )
606 write(0,*)__FILE__,__LINE__,trim(datanames(sst_indx))
607 write(0,*)__FILE__,__LINE__,ips,jps,ipe,jpe
608      out_sst_field = ESMF_FieldCreate(                 &
609                        esmfgrid, tmp_data_out_sst,     &
610                        copyflag=ESMF_DATA_REF,         &
611                        staggerloc=ESMF_STAGGERLOC_CENTER,          &
612                        name=TRIM(datanames(SST_INDX)), &
613                        rc=rc )
614 write(0,*)__FILE__,__LINE__,'Creating out_sst_field for exportState of SST component name ',TRIM(datanames(SST_INDX))
615      IF ( rc /= ESMF_SUCCESS ) THEN
616        WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) failed ', &
617                       __FILE__ ,                                 &
618                       ', line ',                                 &
619                       __LINE__ ,                                 &
620                       ', error code = ',rc
621        CALL wrf_error_fatal ( TRIM(str) )
622      ENDIF
623      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_sst_field)' )
624      write(str,*) 'sst_component_init2: ips:ipe,jps:jpe = ', &
625        ips,':',ipe,',',jps,':',jpe
626      CALL wrf_debug ( 100 , TRIM(str) )
627 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
628      ! validate ESMF allocation
629      IF ( ( ips /= LBOUND(tmp_data_out_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_sst,1) ) .OR. &
630           ( jps /= LBOUND(tmp_data_out_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_sst,2) ) ) THEN
631        WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) allocation failed ', &
632                       __FILE__ ,                                            &
633                       ', line ',                                            &
634                       __LINE__ ,                                            &
635                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
636                       ', tmp_data_out_sst(BOUNDS) = ',LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',', &
637                                               LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2)
638        CALL wrf_error_fatal ( TRIM(str) )
639      ENDIF
640      ALLOCATE( tmp_data_out_landmask(ips:ipe,jps:jpe) )
641      write(str,*) 'sst_component_init2: tmp_data_out_landmask(', &
642        LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',',LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2),')'
643      CALL wrf_debug ( 100 , TRIM(str) )
644      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_landmask_field)' )
645      out_landmask_field = ESMF_FieldCreate(                      &
646                             esmfgrid, tmp_data_out_landmask,     &
647                             copyflag=ESMF_DATA_REF,              &
648                             staggerloc=ESMF_STAGGERLOC_CENTER,          &
649                             name=TRIM(datanames(LANDMASK_INDX)), &
650 !                            lbounds=(/ips,jps/),                 &
651 !                            ubounds=(/ipe,jpe/),                 &
652                             rc=rc )
653      IF ( rc /= ESMF_SUCCESS ) THEN
654        CALL wrf_error_fatal ( 'ESMF_FieldCreate(out_landmask_field) failed' )
655      ENDIF
656      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_landmask_field)' )
657 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
658      ! validate ESMF allocation
659      IF ( ( ips /= LBOUND(tmp_data_out_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_landmask,1) ) .OR. &
660           ( jps /= LBOUND(tmp_data_out_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_landmask,2) ) ) THEN
661        WRITE( str,* ) 'ESMF_FieldCreate(out_landmask_field) allocation failed ', &
662                       __FILE__ ,                                            &
663                       ', line ',                                            &
664                       __LINE__ ,                                            &
665                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
666                       ', tmp_data_out_landmask(BOUNDS) = ',LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',', &
667                                               LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2)
668        CALL wrf_error_fatal ( TRIM(str) )
669      ENDIF
670      ALLOCATE( tmp_data_in_sst(ips:ipe,jps:jpe) )
671      write(str,*) 'sst_component_init2: tmp_data_in_sst(', &
672        LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',',LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2),')'
673      CALL wrf_debug ( 100 , TRIM(str) )
674      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_sst_field)' )
675      in_sst_field = ESMF_FieldCreate(                 &
676                       esmfgrid, tmp_data_in_sst,      &
677                       copyflag=ESMF_DATA_REF,         &
678                       staggerloc=ESMF_STAGGERLOC_CENTER,          &
679                       name=TRIM(datanames(SST_INDX)), &
680 !                      lbounds=(/ips,jps/),            &
681 !                      ubounds=(/ipe,jpe/),            &
682                       rc=rc )
683      IF ( rc /= ESMF_SUCCESS ) THEN
684        CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_sst_field) failed' )
685      ENDIF
686      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_sst_field)' )
687 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
688      ! validate ESMF allocation
689      IF ( ( ips /= LBOUND(tmp_data_in_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_sst,1) ) .OR. &
690           ( jps /= LBOUND(tmp_data_in_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_sst,2) ) ) THEN
691        WRITE( str,* ) 'ESMF_FieldCreate(in_sst_field) allocation failed ', &
692                       __FILE__ ,                                            &
693                       ', line ',                                            &
694                       __LINE__ ,                                            &
695                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
696                       ', tmp_data_in_sst(BOUNDS) = ',LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',', &
697                                               LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2)
698        CALL wrf_error_fatal ( TRIM(str) )
699      ENDIF
700      ALLOCATE( tmp_data_in_landmask(ips:ipe,jps:jpe) )
701      write(str,*) 'sst_component_init2: tmp_data_in_landmask(', &
702        LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',',LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2),')'
703      CALL wrf_debug ( 100 , TRIM(str) )
704      CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_landmask_field)' )
705      in_landmask_field = ESMF_FieldCreate(                      &
706                            esmfgrid, tmp_data_in_landmask,      &
707                            copyflag=ESMF_DATA_REF,              &
708                            staggerloc=ESMF_STAGGERLOC_CENTER,          &
709                            name=TRIM(datanames(LANDMASK_INDX)), &
710 !                           lbounds=(/ips,jps/),                 &
711 !                           ubounds=(/ipe,jpe/),                 &
712                            rc=rc )
713      IF ( rc /= ESMF_SUCCESS ) THEN
714        CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_landmask_field) failed' )
715      ENDIF
716      CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_landmask_field)' )
717 !TODO:  This bit will be useful once ESMF handles allocation/deallocation.  
718      ! validate ESMF allocation
719      IF ( ( ips /= LBOUND(tmp_data_in_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_landmask,1) ) .OR. &
720           ( jps /= LBOUND(tmp_data_in_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_landmask,2) ) ) THEN
721        WRITE( str,* ) 'ESMF_FieldCreate(in_landmask_field) allocation failed ', &
722                       __FILE__ ,                                            &
723                       ', line ',                                            &
724                       __LINE__ ,                                            &
725                       ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe,   &
726                       ', tmp_data_in_landmask(BOUNDS) = ',LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',', &
727                                               LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2)
728        CALL wrf_error_fatal ( TRIM(str) )
729      ENDIF
731      ! attach ESMF_Field to importState
732      CALL ESMF_StateAdd( importState, in_sst_field, rc=rc )
733      IF ( rc /= ESMF_SUCCESS ) THEN
734        CALL wrf_error_fatal ( 'ESMF_StateAdd(in_sst_field) failed' )
735      ENDIF
736      CALL ESMF_StateAdd( importState, in_landmask_field, rc=rc )
737      IF ( rc /= ESMF_SUCCESS ) THEN
738        CALL wrf_error_fatal ( 'ESMF_StateAdd(in_landmask_field) failed' )
739      ENDIF
740      ! attach ESMF_Field to exportState
741      CALL ESMF_StateAdd( exportState, out_sst_field, rc=rc )
742      IF ( rc /= ESMF_SUCCESS ) THEN
743        CALL wrf_error_fatal ( 'ESMF_StateAdd(out_sst_field) failed' )
744      ENDIF
745      CALL ESMF_StateAdd( exportState, out_landmask_field, rc=rc )
746      IF ( rc /= ESMF_SUCCESS ) THEN
747        CALL wrf_error_fatal ( 'ESMF_StateAdd(out_landmask_field) failed' )
748      ENDIF
750      !  Open the "SST" input data file for reading.
751      write(str,'(A,A)') 'sst_component_init2: Opening data file ', &
752        TRIM(sstinfilename)
753      CALL wrf_message ( TRIM(str) )
754      CALL wrf_open_for_read ( TRIM(sstinfilename) , &
755                               mpicom ,              &
756                               mpicom ,              &
757                               "DATASET=INPUT" ,     &
758                               fid ,                 &
759                               ierr )
760      IF ( ierr .NE. 0 ) THEN
761        WRITE( str , FMT='(A,A,A,I8)' )  &
762          'sst_component_init2: error opening ', &
763          TRIM(sstinfilename),' for reading ierr=',ierr
764        CALL wrf_error_fatal ( TRIM(str) )
765      ENDIF
766      WRITE( str , FMT='(A,A,A,I8)' ) &
767        'subroutine sst_component_init2: opened file ', &
768        TRIM(sstinfilename),' for reading fid=',fid
769      CALL wrf_debug ( 100, TRIM(str) )
771      write(str,'(A)') 'sst_component_init2: returning rc=ESMF_SUCCESS'
772      CALL wrf_debug ( 100 , TRIM(str) )
774      rc = ESMF_SUCCESS
776    END SUBROUTINE sst_component_init2
780    SUBROUTINE sst_component_run1( gcomp, importState, exportState, clock, rc )
781      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
782      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
783      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
784      INTEGER,                     INTENT(  OUT) :: rc
785 !<DESCRIPTION>
786 !     SST component run routine, phase 1.
787 !     Read "SST" data from file and stuff into exportState.  
789 !     The arguments are:
790 !       gcomp           Component
791 !       importState     Importstate
792 !       exportState     Exportstate
793 !       clock           External clock
794 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
795 !                       otherwise ESMF_FAILURE.
796 !</DESCRIPTION>
798      rc = ESMF_SUCCESS
800      ! Get "SST" data from file and stuff it into exportState.  
801      CALL read_data( exportState, clock )
803    END SUBROUTINE sst_component_run1
807    SUBROUTINE sst_component_run2( gcomp, importState, exportState, clock, rc )
808      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
809      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
810      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
811      INTEGER,                     INTENT(  OUT) :: rc
812 !<DESCRIPTION>
813 !     SST component run routine, phase 2.
814 !     Get from importState, compare with file data, and error-exit 
815 !     if they differ...  If they are the same, then 
816 !     stuff the file data into the exportState.  
818 !     The arguments are:
819 !       gcomp           Component
820 !       importState     Importstate
821 !       exportState     Exportstate
822 !       clock           External clock
823 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
824 !                       otherwise ESMF_FAILURE.
825 !</DESCRIPTION>
827      rc = ESMF_SUCCESS
829      ! Get from importState, compare with file data, and error_exit 
830      ! if they differ...  
831 !TODO:  change this once WRF can load exportState after integrating
832      ! This works because WRF loads its exportState BEFORE integrating.  
833      CALL wrf_clockprint ( 50, clock, 'sst_component_run2:  clock before call to compare_data()' )
834      CALL compare_data( importState, clock )
835      CALL wrf_clockprint ( 50, clock, 'sst_component_run2:  clock after call to compare_data()' )
837    END SUBROUTINE sst_component_run2
841    SUBROUTINE sst_component_finalize( gcomp, importState, exportState, clock, rc )
842      USE module_io
843      TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
844      TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState, exportState
845      TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
846      INTEGER,                     INTENT(  OUT) :: rc
847 !<DESCRIPTION>
848 !     SST component finalize routine.
850 !     The arguments are:
851 !       gcomp           Component
852 !       importState     Importstate
853 !       exportState     Exportstate
854 !       clock           External clock
855 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
856 !                       otherwise ESMF_FAILURE.
857 !</DESCRIPTION>
859      ! Local variables
860      TYPE(ESMF_Field) :: tmp_field
861      INTEGER :: i, ierr
863      rc = ESMF_SUCCESS
865      ! destroy ESMF_Fields and other "deep" objects created by this component
866      ! note that this component relied on ESMF to allocate data pointers during 
867      ! calls to ESMF_FieldCreate() so it also expects ESMF to free these pointers 
868      DO i=1, datacount
869        ! destroy field in importState
870        CALL ESMF_StateGet( importState, TRIM(datanames(i)), tmp_field, &
871                                 rc=rc )
872        IF (rc /= ESMF_SUCCESS) THEN
873          WRITE( str , * )                                               &
874            'sst_component_finalize:  ESMF_StateGet( importState,', &
875            TRIM(datanames(i)),') failed'
876          CALL wrf_error_fatal ( TRIM(str) )
877        ENDIF
878        CALL ESMF_FieldDestroy( tmp_field, rc=rc )
879        IF (rc /= ESMF_SUCCESS) THEN
880          WRITE( str , * )                                              &
881            'sst_component_finalize:  ESMF_FieldDestroy( importState,', &
882            TRIM(datanames(i)),') failed'
883          CALL wrf_error_fatal ( TRIM(str) )
884        ENDIF
885        ! destroy field in exportState
886        CALL ESMF_StateGet( exportState, TRIM(datanames(i)), tmp_field, &
887                                 rc=rc )
888        IF (rc /= ESMF_SUCCESS) THEN
889          WRITE( str , * )                                               &
890            'sst_component_finalize:  ESMF_StateGet( exportState,', &
891            TRIM(datanames(i)),') failed'
892          CALL wrf_error_fatal ( TRIM(str) )
893        ENDIF
894        CALL ESMF_FieldDestroy( tmp_field, rc=rc )
895        IF (rc /= ESMF_SUCCESS) THEN
896          WRITE( str , * )                                              &
897            'sst_component_finalize:  ESMF_FieldDestroy( exportState,', &
898            TRIM(datanames(i)),') failed'
899          CALL wrf_error_fatal ( TRIM(str) )
900        ENDIF
901      ENDDO
903      ! deallocate space for data read from disk
904      DEALLOCATE( file_sst_data, file_landmask_data )
906      ! close SST data file
907      WRITE( str , FMT='(A,I8)' ) &
908        'subroutine sst_component_finalize: closing file fid=',fid
909      CALL wrf_debug ( 100, TRIM(str) )
910      CALL wrf_ioclose( fid , ierr )
911      IF ( ierr .NE. 0 ) THEN
912        CALL wrf_error_fatal ( 'sst_component_finalize:  wrf_ioclose failed' )
913      ENDIF
915    END SUBROUTINE sst_component_finalize
918 END MODULE module_sst_component_top
923 MODULE module_sst_setservices
924 !<DESCRIPTION>
925 ! This module defines SST "Set Services" method sst_register() 
926 ! used for ESMF coupling.  
927 !</DESCRIPTION>
929    USE module_sst_component_top, ONLY: sst_component_init1,  &
930                                        sst_component_init2,  &
931                                        sst_component_run1,   &
932                                        sst_component_run2,   &
933                                        sst_component_finalize
934    USE ESMF_Mod
936    IMPLICIT NONE
938    ! everything is private by default
939    PRIVATE
941    ! Public entry point for ESMF_GridCompSetServices()
942    PUBLIC SST_register
944    ! private stuff
945    CHARACTER (ESMF_MAXSTR) :: str
947 CONTAINS
950    SUBROUTINE sst_register(gcomp, rc)
951      TYPE(ESMF_GridComp), INTENT(INOUT) :: gcomp
952      INTEGER, INTENT(OUT) :: rc
953      INTEGER :: finalrc
955 !<DESCRIPTION>
956 !     SST_register - Externally visible registration routine
958 !     User-supplied SetServices routine.
959 !     The Register routine sets the subroutines to be called
960 !     as the init, run, and finalize routines.  Note that these are
961 !     private to the module.
963 !     The arguments are:
964 !       gcomp           Component
965 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
966 !                       otherwise ESMF_FAILURE.
967 !</DESCRIPTION>
969      finalrc = ESMF_SUCCESS
970      ! Register the callback routines.
971      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
972                                      sst_component_init1, 1, rc)
973      IF ( rc /= ESMF_SUCCESS) THEN
974         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init1) failed with rc = ', rc
975         CALL wrf_error_fatal ( TRIM(str) )
976      ENDIF
977      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
978                                      sst_component_init2, 2, rc)
979      IF ( rc /= ESMF_SUCCESS) THEN
980         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init2) failed with rc = ', rc
981         CALL wrf_error_fatal ( TRIM(str) )
982      ENDIF
983      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETRUN, &
984                                      sst_component_run1, 1, rc)
985      IF ( rc /= ESMF_SUCCESS) THEN
986         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run1) failed with rc = ', rc
987         CALL wrf_error_fatal ( TRIM(str) )
988      ENDIF
989      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETRUN, &
990                                      sst_component_run2, 2, rc)
991      IF ( rc /= ESMF_SUCCESS) THEN
992         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run2) failed with rc = ', rc
993         CALL wrf_error_fatal ( TRIM(str) )
994      ENDIF
995      call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETFINAL, &
996                                      sst_component_finalize, ESMF_SINGLEPHASE, rc)
997      IF ( rc /= ESMF_SUCCESS) THEN
998         WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_finalize) failed with rc = ', rc
999         CALL wrf_error_fatal ( TRIM(str) )
1000      ENDIF
1002      PRINT *,'SST:  Registered Initialize, Run, and Finalize routines'
1004      rc = finalrc
1006    END SUBROUTINE sst_register
1008 END MODULE module_sst_setservices
1012 !<DESCRIPTION>
1013 ! Module module_wrfsst_coupler defines the 
1014 ! "WRF-SST" coupler component.  It provides two-way coupling between 
1015 ! the "SST" and "WRF" components.  
1016 ! In its run routine it transfers data directly from the 
1017 ! SST Component's export state to the WRF Component's import state.  
1018 ! It also transfers data directly from the 
1019 ! WRF Component's export state to the SST Component's import state.  
1021 ! This is derived from src/demo/coupled_flow/src/CouplerMod.F90
1022 ! created by Nancy Collins and others on the ESMF Core Team.  
1024 !</DESCRIPTION>
1026 MODULE module_wrfsst_coupler
1028     USE ESMF_Mod
1030     IMPLICIT NONE
1031     
1032     ! everything is private by default
1033     PRIVATE
1035     ! Public entry point 
1036     PUBLIC WRFSSTCpl_register
1038     ! private data members
1039     ! route handles and flags
1040     TYPE(ESMF_RouteHandle), SAVE :: fromWRF_rh, fromSST_rh
1041     LOGICAL, SAVE :: fromWRF_rh_ready = .FALSE.
1042     LOGICAL, SAVE :: fromSST_rh_ready = .FALSE.
1043     ! field names
1044     INTEGER, PARAMETER :: datacount = 2
1045     INTEGER, PARAMETER :: SST_INDX = 1
1046     INTEGER, PARAMETER :: LANDMASK_INDX = 2
1047     CHARACTER(LEN=ESMF_MAXSTR), SAVE :: datanames(datacount)
1048     CHARACTER(LEN=ESMF_MAXSTR) :: str
1051 CONTAINS
1054    SUBROUTINE WRFSSTCpl_register(comp, rc)
1055      TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1056      INTEGER, INTENT(OUT) :: rc
1058 !<DESCRIPTION>
1059 !     WRFSSTCpl_register - Externally visible registration routine
1061 !     User-supplied SetServices routine.
1062 !     The Register routine sets the subroutines to be called
1063 !     as the init, run, and finalize routines.  Note that these are
1064 !     private to the module.
1066 !     The arguments are:
1067 !       comp            Component
1068 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1069 !                       otherwise ESMF_FAILURE.
1070 !</DESCRIPTION>
1072       ! guilty until proven innocent
1073       rc = ESMF_FAILURE
1075       ! Register the callback routines.
1077       call ESMF_CplCompSetEntryPoint(comp, ESMF_SETINIT, WRFSSTCpl_init, &
1078                                      ESMF_SINGLEPHASE, rc)
1079       IF ( rc /= ESMF_SUCCESS ) THEN
1080         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_init) failed' )
1081       ENDIF
1082       call ESMF_CplCompSetEntryPoint(comp, ESMF_SETRUN, WRFSSTCpl_run, &
1083                                      ESMF_SINGLEPHASE, rc)
1084       IF ( rc /= ESMF_SUCCESS ) THEN
1085         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_run) failed' )
1086       ENDIF
1087       call ESMF_CplCompSetEntryPoint(comp, ESMF_SETFINAL, WRFSSTCpl_final, &
1088                                      ESMF_SINGLEPHASE, rc)
1089       IF ( rc /= ESMF_SUCCESS ) THEN
1090         CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_final) failed' )
1091       ENDIF
1093       print *, "module_wrfsst_coupler: Registered Initialize, Run, and Finalize routines"
1095     END SUBROUTINE WRFSSTCpl_register
1098     SUBROUTINE WRFSSTCpl_init(comp, importState, exportState, clock, rc)
1099       USE module_metadatautils, ONLY: AttachDecompToState, GetDecompFromState
1100       TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1101       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1102       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1103       INTEGER, INTENT(OUT) :: rc
1104 !<DESCRIPTION>
1105 !     WRF-SST coupler component init routine.  This simply passes needed 
1106 !     metadata from WRF to SST.  Initialization of ESMF_RouteHandle objects 
1107 !     is handled later via lazy evaluation.  
1109 !     The arguments are:
1110 !       comp            Component
1111 !       importState     Importstate
1112 !       exportState     Exportstate
1113 !       clock           External clock
1114 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1115 !                       otherwise ESMF_FAILURE.
1116 !</DESCRIPTION>
1118       ! Local variables
1119       CHARACTER(ESMF_MAXSTR) :: importstatename
1120       ! decomposition information
1121       INTEGER :: ids, ide, jds, jde, kds, kde
1122       INTEGER :: ims, ime, jms, jme, kms, kme
1123       INTEGER :: ips, ipe, jps, jpe, kps, kpe
1124       INTEGER :: domdesc
1125       LOGICAL :: bdy_mask(4)
1127       PRINT *, "DEBUG:  Coupler Init starting"
1129       ! guilty until proven innocent
1130       rc = ESMF_FAILURE
1132       CALL ESMF_StateGet(importState, name=importstatename, rc=rc)
1133       IF ( rc /= ESMF_SUCCESS ) THEN
1134         CALL wrf_error_fatal ( 'WRFSSTCpl_init:  ESMF_StateGet failed' )
1135       ENDIF
1137       IF ( TRIM(importstatename) .EQ. "WRF Export State" ) THEN
1138         ! get metadata from WRF export state
1139         CALL GetDecompFromState( importState,                  &
1140                                  ids, ide, jds, jde, kds, kde, &
1141                                  ims, ime, jms, jme, kms, kme, &
1142                                  ips, ipe, jps, jpe, kps, kpe, &
1143                                  domdesc, bdy_mask )
1144         ! put metadata from in SST import state
1145         CALL AttachDecompToState( exportState,                  &
1146                                   ids, ide, jds, jde, kds, kde, &
1147                                   ims, ime, jms, jme, kms, kme, &
1148                                   ips, ipe, jps, jpe, kps, kpe, &
1149                                   domdesc, bdy_mask )
1152       ELSE
1153         CALL wrf_error_fatal ( 'WRFSSTCpl_init:  invalid importState name' )
1154       ENDIF
1156       ! set up field names
1157 !TODO:  use CF conventions for "standard_name" once WRF Registry supports them
1158 !TODO:      datanames(SST_INDX) = "sea_surface_temperature"
1159 !TODO:      datanames(LANDMASK_INDX) = "land_binary_mask"
1160       datanames(SST_INDX) = "SST"
1161       datanames(LANDMASK_INDX) = "LANDMASK"
1163       PRINT *, "DEBUG:  Coupler Init returning"
1164    
1165     END SUBROUTINE WRFSSTCpl_init
1169     SUBROUTINE WRFSSTCpl_run(comp, importState, exportState, clock, rc)
1170       TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1171       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1172       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1173       INTEGER, INTENT(OUT) :: rc
1174 !<DESCRIPTION>
1175 !     WRF-SST coupler component run routine.
1177 !     The arguments are:
1178 !       comp            Component
1179 !       importState     Importstate
1180 !       exportState     Exportstate
1181 !       clock           External clock
1182 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1183 !                       otherwise ESMF_FAILURE.
1184 !</DESCRIPTION>
1186 ! Note that comments in this code are preserved from the sample coupler 
1187 ! provided by the ESMF core team.  
1189       ! Local variables
1190 character*256 :: mename
1191 character*256 :: melist(100)
1192 integer :: mecount
1193 TYPE(ESMF_StateItemType) :: metypelist(100)
1194       TYPE(ESMF_Field) :: src_field, dst_field
1195       TYPE(ESMF_Array) :: src_array, dst_array
1196       TYPE(ESMF_RouteHandle) :: routehandle
1197       TYPE(ESMF_VM) :: vm
1198       LOGICAL :: build_fromWRF_rh, build_fromSST_rh, fromWRF
1199       CHARACTER(LEN=ESMF_MAXSTR) :: importStatename
1200       CHARACTER(LEN=ESMF_MAXSTR) :: SST_exportStatename, WRF_exportStatename
1201       INTEGER :: i
1202       CHARACTER(LEN=256) :: directionString
1204       WRITE(str,*) 'WRFSSTCpl_run: begin'
1205       CALL wrf_debug ( 100 , TRIM(str) )
1207       ! guilty until proven innocent
1208       rc = ESMF_FAILURE
1210       ! Which way is this coupling going?  
1211       WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateGet(importState,name,...)'
1212       CALL wrf_debug ( 100 , TRIM(str) )
1213       CALL ESMF_StateGet( importState, name=importStatename, rc=rc )
1214 write(0,*)__FILE__,__LINE__, 'importStatename ', trim(importStatename), 'rc = ', rc
1215       IF ( rc /= ESMF_SUCCESS ) THEN
1216         CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(importState,name,...) failed' )
1217       ENDIF
1218       WRITE(str,*) 'WRFSSTCpl_run: back from ESMF_StateGet, importStatename = <',TRIM(importStatename),'>'
1219       CALL wrf_debug ( 100 , TRIM(str) )
1221       ! first time through in each direction:  create route handle and 
1222       ! associated objects
1223       WRF_exportStatename = "WRF Export State"
1224       SST_exportStatename = "SST Export State"
1225       IF ( TRIM(importStatename) .EQ. TRIM(WRF_exportStatename) ) THEN
1226         fromWRF = .TRUE.
1227         directionString = 'WRFtoSST'
1228       ELSE IF ( TRIM(importStatename) .EQ. TRIM(SST_exportStatename) ) THEN
1229         fromWRF = .FALSE.
1230         directionString = 'SSTtoWRF'
1231       ELSE
1232         CALL wrf_error_fatal ( 'WRFSSTCpl_run:  invalid importState name' )
1233       ENDIF
1234       WRITE(str,*) 'WRFSSTCpl_run: fromWRF = ',fromWRF
1235       CALL wrf_debug ( 100 , TRIM(str) )
1236       build_fromWRF_rh =         fromWRF   .AND. ( .NOT. fromWRF_rh_ready )
1237       build_fromSST_rh = ( .NOT. fromWRF ) .AND. ( .NOT. fromSST_rh_ready )
1238       WRITE(str,*) 'WRFSSTCpl_run: build_fromWRF_rh = ',build_fromWRF_rh
1239       CALL wrf_debug ( 100 , TRIM(str) )
1240       WRITE(str,*) 'WRFSSTCpl_run: build_fromSST_rh = ',build_fromSST_rh
1241       CALL wrf_debug ( 100 , TRIM(str) )
1242       IF ( build_fromWRF_rh .OR. build_fromSST_rh ) THEN
1243         CALL ESMF_CplCompGet( comp, vm=vm, rc=rc )
1244         IF ( rc /= ESMF_SUCCESS ) THEN
1245           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_CplCompGet failed' )
1246         ENDIF
1247         ! The use of literal index "1" here indicates that we don't care which 
1248         ! ESMF_Field we get so we might as well get the first one.  
1249         WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1250                      '> from import state'
1251         CALL wrf_debug ( 100 , TRIM(str) )
1253 CALL ESMF_StateGet( importState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1254 write(0,*)'importState mename ',trim(mename)
1255 write(0,*)'importState mecount ',mecount
1256 do i = 1,mecount
1257 write(0,*)i,trim(melist(i))
1258 enddo
1259 do i = 1,mecount
1260 write(0,*)i,metypelist(i)
1261 enddo
1263         CALL ESMF_StateGet( importState, TRIM(datanames(1)), src_field, &
1264                                  rc=rc )
1265 write(0,*)__FILE__,__LINE__, 'from importState: datanames(1) ', TRIM(datanames(1)), ' rc = ', rc
1266         IF ( rc /= ESMF_SUCCESS ) THEN
1267           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(importState) failed' )
1268         ENDIF
1270         CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1271 write(0,*)__FILE__,__LINE__, 'from fieldget:  rc = ', rc
1272         IF ( rc /= ESMF_SUCCESS ) THEN
1273           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldGet src_array failed' )
1274         ENDIF
1275         WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1276                      '> from export state'
1277         CALL wrf_debug ( 100 , TRIM(str) )
1279 CALL ESMF_StateGet( exportState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1280 write(0,*)'Exportstate mename ',trim(mename)
1281 write(0,*)'Exportstate mecount ',mecount
1282 do i = 1,mecount
1283 write(0,*)i,trim(melist(i))
1284 enddo
1285 do i = 1,mecount
1286 write(0,*)i,metypelist(i)
1287 enddo
1289         CALL ESMF_StateGet( exportState, TRIM(datanames(1)), dst_field, &
1290                                  rc=rc )
1291         IF ( rc /= ESMF_SUCCESS ) THEN
1292           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_StateGet(exportState) failed' )
1293         ENDIF
1294         CALL ESMF_FieldGet( dst_field, array=dst_array, &
1295                                  rc=rc )
1296         IF ( rc /= ESMF_SUCCESS ) THEN
1297           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldGet dst_array failed' )
1298         ENDIF
1302         IF ( build_fromWRF_rh ) THEN
1303           WRITE(str,*) 'WRFSSTCpl_run: creating fromWRF_rh'
1304           CALL wrf_debug ( 100 , TRIM(str) )
1305           fromWRF_rh = ESMF_RouteHandleCreate( rc )
1306           IF ( rc /= ESMF_SUCCESS ) THEN
1307             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_RouteHandleCreate(fromWRF_rh) failed' )
1308           ENDIF
1309           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromWRF_rh)'
1310           CALL wrf_debug ( 100 , TRIM(str) )
1311           CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1312                                       routehandle=fromWRF_rh, rc=rc )
1313           IF ( rc /= ESMF_SUCCESS ) THEN
1314             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedistStore(fromWRF_rh) failed' )
1315           ENDIF
1316           fromWRF_rh_ready = .TRUE.
1317         ENDIF
1318         IF ( build_fromSST_rh ) THEN
1319           WRITE(str,*) 'WRFSSTCpl_run: creating fromSST_rh'
1320           CALL wrf_debug ( 100 , TRIM(str) )
1321           fromSST_rh = ESMF_RouteHandleCreate( rc )
1322           IF ( rc /= ESMF_SUCCESS ) THEN
1323             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_RouteHandleCreate(fromSST_rh) failed' )
1324           ENDIF
1325           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromSST_rh)'
1326           CALL wrf_debug ( 100 , TRIM(str) )
1327           CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1328                                       routehandle=fromSST_rh, rc=rc )
1329 write(0,*)__FILE__,__LINE__,'rc = ',rc
1330           IF ( rc /= ESMF_SUCCESS ) THEN
1331             CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedistStore(fromSST_rh) failed' )
1332           ENDIF
1333           fromSST_rh_ready = .TRUE.
1334         ENDIF
1335         DO i=1, datacount
1336           WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateSetNeeded(importState, ',TRIM(datanames(i)),')'
1337           CALL wrf_debug ( 100 , TRIM(str) )
1338           CALL ESMF_StateSetNeeded( importState, TRIM(datanames(i)), &
1339                                     ESMF_NEEDED, rc=rc )
1340           IF ( rc /= ESMF_SUCCESS ) THEN
1341             WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateSetNeeded(',TRIM(datanames(i)),') failed'
1342             CALL wrf_error_fatal ( str )
1343           ENDIF
1344         ENDDO
1345       ENDIF
1347       ! In this case, the coupling is symmetric - you call redist going
1348       ! both ways - so we only care about the coupling direction in order 
1349       ! to get the right routehandle selected.
1350       IF ( fromWRF ) THEN
1351         WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromWRF_rh'
1352         CALL wrf_debug ( 100 , TRIM(str) )
1353         routehandle = fromWRF_rh 
1354       ELSE
1355         WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromSST_rh'
1356         CALL wrf_debug ( 100 , TRIM(str) )
1357         routehandle = fromSST_rh 
1358       ENDIF
1360       DO i=1, datacount
1361         WRITE(str,*) 'WRFSSTCpl_run: grabbing field <',TRIM(datanames(i)),'>'
1362         CALL wrf_debug ( 100 , TRIM(str) )
1363         ! check isneeded flag here
1364         IF ( .NOT. ESMF_StateIsNeeded( importState, TRIM(datanames(i)), rc=rc ) ) THEN 
1365           IF ( rc /= ESMF_SUCCESS ) THEN
1366             WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateIsNeeded(',TRIM(datanames(i)),') failed'
1367             CALL wrf_error_fatal ( str )
1368           ENDIF
1369           WRITE(str,*) 'WRFSSTCpl_run: skipping field <',TRIM(datanames(i)),'>'
1370           CALL wrf_debug ( 100 , TRIM(str) )
1371           CYCLE
1372         ENDIF
1374         WRITE(str,*) 'WRFSSTCpl_run: processing field <',TRIM(datanames(i)),'>'
1375         CALL wrf_debug ( 100 , TRIM(str) )
1377 !   The following piece of code provides an example of calling the data
1378 !   redistribution routine  between two Fields in the Coupler Component.  
1379 !   Unlike regrid, which translates between
1380 !   different Grids, redist translates between different DELayouts on
1381 !   the same Grid.   The first two lines get the Fields from the 
1382 !   States, each corresponding to a different subcomponent.  One is
1383 !   an Export State and the other is an Import State.
1385         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_StateGet(importState,', &
1386                      TRIM(datanames(i)),')...'
1387         CALL wrf_debug ( 100 , TRIM(str) )
1388         CALL ESMF_StateGet( importState, TRIM(datanames(i)), src_field, &
1389                                  rc=rc )
1390         IF ( rc /= ESMF_SUCCESS ) THEN
1391           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateGet(importState,', &
1392                        TRIM(datanames(i)),') failed'
1393           CALL wrf_error_fatal ( str )
1394         ENDIF
1395         CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1396         IF ( rc /= ESMF_SUCCESS ) THEN
1397           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_FieldGet(src_field,src_array,rc) failed'
1398           CALL wrf_error_fatal ( str )
1399         ENDIF
1401         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_StateGet(exportState,', &
1402                      TRIM(datanames(i)),')...'
1403         CALL wrf_debug ( 100 , TRIM(str) )
1404         CALL ESMF_StateGet( exportState, TRIM(datanames(i)), dst_field, &
1405                                  rc=rc )
1406         IF ( rc /= ESMF_SUCCESS ) THEN
1407           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_StateGet(exportState,', &
1408                        TRIM(datanames(i)),') failed'
1409           CALL wrf_error_fatal ( str )
1410         ENDIF
1411         CALL ESMF_FieldGet( dst_field, array=dst_array, rc=rc )
1412         IF ( rc /= ESMF_SUCCESS ) THEN
1413           WRITE(str,*) 'WRFSSTCpl_run:  ESMF_FieldGet(dst_field,dst_array,rc) failed'
1414           CALL wrf_error_fatal ( str )
1415         ENDIF
1417 !   The redist routine uses information contained in the Fields and the
1418 !   Coupler VM object to call the communication routines to move the data.
1419 !   Because many Fields may share the same Grid association, the same
1420 !   routing information may be needed repeatedly.  Route information is 
1421 !   saved so the precomputed information can be retained.  The following 
1422 !   is an example of a Field redist call:
1423         WRITE(str,*) 'WRFSSTCpl_run:  calling ESMF_FieldRedist for <', &
1424                      TRIM(datanames(i)),'>...'
1425         CALL wrf_debug ( 100 , TRIM(str) )
1426         CALL ESMF_ArrayRedist( src_array, dst_array, routehandle, rc=rc )
1427         IF ( rc /= ESMF_SUCCESS ) THEN
1428           CALL wrf_error_fatal ( 'WRFSSTCpl_run:  ESMF_FieldRedist failed' )
1429         ENDIF
1430         WRITE(str,*) 'WRFSSTCpl_run:  back from ESMF_FieldRedist for <', &
1431                      TRIM(datanames(i)),'>...'
1432         CALL wrf_debug ( 100 , TRIM(str) )
1434       ENDDO
1436       WRITE(str,*) 'WRFSSTCpl_run: end'
1437       CALL wrf_debug ( 100 , TRIM(str) )
1439     END SUBROUTINE WRFSSTCpl_run
1443     SUBROUTINE WRFSSTCpl_final(comp, importState, exportState, clock, rc)
1444       TYPE(ESMF_CplComp) :: comp
1445       TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1446       TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1447       INTEGER, INTENT(OUT) :: rc
1448 !<DESCRIPTION>
1449 !     WRF-SST coupler component finalize routine.
1451 !     The arguments are:
1452 !       comp            Component
1453 !       importState     Importstate
1454 !       exportState     Exportstate
1455 !       clock           External clock
1456 !       rc              Return code; equals ESMF_SUCCESS if there are no errors,
1457 !                       otherwise ESMF_FAILURE.
1458 !</DESCRIPTION>
1460       PRINT *, "DEBUG:  Coupler Final starting"
1461    
1462       ! guilty until proven innocent
1463       rc = ESMF_FAILURE
1465       ! Only thing to do here is release redist and route handles
1466       IF ( fromWRF_rh_ready ) THEN
1467         CALL ESMF_RouteHandleDestroy(fromWRF_rh, rc)
1468         IF ( rc /= ESMF_SUCCESS ) THEN
1469           CALL wrf_error_fatal ( 'WRFSSTCpl_final:  ESMF_RouteHandleDestroy(fromWRF_rh) failed' )
1470         ENDIF
1471       ENDIF
1472       IF ( fromSST_rh_ready ) THEN
1473         CALL ESMF_RouteHandleDestroy(fromSST_rh, rc)
1474         IF ( rc /= ESMF_SUCCESS ) THEN
1475           CALL wrf_error_fatal ( 'WRFSSTCpl_final:  ESMF_RouteHandleDestroy(fromSST_rh) failed' )
1476         ENDIF
1477       ENDIF
1479       PRINT *, "DEBUG:  Coupler Final returning"
1480    
1481     END SUBROUTINE WRFSSTCpl_final
1484 END MODULE module_wrfsst_coupler
1485     
1486     
1489 PROGRAM wrf_SST_ESMF
1491 !<DESCRIPTION>
1492 ! ESMF Application Wrapper for coupling WRF with a "dummy" component 
1493 ! that simply reads SSTs from a file and sends them to WRF (one-way 
1494 ! coupling).  Fields are returned from WRF to SST via the coupler for 
1495 ! self-test only.  
1497 ! Note that, like other WRF coupling methods (MCEL, MCT), ESMF coupling is 
1498 ! supported only via auxiliary input and history streams.  
1500 ! This is the main program that creates the ESMF Gridded and Coupler 
1501 ! Component.  
1503 ! "init" looks like this:  
1504 !   1. Init phase 1 for WRF, sets WRF exportState metadata for "time" 
1505 !      and "domain" information needed by WRF IOAPI (which is called from 
1506 !      the SST component).  It also sets up all WRF and WSF modules.  Note 
1507 !      that this must be called before SST phase-1 init because SST uses 
1508 !      WRF IOAPI.  
1509 !   2. Init phase 1 for SST, sets "time" metadata in SST exportState.  
1510 !   3. Initialize coupler, passing decomposition metadata from WRF exportState 
1511 !      to SST importState.  
1512 !   4. Resolve any "time" metadata inconsistencies and create top-level clock.  
1513 !   5. Init phase 2 for SST, gets "domain" information from importState, 
1514 !      creates an ESMF_Grid based on "domain" information using the exact same 
1515 !      method as WRF (so WRF IOAPI calls will work), and sets up SST 
1516 !      importState and exportState.  
1517 !   6. Init phase 2 for WRF, runs up to the end of the head_grid I/O "training" 
1518 !      phase (done in med_before_solve_io()).  This initializes WRF 
1519 !      importState and exportState prior to the first coupling step during the 
1520 !      "run" loop.  Note that this only works for head_grid at present because 
1521 !      recursion in WRF traversal of subdomains is not dealt with yet and 
1522 !      because the code that populates the WRF importState and exportState is 
1523 !      not yet sophisticated enough to handle creating and destroying nested 
1524 !      domains at any time during the model run.  
1525 !TODO:  ESMF auxio must begin at the start of the run.  Remove this 
1526 !TODO:  restriction later, if needed.  
1528 !TODO:  Note that coupling is currently limited to one auxin plus one auxout 
1529 !TODO:  streams.  Extension to multiple pairs of auxio streams requires 
1530 !TODO:  nested states (one for each auxio stream pair).  
1531 !TODO:  For now, only support one input and/or one output stream via 
1532 !TODO:  io_esmf.  This condition is asserted in 
1533 !TODO:  ext_esmf_open_for_read_begin() and 
1534 !TODO:  ext_esmf_open_for_write_begin().  
1536 ! "run" loop looks like this:  
1537 !   1. Run SST phase 1, reads SST from file and writes it to SST exportState 
1538 !      for coupling to WRF.  
1539 !   2. Couple SST exportState -> WRF importState.  First iteration:  set up 
1540 !      SST->WRF routeHandle via lazy evaluation.  
1541 !   3. Run WRF.  First iteration:  head_grid resumes after I/O "training" 
1542 !      phase.  Other iterations and domains:  run normally.  
1543 !      Read WRF importState and write WRF exportState (via med_before_solve_io()).  
1544 !      Note that WRF assigns sst -> tsk for sea points in 
1545 !      share/module_soil_pre.F.  
1546 !   4. Couple WRF exportState -> SST importState.  First iteration:  set up
1547 !      WRF->SST routeHandle via lazy evaluation.
1548 !   5. Run SST phase 2, compare SST from file with SST from WRF (via 
1549 !      SST importState) and error-exit if they differ.  
1550 !   6. Advance clock and goto step 1
1552 ! "finalize" is trivial, except for destruction of ESMF objects which is 
1553 ! quite non-trivial at the moment.  
1555 !</DESCRIPTION>
1557    ! WRF registration routine
1558    USE module_wrf_setservices, ONLY: WRF_register
1559    ! SST registration routine
1560    USE module_sst_setservices, ONLY: SST_register
1561    ! WRF-SST coupler registration routine
1562    USE module_wrfsst_coupler, ONLY: WRFSSTCpl_register
1563    ! ESMF module, defines all ESMF data types and procedures
1564    USE ESMF_Mod
1565    ! Not-yet-implemented ESMF features
1566    USE module_esmf_extensions
1567    ! Component-independent utilities
1568    USE module_metadatautils, ONLY: GetTimesFromStates
1570    IMPLICIT NONE
1572    ! Local variables
1574    ! Components
1575    TYPE(ESMF_GridComp) :: compGriddedWRF   ! WRF
1576    TYPE(ESMF_GridComp) :: compGriddedSST   ! SST reader
1577    TYPE(ESMF_CplComp) :: compCplWRFSST     ! WRF-SST coupler
1579    ! State, Virtual Machine, and DELayout
1580    TYPE(ESMF_VM) :: vm
1581    TYPE(ESMF_State) :: importStateWRF, exportStateWRF
1582    TYPE(ESMF_State) :: importStateSST, exportStateSST
1584    ! A clock, some times, and a time step
1585    TYPE(ESMF_Clock) :: driverClock
1586    TYPE(ESMF_Time) :: startTime
1587    TYPE(ESMF_Time) :: stopTime
1588    TYPE(ESMF_TimeInterval) :: couplingInterval
1590    ! other misc stuff
1591    TYPE(ESMF_State) :: tmpState
1592    INTEGER :: timestepdebug
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(parentVm=vm, 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(parentVm=vm, 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(parentVm=vm, 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 call esmf_attributeget(exportstatewrf,'ComponentCouplingInterval',size(timevals),timevals,rc=rc)
1709 write(0,*) 'exportStateWRF year ',timevals(1),__LINE__
1710 write(0,*) 'exportStateWRF month ',timevals(2),__LINE__
1711 write(0,*) 'exportStateWRF day ',timevals(3),__LINE__
1712 write(0,*) 'exportStateWRF hour ',timevals(4),__LINE__
1713 write(0,*) 'exportStateWRF minute ',timevals(5),__LINE__
1714 write(0,*) 'exportStateWRF second ',timevals(6),__LINE__
1715    ! Note:  wrf_debug and wrf_error_fatal are now initialized
1716    IF ( rc /= ESMF_SUCCESS ) THEN
1717      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(WRF phase 1) failed' )
1718    ENDIF
1720    ! initialize SST, phase 1
1721    ! Phase 1 init returns SST time information as
1722    ! exportState metadata.
1723    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 SST init (sst_component_init1)'
1724    CALL ESMF_GridCompInitialize(compGriddedSST, importStateSST, &
1725                                 exportStateSST, driverClock, phase=1, rc=rc)
1726 call esmf_attributeget(exportstatesst,'ComponentCouplingInterval',size(timevals),timevals,rc=rc)
1727 write(0,*) 'exportStateSST year ',timevals(1),__LINE__
1728 write(0,*) 'exportStateSST month ',timevals(2),__LINE__
1729 write(0,*) 'exportStateSST day ',timevals(3),__LINE__
1730 write(0,*) 'exportStateSST hour ',timevals(4),__LINE__
1731 write(0,*) 'exportStateSST minute ',timevals(5),__LINE__
1732 write(0,*) 'exportStateSST second ',timevals(6),__LINE__
1733    IF ( rc /= ESMF_SUCCESS ) THEN
1734      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(SST phase 1) failed' )
1735    ENDIF
1737    ! Reconcile clock settings from WRF and SST components to set up 
1738    ! top-level clock.  These are passed back from each "init" as attributes 
1739    ! on exportState*.  
1740    ! Stuff both States into a single State to pass into GetTimesFromStates() 
1741    ! which is smart enough to deal with a Composite.  
1742    PRINT *, 'DEBUG wrf_SST_ESMF:  reconciling clock from WRF and SST components'
1743    tmpState = ESMF_StateCreate( rc=rc )
1744    IF ( rc /= ESMF_SUCCESS ) THEN
1745      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateCreate(tmpState) failed' )
1746    ENDIF
1747    CALL ESMF_StateAdd( tmpState, exportStateWRF, rc )
1748    IF ( rc /= ESMF_SUCCESS ) THEN
1749      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateAdd(exportStateWRF) failed' )
1750    ENDIF
1751    CALL ESMF_StateAdd( tmpState, exportStateSST, rc )
1752    IF ( rc /= ESMF_SUCCESS ) THEN
1753      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateAdd(exportStateSST) failed' )
1754    ENDIF
1755    CALL GetTimesFromStates( tmpState, startTime, stopTime, couplingInterval )
1756    CALL ESMF_TimeIntervalGet( couplingInterval, TimeString=couplingIntervalString, &
1757                               rc=rc )
1758    IF ( rc /= ESMF_SUCCESS ) THEN
1759      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_TimeIntervalGet failed' )
1760    ENDIF
1761    CALL wrf_debug( 100, 'wrf_SST_ESMF:  couplingInterval = '//TRIM(couplingIntervalString) )
1762    CALL ESMF_StateDestroy( tmpState, rc )
1763    IF ( rc /= ESMF_SUCCESS ) THEN
1764      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(tmpState) failed' )
1765    ENDIF
1766    ! update driver clock
1767    CALL ESMF_ClockDestroy(driverClock, rc)
1768    IF ( rc /= ESMF_SUCCESS ) THEN
1769      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockDestroy failed' )
1770    ENDIF
1771    driverClock = ESMF_ClockCreate(timeStep=couplingInterval, &
1772                                   startTime=startTime,       &
1773                                   stopTime=stopTime, rc=rc)
1774    IF ( rc /= ESMF_SUCCESS ) THEN
1775      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockCreate(driverClock) failed' )
1776    ENDIF
1777    PRINT *, 'DEBUG wrf_SST_ESMF:  done reconciling clock from WRF and SST components'
1778    CALL wrf_clockprint(50, driverClock, &
1779           'DEBUG wrf_SST_ESMF:  driverClock after creation,')
1781    ! initialize WRF-SST Coupler
1782    PRINT *, 'DEBUG wrf_SST_ESMF:  calling phase-1 CPL init (WRFSSTCpl_init)'
1783    CALL ESMF_CplCompInitialize(compCplWRFSST, exportStateWRF, &
1784                                importStateSST, driverClock, rc=rc)
1785    IF ( rc /= ESMF_SUCCESS ) THEN
1786      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompInitialize(WRF -> SST) failed' )
1787    ENDIF
1789 ! TBH:  this bit is not needed, but would be in general
1790 !   CALL ESMF_CplCompInitialize(compCplWRFSST, exportStateSST, &
1791 !                               importStateWRF, driverClock, rc=rc)
1792 !   IF ( rc /= ESMF_SUCCESS ) THEN
1793 !     CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompInitialize(SST -> WRF) failed' )
1794 !   ENDIF
1796    ! initialize SST, phase 2
1797    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for SST (sst_component_init2)'
1798    CALL wrf_debug ( 100 , TRIM(str) )
1799    CALL ESMF_GridCompInitialize(compGriddedSST, importStateSST, &
1800                                 exportStateSST, driverClock, phase=2, rc=rc)
1801    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for SST'
1802    CALL wrf_debug ( 100 , TRIM(str) )
1803    IF ( rc /= ESMF_SUCCESS ) THEN
1804      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(SST phase 2) failed' )
1805    ENDIF
1807    ! initialize WRF, phase 2
1808    ! Phase 2 init sets up WRF importState and exportState.
1809    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for WRF (wrf_component_init2)'
1810    CALL wrf_debug ( 100 , TRIM(str) )
1811    CALL ESMF_GridCompInitialize(compGriddedWRF, importStateWRF, &
1812                                 exportStateWRF, driverClock, phase=2, rc=rc)
1813    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for WRF'
1814    CALL wrf_debug ( 100 , TRIM(str) )
1815    IF ( rc /= ESMF_SUCCESS ) THEN
1816      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompInitialize(WRF phase 2) failed' )
1817    ENDIF
1819    CALL wrf_clockprint(50, driverClock, &
1820           'DEBUG wrf_SST_ESMF:  driverClock before main time-stepping loop,')
1821    ! Run...
1822    ! main time-stepping loop
1823    timestepdebug = 0
1824    DO WHILE ( .NOT. ESMF_ClockIsStopTime(driverClock, rc) )
1826      timestepdebug = timestepdebug + 1
1827      WRITE(str,'(A,I8)') 'PROGRAM wrf_SST_ESMF: Top of time-stepping loop, timestepdebug = ',timestepdebug
1828      CALL wrf_debug ( 100 , TRIM(str) )
1829      CALL wrf_clockprint(50, driverClock, &
1830             'DEBUG wrf_SST_ESMF:  driverClock at top of time-stepping loop,')
1832      ! Run SST phase 1
1833      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-1 run for SST (sst_component_run1)'
1834      CALL wrf_debug ( 100 , TRIM(str) )
1835      CALL ESMF_GridCompRun(compGriddedSST, importStateSST, exportStateSST, &
1836                            driverClock, phase=1, rc=rc)
1837      IF ( rc /= ESMF_SUCCESS ) THEN
1838        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(SST phase 1) failed' )
1839      ENDIF
1840      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-1 run for SST (sst_component_run1)'
1841      CALL wrf_debug ( 100 , TRIM(str) )
1843      ! couple SST export -> WRF import
1844      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL SST->WRF (WRFSSTCpl_run)'
1845      CALL wrf_debug ( 100 , TRIM(str) )
1846      CALL ESMF_CplCompRun(compCplWRFSST, exportStateSST, &
1847                           importStateWRF, driverClock, rc=rc)
1848      IF ( rc /= ESMF_SUCCESS ) THEN
1849        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompRun(SST -> WRF) failed' )
1850      ENDIF
1851      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL SST->WRF (WRFSSTCpl_run)'
1852      CALL wrf_debug ( 100 , TRIM(str) )
1854      ! Run WRF
1855      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for WRF (wrf_component_run)'
1856      CALL wrf_debug ( 100 , TRIM(str) )
1857      CALL ESMF_GridCompRun(compGriddedWRF, importStateWRF, exportStateWRF, &
1858                            driverClock, rc=rc)
1859      IF ( rc /= ESMF_SUCCESS ) THEN
1860        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(WRF) failed' )
1861      ENDIF
1862      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for WRF (wrf_component_run)'
1863      CALL wrf_debug ( 100 , TRIM(str) )
1865      ! couple WRF export -> SST import
1866      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL WRF->SST (WRFSSTCpl_run)'
1867      CALL wrf_debug ( 100 , TRIM(str) )
1868      CALL ESMF_CplCompRun(compCplWRFSST, exportStateWRF, &
1869                           importStateSST, driverClock, rc=rc)
1870      IF ( rc /= ESMF_SUCCESS ) THEN
1871        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompRun(WRF -> SST) failed' )
1872      ENDIF
1873      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL WRF->SST (WRFSSTCpl_run)'
1874      CALL wrf_debug ( 100 , TRIM(str) )
1876      ! Run SST phase 2
1877      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 run for SST (sst_component_run2)'
1878      CALL wrf_debug ( 100 , TRIM(str) )
1879      CALL ESMF_GridCompRun(compGriddedSST, importStateSST, exportStateSST, &
1880                            driverClock, phase=2, rc=rc)
1881      IF ( rc /= ESMF_SUCCESS ) THEN
1882        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompRun(SST phase 2) failed' )
1883      ENDIF
1884      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 run for SST (sst_component_run2)'
1885      CALL wrf_debug ( 100 , TRIM(str) )
1887      ! advance clock to next coupling time step
1888      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: advancing clock'
1889      CALL wrf_debug ( 100 , TRIM(str) )
1890      CALL ESMF_ClockAdvance( driverClock, rc=rc )
1891      IF ( rc /= ESMF_SUCCESS ) THEN
1892        CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockAdvance failed' )
1893      ENDIF
1894      WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done advancing clock'
1895      CALL wrf_debug ( 100 , TRIM(str) )
1897      CALL wrf_clockprint(50, driverClock, &
1898             'DEBUG wrf_SST_ESMF:  driverClock at end of time-stepping loop,')
1900    ENDDO
1902    WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done with time-stepping loop'
1903    CALL wrf_debug ( 100 , TRIM(str) )
1905    ! clean up SST
1906    CALL ESMF_GridCompFinalize(compGriddedSST, importStateSST, exportStateSST, &
1907                               driverClock, rc=rc)
1908    IF ( rc /= ESMF_SUCCESS ) THEN
1909      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompFinalize(compGriddedSST) failed' )
1910    ENDIF
1912    ! clean up compCplWRFSST
1913    CALL ESMF_CplCompFinalize( compCplWRFSST, exportStateWRF, importStateSST, &
1914                               driverClock, rc=rc)
1915    IF ( rc /= ESMF_SUCCESS ) THEN
1916      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_CplCompFinalize(compCplWRFSST) failed' )
1917    ENDIF
1919    ! clean up WRF
1920    ! must do this AFTER clean up of SST since SST uses WRF IOAPI
1921    CALL ESMF_GridCompFinalize(compGriddedWRF, importStateWRF, exportStateWRF, &
1922                               driverClock, rc=rc)
1923    IF ( rc /= ESMF_SUCCESS ) THEN
1924      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompFinalize(compGriddedWRF) failed' )
1925    ENDIF
1927    ! Clean up
1929    CALL ESMF_GridCompDestroy(compGriddedWRF, rc)
1930    IF ( rc /= ESMF_SUCCESS ) THEN
1931      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_GridCompDestroy(compGriddedWRF) failed' )
1932    ENDIF
1933    CALL ESMF_StateDestroy(importStateWRF, rc)
1934    IF ( rc /= ESMF_SUCCESS ) THEN
1935      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(importStateWRF) failed' )
1936    ENDIF
1937    CALL ESMF_StateDestroy(exportStateWRF, rc)
1938    IF ( rc /= ESMF_SUCCESS ) THEN
1939      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(exportStateWRF) failed' )
1940    ENDIF
1941    CALL ESMF_StateDestroy(importStateSST, rc)
1942    IF ( rc /= ESMF_SUCCESS ) THEN
1943      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(importStateSST) failed' )
1944    ENDIF
1945    CALL ESMF_StateDestroy(exportStateSST, rc)
1946    IF ( rc /= ESMF_SUCCESS ) THEN
1947      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_StateDestroy(exportStateSST) failed' )
1948    ENDIF
1949    CALL ESMF_ClockDestroy(driverClock, rc)
1950    IF ( rc /= ESMF_SUCCESS ) THEN
1951      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_ClockDestroy(driverClock) failed' )
1952    ENDIF
1954    CALL ESMF_Finalize( rc=rc )
1955    IF ( rc /= ESMF_SUCCESS ) THEN
1956      CALL wrf_error_fatal ( 'wrf_SST_ESMF:  ESMF_Finalize failed' )
1957    ENDIF
1959 END PROGRAM wrf_SST_ESMF