source: trunk/WRF.COMMON/WRFV3/main/wrf_SST_ESMF.F @ 3553

Last change on this file since 3553 was 2759, checked in by aslmd, 2 years ago

adding unmodified code from WRFV3.0.1.1, expurged from useless data +1M size

File size: 82.3 KB
Line 
1!WRF:DRIVER_LAYER:MAIN
2!
3
4!<DESCRIPTION>
5! ESMF Application Wrapper for coupling WRF with a "dummy" component
6! that simply reads SSTs from a file, sends to WRF, receives SST from
7! WRF (two-way coupling). and checks that the SSTs match. 
8!
9! This file contains the main program and associated modules for the
10! SST "dummy" component and a simple coupler.  It creates ESMF Gridded
11! and Coupler Components. 
12!
13! This source file is only built when ESMF coupling is used. 
14!
15!</DESCRIPTION>
16
17
18
19!<DESCRIPTION>
20! Modules module_sst_component_top and module_sst_setservices define the
21! "SST" dummy component. 
22!</DESCRIPTION>
23
24MODULE module_sst_component_top
25!<DESCRIPTION>
26! This module defines sst_component_init1(), sst_component_init2(),
27! sst_component_run1(), sst_component_run2(), and sst_component_finalize()
28! routines that are called when SST is run as an ESMF component. 
29!</DESCRIPTION>
30
31   USE ESMF_Mod
32   USE module_esmf_extensions
33   USE module_metadatautils, ONLY: AttachTimesToState
34
35
36   IMPLICIT NONE
37
38   ! everything is private by default
39   PRIVATE
40
41   ! Public entry points
42   PUBLIC sst_component_init1
43   PUBLIC sst_component_init2
44   PUBLIC sst_component_run1
45   PUBLIC sst_component_run2
46   PUBLIC sst_component_finalize
47
48   ! private stuff
49   TYPE(ESMF_Grid), SAVE :: esmfgrid  ! grid used in fields
50   CHARACTER (4096) :: str
51   INTEGER, SAVE :: fid               ! file handle
52   ! decomposition information
53   INTEGER, SAVE :: ids, ide, jds, jde, kds, kde
54   INTEGER, SAVE :: ims, ime, jms, jme, kms, kme
55   INTEGER, SAVE :: ips, ipe, jps, jpe, kps, kpe
56   REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_out_sst(:,:)
57   REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_out_landmask(:,:)
58   REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_in_sst(:,:)
59   REAL(ESMF_KIND_R4), POINTER, SAVE :: tmp_data_in_landmask(:,:)
60   INTEGER, SAVE :: domdesc
61   LOGICAL, SAVE :: bdy_mask(4)
62   ! MPI communicator, if needed
63   INTEGER, SAVE :: mpicom
64   ! field data
65   REAL, POINTER, SAVE :: file_landmask_data(:,:), file_sst_data(:,:)
66   ! input data file name
67   CHARACTER ( ESMF_MAXSTR ), SAVE :: sstinfilename
68   ! field names
69   INTEGER, PARAMETER :: datacount = 2
70   INTEGER, PARAMETER :: SST_INDX = 1
71   INTEGER, PARAMETER :: LANDMASK_INDX = 2
72   CHARACTER(LEN=ESMF_MAXSTR), SAVE :: datanames(datacount)
73   TYPE real2d
74     REAL, POINTER :: r2d(:,:)
75   END TYPE real2d
76   TYPE(real2d) :: this_data(datacount)
77
78
79CONTAINS
80
81
82
83   ! First-phase "init" reads "SST" data file and returns "time" metadata in
84   ! exportState. 
85   SUBROUTINE sst_component_init1( gcomp, importState, exportState, clock, rc )
86     USE module_io
87     TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
88     TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: importState
89     TYPE(ESMF_State),    TARGET, INTENT(INOUT) :: exportState
90     TYPE(ESMF_Clock),    TARGET, INTENT(INOUT) :: clock
91     INTEGER,                     INTENT(  OUT) :: rc
92!<DESCRIPTION>
93!     SST component init routine, phase 1.
94!
95!     The arguments are:
96!       gcomp           Component
97!       importState     Importstate
98!       exportState     Exportstate
99!       clock           External clock
100!       rc              Return code; equals ESMF_SUCCESS if there are no errors,
101!                       otherwise ESMF_FAILURE.
102!</DESCRIPTION>
103
104#ifdef DM_PARALLEL
105     INCLUDE 'mpif.h'
106#endif
107
108     ! Local variables
109     CHARACTER (LEN=19) :: date_string
110#ifdef DM_PARALLEL
111     TYPE(ESMF_VM) :: vm
112     INTEGER :: mpicomtmp
113#endif
114     TYPE(ESMF_Time) :: startTime, stopTime, currentTime, dataTime
115     TYPE(ESMF_TimeInterval) :: timeStep
116     INTEGER :: ierr, num_steps, time_loop_max
117     INTEGER :: status_next_var
118
119!TODO:  For now, sstinfilename is hard-coded
120!TODO:  Upgrade to use a variant of construct_filename() via startTime
121!TODO:  extracted from clock. 
122     sstinfilename = 'sstin_d01_000000'
123
124     ! get MPI communicator out of current VM and duplicate (if needed)
125#ifdef DM_PARALLEL
126     CALL ESMF_VMGetCurrent(vm, rc=rc)
127     IF ( rc /= ESMF_SUCCESS ) THEN
128       CALL wrf_error_fatal ( 'sst_component_init1:  ESMF_VMGetCurrent failed' )
129     ENDIF
130     CALL ESMF_VMGet(vm, mpiCommunicator=mpicomtmp, rc=rc)
131     IF ( rc /= ESMF_SUCCESS ) THEN
132       CALL wrf_error_fatal ( 'sst_component_init1:  ESMF_VMGet failed' )
133     ENDIF
134     CALL MPI_Comm_dup( mpicomtmp, mpicom, ierr )
135#else
136     mpicom = 0
137#endif
138     !  Open the "SST" input data file for reading.
139     write(str,'(A,A)') 'Subroutine sst_component_init1: Opening data file ', &
140       TRIM(sstinfilename)
141     CALL wrf_message ( TRIM(str) )
142     CALL wrf_open_for_read ( TRIM(sstinfilename) , &
143                              mpicom ,              &
144                              mpicom ,              &
145                              "DATASET=INPUT" ,     &
146                              fid ,                 &
147                              ierr )
148     IF ( ierr .NE. 0 ) THEN
149        WRITE( str , FMT='(A,A,A,I8)' ) &
150          'subroutine sst_component_init1: error opening ', &
151          TRIM(sstinfilename),' for reading ierr=',ierr
152        CALL wrf_error_fatal ( TRIM(str) )
153     ENDIF
154     WRITE( str , FMT='(A,A,A,I8)' ) &
155       'subroutine sst_component_init1: opened file ', &
156       TRIM(sstinfilename),' for reading fid=',fid
157     CALL wrf_debug ( 100, TRIM(str) )
158
159     ! How many data time levels are in the SST input file? 
160     num_steps = -1
161     time_loop_max = 0
162     CALL wrf_debug    ( 100, 'subroutine sst_component_init1: find time_loop_max' )
163     ! compute SST start time, time step, and end time here
164     get_the_right_time : DO
165        CALL wrf_get_next_time ( fid, date_string, status_next_var )
166        write(str,'(A,A)') 'Subroutine sst_component_init1: SST data startTime: ', &
167          date_string
168        CALL wrf_debug ( 100 , TRIM(str) )
169        IF ( status_next_var == 0 ) THEN
170           IF ( time_loop_max == 0 ) THEN
171             CALL wrf_atotime( date_string, startTime )
172           ELSEIF ( time_loop_max == 1 ) THEN
173             ! assumes fixed time step!
174             CALL wrf_atotime( date_string, dataTime )
175             timeStep = dataTime - startTime
176           ENDIF
177           time_loop_max = time_loop_max + 1
178           CALL wrf_atotime( date_string, stopTime )
179        ELSE
180           EXIT get_the_right_time
181        ENDIF
182     END DO get_the_right_time
183     CALL wrf_timetoa ( stopTime, date_string )
184     write(str,'(A,A)') 'Subroutine sst_component_init1: SST data stopTime: ', &
185       date_string
186     CALL wrf_debug ( 100 , TRIM(str) )
187     ! attach times to exportState for use by driver
188     CALL AttachTimesToState( exportState, startTime, stopTime, timeStep )
189
190     ! There should be a more elegant way to get to the beginning of the
191     ! file, but this will do.
192     CALL wrf_ioclose( fid , ierr )
193     IF ( ierr .NE. 0 ) THEN
194        CALL wrf_error_fatal ( 'sst_component_init1:  wrf_ioclose failed' )
195     ENDIF
196     WRITE( str , FMT='(A,I8)' ) &
197       'subroutine sst_component_init1: closed file fid=',fid
198     CALL wrf_debug ( 100, TRIM(str) )
199
200     ! set up field names
201!TODO:  use CF conventions for "standard_name" once WRF Registry supports them
202!TODO:      datanames(SST_INDX) = "sea_surface_temperature"
203!TODO:      datanames(LANDMASK_INDX) = "land_binary_mask"
204     datanames(SST_INDX) = "SST"
205     datanames(LANDMASK_INDX) = "LANDMASK"
206
207     rc = ESMF_SUCCESS
208
209   END SUBROUTINE sst_component_init1
210
211
212
213   SUBROUTINE read_data( exportState, clock )
214     USE module_io
215     TYPE(ESMF_State), INTENT(INOUT) :: exportState
216     TYPE(ESMF_Clock), INTENT(IN   ) :: clock
217!<DESCRIPTION>
218!     Reads data from file and stores.  Then
219!     stuffs the file data into the SST exportState. 
220!</DESCRIPTION>
221
222     #include <wrf_status_codes.h>
223     #include <wrf_io_flags.h>
224
225     ! Local variables
226     CHARACTER (LEN=19) :: date_string
227     TYPE(ESMF_Time) :: currentTime, dataTime
228     REAL(ESMF_KIND_R4), POINTER :: out_sst_ptr(:,:), out_landmask_ptr(:,:)
229     TYPE(ESMF_Field) :: out_sst_field, out_landmask_field
230     TYPE(ESMF_Field) :: in_sst_field, in_landmask_field
231     INTEGER :: i, j
232     CHARACTER(LEN=ESMF_MAXSTR) :: fieldname, debugmsg, errormsg, timestr
233     INTEGER :: ierr
234     INTEGER :: rc
235
236     ! This call to wrf_get_next_time will position the dataset over the next
237     ! time-frame in the file and return the date_string, which is used as an
238     ! argument to the read_field routines in the blocks of code included
239     ! below. 
240
241     CALL wrf_get_next_time( fid, date_string , ierr )
242     WRITE(str,'(A,A)') 'Subroutine read_data: SST data time: ', &
243       date_string
244     CALL wrf_debug ( 100 , TRIM(str) )
245     IF ( ierr .NE. 0 .AND. ierr .NE. WRF_WARN_NOTSUPPORTED .AND.  &
246          ierr .NE. WRF_WARN_DRYRUN_READ ) THEN
247       CALL wrf_error_fatal ( "... May have run out of valid SST data ..." )
248     ELSE IF ( ierr .NE. WRF_WARN_NOTSUPPORTED .AND. &
249               ierr .NE. WRF_WARN_DRYRUN_READ) THEN
250       ! check input time against current time (which will be start time at
251       ! beginning)
252       CALL wrf_atotime( date_string, dataTime )
253       CALL ESMF_ClockGet( clock, CurrTime=currentTime, rc=rc )
254       IF (rc /= ESMF_SUCCESS) THEN
255         CALL wrf_error_fatal ( 'read_data:  ESMF_ClockGet() failed' )
256       ENDIF
257       CALL wrf_clockprint(150, clock, &
258              'DEBUG read_data():  get currentTime from clock,')
259       IF ( dataTime .NE. currentTime ) THEN
260           CALL wrf_timetoa ( dataTime, timestr )
261           WRITE( errormsg , * )'Time in file: ',trim( timestr )
262           CALL wrf_message ( trim(errormsg) )
263           CALL wrf_timetoa ( currentTime, timestr )
264           WRITE( errormsg , * )'Time on domain: ',trim( timestr )
265           CALL wrf_message ( trim(errormsg) )
266           CALL wrf_error_fatal( &
267             "**ERROR** Time in input file not equal to time on domain **ERROR**" )
268       ENDIF
269     ENDIF
270
271     ! doing this in a loop only works if staggering is the same for all fields
272     this_data(SST_INDX)%r2d => file_sst_data
273     this_data(LANDMASK_INDX)%r2d => file_landmask_data
274     DO i=1, datacount
275       fieldname = TRIM(datanames(i))
276       debugmsg  = 'ext_read_field '//TRIM(fieldname)//' memorder XY'
277       errormsg  = 'could not read '//TRIM(fieldname)//' data from file'
278       CALL wrf_ext_read_field (    &
279              fid                 , &  ! DataHandle
280              date_string         , &  ! DateStr
281              TRIM(fieldname)     , &  ! Data Name
282              this_data(i)%r2d    , &  ! Field
283              WRF_REAL            , &  ! FieldType
284              mpicom              , &  ! Comm
285              mpicom              , &  ! I/O Comm
286              domdesc             , &  ! Domain descriptor
287              bdy_mask            , &  ! bdy_mask
288              'XY'                , &  ! MemoryOrder
289              ''                  , &  ! Stagger
290              TRIM(debugmsg)      , &  ! Debug message
291!              ids , (ide-1) , jds , (jde-1) , 1 , 1 , &
292!              ims , ime , jms , jme , 1 , 1         , &
293!              ips , MIN( (ide-1), ipe ) , jps , MIN( (jde-1), jpe ) , 1 , 1 , &
294!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
304
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
338
339   END SUBROUTINE read_data
340
341
342
343
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. 
352!
353!     The arguments are:
354!       importState     Importstate
355!</DESCRIPTION>
356
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
368
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) )
378
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))
433
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
454
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
475
476     DEALLOCATE( in_sst_ptr_real, in_landmask_ptr_real )
477
478     WRITE(str,*) 'compare_data:  end, numtimes = ',numtimes
479     CALL wrf_debug ( 100 , TRIM(str) )
480
481   END SUBROUTINE compare_data
482
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.
495!
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>
504
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
517
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. 
526write(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) )
542
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
559
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
569write(0,*)__FILE__,__LINE__,'DomainStart ',DomainStart(1:2)
570write(0,*)__FILE__,__LINE__,'DomainEnd ',DomainEnd(1:2)
571write(0,*)__FILE__,__LINE__,'MemoryStart ',MemoryStart(1:2)
572write(0,*)__FILE__,__LINE__,'MemoryEnd ',MemoryEnd(1:2)
573write(0,*)__FILE__,__LINE__,'PatchStart ',PatchStart(1:2)
574write(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 )
580write(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 )
586write(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... 
599write(0,*)__FILE__,__LINE__
600     ALLOCATE( tmp_data_out_sst(ips:ipe,jps:jpe) )
601write(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)' )
606write(0,*)__FILE__,__LINE__,trim(datanames(sst_indx))
607write(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 )
614write(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
730
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
749
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) )
770
771     write(str,'(A)') 'sst_component_init2: returning rc=ESMF_SUCCESS'
772     CALL wrf_debug ( 100 , TRIM(str) )
773
774     rc = ESMF_SUCCESS
775
776   END SUBROUTINE sst_component_init2
777
778
779
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. 
788!
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>
797
798     rc = ESMF_SUCCESS
799
800     ! Get "SST" data from file and stuff it into exportState. 
801     CALL read_data( exportState, clock )
802
803   END SUBROUTINE sst_component_run1
804
805
806
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. 
817!
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>
826
827     rc = ESMF_SUCCESS
828
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()' )
836
837   END SUBROUTINE sst_component_run2
838
839
840
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.
849!
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>
858
859     ! Local variables
860     TYPE(ESMF_Field) :: tmp_field
861     INTEGER :: i, ierr
862
863     rc = ESMF_SUCCESS
864
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
902
903     ! deallocate space for data read from disk
904     DEALLOCATE( file_sst_data, file_landmask_data )
905
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
914
915   END SUBROUTINE sst_component_finalize
916
917
918END MODULE module_sst_component_top
919
920
921
922
923MODULE module_sst_setservices
924!<DESCRIPTION>
925! This module defines SST "Set Services" method sst_register()
926! used for ESMF coupling. 
927!</DESCRIPTION>
928
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
935
936   IMPLICIT NONE
937
938   ! everything is private by default
939   PRIVATE
940
941   ! Public entry point for ESMF_GridCompSetServices()
942   PUBLIC SST_register
943
944   ! private stuff
945   CHARACTER (ESMF_MAXSTR) :: str
946
947CONTAINS
948
949
950   SUBROUTINE sst_register(gcomp, rc)
951     TYPE(ESMF_GridComp), INTENT(INOUT) :: gcomp
952     INTEGER, INTENT(OUT) :: rc
953     INTEGER :: finalrc
954!
955!<DESCRIPTION>
956!     SST_register - Externally visible registration routine
957!
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.
962!
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>
968
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
1001
1002     PRINT *,'SST:  Registered Initialize, Run, and Finalize routines'
1003
1004     rc = finalrc
1005
1006   END SUBROUTINE sst_register
1007
1008END MODULE module_sst_setservices
1009
1010
1011
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. 
1020!
1021! This is derived from src/demo/coupled_flow/src/CouplerMod.F90
1022! created by Nancy Collins and others on the ESMF Core Team. 
1023!
1024!</DESCRIPTION>
1025
1026MODULE module_wrfsst_coupler
1027
1028    USE ESMF_Mod
1029
1030    IMPLICIT NONE
1031   
1032    ! everything is private by default
1033    PRIVATE
1034
1035    ! Public entry point
1036    PUBLIC WRFSSTCpl_register
1037
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
1049
1050
1051CONTAINS
1052
1053
1054   SUBROUTINE WRFSSTCpl_register(comp, rc)
1055     TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1056     INTEGER, INTENT(OUT) :: rc
1057!
1058!<DESCRIPTION>
1059!     WRFSSTCpl_register - Externally visible registration routine
1060!
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.
1065!
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>
1071
1072      ! guilty until proven innocent
1073      rc = ESMF_FAILURE
1074
1075      ! Register the callback routines.
1076
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
1092
1093      print *, "module_wrfsst_coupler: Registered Initialize, Run, and Finalize routines"
1094
1095    END SUBROUTINE WRFSSTCpl_register
1096
1097
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. 
1108!
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>
1117
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)
1126
1127      PRINT *, "DEBUG:  Coupler Init starting"
1128
1129      ! guilty until proven innocent
1130      rc = ESMF_FAILURE
1131
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
1136
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 )
1150
1151
1152      ELSE
1153        CALL wrf_error_fatal ( 'WRFSSTCpl_init:  invalid importState name' )
1154      ENDIF
1155
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"
1162
1163      PRINT *, "DEBUG:  Coupler Init returning"
1164   
1165    END SUBROUTINE WRFSSTCpl_init
1166
1167
1168
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.
1176!
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>
1185
1186! Note that comments in this code are preserved from the sample coupler
1187! provided by the ESMF core team. 
1188
1189      ! Local variables
1190character*256 :: mename
1191character*256 :: melist(100)
1192integer :: mecount
1193TYPE(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
1203
1204      WRITE(str,*) 'WRFSSTCpl_run: begin'
1205      CALL wrf_debug ( 100 , TRIM(str) )
1206
1207      ! guilty until proven innocent
1208      rc = ESMF_FAILURE
1209
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 )
1214write(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) )
1220
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) )
1252
1253CALL ESMF_StateGet( importState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1254write(0,*)'importState mename ',trim(mename)
1255write(0,*)'importState mecount ',mecount
1256do i = 1,mecount
1257write(0,*)i,trim(melist(i))
1258enddo
1259do i = 1,mecount
1260write(0,*)i,metypelist(i)
1261enddo
1262
1263        CALL ESMF_StateGet( importState, TRIM(datanames(1)), src_field, &
1264                                 rc=rc )
1265write(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
1269
1270        CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1271write(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) )
1278
1279CALL ESMF_StateGet( exportState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1280write(0,*)'Exportstate mename ',trim(mename)
1281write(0,*)'Exportstate mecount ',mecount
1282do i = 1,mecount
1283write(0,*)i,trim(melist(i))
1284enddo
1285do i = 1,mecount
1286write(0,*)i,metypelist(i)
1287enddo
1288
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
1299
1300
1301
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 )
1329write(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
1346
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
1359
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
1373
1374        WRITE(str,*) 'WRFSSTCpl_run: processing field <',TRIM(datanames(i)),'>'
1375        CALL wrf_debug ( 100 , TRIM(str) )
1376
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.
1384!
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
1400
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
1416
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) )
1433
1434      ENDDO
1435
1436      WRITE(str,*) 'WRFSSTCpl_run: end'
1437      CALL wrf_debug ( 100 , TRIM(str) )
1438
1439    END SUBROUTINE WRFSSTCpl_run
1440
1441
1442
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.
1450!
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>
1459
1460      PRINT *, "DEBUG:  Coupler Final starting"
1461   
1462      ! guilty until proven innocent
1463      rc = ESMF_FAILURE
1464
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
1478
1479      PRINT *, "DEBUG:  Coupler Final returning"
1480   
1481    END SUBROUTINE WRFSSTCpl_final
1482
1483
1484END MODULE module_wrfsst_coupler
1485   
1486   
1487
1488
1489PROGRAM wrf_SST_ESMF
1490
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. 
1496!
1497! Note that, like other WRF coupling methods (MCEL, MCT), ESMF coupling is
1498! supported only via auxiliary input and history streams. 
1499!
1500! This is the main program that creates the ESMF Gridded and Coupler
1501! Component. 
1502!
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. 
1527!
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(). 
1535!
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
1551!
1552! "finalize" is trivial, except for destruction of ESMF objects which is
1553! quite non-trivial at the moment. 
1554!
1555!</DESCRIPTION>
1556
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
1569
1570   IMPLICIT NONE
1571
1572   ! Local variables
1573
1574   ! Components
1575   TYPE(ESMF_GridComp) :: compGriddedWRF   ! WRF
1576   TYPE(ESMF_GridComp) :: compGriddedSST   ! SST reader
1577   TYPE(ESMF_CplComp) :: compCplWRFSST     ! WRF-SST coupler
1578
1579   ! State, Virtual Machine, and DELayout
1580   TYPE(ESMF_VM) :: vm
1581   TYPE(ESMF_State) :: importStateWRF, exportStateWRF
1582   TYPE(ESMF_State) :: importStateSST, exportStateSST
1583
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
1589
1590   ! other misc stuff
1591   TYPE(ESMF_State) :: tmpState
1592   INTEGER :: timestepdebug
1593
1594   ! Return codes for error checks
1595   INTEGER :: rc
1596   CHARACTER (ESMF_MAXSTR) :: str
1597
1598   ! debugging
1599   CHARACTER(LEN=256) :: couplingIntervalString
1600integer(ESMF_KIND_I4) :: timevals(6)
1601
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            '
1608
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
1618
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
1624
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
1630
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
1636
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
1646
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
1656
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
1662
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
1668
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
1674
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
1698
1699   ! Init, Run, and Finalize section
1700
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)
1708call esmf_attributeget(exportstatewrf,'ComponentCouplingInterval',size(timevals),timevals,rc=rc)
1709write(0,*) 'exportStateWRF year ',timevals(1),__LINE__
1710write(0,*) 'exportStateWRF month ',timevals(2),__LINE__
1711write(0,*) 'exportStateWRF day ',timevals(3),__LINE__
1712write(0,*) 'exportStateWRF hour ',timevals(4),__LINE__
1713write(0,*) 'exportStateWRF minute ',timevals(5),__LINE__
1714write(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
1719
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)
1726call esmf_attributeget(exportstatesst,'ComponentCouplingInterval',size(timevals),timevals,rc=rc)
1727write(0,*) 'exportStateSST year ',timevals(1),__LINE__
1728write(0,*) 'exportStateSST month ',timevals(2),__LINE__
1729write(0,*) 'exportStateSST day ',timevals(3),__LINE__
1730write(0,*) 'exportStateSST hour ',timevals(4),__LINE__
1731write(0,*) 'exportStateSST minute ',timevals(5),__LINE__
1732write(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
1736
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,')
1780
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
1788
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
1795
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
1806
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
1818
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) )
1825
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,')
1831
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) )
1842
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) )
1853
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) )
1864
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) )
1875
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) )
1886
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) )
1896
1897     CALL wrf_clockprint(50, driverClock, &
1898            'DEBUG wrf_SST_ESMF:  driverClock at end of time-stepping loop,')
1899
1900   ENDDO
1901
1902   WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done with time-stepping loop'
1903   CALL wrf_debug ( 100 , TRIM(str) )
1904
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
1911 
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
1918 
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
1926 
1927   ! Clean up
1928
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
1953
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
1958
1959END PROGRAM wrf_SST_ESMF
1960
1961
Note: See TracBrowser for help on using the repository browser.