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.
20 ! Modules module_sst_component_top and module_sst_setservices define the
21 ! "SST" dummy component.
24 MODULE module_sst_component_top
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.
32 USE module_esmf_extensions
33 USE module_metadatautils, ONLY: AttachTimesToState
38 ! everything is private by default
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
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
65 REAL, POINTER, SAVE :: file_landmask_data(:,:), file_sst_data(:,:)
66 ! input data file name
67 CHARACTER ( ESMF_MAXSTR ), SAVE :: sstinfilename
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)
74 REAL, POINTER :: r2d(:,:)
76 TYPE(real2d) :: this_data(datacount)
83 ! First-phase "init" reads "SST" data file and returns "time" metadata in
85 SUBROUTINE sst_component_init1( gcomp, importState, exportState, clock, rc )
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
93 ! SST component init routine, phase 1.
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.
109 CHARACTER (LEN=19) :: date_string
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)
126 CALL ESMF_VMGetCurrent(vm, rc=rc)
127 IF ( rc /= ESMF_SUCCESS ) THEN
128 CALL wrf_error_fatal ( 'sst_component_init1: ESMF_VMGetCurrent failed' )
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' )
134 CALL MPI_Comm_dup( mpicomtmp, mpicom, ierr )
138 ! Open the "SST" input data file for reading.
139 write(str,'(A,A)') 'Subroutine sst_component_init1: Opening data file ', &
141 CALL wrf_message ( TRIM(str) )
142 CALL wrf_open_for_read ( TRIM(sstinfilename) , &
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) )
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?
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: ', &
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
177 time_loop_max = time_loop_max + 1
178 CALL wrf_atotime( date_string, stopTime )
180 EXIT get_the_right_time
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: ', &
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' )
196 WRITE( str , FMT='(A,I8)' ) &
197 'subroutine sst_component_init1: closed file fid=',fid
198 CALL wrf_debug ( 100, TRIM(str) )
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"
209 END SUBROUTINE sst_component_init1
213 SUBROUTINE read_data( exportState, clock )
215 TYPE(ESMF_State), INTENT(INOUT) :: exportState
216 TYPE(ESMF_Clock), INTENT(IN ) :: clock
218 ! Reads data from file and stores. Then
219 ! stuffs the file data into the SST exportState.
222 #include <wrf_status_codes.h>
223 #include <wrf_io_flags.h>
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
232 CHARACTER(LEN=ESMF_MAXSTR) :: fieldname, debugmsg, errormsg, timestr
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
241 CALL wrf_get_next_time( fid, date_string , ierr )
242 WRITE(str,'(A,A)') 'Subroutine read_data: SST data time: ', &
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
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' )
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**" )
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
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 ( &
280 date_string , & ! DateStr
281 TRIM(fieldname) , & ! Data Name
282 this_data(i)%r2d , & ! Field
283 WRF_REAL , & ! FieldType
285 mpicom , & ! I/O Comm
286 domdesc , & ! Domain descriptor
287 bdy_mask , & ! bdy_mask
288 'XY' , & ! MemoryOrder
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 , &
301 CALL wrf_error_fatal ( TRIM(errormsg) )
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' )
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' )
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' )
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' )
331 ! staggered starts/ends
334 out_sst_ptr(i,j) = file_sst_data(i,j)
335 out_landmask_ptr(i,j) = file_landmask_data(i,j)
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
349 ! Gets data from coupler via importState
350 ! and compares with data read from file and
351 ! error-exits if they differ.
354 ! importState Importstate
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(:,:)
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' )
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' )
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' )
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' )
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) )
408 in_sst_ptr_real(i,j) = -(i*1000.0 + j)/100000.0 ! obvious bad value for debugging
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' )
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) )
428 in_landmask_ptr_real(i,j) = -(i*1000.0 + j)/100000.0 ! obvious bad value for debugging
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...
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
447 ENDDO LANDMASK_COMPARE
448 IF ( landmask_ok ) THEN
449 WRITE(str,*) 'compare_data: LANDMASK compares OK'
450 CALL wrf_debug ( 100 , TRIM(str) )
452 CALL wrf_error_fatal ( TRIM(str) )
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
462 WRITE( str , * ) 'error sst mismatch at (i,j) = (',i,',',j, &
463 '), values are',file_sst_data(i,j),' and ', &
470 WRITE(str,*) 'compare_data: SST compares OK'
471 CALL wrf_debug ( 100 , TRIM(str) )
473 CALL wrf_error_fatal ( TRIM(str) )
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
485 SUBROUTINE sst_component_init2( gcomp, importState, exportState, clock, rc )
486 USE module_metadatautils, ONLY: GetDecompFromState
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
494 ! SST component init routine, phase 2.
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.
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)
518 ! Get decomposition information from importState. Note that index
519 ! values are for staggered dimensions, following the WRF convention.
520 !TODO: Note that this will only work for SPMD serial operation. For
521 !TODO: concurrent operation (SPMD or MPMD), we will need to create a new
522 !TODO: "domdesc" suitable for the task layout of the SST component. For
523 !TODO: MPMD serial operation, we will need to extract serialized domdesc
524 !TODO: from export state metadata and de-serialize it. Similar arguments
525 !TODO: apply to [ij][mp][se] and bdy_mask.
526 write(str,*) 'sst_component_init2: calling GetDecompFromState'
527 CALL wrf_debug ( 100 , TRIM(str) )
528 CALL GetDecompFromState( importState, &
529 ids, ide, jds, jde, kds, kde, &
530 ims, ime, jms, jme, kms, kme, &
531 ips, ipe, jps, jpe, kps, kpe, &
533 write(str,*) 'sst_component_init2: back from GetDecompFromState'
534 CALL wrf_debug ( 100 , TRIM(str) )
535 write(str,*) 'sst_component_init2: ids, ide, jds, jde, kds, kde = ', ids, ide, jds, jde, kds, kde
536 CALL wrf_debug ( 100 , TRIM(str) )
537 write(str,*) 'sst_component_init2: ims, ime, jms, jme, kms, kme = ', ims, ime, jms, jme, kms, kme
538 CALL wrf_debug ( 100 , TRIM(str) )
539 write(str,*) 'sst_component_init2: ips, ipe, jps, jpe, kps, kpe = ', ips, ipe, jps, jpe, kps, kpe
540 CALL wrf_debug ( 100 , TRIM(str) )
542 ! allocate space for data read from disk
543 ALLOCATE( file_sst_data (ims:ime,jms:jme) )
546 file_sst_data(i,j) = -(i*1000.0 + j)/100000.0 ! obvious bad value for debugging
549 !TODO: Hmmm... really need to load these pointers here? Check...
550 this_data(SST_INDX)%r2d => file_sst_data
551 ALLOCATE( file_landmask_data(ims:ime,jms:jme) )
554 file_landmask_data(i,j) = -(i*1000.0 + j)/100000.0 ! obvious bad value for debugging
557 this_data(LANDMASK_INDX)%r2d => file_landmask_data
559 ! Create ESMF_Fields in importState and exportState
560 ! Create ESMF_Grid. Use exactly the same method as WRF so WRFIO will
562 DomainStart(1) = ids; DomainEnd(1) = ide;
563 DomainStart(2) = jds; DomainEnd(2) = jde;
564 MemoryStart(1) = ims; MemoryEnd(1) = ime;
565 MemoryStart(2) = jms; MemoryEnd(2) = jme;
566 PatchStart(1) = ips; PatchEnd(1) = ipe;
567 PatchStart(2) = jps; PatchEnd(2) = jpe
568 !write(0,*)__FILE__,__LINE__,'DomainStart ',DomainStart(1:2)
569 !write(0,*)__FILE__,__LINE__,'DomainEnd ',DomainEnd(1:2)
570 !write(0,*)__FILE__,__LINE__,'MemoryStart ',MemoryStart(1:2)
571 !write(0,*)__FILE__,__LINE__,'MemoryEnd ',MemoryEnd(1:2)
572 !write(0,*)__FILE__,__LINE__,'PatchStart ',PatchStart(1:2)
573 !write(0,*)__FILE__,__LINE__,'PatchEnd ',PatchEnd(1:2)
574 CALL wrf_debug ( 5 , 'DEBUG sst_component_init2: Calling ioesmf_create_grid_int()' )
575 CALL ioesmf_create_grid_int( esmfgrid, NUMDIMS, &
576 DomainStart, DomainEnd, &
577 MemoryStart, MemoryEnd, &
578 PatchStart, PatchEnd )
579 !write(0,*)__FILE__,__LINE__
580 CALL wrf_debug ( 5 , 'DEBUG sst_component_init2: back from ioesmf_create_grid_int()' )
582 ! Note use of patch dimension for POINTERs allocated by ESMF.
583 CALL wrf_debug ( 5 , 'DEBUG sst_component_init2: Calling ESMF_GridValidate(esmfgrid)' )
584 CALL ESMF_GridValidate( esmfgrid, rc=rc )
585 !write(0,*)__FILE__,__LINE__
586 IF ( rc /= ESMF_SUCCESS ) THEN
587 WRITE( str,* ) 'Error in ESMF_GridValidate ', &
592 CALL wrf_error_fatal ( TRIM(str) )
594 CALL wrf_debug ( 5 , 'DEBUG sst_component_init2: back OK from ESMF_GridValidate(esmfgrid)' )
595 !TODO: Once new ESMF 3.0 interfaces have settled down, eliminate "tmp_data_"
596 !TODO: arrays and let ESMF allocate/deallocate them. Assuming of course that
597 !TODO: we can convince ESMF to deallocate safely...
598 !write(0,*)__FILE__,__LINE__
599 ALLOCATE( tmp_data_out_sst(ips:ipe,jps:jpe) )
600 !write(0,*)__FILE__,__LINE__
601 write(str,*) 'sst_component_init2: tmp_data_out_sst(', &
602 LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',',LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2),')'
603 CALL wrf_debug ( 100 , TRIM(str) )
604 CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_sst_field)' )
605 !write(0,*)__FILE__,__LINE__,trim(datanames(sst_indx))
606 !write(0,*)__FILE__,__LINE__,ips,jps,ipe,jpe
607 out_sst_field = ESMF_FieldCreate( &
608 esmfgrid, tmp_data_out_sst, &
609 copyflag=ESMF_DATA_REF, &
610 staggerloc=ESMF_STAGGERLOC_CENTER, &
611 name=TRIM(datanames(SST_INDX)), &
613 !write(0,*)__FILE__,__LINE__,'Creating out_sst_field for exportState of SST component name ',TRIM(datanames(SST_INDX))
614 IF ( rc /= ESMF_SUCCESS ) THEN
615 WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) failed ', &
620 CALL wrf_error_fatal ( TRIM(str) )
622 CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_sst_field)' )
623 write(str,*) 'sst_component_init2: ips:ipe,jps:jpe = ', &
624 ips,':',ipe,',',jps,':',jpe
625 CALL wrf_debug ( 100 , TRIM(str) )
626 !TODO: This bit will be useful once ESMF handles allocation/deallocation.
627 ! validate ESMF allocation
628 IF ( ( ips /= LBOUND(tmp_data_out_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_sst,1) ) .OR. &
629 ( jps /= LBOUND(tmp_data_out_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_sst,2) ) ) THEN
630 WRITE( str,* ) 'ESMF_FieldCreate(out_sst_field) allocation failed ', &
634 ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe, &
635 ', tmp_data_out_sst(BOUNDS) = ',LBOUND(tmp_data_out_sst,1),':',UBOUND(tmp_data_out_sst,1),',', &
636 LBOUND(tmp_data_out_sst,2),':',UBOUND(tmp_data_out_sst,2)
637 CALL wrf_error_fatal ( TRIM(str) )
639 ALLOCATE( tmp_data_out_landmask(ips:ipe,jps:jpe) )
640 write(str,*) 'sst_component_init2: tmp_data_out_landmask(', &
641 LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',',LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2),')'
642 CALL wrf_debug ( 100 , TRIM(str) )
643 CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(out_landmask_field)' )
644 out_landmask_field = ESMF_FieldCreate( &
645 esmfgrid, tmp_data_out_landmask, &
646 copyflag=ESMF_DATA_REF, &
647 staggerloc=ESMF_STAGGERLOC_CENTER, &
648 name=TRIM(datanames(LANDMASK_INDX)), &
649 ! lbounds=(/ips,jps/), &
650 ! ubounds=(/ipe,jpe/), &
652 IF ( rc /= ESMF_SUCCESS ) THEN
653 CALL wrf_error_fatal ( 'ESMF_FieldCreate(out_landmask_field) failed' )
655 CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(out_landmask_field)' )
656 !TODO: This bit will be useful once ESMF handles allocation/deallocation.
657 ! validate ESMF allocation
658 IF ( ( ips /= LBOUND(tmp_data_out_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_out_landmask,1) ) .OR. &
659 ( jps /= LBOUND(tmp_data_out_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_out_landmask,2) ) ) THEN
660 WRITE( str,* ) 'ESMF_FieldCreate(out_landmask_field) allocation failed ', &
664 ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe, &
665 ', tmp_data_out_landmask(BOUNDS) = ',LBOUND(tmp_data_out_landmask,1),':',UBOUND(tmp_data_out_landmask,1),',', &
666 LBOUND(tmp_data_out_landmask,2),':',UBOUND(tmp_data_out_landmask,2)
667 CALL wrf_error_fatal ( TRIM(str) )
669 ALLOCATE( tmp_data_in_sst(ips:ipe,jps:jpe) )
670 write(str,*) 'sst_component_init2: tmp_data_in_sst(', &
671 LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',',LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2),')'
672 CALL wrf_debug ( 100 , TRIM(str) )
673 CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_sst_field)' )
674 in_sst_field = ESMF_FieldCreate( &
675 esmfgrid, tmp_data_in_sst, &
676 copyflag=ESMF_DATA_REF, &
677 staggerloc=ESMF_STAGGERLOC_CENTER, &
678 name=TRIM(datanames(SST_INDX)), &
679 ! lbounds=(/ips,jps/), &
680 ! ubounds=(/ipe,jpe/), &
682 IF ( rc /= ESMF_SUCCESS ) THEN
683 CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_sst_field) failed' )
685 CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_sst_field)' )
686 !TODO: This bit will be useful once ESMF handles allocation/deallocation.
687 ! validate ESMF allocation
688 IF ( ( ips /= LBOUND(tmp_data_in_sst,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_sst,1) ) .OR. &
689 ( jps /= LBOUND(tmp_data_in_sst,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_sst,2) ) ) THEN
690 WRITE( str,* ) 'ESMF_FieldCreate(in_sst_field) allocation failed ', &
694 ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe, &
695 ', tmp_data_in_sst(BOUNDS) = ',LBOUND(tmp_data_in_sst,1),':',UBOUND(tmp_data_in_sst,1),',', &
696 LBOUND(tmp_data_in_sst,2),':',UBOUND(tmp_data_in_sst,2)
697 CALL wrf_error_fatal ( TRIM(str) )
699 ALLOCATE( tmp_data_in_landmask(ips:ipe,jps:jpe) )
700 write(str,*) 'sst_component_init2: tmp_data_in_landmask(', &
701 LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',',LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2),')'
702 CALL wrf_debug ( 100 , TRIM(str) )
703 CALL wrf_debug ( 100, 'sst_component_init2: calling ESMF_FieldCreate(in_landmask_field)' )
704 in_landmask_field = ESMF_FieldCreate( &
705 esmfgrid, tmp_data_in_landmask, &
706 copyflag=ESMF_DATA_REF, &
707 staggerloc=ESMF_STAGGERLOC_CENTER, &
708 name=TRIM(datanames(LANDMASK_INDX)), &
709 ! lbounds=(/ips,jps/), &
710 ! ubounds=(/ipe,jpe/), &
712 IF ( rc /= ESMF_SUCCESS ) THEN
713 CALL wrf_error_fatal ( 'ESMF_FieldCreate(in_landmask_field) failed' )
715 CALL wrf_debug ( 100, 'sst_component_init2: back from ESMF_FieldCreate(in_landmask_field)' )
716 !TODO: This bit will be useful once ESMF handles allocation/deallocation.
717 ! validate ESMF allocation
718 IF ( ( ips /= LBOUND(tmp_data_in_landmask,1) ) .OR. ( ipe /= UBOUND(tmp_data_in_landmask,1) ) .OR. &
719 ( jps /= LBOUND(tmp_data_in_landmask,2) ) .OR. ( jpe /= UBOUND(tmp_data_in_landmask,2) ) ) THEN
720 WRITE( str,* ) 'ESMF_FieldCreate(in_landmask_field) allocation failed ', &
724 ', ips:ipe,jps:jpe = ',ips,':',ipe,',',jps,':',jpe, &
725 ', tmp_data_in_landmask(BOUNDS) = ',LBOUND(tmp_data_in_landmask,1),':',UBOUND(tmp_data_in_landmask,1),',', &
726 LBOUND(tmp_data_in_landmask,2),':',UBOUND(tmp_data_in_landmask,2)
727 CALL wrf_error_fatal ( TRIM(str) )
730 ! attach ESMF_Field to importState
731 CALL ESMF_StateAdd( importState, in_sst_field, rc=rc )
732 IF ( rc /= ESMF_SUCCESS ) THEN
733 CALL wrf_error_fatal ( 'ESMF_StateAdd(in_sst_field) failed' )
735 CALL ESMF_StateAdd( importState, in_landmask_field, rc=rc )
736 IF ( rc /= ESMF_SUCCESS ) THEN
737 CALL wrf_error_fatal ( 'ESMF_StateAdd(in_landmask_field) failed' )
739 ! attach ESMF_Field to exportState
740 CALL ESMF_StateAdd( exportState, out_sst_field, rc=rc )
741 IF ( rc /= ESMF_SUCCESS ) THEN
742 CALL wrf_error_fatal ( 'ESMF_StateAdd(out_sst_field) failed' )
744 CALL ESMF_StateAdd( exportState, out_landmask_field, rc=rc )
745 IF ( rc /= ESMF_SUCCESS ) THEN
746 CALL wrf_error_fatal ( 'ESMF_StateAdd(out_landmask_field) failed' )
749 ! Open the "SST" input data file for reading.
750 write(str,'(A,A)') 'sst_component_init2: Opening data file ', &
752 CALL wrf_message ( TRIM(str) )
753 CALL wrf_open_for_read ( TRIM(sstinfilename) , &
759 IF ( ierr .NE. 0 ) THEN
760 WRITE( str , FMT='(A,A,A,I8)' ) &
761 'sst_component_init2: error opening ', &
762 TRIM(sstinfilename),' for reading ierr=',ierr
763 CALL wrf_error_fatal ( TRIM(str) )
765 WRITE( str , FMT='(A,A,A,I8)' ) &
766 'subroutine sst_component_init2: opened file ', &
767 TRIM(sstinfilename),' for reading fid=',fid
768 CALL wrf_debug ( 100, TRIM(str) )
770 write(str,'(A)') 'sst_component_init2: returning rc=ESMF_SUCCESS'
771 CALL wrf_debug ( 100 , TRIM(str) )
775 END SUBROUTINE sst_component_init2
779 SUBROUTINE sst_component_run1( gcomp, importState, exportState, clock, rc )
780 TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
781 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: importState, exportState
782 TYPE(ESMF_Clock), TARGET, INTENT(INOUT) :: clock
783 INTEGER, INTENT( OUT) :: rc
785 ! SST component run routine, phase 1.
786 ! Read "SST" data from file and stuff into exportState.
790 ! importState Importstate
791 ! exportState Exportstate
792 ! clock External clock
793 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
794 ! otherwise ESMF_FAILURE.
799 ! Get "SST" data from file and stuff it into exportState.
800 CALL read_data( exportState, clock )
802 END SUBROUTINE sst_component_run1
806 SUBROUTINE sst_component_run2( gcomp, importState, exportState, clock, rc )
807 TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
808 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: importState, exportState
809 TYPE(ESMF_Clock), TARGET, INTENT(INOUT) :: clock
810 INTEGER, INTENT( OUT) :: rc
812 ! SST component run routine, phase 2.
813 ! Get from importState, compare with file data, and error-exit
814 ! if they differ... If they are the same, then
815 ! stuff the file data into the exportState.
819 ! importState Importstate
820 ! exportState Exportstate
821 ! clock External clock
822 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
823 ! otherwise ESMF_FAILURE.
828 ! Get from importState, compare with file data, and error_exit
830 !TODO: change this once WRF can load exportState after integrating
831 ! This works because WRF loads its exportState BEFORE integrating.
832 CALL wrf_clockprint ( 50, clock, 'sst_component_run2: clock before call to compare_data()' )
833 CALL compare_data( importState, clock )
834 CALL wrf_clockprint ( 50, clock, 'sst_component_run2: clock after call to compare_data()' )
836 END SUBROUTINE sst_component_run2
840 SUBROUTINE sst_component_finalize( gcomp, importState, exportState, clock, rc )
842 TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
843 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: importState, exportState
844 TYPE(ESMF_Clock), TARGET, INTENT(INOUT) :: clock
845 INTEGER, INTENT( OUT) :: rc
847 ! SST component finalize routine.
851 ! importState Importstate
852 ! exportState Exportstate
853 ! clock External clock
854 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
855 ! otherwise ESMF_FAILURE.
859 TYPE(ESMF_Field) :: tmp_field
864 ! destroy ESMF_Fields and other "deep" objects created by this component
865 ! note that this component relied on ESMF to allocate data pointers during
866 ! calls to ESMF_FieldCreate() so it also expects ESMF to free these pointers
868 ! destroy field in importState
869 CALL ESMF_StateGet( importState, TRIM(datanames(i)), tmp_field, &
871 IF (rc /= ESMF_SUCCESS) THEN
873 'sst_component_finalize: ESMF_StateGet( importState,', &
874 TRIM(datanames(i)),') failed'
875 CALL wrf_error_fatal ( TRIM(str) )
877 CALL ESMF_FieldDestroy( tmp_field, rc=rc )
878 IF (rc /= ESMF_SUCCESS) THEN
880 'sst_component_finalize: ESMF_FieldDestroy( importState,', &
881 TRIM(datanames(i)),') failed'
882 CALL wrf_error_fatal ( TRIM(str) )
884 ! destroy field in exportState
885 CALL ESMF_StateGet( exportState, TRIM(datanames(i)), tmp_field, &
887 IF (rc /= ESMF_SUCCESS) THEN
889 'sst_component_finalize: ESMF_StateGet( exportState,', &
890 TRIM(datanames(i)),') failed'
891 CALL wrf_error_fatal ( TRIM(str) )
893 CALL ESMF_FieldDestroy( tmp_field, rc=rc )
894 IF (rc /= ESMF_SUCCESS) THEN
896 'sst_component_finalize: ESMF_FieldDestroy( exportState,', &
897 TRIM(datanames(i)),') failed'
898 CALL wrf_error_fatal ( TRIM(str) )
902 ! deallocate space for data read from disk
903 DEALLOCATE( file_sst_data, file_landmask_data )
905 ! close SST data file
906 WRITE( str , FMT='(A,I8)' ) &
907 'subroutine sst_component_finalize: closing file fid=',fid
908 CALL wrf_debug ( 100, TRIM(str) )
909 CALL wrf_ioclose( fid , ierr )
910 IF ( ierr .NE. 0 ) THEN
911 CALL wrf_error_fatal ( 'sst_component_finalize: wrf_ioclose failed' )
914 END SUBROUTINE sst_component_finalize
917 END MODULE module_sst_component_top
922 MODULE module_sst_setservices
924 ! This module defines SST "Set Services" method sst_register()
925 ! used for ESMF coupling.
928 USE module_sst_component_top, ONLY: sst_component_init1, &
929 sst_component_init2, &
930 sst_component_run1, &
931 sst_component_run2, &
932 sst_component_finalize
937 ! everything is private by default
940 ! Public entry point for ESMF_GridCompSetServices()
944 CHARACTER (ESMF_MAXSTR) :: str
949 SUBROUTINE sst_register(gcomp, rc)
950 TYPE(ESMF_GridComp), INTENT(INOUT) :: gcomp
951 INTEGER, INTENT(OUT) :: rc
955 ! SST_register - Externally visible registration routine
957 ! User-supplied SetServices routine.
958 ! The Register routine sets the subroutines to be called
959 ! as the init, run, and finalize routines. Note that these are
960 ! private to the module.
964 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
965 ! otherwise ESMF_FAILURE.
968 finalrc = ESMF_SUCCESS
969 ! Register the callback routines.
970 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
971 sst_component_init1, 1, rc)
972 IF ( rc /= ESMF_SUCCESS) THEN
973 WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init1) failed with rc = ', rc
974 CALL wrf_error_fatal ( TRIM(str) )
976 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
977 sst_component_init2, 2, rc)
978 IF ( rc /= ESMF_SUCCESS) THEN
979 WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_init2) failed with rc = ', rc
980 CALL wrf_error_fatal ( TRIM(str) )
982 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETRUN, &
983 sst_component_run1, 1, rc)
984 IF ( rc /= ESMF_SUCCESS) THEN
985 WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run1) failed with rc = ', rc
986 CALL wrf_error_fatal ( TRIM(str) )
988 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETRUN, &
989 sst_component_run2, 2, rc)
990 IF ( rc /= ESMF_SUCCESS) THEN
991 WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_run2) failed with rc = ', rc
992 CALL wrf_error_fatal ( TRIM(str) )
994 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETFINAL, &
995 sst_component_finalize, ESMF_SINGLEPHASE, rc)
996 IF ( rc /= ESMF_SUCCESS) THEN
997 WRITE(str,*) 'ESMF_GridCompSetEntryPoint(sst_component_finalize) failed with rc = ', rc
998 CALL wrf_error_fatal ( TRIM(str) )
1001 PRINT *,'SST: Registered Initialize, Run, and Finalize routines'
1005 END SUBROUTINE sst_register
1007 END MODULE module_sst_setservices
1012 ! Module module_wrfsst_coupler defines the
1013 ! "WRF-SST" coupler component. It provides two-way coupling between
1014 ! the "SST" and "WRF" components.
1015 ! In its run routine it transfers data directly from the
1016 ! SST Component's export state to the WRF Component's import state.
1017 ! It also transfers data directly from the
1018 ! WRF Component's export state to the SST Component's import state.
1020 ! This is derived from src/demo/coupled_flow/src/CouplerMod.F90
1021 ! created by Nancy Collins and others on the ESMF Core Team.
1025 MODULE module_wrfsst_coupler
1031 ! everything is private by default
1034 ! Public entry point
1035 PUBLIC WRFSSTCpl_register
1037 ! private data members
1038 ! route handles and flags
1039 TYPE(ESMF_RouteHandle), SAVE :: fromWRF_rh, fromSST_rh
1040 LOGICAL, SAVE :: fromWRF_rh_ready = .FALSE.
1041 LOGICAL, SAVE :: fromSST_rh_ready = .FALSE.
1043 INTEGER, PARAMETER :: datacount = 2
1044 INTEGER, PARAMETER :: SST_INDX = 1
1045 INTEGER, PARAMETER :: LANDMASK_INDX = 2
1046 CHARACTER(LEN=ESMF_MAXSTR), SAVE :: datanames(datacount)
1047 CHARACTER(LEN=ESMF_MAXSTR) :: str
1053 SUBROUTINE WRFSSTCpl_register(comp, rc)
1054 TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1055 INTEGER, INTENT(OUT) :: rc
1058 ! WRFSSTCpl_register - Externally visible registration routine
1060 ! User-supplied SetServices routine.
1061 ! The Register routine sets the subroutines to be called
1062 ! as the init, run, and finalize routines. Note that these are
1063 ! private to the module.
1065 ! The arguments are:
1067 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
1068 ! otherwise ESMF_FAILURE.
1071 ! guilty until proven innocent
1074 ! Register the callback routines.
1076 call ESMF_CplCompSetEntryPoint(comp, ESMF_SETINIT, WRFSSTCpl_init, &
1077 ESMF_SINGLEPHASE, rc)
1078 IF ( rc /= ESMF_SUCCESS ) THEN
1079 CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_init) failed' )
1081 call ESMF_CplCompSetEntryPoint(comp, ESMF_SETRUN, WRFSSTCpl_run, &
1082 ESMF_SINGLEPHASE, rc)
1083 IF ( rc /= ESMF_SUCCESS ) THEN
1084 CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_run) failed' )
1086 call ESMF_CplCompSetEntryPoint(comp, ESMF_SETFINAL, WRFSSTCpl_final, &
1087 ESMF_SINGLEPHASE, rc)
1088 IF ( rc /= ESMF_SUCCESS ) THEN
1089 CALL wrf_error_fatal ( 'ESMF_CplCompSetEntryPoint(WRFSSTCpl_final) failed' )
1092 print *, "module_wrfsst_coupler: Registered Initialize, Run, and Finalize routines"
1094 END SUBROUTINE WRFSSTCpl_register
1097 SUBROUTINE WRFSSTCpl_init(comp, importState, exportState, clock, rc)
1098 USE module_metadatautils, ONLY: AttachDecompToState, GetDecompFromState
1099 TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1100 TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1101 TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1102 INTEGER, INTENT(OUT) :: rc
1104 ! WRF-SST coupler component init routine. This simply passes needed
1105 ! metadata from WRF to SST. Initialization of ESMF_RouteHandle objects
1106 ! is handled later via lazy evaluation.
1108 ! The arguments are:
1110 ! importState Importstate
1111 ! exportState Exportstate
1112 ! clock External clock
1113 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
1114 ! otherwise ESMF_FAILURE.
1118 CHARACTER(ESMF_MAXSTR) :: importstatename
1119 ! decomposition information
1120 INTEGER :: ids, ide, jds, jde, kds, kde
1121 INTEGER :: ims, ime, jms, jme, kms, kme
1122 INTEGER :: ips, ipe, jps, jpe, kps, kpe
1124 LOGICAL :: bdy_mask(4)
1126 PRINT *, "DEBUG: Coupler Init starting"
1128 ! guilty until proven innocent
1131 CALL ESMF_StateGet(importState, name=importstatename, rc=rc)
1132 IF ( rc /= ESMF_SUCCESS ) THEN
1133 CALL wrf_error_fatal ( 'WRFSSTCpl_init: ESMF_StateGet failed' )
1136 IF ( TRIM(importstatename) .EQ. "WRF Export State" ) THEN
1137 ! get metadata from WRF export state
1138 CALL GetDecompFromState( importState, &
1139 ids, ide, jds, jde, kds, kde, &
1140 ims, ime, jms, jme, kms, kme, &
1141 ips, ipe, jps, jpe, kps, kpe, &
1143 ! put metadata from in SST import state
1144 CALL AttachDecompToState( exportState, &
1145 ids, ide, jds, jde, kds, kde, &
1146 ims, ime, jms, jme, kms, kme, &
1147 ips, ipe, jps, jpe, kps, kpe, &
1152 CALL wrf_error_fatal ( 'WRFSSTCpl_init: invalid importState name' )
1155 ! set up field names
1156 !TODO: use CF conventions for "standard_name" once WRF Registry supports them
1157 !TODO: datanames(SST_INDX) = "sea_surface_temperature"
1158 !TODO: datanames(LANDMASK_INDX) = "land_binary_mask"
1159 datanames(SST_INDX) = "SST"
1160 datanames(LANDMASK_INDX) = "LANDMASK"
1162 PRINT *, "DEBUG: Coupler Init returning"
1164 END SUBROUTINE WRFSSTCpl_init
1168 SUBROUTINE WRFSSTCpl_run(comp, importState, exportState, clock, rc)
1169 TYPE(ESMF_CplComp), INTENT(INOUT) :: comp
1170 TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1171 TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1172 INTEGER, INTENT(OUT) :: rc
1174 ! WRF-SST coupler component run routine.
1176 ! The arguments are:
1178 ! importState Importstate
1179 ! exportState Exportstate
1180 ! clock External clock
1181 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
1182 ! otherwise ESMF_FAILURE.
1185 ! Note that comments in this code are preserved from the sample coupler
1186 ! provided by the ESMF core team.
1189 character*256 :: mename
1190 character*256 :: melist(100)
1192 TYPE(ESMF_StateItemType) :: metypelist(100)
1193 TYPE(ESMF_Field) :: src_field, dst_field
1194 TYPE(ESMF_Array) :: src_array, dst_array
1195 TYPE(ESMF_RouteHandle) :: routehandle
1197 LOGICAL :: build_fromWRF_rh, build_fromSST_rh, fromWRF
1198 CHARACTER(LEN=ESMF_MAXSTR) :: importStatename
1199 CHARACTER(LEN=ESMF_MAXSTR) :: SST_exportStatename, WRF_exportStatename
1201 CHARACTER(LEN=256) :: directionString
1203 WRITE(str,*) 'WRFSSTCpl_run: begin'
1204 CALL wrf_debug ( 100 , TRIM(str) )
1206 ! guilty until proven innocent
1209 ! Which way is this coupling going?
1210 WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateGet(importState,name,...)'
1211 CALL wrf_debug ( 100 , TRIM(str) )
1212 CALL ESMF_StateGet( importState, name=importStatename, rc=rc )
1213 !write(0,*)__FILE__,__LINE__, 'importStatename ', trim(importStatename), 'rc = ', rc
1214 IF ( rc /= ESMF_SUCCESS ) THEN
1215 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_StateGet(importState,name,...) failed' )
1217 WRITE(str,*) 'WRFSSTCpl_run: back from ESMF_StateGet, importStatename = <',TRIM(importStatename),'>'
1218 CALL wrf_debug ( 100 , TRIM(str) )
1220 ! first time through in each direction: create route handle and
1221 ! associated objects
1222 WRF_exportStatename = "WRF Export State"
1223 SST_exportStatename = "SST Export State"
1224 IF ( TRIM(importStatename) .EQ. TRIM(WRF_exportStatename) ) THEN
1226 directionString = 'WRFtoSST'
1227 ELSE IF ( TRIM(importStatename) .EQ. TRIM(SST_exportStatename) ) THEN
1229 directionString = 'SSTtoWRF'
1231 CALL wrf_error_fatal ( 'WRFSSTCpl_run: invalid importState name' )
1233 WRITE(str,*) 'WRFSSTCpl_run: fromWRF = ',fromWRF
1234 CALL wrf_debug ( 100 , TRIM(str) )
1235 build_fromWRF_rh = fromWRF .AND. ( .NOT. fromWRF_rh_ready )
1236 build_fromSST_rh = ( .NOT. fromWRF ) .AND. ( .NOT. fromSST_rh_ready )
1237 WRITE(str,*) 'WRFSSTCpl_run: build_fromWRF_rh = ',build_fromWRF_rh
1238 CALL wrf_debug ( 100 , TRIM(str) )
1239 WRITE(str,*) 'WRFSSTCpl_run: build_fromSST_rh = ',build_fromSST_rh
1240 CALL wrf_debug ( 100 , TRIM(str) )
1241 IF ( build_fromWRF_rh .OR. build_fromSST_rh ) THEN
1242 CALL ESMF_CplCompGet( comp, vm=vm, rc=rc )
1243 IF ( rc /= ESMF_SUCCESS ) THEN
1244 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_CplCompGet failed' )
1246 ! The use of literal index "1" here indicates that we don't care which
1247 ! ESMF_Field we get so we might as well get the first one.
1248 WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1249 '> from import state'
1250 CALL wrf_debug ( 100 , TRIM(str) )
1252 CALL ESMF_StateGet( importState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1253 !write(0,*)'importState mename ',trim(mename)
1254 !write(0,*)'importState mecount ',mecount
1256 !write(0,*)i,trim(melist(i))
1259 !write(0,*)i,metypelist(i)
1262 CALL ESMF_StateGet( importState, TRIM(datanames(1)), src_field, &
1264 !write(0,*)__FILE__,__LINE__, 'from importState: datanames(1) ', TRIM(datanames(1)), ' rc = ', rc
1265 IF ( rc /= ESMF_SUCCESS ) THEN
1266 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_StateGet(importState) failed' )
1269 CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1270 !write(0,*)__FILE__,__LINE__, 'from fieldget: rc = ', rc
1271 IF ( rc /= ESMF_SUCCESS ) THEN
1272 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_FieldGet src_array failed' )
1274 WRITE(str,*) 'WRFSSTCpl_run: grabbing first field <',TRIM(datanames(1)), &
1275 '> from export state'
1276 CALL wrf_debug ( 100 , TRIM(str) )
1278 CALL ESMF_StateGet( exportState, name=mename, itemCount=mecount, itemNameList=melist, stateitemtypelist=metypelist, rc=rc )
1279 !write(0,*)'Exportstate mename ',trim(mename)
1280 !write(0,*)'Exportstate mecount ',mecount
1282 !write(0,*)i,trim(melist(i))
1285 !write(0,*)i,metypelist(i)
1288 CALL ESMF_StateGet( exportState, TRIM(datanames(1)), dst_field, &
1290 IF ( rc /= ESMF_SUCCESS ) THEN
1291 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_StateGet(exportState) failed' )
1293 CALL ESMF_FieldGet( dst_field, array=dst_array, &
1295 IF ( rc /= ESMF_SUCCESS ) THEN
1296 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_FieldGet dst_array failed' )
1301 IF ( build_fromWRF_rh ) THEN
1302 WRITE(str,*) 'WRFSSTCpl_run: creating fromWRF_rh'
1303 CALL wrf_debug ( 100 , TRIM(str) )
1304 fromWRF_rh = ESMF_RouteHandleCreate( rc )
1305 IF ( rc /= ESMF_SUCCESS ) THEN
1306 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_RouteHandleCreate(fromWRF_rh) failed' )
1308 WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromWRF_rh)'
1309 CALL wrf_debug ( 100 , TRIM(str) )
1310 CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1311 routehandle=fromWRF_rh, rc=rc )
1312 IF ( rc /= ESMF_SUCCESS ) THEN
1313 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_FieldRedistStore(fromWRF_rh) failed' )
1315 fromWRF_rh_ready = .TRUE.
1317 IF ( build_fromSST_rh ) THEN
1318 WRITE(str,*) 'WRFSSTCpl_run: creating fromSST_rh'
1319 CALL wrf_debug ( 100 , TRIM(str) )
1320 fromSST_rh = ESMF_RouteHandleCreate( rc )
1321 IF ( rc /= ESMF_SUCCESS ) THEN
1322 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_RouteHandleCreate(fromSST_rh) failed' )
1324 WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedistStore(fromSST_rh)'
1325 CALL wrf_debug ( 100 , TRIM(str) )
1326 CALL ESMF_ArrayRedistStore( src_array, dst_array, &
1327 routehandle=fromSST_rh, rc=rc )
1328 !write(0,*)__FILE__,__LINE__,'rc = ',rc
1329 IF ( rc /= ESMF_SUCCESS ) THEN
1330 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_FieldRedistStore(fromSST_rh) failed' )
1332 fromSST_rh_ready = .TRUE.
1335 WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateSetNeeded(importState, ',TRIM(datanames(i)),')'
1336 CALL wrf_debug ( 100 , TRIM(str) )
1337 CALL ESMF_StateSetNeeded( importState, TRIM(datanames(i)), &
1338 ESMF_NEEDED, rc=rc )
1339 IF ( rc /= ESMF_SUCCESS ) THEN
1340 WRITE(str,*) 'WRFSSTCpl_run: ESMF_StateSetNeeded(',TRIM(datanames(i)),') failed'
1341 CALL wrf_error_fatal ( str )
1346 ! In this case, the coupling is symmetric - you call redist going
1347 ! both ways - so we only care about the coupling direction in order
1348 ! to get the right routehandle selected.
1350 WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromWRF_rh'
1351 CALL wrf_debug ( 100 , TRIM(str) )
1352 routehandle = fromWRF_rh
1354 WRITE(str,*) 'WRFSSTCpl_run: routehandle = fromSST_rh'
1355 CALL wrf_debug ( 100 , TRIM(str) )
1356 routehandle = fromSST_rh
1360 WRITE(str,*) 'WRFSSTCpl_run: grabbing field <',TRIM(datanames(i)),'>'
1361 CALL wrf_debug ( 100 , TRIM(str) )
1362 ! check isneeded flag here
1363 IF ( .NOT. ESMF_StateIsNeeded( importState, TRIM(datanames(i)), rc=rc ) ) THEN
1364 IF ( rc /= ESMF_SUCCESS ) THEN
1365 WRITE(str,*) 'WRFSSTCpl_run: ESMF_StateIsNeeded(',TRIM(datanames(i)),') failed'
1366 CALL wrf_error_fatal ( str )
1368 WRITE(str,*) 'WRFSSTCpl_run: skipping field <',TRIM(datanames(i)),'>'
1369 CALL wrf_debug ( 100 , TRIM(str) )
1373 WRITE(str,*) 'WRFSSTCpl_run: processing field <',TRIM(datanames(i)),'>'
1374 CALL wrf_debug ( 100 , TRIM(str) )
1376 ! The following piece of code provides an example of calling the data
1377 ! redistribution routine between two Fields in the Coupler Component.
1378 ! Unlike regrid, which translates between
1379 ! different Grids, redist translates between different DELayouts on
1380 ! the same Grid. The first two lines get the Fields from the
1381 ! States, each corresponding to a different subcomponent. One is
1382 ! an Export State and the other is an Import State.
1384 WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateGet(importState,', &
1385 TRIM(datanames(i)),')...'
1386 CALL wrf_debug ( 100 , TRIM(str) )
1387 CALL ESMF_StateGet( importState, TRIM(datanames(i)), src_field, &
1389 IF ( rc /= ESMF_SUCCESS ) THEN
1390 WRITE(str,*) 'WRFSSTCpl_run: ESMF_StateGet(importState,', &
1391 TRIM(datanames(i)),') failed'
1392 CALL wrf_error_fatal ( str )
1394 CALL ESMF_FieldGet( src_field, array=src_array, rc=rc )
1395 IF ( rc /= ESMF_SUCCESS ) THEN
1396 WRITE(str,*) 'WRFSSTCpl_run: ESMF_FieldGet(src_field,src_array,rc) failed'
1397 CALL wrf_error_fatal ( str )
1400 WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_StateGet(exportState,', &
1401 TRIM(datanames(i)),')...'
1402 CALL wrf_debug ( 100 , TRIM(str) )
1403 CALL ESMF_StateGet( exportState, TRIM(datanames(i)), dst_field, &
1405 IF ( rc /= ESMF_SUCCESS ) THEN
1406 WRITE(str,*) 'WRFSSTCpl_run: ESMF_StateGet(exportState,', &
1407 TRIM(datanames(i)),') failed'
1408 CALL wrf_error_fatal ( str )
1410 CALL ESMF_FieldGet( dst_field, array=dst_array, rc=rc )
1411 IF ( rc /= ESMF_SUCCESS ) THEN
1412 WRITE(str,*) 'WRFSSTCpl_run: ESMF_FieldGet(dst_field,dst_array,rc) failed'
1413 CALL wrf_error_fatal ( str )
1416 ! The redist routine uses information contained in the Fields and the
1417 ! Coupler VM object to call the communication routines to move the data.
1418 ! Because many Fields may share the same Grid association, the same
1419 ! routing information may be needed repeatedly. Route information is
1420 ! saved so the precomputed information can be retained. The following
1421 ! is an example of a Field redist call:
1422 WRITE(str,*) 'WRFSSTCpl_run: calling ESMF_FieldRedist for <', &
1423 TRIM(datanames(i)),'>...'
1424 CALL wrf_debug ( 100 , TRIM(str) )
1425 CALL ESMF_ArrayRedist( src_array, dst_array, routehandle, rc=rc )
1426 IF ( rc /= ESMF_SUCCESS ) THEN
1427 CALL wrf_error_fatal ( 'WRFSSTCpl_run: ESMF_FieldRedist failed' )
1429 WRITE(str,*) 'WRFSSTCpl_run: back from ESMF_FieldRedist for <', &
1430 TRIM(datanames(i)),'>...'
1431 CALL wrf_debug ( 100 , TRIM(str) )
1435 WRITE(str,*) 'WRFSSTCpl_run: end'
1436 CALL wrf_debug ( 100 , TRIM(str) )
1438 END SUBROUTINE WRFSSTCpl_run
1442 SUBROUTINE WRFSSTCpl_final(comp, importState, exportState, clock, rc)
1443 TYPE(ESMF_CplComp) :: comp
1444 TYPE(ESMF_State), INTENT(INOUT) :: importState, exportState
1445 TYPE(ESMF_Clock), INTENT(INOUT) :: clock
1446 INTEGER, INTENT(OUT) :: rc
1448 ! WRF-SST coupler component finalize routine.
1450 ! The arguments are:
1452 ! importState Importstate
1453 ! exportState Exportstate
1454 ! clock External clock
1455 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
1456 ! otherwise ESMF_FAILURE.
1459 PRINT *, "DEBUG: Coupler Final starting"
1461 ! guilty until proven innocent
1464 ! Only thing to do here is release redist and route handles
1465 IF ( fromWRF_rh_ready ) THEN
1466 CALL ESMF_RouteHandleDestroy(fromWRF_rh, rc)
1467 IF ( rc /= ESMF_SUCCESS ) THEN
1468 CALL wrf_error_fatal ( 'WRFSSTCpl_final: ESMF_RouteHandleDestroy(fromWRF_rh) failed' )
1471 IF ( fromSST_rh_ready ) THEN
1472 CALL ESMF_RouteHandleDestroy(fromSST_rh, rc)
1473 IF ( rc /= ESMF_SUCCESS ) THEN
1474 CALL wrf_error_fatal ( 'WRFSSTCpl_final: ESMF_RouteHandleDestroy(fromSST_rh) failed' )
1478 PRINT *, "DEBUG: Coupler Final returning"
1480 END SUBROUTINE WRFSSTCpl_final
1483 END MODULE module_wrfsst_coupler
1488 PROGRAM wrf_SST_ESMF
1491 ! ESMF Application Wrapper for coupling WRF with a "dummy" component
1492 ! that simply reads SSTs from a file and sends them to WRF (one-way
1493 ! coupling). Fields are returned from WRF to SST via the coupler for
1496 ! Note that, like other WRF coupling methods (MCEL, MCT), ESMF coupling is
1497 ! supported only via auxiliary input and history streams.
1499 ! This is the main program that creates the ESMF Gridded and Coupler
1502 ! "init" looks like this:
1503 ! 1. Init phase 1 for WRF, sets WRF exportState metadata for "time"
1504 ! and "domain" information needed by WRF IOAPI (which is called from
1505 ! the SST component). It also sets up all WRF and WSF modules. Note
1506 ! that this must be called before SST phase-1 init because SST uses
1508 ! 2. Init phase 1 for SST, sets "time" metadata in SST exportState.
1509 ! 3. Initialize coupler, passing decomposition metadata from WRF exportState
1510 ! to SST importState.
1511 ! 4. Resolve any "time" metadata inconsistencies and create top-level clock.
1512 ! 5. Init phase 2 for SST, gets "domain" information from importState,
1513 ! creates an ESMF_Grid based on "domain" information using the exact same
1514 ! method as WRF (so WRF IOAPI calls will work), and sets up SST
1515 ! importState and exportState.
1516 ! 6. Init phase 2 for WRF, runs up to the end of the head_grid I/O "training"
1517 ! phase (done in med_before_solve_io()). This initializes WRF
1518 ! importState and exportState prior to the first coupling step during the
1519 ! "run" loop. Note that this only works for head_grid at present because
1520 ! recursion in WRF traversal of subdomains is not dealt with yet and
1521 ! because the code that populates the WRF importState and exportState is
1522 ! not yet sophisticated enough to handle creating and destroying nested
1523 ! domains at any time during the model run.
1524 !TODO: ESMF auxio must begin at the start of the run. Remove this
1525 !TODO: restriction later, if needed.
1527 !TODO: Note that coupling is currently limited to one auxin plus one auxout
1528 !TODO: streams. Extension to multiple pairs of auxio streams requires
1529 !TODO: nested states (one for each auxio stream pair).
1530 !TODO: For now, only support one input and/or one output stream via
1531 !TODO: io_esmf. This condition is asserted in
1532 !TODO: ext_esmf_open_for_read_begin() and
1533 !TODO: ext_esmf_open_for_write_begin().
1535 ! "run" loop looks like this:
1536 ! 1. Run SST phase 1, reads SST from file and writes it to SST exportState
1537 ! for coupling to WRF.
1538 ! 2. Couple SST exportState -> WRF importState. First iteration: set up
1539 ! SST->WRF routeHandle via lazy evaluation.
1540 ! 3. Run WRF. First iteration: head_grid resumes after I/O "training"
1541 ! phase. Other iterations and domains: run normally.
1542 ! Read WRF importState and write WRF exportState (via med_before_solve_io()).
1543 ! Note that WRF assigns sst -> tsk for sea points in
1544 ! share/module_soil_pre.F.
1545 ! 4. Couple WRF exportState -> SST importState. First iteration: set up
1546 ! WRF->SST routeHandle via lazy evaluation.
1547 ! 5. Run SST phase 2, compare SST from file with SST from WRF (via
1548 ! SST importState) and error-exit if they differ.
1549 ! 6. Advance clock and goto step 1
1551 ! "finalize" is trivial, except for destruction of ESMF objects which is
1552 ! quite non-trivial at the moment.
1556 ! WRF registration routine
1557 USE module_wrf_setservices, ONLY: WRF_register
1558 ! SST registration routine
1559 USE module_sst_setservices, ONLY: SST_register
1560 ! WRF-SST coupler registration routine
1561 USE module_wrfsst_coupler, ONLY: WRFSSTCpl_register
1562 ! ESMF module, defines all ESMF data types and procedures
1564 ! Not-yet-implemented ESMF features
1565 USE module_esmf_extensions
1566 ! Component-independent utilities
1567 USE module_metadatautils, ONLY: GetTimesFromStates
1574 TYPE(ESMF_GridComp) :: compGriddedWRF ! WRF
1575 TYPE(ESMF_GridComp) :: compGriddedSST ! SST reader
1576 TYPE(ESMF_CplComp) :: compCplWRFSST ! WRF-SST coupler
1578 ! State, Virtual Machine, and DELayout
1580 TYPE(ESMF_State) :: importStateWRF, exportStateWRF
1581 TYPE(ESMF_State) :: importStateSST, exportStateSST
1583 ! A clock, some times, and a time step
1584 TYPE(ESMF_Clock) :: driverClock
1585 TYPE(ESMF_Time) :: startTime
1586 TYPE(ESMF_Time) :: stopTime
1587 TYPE(ESMF_TimeInterval) :: couplingInterval
1590 TYPE(ESMF_State) :: tmpState
1591 INTEGER :: timestepdebug
1592 INTEGER :: thecount ! ah ah ah
1594 ! Return codes for error checks
1596 CHARACTER (ESMF_MAXSTR) :: str
1599 CHARACTER(LEN=256) :: couplingIntervalString
1600 integer(ESMF_KIND_I4) :: timevals(6)
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'
1615 ! Note: wrf_debug and wrf_error_fatal are not initialized yet
1616 PRINT *, 'DEBUG wrf_SST_ESMF: returned from ESMF_Initialize'
1617 CALL ESMF_SetInitialized() ! eliminate this once ESMF does it internally
1619 ! Create the WRF Gridded Component, passing in the default VM.
1620 compGriddedWRF = ESMF_GridCompCreate( name="WRF Model", rc=rc)
1621 IF ( rc /= ESMF_SUCCESS ) THEN
1622 PRINT *, 'wrf_SST_ESMF: ESMF_GridCompCreate(WRF Model) failed'
1625 ! Create the SST Gridded Component, passing in the default VM.
1626 compGriddedSST = ESMF_GridCompCreate( name="SST Dummy Model", rc=rc)
1627 IF ( rc /= ESMF_SUCCESS ) THEN
1628 PRINT *, 'wrf_SST_ESMF: ESMF_GridCompCreate(WRF Dummy Model) failed'
1631 ! Create the WRF-SST Coupler Component, passing in the default VM.
1632 compCplWRFSST = ESMF_CplCompCreate( name="WRF-SST Coupler", rc=rc)
1633 IF ( rc /= ESMF_SUCCESS ) THEN
1634 PRINT *, 'wrf_SST_ESMF: ESMF_CplCompCreate failed'
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'
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'
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'
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'
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'
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'
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'
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'
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'
1688 CALL ESMF_TimeIntervalSet(couplingInterval, s=2, rc=rc)
1689 IF ( rc /= ESMF_SUCCESS ) THEN
1690 PRINT *, 'wrf_SST_ESMF: ESMF_TimeIntervalSet failed'
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'
1699 ! Init, Run, and Finalize section
1702 ! initialize WRF, phase 1
1703 ! Phase 1 init returns WRF time and decomposition information as
1704 ! exportState metadata.
1705 PRINT *, 'DEBUG wrf_SST_ESMF: calling phase-1 WRF init (wrf_component_init1)'
1706 CALL ESMF_GridCompInitialize(compGriddedWRF, importStateWRF, &
1707 exportStateWRF, driverClock, phase=1, rc=rc)
1708 thecount = size(timevals)
1709 call esmf_attributeget(exportstatewrf,'ComponentCouplingInterval',timevals,itemcount=thecount,rc=rc)
1710 !write(0,*) 'exportStateWRF year ',timevals(1),__LINE__
1711 !write(0,*) 'exportStateWRF month ',timevals(2),__LINE__
1712 !write(0,*) 'exportStateWRF day ',timevals(3),__LINE__
1713 !write(0,*) 'exportStateWRF hour ',timevals(4),__LINE__
1714 !write(0,*) 'exportStateWRF minute ',timevals(5),__LINE__
1715 !write(0,*) 'exportStateWRF second ',timevals(6),__LINE__
1716 ! Note: wrf_debug and wrf_error_fatal are now initialized
1717 IF ( rc /= ESMF_SUCCESS ) THEN
1718 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompInitialize(WRF phase 1) failed' )
1721 ! initialize SST, phase 1
1722 ! Phase 1 init returns SST time information as
1723 ! exportState metadata.
1724 PRINT *, 'DEBUG wrf_SST_ESMF: calling phase-1 SST init (sst_component_init1)'
1725 CALL ESMF_GridCompInitialize(compGriddedSST, importStateSST, &
1726 exportStateSST, driverClock, phase=1, rc=rc)
1727 thecount = size(timevals)
1728 call esmf_attributeget(exportstatesst,'ComponentCouplingInterval',timevals,itemcount=thecount,rc=rc)
1729 !write(0,*) 'exportStateSST year ',timevals(1),__LINE__
1730 !write(0,*) 'exportStateSST month ',timevals(2),__LINE__
1731 !write(0,*) 'exportStateSST day ',timevals(3),__LINE__
1732 !write(0,*) 'exportStateSST hour ',timevals(4),__LINE__
1733 !write(0,*) 'exportStateSST minute ',timevals(5),__LINE__
1734 !write(0,*) 'exportStateSST second ',timevals(6),__LINE__
1735 IF ( rc /= ESMF_SUCCESS ) THEN
1736 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompInitialize(SST phase 1) failed' )
1739 ! Reconcile clock settings from WRF and SST components to set up
1740 ! top-level clock. These are passed back from each "init" as attributes
1742 ! Stuff both States into a single State to pass into GetTimesFromStates()
1743 ! which is smart enough to deal with a Composite.
1744 PRINT *, 'DEBUG wrf_SST_ESMF: reconciling clock from WRF and SST components'
1745 tmpState = ESMF_StateCreate( rc=rc )
1746 IF ( rc /= ESMF_SUCCESS ) THEN
1747 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateCreate(tmpState) failed' )
1749 CALL ESMF_StateAdd( tmpState, exportStateWRF, rc )
1750 IF ( rc /= ESMF_SUCCESS ) THEN
1751 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateAdd(exportStateWRF) failed' )
1753 CALL ESMF_StateAdd( tmpState, exportStateSST, rc )
1754 IF ( rc /= ESMF_SUCCESS ) THEN
1755 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateAdd(exportStateSST) failed' )
1757 CALL GetTimesFromStates( tmpState, startTime, stopTime, couplingInterval )
1758 CALL ESMF_TimeIntervalGet( couplingInterval, TimeString=couplingIntervalString, &
1760 IF ( rc /= ESMF_SUCCESS ) THEN
1761 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_TimeIntervalGet failed' )
1763 CALL wrf_debug( 100, 'wrf_SST_ESMF: couplingInterval = '//TRIM(couplingIntervalString) )
1764 CALL ESMF_StateDestroy( tmpState, rc )
1765 IF ( rc /= ESMF_SUCCESS ) THEN
1766 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateDestroy(tmpState) failed' )
1768 ! update driver clock
1769 CALL ESMF_ClockDestroy(driverClock, rc)
1770 IF ( rc /= ESMF_SUCCESS ) THEN
1771 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_ClockDestroy failed' )
1773 driverClock = ESMF_ClockCreate(timeStep=couplingInterval, &
1774 startTime=startTime, &
1775 stopTime=stopTime, rc=rc)
1776 IF ( rc /= ESMF_SUCCESS ) THEN
1777 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_ClockCreate(driverClock) failed' )
1779 PRINT *, 'DEBUG wrf_SST_ESMF: done reconciling clock from WRF and SST components'
1780 CALL wrf_clockprint(50, driverClock, &
1781 'DEBUG wrf_SST_ESMF: driverClock after creation,')
1783 ! initialize WRF-SST Coupler
1784 PRINT *, 'DEBUG wrf_SST_ESMF: calling phase-1 CPL init (WRFSSTCpl_init)'
1785 CALL ESMF_CplCompInitialize(compCplWRFSST, exportStateWRF, &
1786 importStateSST, driverClock, rc=rc)
1787 IF ( rc /= ESMF_SUCCESS ) THEN
1788 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_CplCompInitialize(WRF -> SST) failed' )
1791 ! TBH: this bit is not needed, but would be in general
1792 ! CALL ESMF_CplCompInitialize(compCplWRFSST, exportStateSST, &
1793 ! importStateWRF, driverClock, rc=rc)
1794 ! IF ( rc /= ESMF_SUCCESS ) THEN
1795 ! CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_CplCompInitialize(SST -> WRF) failed' )
1798 ! initialize SST, phase 2
1799 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for SST (sst_component_init2)'
1800 CALL wrf_debug ( 100 , TRIM(str) )
1801 CALL ESMF_GridCompInitialize(compGriddedSST, importStateSST, &
1802 exportStateSST, driverClock, phase=2, rc=rc)
1803 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for SST'
1804 CALL wrf_debug ( 100 , TRIM(str) )
1805 IF ( rc /= ESMF_SUCCESS ) THEN
1806 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompInitialize(SST phase 2) failed' )
1809 ! initialize WRF, phase 2
1810 ! Phase 2 init sets up WRF importState and exportState.
1811 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 init for WRF (wrf_component_init2)'
1812 CALL wrf_debug ( 100 , TRIM(str) )
1813 CALL ESMF_GridCompInitialize(compGriddedWRF, importStateWRF, &
1814 exportStateWRF, driverClock, phase=2, rc=rc)
1815 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 init for WRF'
1816 CALL wrf_debug ( 100 , TRIM(str) )
1817 IF ( rc /= ESMF_SUCCESS ) THEN
1818 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompInitialize(WRF phase 2) failed' )
1821 CALL wrf_clockprint(50, driverClock, &
1822 'DEBUG wrf_SST_ESMF: driverClock before main time-stepping loop,')
1824 ! main time-stepping loop
1826 DO WHILE ( .NOT. ESMF_ClockIsStopTime(driverClock, rc) )
1828 timestepdebug = timestepdebug + 1
1829 WRITE(str,'(A,I8)') 'PROGRAM wrf_SST_ESMF: Top of time-stepping loop, timestepdebug = ',timestepdebug
1830 CALL wrf_debug ( 100 , TRIM(str) )
1831 CALL wrf_clockprint(50, driverClock, &
1832 'DEBUG wrf_SST_ESMF: driverClock at top of time-stepping loop,')
1835 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-1 run for SST (sst_component_run1)'
1836 CALL wrf_debug ( 100 , TRIM(str) )
1837 CALL ESMF_GridCompRun(compGriddedSST, importStateSST, exportStateSST, &
1838 driverClock, phase=1, rc=rc)
1839 IF ( rc /= ESMF_SUCCESS ) THEN
1840 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompRun(SST phase 1) failed' )
1842 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-1 run for SST (sst_component_run1)'
1843 CALL wrf_debug ( 100 , TRIM(str) )
1845 ! couple SST export -> WRF import
1846 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL SST->WRF (WRFSSTCpl_run)'
1847 CALL wrf_debug ( 100 , TRIM(str) )
1848 CALL ESMF_CplCompRun(compCplWRFSST, exportStateSST, &
1849 importStateWRF, driverClock, rc=rc)
1850 IF ( rc /= ESMF_SUCCESS ) THEN
1851 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_CplCompRun(SST -> WRF) failed' )
1853 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL SST->WRF (WRFSSTCpl_run)'
1854 CALL wrf_debug ( 100 , TRIM(str) )
1857 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for WRF (wrf_component_run)'
1858 CALL wrf_debug ( 100 , TRIM(str) )
1859 CALL ESMF_GridCompRun(compGriddedWRF, importStateWRF, exportStateWRF, &
1861 IF ( rc /= ESMF_SUCCESS ) THEN
1862 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompRun(WRF) failed' )
1864 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for WRF (wrf_component_run)'
1865 CALL wrf_debug ( 100 , TRIM(str) )
1867 ! couple WRF export -> SST import
1868 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling run for CPL WRF->SST (WRFSSTCpl_run)'
1869 CALL wrf_debug ( 100 , TRIM(str) )
1870 CALL ESMF_CplCompRun(compCplWRFSST, exportStateWRF, &
1871 importStateSST, driverClock, rc=rc)
1872 IF ( rc /= ESMF_SUCCESS ) THEN
1873 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_CplCompRun(WRF -> SST) failed' )
1875 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from run for CPL WRF->SST (WRFSSTCpl_run)'
1876 CALL wrf_debug ( 100 , TRIM(str) )
1879 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: Calling phase-2 run for SST (sst_component_run2)'
1880 CALL wrf_debug ( 100 , TRIM(str) )
1881 CALL ESMF_GridCompRun(compGriddedSST, importStateSST, exportStateSST, &
1882 driverClock, phase=2, rc=rc)
1883 IF ( rc /= ESMF_SUCCESS ) THEN
1884 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompRun(SST phase 2) failed' )
1886 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: back from phase-2 run for SST (sst_component_run2)'
1887 CALL wrf_debug ( 100 , TRIM(str) )
1889 ! advance clock to next coupling time step
1890 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: advancing clock'
1891 CALL wrf_debug ( 100 , TRIM(str) )
1892 CALL ESMF_ClockAdvance( driverClock, rc=rc )
1893 IF ( rc /= ESMF_SUCCESS ) THEN
1894 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_ClockAdvance failed' )
1896 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done advancing clock'
1897 CALL wrf_debug ( 100 , TRIM(str) )
1899 CALL wrf_clockprint(50, driverClock, &
1900 'DEBUG wrf_SST_ESMF: driverClock at end of time-stepping loop,')
1904 WRITE(str,'(A)') 'PROGRAM wrf_SST_ESMF: done with time-stepping loop'
1905 CALL wrf_debug ( 100 , TRIM(str) )
1908 CALL ESMF_GridCompFinalize(compGriddedSST, importStateSST, exportStateSST, &
1910 IF ( rc /= ESMF_SUCCESS ) THEN
1911 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompFinalize(compGriddedSST) failed' )
1914 ! clean up compCplWRFSST
1915 CALL ESMF_CplCompFinalize( compCplWRFSST, exportStateWRF, importStateSST, &
1917 IF ( rc /= ESMF_SUCCESS ) THEN
1918 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_CplCompFinalize(compCplWRFSST) failed' )
1922 ! must do this AFTER clean up of SST since SST uses WRF IOAPI
1923 CALL ESMF_GridCompFinalize(compGriddedWRF, importStateWRF, exportStateWRF, &
1925 IF ( rc /= ESMF_SUCCESS ) THEN
1926 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompFinalize(compGriddedWRF) failed' )
1931 CALL ESMF_GridCompDestroy(compGriddedWRF, rc)
1932 IF ( rc /= ESMF_SUCCESS ) THEN
1933 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_GridCompDestroy(compGriddedWRF) failed' )
1935 CALL ESMF_StateDestroy(importStateWRF, rc)
1936 IF ( rc /= ESMF_SUCCESS ) THEN
1937 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateDestroy(importStateWRF) failed' )
1939 CALL ESMF_StateDestroy(exportStateWRF, rc)
1940 IF ( rc /= ESMF_SUCCESS ) THEN
1941 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateDestroy(exportStateWRF) failed' )
1943 CALL ESMF_StateDestroy(importStateSST, rc)
1944 IF ( rc /= ESMF_SUCCESS ) THEN
1945 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateDestroy(importStateSST) failed' )
1947 CALL ESMF_StateDestroy(exportStateSST, rc)
1948 IF ( rc /= ESMF_SUCCESS ) THEN
1949 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_StateDestroy(exportStateSST) failed' )
1951 CALL ESMF_ClockDestroy(driverClock, rc)
1952 IF ( rc /= ESMF_SUCCESS ) THEN
1953 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_ClockDestroy(driverClock) failed' )
1956 CALL ESMF_Finalize( rc=rc )
1957 IF ( rc /= ESMF_SUCCESS ) THEN
1958 CALL wrf_error_fatal ( 'wrf_SST_ESMF: ESMF_Finalize failed' )
1961 END PROGRAM wrf_SST_ESMF