5 ! ESMF-specific modules for building WRF as an ESMF component.
7 ! This source file is only built when ESMF coupling is used.
13 MODULE module_metadatautils
15 ! This module defines component-independent "model metadata" utilities
16 ! used for ESMF coupling.
18 !TODO: Upgrade this later to support multiple coupling intervals via Alarms
19 !TODO: associated with top-level clock. Do this by adding TimesAttachedToState()
20 !TODO: inquiry function that will test an ESMF_State to see if the times are
21 !TODO: present via names defined in this module. Then call it for every
22 !TODO: component and resolve conflicts (somehow) for cases where two components
23 !TODO: define conflicting clocks. Of course, a component is allowed to not attach
24 !TODO: times to a state at all, if it can handle any time step.
26 !TODO: Replace meta-data names with "model metadata" conventions such as CF
27 !TODO: (once they exist)
29 !TODO: Refactor to remove duplication of hard-coded names.
35 ! everything is private by default
39 PUBLIC AttachTimesToState
40 PUBLIC GetTimesFromStates
41 PUBLIC AttachDecompToState
42 PUBLIC GetDecompFromState
45 CHARACTER (ESMF_MAXSTR) :: str
51 ! Attach time information to state as meta-data.
52 ! Update later to use some form of meta-data standards/conventions for
53 ! model "time" meta-data.
54 SUBROUTINE AttachTimesToState( state, startTime, stopTime, couplingInterval )
55 TYPE(ESMF_State), INTENT(INOUT) :: state
56 TYPE(ESMF_Time), INTENT(INOUT) :: startTime
57 TYPE(ESMF_Time), INTENT(INOUT) :: stopTime
58 TYPE(ESMF_TimeInterval), INTENT(INOUT) :: couplingInterval
61 INTEGER :: year, month, day, hour, minute, second
62 INTEGER(ESMF_KIND_I4) :: timevals(6) ! big enough to hold the vars listed above
64 CALL ESMF_TimeGet(startTime, yy=year, mm=month, dd=day, &
65 h=hour, m=minute, s=second, rc=rc)
66 IF ( rc /= ESMF_SUCCESS ) THEN
67 CALL wrf_error_fatal ( 'ESMF_TimeGet(startTime) failed' )
75 CALL ESMF_AttributeSet(state, 'ComponentStartTime', SIZE(timevals), timevals, rc=rc)
76 IF ( rc /= ESMF_SUCCESS ) THEN
77 CALL wrf_error_fatal ( 'ESMF_AttributeSet(ComponentStartTime) failed' )
80 CALL ESMF_TimeGet(stopTime, yy=year, mm=month, dd=day, &
81 h=hour, m=minute, s=second, rc=rc)
82 IF ( rc /= ESMF_SUCCESS ) THEN
83 CALL wrf_error_fatal ( 'ESMF_TimeGet(stopTime) failed' )
91 CALL ESMF_AttributeSet(state, 'ComponentStopTime', SIZE(timevals), timevals, rc=rc)
92 IF ( rc /= ESMF_SUCCESS ) THEN
93 CALL wrf_error_fatal ( 'ESMF_AttributeSet(ComponentStopTime) failed' )
96 CALL ESMF_TimeIntervalGet(couplingInterval, yy=year, mm=month, d=day, &
97 h=hour, m=minute, s=second, rc=rc)
98 IF ( rc /= ESMF_SUCCESS ) THEN
99 CALL wrf_error_fatal ( 'ESMF_TimeIntervalGet(couplingInterval) failed' )
107 CALL ESMF_AttributeSet(state, 'ComponentCouplingInterval', SIZE(timevals), timevals, rc=rc)
108 IF ( rc /= ESMF_SUCCESS ) THEN
109 CALL wrf_error_fatal ( 'ESMF_AttributeSet(ComponentCouplingInterval) failed' )
111 END SUBROUTINE AttachTimesToState
115 ! Extract time information attached as meta-data from a single
117 ! Update later to use some form of meta-data standards/conventions for
118 ! model "time" meta-data.
119 SUBROUTINE GetTimesFromState( state, startTime, stopTime, couplingInterval, rc )
120 TYPE(ESMF_State), INTENT(IN ) :: state
121 TYPE(ESMF_Time), INTENT(INOUT) :: startTime
122 TYPE(ESMF_Time), INTENT(INOUT) :: stopTime
123 TYPE(ESMF_TimeInterval), INTENT(INOUT) :: couplingInterval
124 INTEGER, INTENT(INOUT) :: rc
126 INTEGER :: year, month, day, hour, minute, second
127 INTEGER(ESMF_KIND_I4) :: timevals(6) ! big enough to hold the vars listed above
129 CALL ESMF_AttributeGet(state, 'ComponentStartTime', SIZE(timevals), timevals, rc=rc)
130 IF ( rc /= ESMF_SUCCESS ) THEN
131 CALL wrf_error_fatal ( 'ESMF_AttributeSet(ComponentStartTime) failed' )
140 write(0,*) ' year ',year,__LINE__
141 write(0,*) ' month ',month,__LINE__
142 write(0,*) ' day ',day,__LINE__
143 write(0,*) ' hour ',hour,__LINE__
144 write(0,*) ' minute ',minute,__LINE__
145 write(0,*) ' second ',second,__LINE__
146 CALL ESMF_TimeSet(startTime, yy=year, mm=month, dd=day, &
147 h=hour, m=minute, s=second, rc=rc)
148 IF ( rc /= ESMF_SUCCESS ) THEN
149 CALL wrf_error_fatal ( 'ESMF_TimeSet(startTime) failed' )
152 CALL ESMF_AttributeGet(state, 'ComponentStopTime', SIZE(timevals), timevals, rc=rc)
153 IF ( rc /= ESMF_SUCCESS ) THEN
154 CALL wrf_error_fatal ( 'ESMF_AttributeGet(ComponentStopTime) failed' )
162 write(0,*) ' year ',year,__LINE__
163 write(0,*) ' month ',month,__LINE__
164 write(0,*) ' day ',day,__LINE__
165 write(0,*) ' hour ',hour,__LINE__
166 write(0,*) ' minute ',minute,__LINE__
167 write(0,*) ' second ',second,__LINE__
168 CALL ESMF_TimeSet(stopTime, yy=year, mm=month, dd=day, &
169 h=hour, m=minute, s=second, rc=rc)
170 IF ( rc /= ESMF_SUCCESS ) THEN
171 CALL wrf_error_fatal ( 'ESMF_TimeSet(stopTime) failed' )
174 CALL ESMF_AttributeGet(state, 'ComponentCouplingInterval', SIZE(timevals), timevals, rc=rc)
175 IF ( rc /= ESMF_SUCCESS ) THEN
176 CALL wrf_error_fatal ( 'ESMF_AttributeGet(ComponentCouplingInterval) failed' )
184 write(0,*) ' year ',year,__LINE__
185 write(0,*) ' month ',month,__LINE__
186 write(0,*) ' day ',day,__LINE__
187 write(0,*) ' hour ',hour,__LINE__
188 write(0,*) ' minute ',minute,__LINE__
189 write(0,*) ' second ',second,__LINE__
190 CALL ESMF_TimeIntervalSet(couplingInterval, yy=year, mm=month, d=day, &
191 h=hour, m=minute, s=second, rc=rc)
192 IF ( rc /= ESMF_SUCCESS ) THEN
193 CALL wrf_error_fatal ( 'ESMF_TimeIntervalSet(couplingInterval) failed' )
195 END SUBROUTINE GetTimesFromState
199 ! Extract time information attached as meta-data from one or more
200 ! ESMF_States. To use this with more than one ESMF_State, put the
201 ! ESMF_States into a single ESMF_State. If times differ, an attempt
202 ! is made to reconcile them.
203 SUBROUTINE GetTimesFromStates( state, startTime, stopTime, couplingInterval )
205 TYPE(ESMF_State), INTENT(IN ) :: state
206 TYPE(ESMF_Time), INTENT(INOUT) :: startTime
207 TYPE(ESMF_Time), INTENT(INOUT) :: stopTime
208 TYPE(ESMF_TimeInterval), INTENT(INOUT) :: couplingInterval
211 INTEGER :: numItems, numStates, i, istate
212 TYPE(ESMF_StateItemType), ALLOCATABLE :: itemTypes(:)
213 TYPE(ESMF_State) :: tmpState
214 CHARACTER (len=ESMF_MAXSTR), ALLOCATABLE :: itemNames(:)
215 TYPE(ESMF_Time), ALLOCATABLE :: startTimes(:)
216 TYPE(ESMF_Time), ALLOCATABLE :: stopTimes(:)
217 TYPE(ESMF_TimeInterval), ALLOCATABLE :: couplingIntervals(:)
219 ! Unfortunately, implementing this is unnecessarily difficult due
220 ! to lack of Iterators for ESMF_State.
222 ! Since there are no convenient iterators for ESMF_State,
223 ! write a lot of code...
224 ! Figure out how many items are in the ESMF_State
225 CALL ESMF_StateGet(state, itemCount=numItems, rc=rc)
226 IF ( rc /= ESMF_SUCCESS) THEN
227 CALL wrf_error_fatal ( 'ESMF_StateGet(numItems) failed' )
229 ! allocate an array to hold the types of all items
230 ALLOCATE( itemTypes(numItems) )
231 ! allocate an array to hold the names of all items
232 ALLOCATE( itemNames(numItems) )
233 ! get the item types and names
234 CALL ESMF_StateGet(state, stateitemtypeList=itemTypes, &
235 itemNameList=itemNames, rc=rc)
236 IF ( rc /= ESMF_SUCCESS) THEN
237 WRITE(str,*) 'ESMF_StateGet itemTypes failed with rc = ', rc
238 CALL wrf_error_fatal ( str )
240 ! count how many items are ESMF_States
243 IF ( itemTypes(i) == ESMF_STATEITEM_STATE ) THEN
244 numStates = numStates + 1
247 ALLOCATE( startTimes(numStates), stopTimes(numStates), &
248 couplingIntervals(numStates) )
249 IF ( numStates > 0) THEN
250 ! finally, extract nested ESMF_States by name, if there are any
251 ! (should be able to do this by index at least!)
254 IF ( itemTypes(i) == ESMF_STATEITEM_STATE ) THEN
255 CALL ESMF_StateGet( state, itemName=TRIM(itemNames(i)), &
256 nestedState=tmpState, rc=rc )
257 IF ( rc /= ESMF_SUCCESS) THEN
258 WRITE(str,*) 'ESMF_StateGet(',TRIM(itemNames(i)),') failed'
259 CALL wrf_error_fatal ( str )
262 CALL GetTimesFromState( tmpState, startTimes(istate), &
264 couplingIntervals(istate), rc )
265 IF ( rc /= ESMF_SUCCESS ) THEN
270 CALL ReconcileTimes( startTimes, stopTimes, couplingIntervals, &
271 startTime, stopTime, couplingInterval )
273 ! there are no nested ESMF_States so use parent state only
274 CALL GetTimesFromState( state, startTime, stopTime, &
275 couplingInterval , rc )
279 DEALLOCATE( itemTypes )
280 DEALLOCATE( itemNames )
281 DEALLOCATE( startTimes, stopTimes, couplingIntervals )
283 END SUBROUTINE GetTimesFromStates
286 ! Reconcile all times and intervals in startTimes, stopTimes, and
287 ! couplingIntervals and return the results in startTime, stopTime, and
288 ! couplingInterval. Abort if reconciliation is not possible.
289 SUBROUTINE ReconcileTimes( startTimes, stopTimes, couplingIntervals, &
290 startTime, stopTime, couplingInterval )
291 TYPE(ESMF_Time), INTENT(INOUT) :: startTimes(:)
292 TYPE(ESMF_Time), INTENT(INOUT) :: stopTimes(:)
293 TYPE(ESMF_TimeInterval), INTENT(INOUT) :: couplingIntervals(:)
294 TYPE(ESMF_Time), INTENT(INOUT) :: startTime
295 TYPE(ESMF_Time), INTENT(INOUT) :: stopTime
296 TYPE(ESMF_TimeInterval), INTENT(INOUT) :: couplingInterval
298 INTEGER :: numTimes, numTimesTmp, i
299 character*256 buttwhump
302 ! how many sets of time info?
303 numTimes = SIZE(startTimes)
304 IF ( numTimes < 2 ) THEN
305 CALL wrf_error_fatal ( 'SIZE(startTimes) too small' )
307 numTimesTmp = SIZE(stopTimes)
308 IF ( numTimes /= numTimesTmp ) THEN
309 CALL wrf_error_fatal ( 'incorrect SIZE(stopTimes)' )
311 numTimesTmp = SIZE(couplingIntervals)
312 IF ( numTimes /= numTimesTmp ) THEN
313 CALL wrf_error_fatal ( 'incorrect SIZE(couplingIntervals)' )
317 !TODO: For now this is very simple. Fancy it up later.
319 call esmf_timeget(starttimes(i),timestring=buttwhump,rc=rc)
320 write(*,*)__LINE__,'startimes',i,trim(buttwhump)
321 write(0,*)__LINE__,'startimes',i,trim(buttwhump)
322 call esmf_timeget(stoptimes(i),timestring=buttwhump,rc=rc)
323 write(*,*)__LINE__,'stoptimes',i,trim(buttwhump)
324 write(0,*)__LINE__,'stopimes',i,trim(buttwhump)
325 call esmf_timeintervalget(couplingintervals(i),timestring=buttwhump,rc=rc)
326 write(*,*)__LINE__,'coupling intervals',i,trim(buttwhump)
327 write(0,*)__LINE__,'coupling intervals',i,trim(buttwhump)
329 startTime = startTimes(i)
330 stopTime = stopTimes(i)
331 couplingInterval = couplingIntervals(i)
333 IF ( startTimes(i) /= startTime ) THEN
334 CALL wrf_error_fatal ( 'ReconcileTimes: inconsistent startTimes' )
336 IF ( stopTimes(i) /= stopTime ) THEN
337 CALL wrf_error_fatal ( 'ReconcileTimes: inconsistent stopTimes' )
339 IF ( couplingIntervals(i) /= couplingInterval ) THEN
340 CALL wrf_error_fatal ( 'ReconcileTimes: inconsistent couplingIntervals' )
346 END SUBROUTINE ReconcileTimes
350 !TODO: Eliminate this once this information can be derived via other
352 SUBROUTINE AttachDecompToState( state, &
353 ids, ide, jds, jde, kds, kde, &
354 ims, ime, jms, jme, kms, kme, &
355 ips, ipe, jps, jpe, kps, kpe, &
357 TYPE(ESMF_State), INTENT(INOUT) :: state
358 INTEGER, INTENT(IN ) :: ids, ide, jds, jde, kds, kde
359 INTEGER, INTENT(IN ) :: ims, ime, jms, jme, kms, kme
360 INTEGER, INTENT(IN ) :: ips, ipe, jps, jpe, kps, kpe
361 INTEGER, INTENT(IN ) :: domdesc
362 LOGICAL, INTENT(IN ) :: bdy_mask(4)
365 ! big enough to hold the integer values listed above
366 INTEGER(ESMF_KIND_I4) :: intvals(19)
367 ! big enough to hold the logical values listed above
368 TYPE(ESMF_Logical) :: logvals(4)
371 ! Usually, when writing an API for a target language, it is considered
372 ! good practice to use native types of the target language in the
375 DO i = 1, SIZE(bdy_mask)
376 IF (bdy_mask(i)) THEN
377 logvals(i) = ESMF_TRUE
380 CALL ESMF_AttributeSet(state, 'DecompositionLogicals', SIZE(logvals), logvals, rc=rc)
381 IF ( rc /= ESMF_SUCCESS) THEN
382 CALL wrf_error_fatal ( 'ESMF_AttributeSet(DecompositionLogicals) failed' )
403 intvals(19) = domdesc
404 CALL ESMF_AttributeSet(state, 'DecompositionIntegers', SIZE(intvals), intvals, rc=rc)
405 IF ( rc /= ESMF_SUCCESS) THEN
406 CALL wrf_error_fatal ( 'ESMF_AttributeSet(DecompositionIntegers) failed' )
408 END SUBROUTINE AttachDecompToState
412 !TODO: Eliminate this once this information can be derived via other
414 SUBROUTINE GetDecompFromState( state, &
415 ids, ide, jds, jde, kds, kde, &
416 ims, ime, jms, jme, kms, kme, &
417 ips, ipe, jps, jpe, kps, kpe, &
419 TYPE(ESMF_State), INTENT(IN ) :: state
420 INTEGER, INTENT( OUT) :: ids, ide, jds, jde, kds, kde
421 INTEGER, INTENT( OUT) :: ims, ime, jms, jme, kms, kme
422 INTEGER, INTENT( OUT) :: ips, ipe, jps, jpe, kps, kpe
423 INTEGER, INTENT( OUT) :: domdesc
424 LOGICAL, INTENT( OUT) :: bdy_mask(4)
427 ! big enough to hold the integer values listed above
428 INTEGER(ESMF_KIND_I4) :: intvals(19)
429 ! big enough to hold the logical values listed above
430 TYPE(ESMF_Logical) :: logvals(4)
433 CALL ESMF_AttributeGet(state, 'DecompositionLogicals', SIZE(logvals), logvals, rc=rc)
434 IF ( rc /= ESMF_SUCCESS) THEN
435 CALL wrf_error_fatal ( 'ESMF_AttributeGet(DecompositionLogicals) failed' )
437 ! Usually, when writing an API for a target language, it is considered
438 ! good practice to use native types of the target language in the
441 DO i = 1, SIZE(logvals)
442 IF (logvals(i) == ESMF_TRUE) THEN
447 CALL ESMF_AttributeGet(state, 'DecompositionIntegers', SIZE(intvals), intvals, rc=rc)
448 IF ( rc /= ESMF_SUCCESS) THEN
449 CALL wrf_error_fatal ( 'ESMF_AttributeGet(DecompositionIntegers) failed' )
469 domdesc = intvals(19)
470 END SUBROUTINE GetDecompFromState
474 END MODULE module_metadatautils
478 MODULE module_wrf_component_top
480 ! This module defines wrf_component_init1(), wrf_component_init2(),
481 ! wrf_component_run(), and wrf_component_finalize() routines that are called
482 ! when WRF is run as an ESMF component.
486 USE module_wrf_top, ONLY : wrf_init, wrf_run, wrf_finalize
487 USE module_domain, ONLY : head_grid, auxhist4_alarm, auxhist5_alarm, auxhist3_alarm, auxhist1_alarm, &
488 auxhist2_alarm, auxhist6_alarm, auxhist10_alarm, auxhist11_alarm, auxhist9_alarm, &
489 auxhist7_alarm, auxhist8_alarm, auxinput11_alarm, auxinput3_alarm, auxinput4_alarm, &
490 auxinput2_alarm, io_esmf, auxinput1_alarm, auxinput5_alarm, auxinput9_alarm, &
491 auxinput10_alarm, auxinput8_alarm, auxinput6_alarm, auxinput7_alarm, &
494 USE module_esmf_extensions
495 USE module_metadatautils, ONLY: AttachTimesToState, AttachDecompToState
501 ! everything is private by default
504 ! Public entry points
505 PUBLIC wrf_component_init1
506 PUBLIC wrf_component_init2
507 PUBLIC wrf_component_run
508 PUBLIC wrf_component_finalize
511 CHARACTER (ESMF_MAXSTR) :: str
516 SUBROUTINE wrf_component_init1( gcomp, importState, exportState, clock, rc )
517 TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
518 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: importState
519 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: exportState
520 TYPE(ESMF_Clock), TARGET, INTENT(INOUT) :: clock
521 INTEGER, INTENT( OUT) :: rc
523 ! WRF component init routine, phase 1. Passes relevant coupling
524 ! information back as metadata on exportState.
528 ! importState Importstate
529 ! exportState Exportstate
530 ! clock External clock
531 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
532 ! otherwise ESMF_FAILURE.
534 !TODO: Note that much of the decomposition-related meta-data attached to the
535 !TODO: exportState are WRF-specific and are only useful if other components
536 !TODO: want to re-use the WRF IOAPI with the same decomposition as the WRF
537 !TODO: model. This is true for the simple WRF+CPL+SST test case, but will
538 !TODO: not be in general. Of course other components are free to ignore this
542 TYPE(ESMF_GridComp), POINTER :: p_gcomp
543 TYPE(ESMF_State), POINTER :: p_importState
544 TYPE(ESMF_State), POINTER :: p_exportState
545 TYPE(ESMF_Clock), POINTER :: p_clock
547 TYPE(ESMF_Time) :: startTime
548 TYPE(ESMF_Time) :: stopTime
549 TYPE(ESMF_TimeInterval) :: couplingInterval
550 ! decomposition hackery
551 INTEGER :: ids, ide, jds, jde, kds, kde
552 INTEGER :: ims, ime, jms, jme, kms, kme
553 INTEGER :: ips, ipe, jps, jpe, kps, kpe
555 LOGICAL :: bdy_mask(4)
556 CHARACTER(LEN=256) :: couplingIntervalString
561 p_importState => importState
562 p_exportState => exportState
564 ! NOTE: It will be possible to remove this call once ESMF supports
565 ! interfaces ESMF_ClockGetCurrent(), ESMF_ImportStateGetCurrent(),
566 ! ESMF_ExportStateGetCurrent(), and ESMF_GridCompGetCurrent().
567 CALL ESMF_SetCurrent( gcomp=p_gcomp, importState=p_importState, &
568 exportState=p_exportState, clock=p_clock )
570 ! Call WRF "init" routine, which, for a DM_PARALLEL run, will recognize
571 ! that ESMF has already called MPI_INIT and respond appropriately.
572 CALL wrf_init( no_init1=.TRUE. )
574 ! For now, use settings from WRF component intialization to set up
575 ! top-level clock. Per suggestion from ESMF Core team, these are passed
576 ! back as attributes on exportState.
577 CALL wrf_clockprint( 100, head_grid%domain_clock, &
578 'DEBUG wrf_component_init1(): head_grid%domain_clock,' )
579 CALL ESMF_ClockGet(head_grid%domain_clock, startTime=startTime, &
580 stopTime=stopTime, rc=rc)
581 IF ( rc /= ESMF_SUCCESS ) THEN
582 CALL wrf_error_fatal ( 'wrf_component_init1: ESMF_ClockGet failed' )
584 CALL wrf_debug( 500, 'DEBUG wrf_component_init1(): before wrf_findCouplingInterval' )
585 CALL wrf_findCouplingInterval( startTime, stopTime, couplingInterval )
586 CALL wrf_debug( 500, 'DEBUG wrf_component_init1(): after wrf_findCouplingInterval' )
587 CALL ESMF_TimeIntervalGet( couplingInterval, TimeString=couplingIntervalString, &
589 IF ( rc /= ESMF_SUCCESS ) THEN
590 CALL wrf_error_fatal ( 'wrf_component_init1: ESMF_TimeIntervalGet failed' )
592 CALL wrf_debug( 100, 'DEBUG wrf_component_init1(): couplingInterval = '//TRIM(couplingIntervalString) )
593 CALL AttachTimesToState( exportState, startTime, stopTime, couplingInterval )
594 CALL wrf_getDecompInfo( ids, ide, jds, jde, kds, kde, &
595 ims, ime, jms, jme, kms, kme, &
596 ips, ipe, jps, jpe, kps, kpe, &
598 CALL AttachDecompToState( exportState, &
599 ids, ide, jds, jde, kds, kde, &
600 ims, ime, jms, jme, kms, kme, &
601 ips, ipe, jps, jpe, kps, kpe, &
604 END SUBROUTINE wrf_component_init1
608 SUBROUTINE wrf_component_init2( gcomp, importState, exportState, clock, rc )
609 TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
610 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: importState
611 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: exportState
612 TYPE(ESMF_Clock), TARGET, INTENT(INOUT) :: clock
613 INTEGER, INTENT( OUT) :: rc
615 ! WRF component init routine, phase 2. Initializes importState and
620 ! importState Importstate
621 ! exportState Exportstate
622 ! clock External clock
623 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
624 ! otherwise ESMF_FAILURE.
628 TYPE(ESMF_GridComp), POINTER :: p_gcomp
629 TYPE(ESMF_State), POINTER :: p_importState
630 TYPE(ESMF_State), POINTER :: p_exportState
631 TYPE(ESMF_Clock), POINTER :: p_clock
633 TYPE(ESMF_Time) :: startTime
634 TYPE(ESMF_Time) :: stopTime
635 TYPE(ESMF_TimeInterval) :: couplingInterval
636 ! decomposition hackery
637 INTEGER :: ids, ide, jds, jde, kds, kde
638 INTEGER :: ims, ime, jms, jme, kms, kme
639 INTEGER :: ips, ipe, jps, jpe, kps, kpe
641 LOGICAL :: bdy_mask(4)
642 TYPE(ESMF_StateType) :: statetype
643 INTEGER :: itemCount, i
644 CHARACTER (ESMF_MAXSTR) :: statename
645 CHARACTER (ESMF_MAXSTR), ALLOCATABLE :: itemNames(:)
646 TYPE(ESMF_StateItemType), ALLOCATABLE :: itemTypes(:)
648 CALL wrf_debug ( 100, 'wrf_component_init2(): begin' )
650 CALL ESMF_StateGet( exportState, itemCount=itemCount, &
651 statetype=statetype, rc=rc )
652 IF ( rc /= ESMF_SUCCESS ) THEN
653 CALL wrf_error_fatal("wrf_component_init2: ESMF_StateGet(exportState) failed" )
655 WRITE (str,*) 'wrf_component_init2: exportState itemCount = ', itemCount
656 CALL wrf_debug ( 100 , TRIM(str) )
657 IF ( statetype /= ESMF_STATE_EXPORT ) THEN
658 CALL wrf_error_fatal("wrf_component_init2: exportState is not an export state" )
661 CALL ESMF_StateGet( importState, itemCount=itemCount, &
662 statetype=statetype, rc=rc )
663 IF ( rc /= ESMF_SUCCESS ) THEN
664 CALL wrf_error_fatal("wrf_component_init2: ESMF_StateGet(importState) failed" )
666 WRITE (str,*) 'wrf_component_init2: importState itemCount = ', itemCount
667 CALL wrf_debug ( 100 , TRIM(str) )
668 IF ( statetype /= ESMF_STATE_IMPORT ) THEN
669 CALL wrf_error_fatal("wrf_component_init2: importState is not an import state" )
673 p_importState => importState
674 p_exportState => exportState
676 ! NOTE: It will be possible to remove this call once ESMF supports
677 ! interfaces ESMF_ClockGetCurrent(), ESMF_ImportStateGetCurrent(),
678 ! ESMF_ExportStateGetCurrent(), and ESMF_GridCompGetCurrent().
679 CALL ESMF_SetCurrent( gcomp=p_gcomp, importState=p_importState, &
680 exportState=p_exportState, clock=p_clock )
682 ! populate ESMF import and export states
683 CALL wrf_state_populate( rc )
685 CALL wrf_error_fatal ( 'wrf_component_init2: wrf_state_populate failed' )
688 ! examine importState
689 WRITE (str,*) 'wrf_component_init2: EXAMINING importState...'
690 CALL wrf_debug ( 100 , TRIM(str) )
691 CALL ESMF_StateGet( importState, itemCount=itemCount, &
692 statetype=statetype, name=statename, rc=rc )
693 IF ( rc /= ESMF_SUCCESS ) THEN
694 CALL wrf_error_fatal("wrf_component_init2: ESMF_StateGet(importState) failed B" )
696 IF ( statetype /= ESMF_STATE_IMPORT ) THEN
697 CALL wrf_error_fatal("wrf_component_init2: importState is not an import state" )
699 WRITE (str,*) 'wrf_component_init2: importState <',TRIM(statename), &
700 '> itemCount = ', itemCount
701 CALL wrf_debug ( 100 , TRIM(str) )
702 ALLOCATE ( itemNames(itemCount), itemTypes(itemCount) )
703 CALL ESMF_StateGet( importState, itemNameList=itemNames, &
704 stateitemtypeList=itemTypes, rc=rc )
705 IF ( rc /= ESMF_SUCCESS ) THEN
706 CALL wrf_error_fatal("wrf_component_init2: ESMF_StateGet(importState) failed C" )
709 IF ( itemTypes(i) == ESMF_STATEITEM_FIELD ) THEN
710 WRITE(str,*) 'wrf_component_init2: importState contains field <',TRIM(itemNames(i)),'>'
711 CALL wrf_debug ( 100 , TRIM(str) )
714 DEALLOCATE ( itemNames, itemTypes )
715 WRITE (str,*) 'wrf_component_init2: DONE EXAMINING importState...'
716 CALL wrf_debug ( 100 , TRIM(str) )
718 ! examine exportState
719 WRITE (str,*) 'wrf_component_init2: EXAMINING exportState...'
720 CALL wrf_debug ( 100 , TRIM(str) )
721 CALL ESMF_StateGet( exportState, itemCount=itemCount, &
722 statetype=statetype, name=statename, rc=rc )
723 IF ( rc /= ESMF_SUCCESS ) THEN
724 CALL wrf_error_fatal("wrf_component_init2: ESMF_StateGet(exportState) failed B" )
726 IF ( statetype /= ESMF_STATE_EXPORT ) THEN
727 CALL wrf_error_fatal("wrf_component_init2: exportState is not an export state" )
729 WRITE (str,*) 'wrf_component_init2: exportState <',TRIM(statename), &
730 '> itemCount = ', itemCount
731 CALL wrf_debug ( 100 , TRIM(str) )
732 ALLOCATE ( itemNames(itemCount), itemTypes(itemCount) )
733 CALL ESMF_StateGet( exportState, itemNameList=itemNames, &
734 stateitemtypeList=itemTypes, rc=rc )
735 IF ( rc /= ESMF_SUCCESS ) THEN
736 CALL wrf_error_fatal("wrf_component_init2: ESMF_StateGet(exportState) failed C" )
739 IF ( itemTypes(i) == ESMF_STATEITEM_FIELD ) THEN
740 WRITE(str,*) 'wrf_component_init2: exportState contains field <',TRIM(itemNames(i)),'>'
741 CALL wrf_debug ( 100 , TRIM(str) )
744 DEALLOCATE ( itemNames, itemTypes )
745 WRITE (str,*) 'wrf_component_init2: DONE EXAMINING exportState...'
746 CALL wrf_debug ( 100 , TRIM(str) )
748 CALL wrf_debug ( 100, 'DEBUG wrf_component_init2(): end' )
750 END SUBROUTINE wrf_component_init2
754 SUBROUTINE wrf_component_run( gcomp, importState, exportState, clock, rc )
755 TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
756 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: importState, exportState
757 TYPE(ESMF_Clock), TARGET, INTENT(INOUT) :: clock
758 INTEGER, INTENT( OUT) :: rc
760 ! WRF component run routine.
764 ! importState Importstate
765 ! exportState Exportstate
766 ! clock External clock
767 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
768 ! otherwise ESMF_FAILURE.
772 TYPE(ESMF_GridComp), POINTER :: p_gcomp
773 TYPE(ESMF_State), POINTER :: p_importState
774 TYPE(ESMF_State), POINTER :: p_exportState
775 TYPE(ESMF_Clock), POINTER :: p_clock
777 TYPE(ESMF_Time) :: currentTime, nextTime
778 TYPE(ESMF_TimeInterval) :: runLength ! how long to run in this call
779 CHARACTER(LEN=256) :: timeStr
781 CALL wrf_debug ( 100 , 'DEBUG wrf_component_run(): begin' )
784 p_importState => importState
785 p_exportState => exportState
787 ! NOTE: It will be possible to remove this call once ESMF supports
788 ! interfaces ESMF_ClockGetCurrent(), ESMF_ImportStateGetCurrent(),
789 ! ESMF_ExportStateGetCurrent(), and ESMF_GridCompGetCurrent().
790 CALL ESMF_SetCurrent( gcomp=p_gcomp, importState=p_importState, &
791 exportState=p_exportState, clock=p_clock )
793 ! connect ESMF clock with WRF domain clock
794 CALL ESMF_ClockGet( clock, currTime=currentTime, timeStep=runLength, rc=rc )
795 IF ( rc /= ESMF_SUCCESS ) THEN
796 CALL wrf_error_fatal ( 'wrf_component_run: ESMF_ClockGet failed' )
798 CALL wrf_clockprint(100, clock, &
799 'DEBUG wrf_component_run(): clock,')
800 nextTime = currentTime + runLength
801 head_grid%start_subtime = currentTime
802 head_grid%stop_subtime = nextTime
803 CALL wrf_timetoa ( head_grid%start_subtime, timeStr )
804 WRITE (str,*) 'wrf_component_run: head_grid%start_subtime ',TRIM(timeStr)
805 CALL wrf_debug ( 100 , TRIM(str) )
806 CALL wrf_timetoa ( head_grid%stop_subtime, timeStr )
807 WRITE (str,*) 'wrf_component_run: head_grid%stop_subtime ',TRIM(timeStr)
808 CALL wrf_debug ( 100 , TRIM(str) )
810 ! Call WRF "run" routine
811 CALL wrf_debug ( 100 , 'DEBUG wrf_component_run(): calling wrf_run()' )
813 CALL wrf_debug ( 100 , 'DEBUG wrf_component_run(): back from wrf_run()' )
815 CALL wrf_debug ( 100 , 'DEBUG wrf_component_run(): end' )
817 END SUBROUTINE wrf_component_run
821 SUBROUTINE wrf_component_finalize( gcomp, importState, exportState, clock, rc )
822 TYPE(ESMF_GridComp), TARGET, INTENT(INOUT) :: gcomp
823 TYPE(ESMF_State), TARGET, INTENT(INOUT) :: importState, exportState
824 TYPE(ESMF_Clock), TARGET, INTENT(INOUT) :: clock
825 INTEGER, INTENT( OUT) :: rc
827 ! WRF component finalize routine.
831 ! importState Importstate
832 ! exportState Exportstate
833 ! clock External clock
834 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
835 ! otherwise ESMF_FAILURE.
839 TYPE(ESMF_GridComp), POINTER :: p_gcomp
840 TYPE(ESMF_State), POINTER :: p_importState
841 TYPE(ESMF_State), POINTER :: p_exportState
842 TYPE(ESMF_Clock), POINTER :: p_clock
845 p_importState => importState
846 p_exportState => exportState
848 ! NOTE: It will be possible to remove this call once ESMF supports
849 ! interfaces ESMF_ClockGetCurrent(), ESMF_ImportStateGetCurrent(),
850 ! ESMF_ExportStateGetCurrent(), and ESMF_GridCompGetCurrent().
851 CALL ESMF_SetCurrent( gcomp=p_gcomp, importState=p_importState, &
852 exportState=p_exportState, clock=p_clock )
854 ! Call WRF "finalize" routine, suppressing call to MPI_FINALIZE so
855 ! ESMF can do it (if needed) during ESMF_Finalize().
856 CALL wrf_finalize( no_shutdown=.TRUE. )
860 END SUBROUTINE wrf_component_finalize
864 SUBROUTINE wrf_findCouplingInterval( startTime, stopTime, couplingInterval )
865 TYPE(ESMF_Time), INTENT(IN ) :: startTime
866 TYPE(ESMF_Time), INTENT(IN ) :: stopTime
867 TYPE(ESMF_TimeInterval), INTENT( OUT) :: couplingInterval
869 ! WRF convenience routine for deducing coupling interval. The startTime
870 ! and stopTime arguments are only used for determining a default value
871 ! when coupling is not actually being done.
874 ! startTime start time
876 ! couplingInterval coupling interval
879 LOGICAL :: foundcoupling
882 ! external function prototype
883 INTEGER, EXTERNAL :: use_package
885 ! deduce coupling time-step
886 foundcoupling = .FALSE.
887 !TODO: This bit just finds the FIRST case and extracts coupling interval...
888 !TODO: Add error-checking for over-specification.
889 !TODO: Add support for multiple coupling intervals later...
890 !TODO: Add support for coupling that does not begin immediately later...
891 !TODO: Get rid of duplication once I/O refactoring is finished (and
892 !TODO: auxio streams can be addressed via index).
893 IF ( .NOT. foundcoupling ) THEN
894 CALL nl_get_io_form_auxinput1( 1, io_form )
895 IF ( use_package( io_form ) == IO_ESMF ) THEN
896 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT1_ALARM ), &
897 RingInterval=couplingInterval, rc=rc )
898 IF ( rc /= ESMF_SUCCESS ) THEN
899 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT1_ALARM) failed' )
901 foundcoupling = .TRUE.
904 IF ( .NOT. foundcoupling ) THEN
905 CALL nl_get_io_form_auxinput2( 1, io_form )
906 IF ( use_package( io_form ) == IO_ESMF ) THEN
907 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT2_ALARM ), &
908 RingInterval=couplingInterval, rc=rc )
909 IF ( rc /= ESMF_SUCCESS ) THEN
910 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT2_ALARM) failed' )
912 foundcoupling = .TRUE.
915 IF ( .NOT. foundcoupling ) THEN
916 CALL nl_get_io_form_auxinput3( 1, io_form )
917 IF ( use_package( io_form ) == IO_ESMF ) THEN
918 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT3_ALARM ), &
919 RingInterval=couplingInterval, rc=rc )
920 IF ( rc /= ESMF_SUCCESS ) THEN
921 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT3_ALARM) failed' )
923 foundcoupling = .TRUE.
926 IF ( .NOT. foundcoupling ) THEN
927 CALL nl_get_io_form_auxinput4( 1, io_form )
928 IF ( use_package( io_form ) == IO_ESMF ) THEN
929 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT4_ALARM ), &
930 RingInterval=couplingInterval, rc=rc )
931 IF ( rc /= ESMF_SUCCESS ) THEN
932 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT4_ALARM) failed' )
934 foundcoupling = .TRUE.
937 IF ( .NOT. foundcoupling ) THEN
938 CALL nl_get_io_form_auxinput5( 1, io_form )
939 IF ( use_package( io_form ) == IO_ESMF ) THEN
940 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT5_ALARM ), &
941 RingInterval=couplingInterval, rc=rc )
942 IF ( rc /= ESMF_SUCCESS ) THEN
943 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT5_ALARM) failed' )
945 foundcoupling = .TRUE.
948 IF ( .NOT. foundcoupling ) THEN
949 CALL nl_get_io_form_auxinput6( 1, io_form )
950 IF ( use_package( io_form ) == IO_ESMF ) THEN
951 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT6_ALARM ), &
952 RingInterval=couplingInterval, rc=rc )
953 IF ( rc /= ESMF_SUCCESS ) THEN
954 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT6_ALARM) failed' )
956 foundcoupling = .TRUE.
959 IF ( .NOT. foundcoupling ) THEN
960 CALL nl_get_io_form_auxinput7( 1, io_form )
961 IF ( use_package( io_form ) == IO_ESMF ) THEN
962 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT7_ALARM ), &
963 RingInterval=couplingInterval, rc=rc )
964 IF ( rc /= ESMF_SUCCESS ) THEN
965 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT7_ALARM) failed' )
967 foundcoupling = .TRUE.
970 IF ( .NOT. foundcoupling ) THEN
971 CALL nl_get_io_form_auxinput8( 1, io_form )
972 IF ( use_package( io_form ) == IO_ESMF ) THEN
973 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT8_ALARM ), &
974 RingInterval=couplingInterval, rc=rc )
975 IF ( rc /= ESMF_SUCCESS ) THEN
976 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT8_ALARM) failed' )
978 foundcoupling = .TRUE.
981 IF ( .NOT. foundcoupling ) THEN
982 CALL nl_get_io_form_auxinput9( 1, io_form )
983 IF ( use_package( io_form ) == IO_ESMF ) THEN
984 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT9_ALARM ), &
985 RingInterval=couplingInterval, rc=rc )
986 IF ( rc /= ESMF_SUCCESS ) THEN
987 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT9_ALARM) failed' )
989 foundcoupling = .TRUE.
992 IF ( .NOT. foundcoupling ) THEN
993 CALL nl_get_io_form_gfdda( 1, io_form )
994 IF ( use_package( io_form ) == IO_ESMF ) THEN
995 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT10_ALARM ), &
996 RingInterval=couplingInterval, rc=rc )
997 IF ( rc /= ESMF_SUCCESS ) THEN
998 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT10_ALARM) failed' )
1000 foundcoupling = .TRUE.
1003 IF ( .NOT. foundcoupling ) THEN
1004 CALL nl_get_io_form_auxinput11( 1, io_form )
1005 IF ( use_package( io_form ) == IO_ESMF ) THEN
1006 CALL ESMF_AlarmGet( head_grid%alarms( AUXINPUT11_ALARM ), &
1007 RingInterval=couplingInterval, rc=rc )
1008 IF ( rc /= ESMF_SUCCESS ) THEN
1009 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXINPUT11_ALARM) failed' )
1011 foundcoupling = .TRUE.
1016 IF ( .NOT. foundcoupling ) THEN
1017 CALL nl_get_io_form_auxhist1( 1, io_form )
1018 IF ( use_package( io_form ) == IO_ESMF ) THEN
1019 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST1_ALARM ), &
1020 RingInterval=couplingInterval, rc=rc )
1021 IF ( rc /= ESMF_SUCCESS ) THEN
1022 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST1_ALARM) failed' )
1024 foundcoupling = .TRUE.
1027 IF ( .NOT. foundcoupling ) THEN
1028 CALL nl_get_io_form_auxhist2( 1, io_form )
1029 IF ( use_package( io_form ) == IO_ESMF ) THEN
1030 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST2_ALARM ), &
1031 RingInterval=couplingInterval, rc=rc )
1032 IF ( rc /= ESMF_SUCCESS ) THEN
1033 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST2_ALARM) failed' )
1035 foundcoupling = .TRUE.
1038 IF ( .NOT. foundcoupling ) THEN
1039 CALL nl_get_io_form_auxhist3( 1, io_form )
1040 IF ( use_package( io_form ) == IO_ESMF ) THEN
1041 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST3_ALARM ), &
1042 RingInterval=couplingInterval, rc=rc )
1043 IF ( rc /= ESMF_SUCCESS ) THEN
1044 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST3_ALARM) failed' )
1046 foundcoupling = .TRUE.
1049 IF ( .NOT. foundcoupling ) THEN
1050 CALL nl_get_io_form_auxhist4( 1, io_form )
1051 IF ( use_package( io_form ) == IO_ESMF ) THEN
1052 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST4_ALARM ), &
1053 RingInterval=couplingInterval, rc=rc )
1054 IF ( rc /= ESMF_SUCCESS ) THEN
1055 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST4_ALARM) failed' )
1057 foundcoupling = .TRUE.
1060 IF ( .NOT. foundcoupling ) THEN
1061 CALL nl_get_io_form_auxhist5( 1, io_form )
1062 IF ( use_package( io_form ) == IO_ESMF ) THEN
1063 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST5_ALARM ), &
1064 RingInterval=couplingInterval, rc=rc )
1065 IF ( rc /= ESMF_SUCCESS ) THEN
1066 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST5_ALARM) failed' )
1068 foundcoupling = .TRUE.
1071 IF ( .NOT. foundcoupling ) THEN
1072 CALL nl_get_io_form_auxhist6( 1, io_form )
1073 IF ( use_package( io_form ) == IO_ESMF ) THEN
1074 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST6_ALARM ), &
1075 RingInterval=couplingInterval, rc=rc )
1076 IF ( rc /= ESMF_SUCCESS ) THEN
1077 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST6_ALARM) failed' )
1079 foundcoupling = .TRUE.
1082 IF ( .NOT. foundcoupling ) THEN
1083 CALL nl_get_io_form_auxhist7( 1, io_form )
1084 IF ( use_package( io_form ) == IO_ESMF ) THEN
1085 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST7_ALARM ), &
1086 RingInterval=couplingInterval, rc=rc )
1087 IF ( rc /= ESMF_SUCCESS ) THEN
1088 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST7_ALARM) failed' )
1090 foundcoupling = .TRUE.
1093 IF ( .NOT. foundcoupling ) THEN
1094 CALL nl_get_io_form_auxhist8( 1, io_form )
1095 IF ( use_package( io_form ) == IO_ESMF ) THEN
1096 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST8_ALARM ), &
1097 RingInterval=couplingInterval, rc=rc )
1098 IF ( rc /= ESMF_SUCCESS ) THEN
1099 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST8_ALARM) failed' )
1101 foundcoupling = .TRUE.
1104 IF ( .NOT. foundcoupling ) THEN
1105 CALL nl_get_io_form_auxhist9( 1, io_form )
1106 IF ( use_package( io_form ) == IO_ESMF ) THEN
1107 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST9_ALARM ), &
1108 RingInterval=couplingInterval, rc=rc )
1109 IF ( rc /= ESMF_SUCCESS ) THEN
1110 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST9_ALARM) failed' )
1112 foundcoupling = .TRUE.
1115 IF ( .NOT. foundcoupling ) THEN
1116 CALL nl_get_io_form_auxhist10( 1, io_form )
1117 IF ( use_package( io_form ) == IO_ESMF ) THEN
1118 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST10_ALARM ), &
1119 RingInterval=couplingInterval, rc=rc )
1120 IF ( rc /= ESMF_SUCCESS ) THEN
1121 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST10_ALARM) failed' )
1123 foundcoupling = .TRUE.
1126 IF ( .NOT. foundcoupling ) THEN
1127 CALL nl_get_io_form_auxhist11( 1, io_form )
1128 IF ( use_package( io_form ) == IO_ESMF ) THEN
1129 CALL ESMF_AlarmGet( head_grid%alarms( AUXHIST11_ALARM ), &
1130 RingInterval=couplingInterval, rc=rc )
1131 IF ( rc /= ESMF_SUCCESS ) THEN
1132 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ESMF_AlarmGet(AUXHIST11_ALARM) failed' )
1134 foundcoupling = .TRUE.
1138 ! look for erroneous use of io_form...
1139 CALL nl_get_io_form_restart( 1, io_form )
1140 IF ( use_package( io_form ) == IO_ESMF ) THEN
1141 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ERROR: ESMF cannot be used for WRF restart I/O' )
1143 CALL nl_get_io_form_input( 1, io_form )
1144 IF ( use_package( io_form ) == IO_ESMF ) THEN
1145 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ERROR: ESMF cannot be used for WRF input' )
1147 CALL nl_get_io_form_history( 1, io_form )
1148 IF ( use_package( io_form ) == IO_ESMF ) THEN
1149 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ERROR: ESMF cannot be used for WRF history output' )
1151 CALL nl_get_io_form_boundary( 1, io_form )
1152 IF ( use_package( io_form ) == IO_ESMF ) THEN
1153 CALL wrf_error_fatal ( 'wrf_findCouplingInterval: ERROR: ESMF cannot be used for WRF boundary I/O' )
1156 ! If nobody uses IO_ESMF, then default is to run WRF all the way to
1158 IF ( .NOT. foundcoupling ) THEN
1159 couplingInterval = stopTime - startTime
1160 call wrf_debug ( 1, 'WARNING: ESMF coupling not used in this WRF run' )
1163 END SUBROUTINE wrf_findCouplingInterval
1167 SUBROUTINE wrf_getDecompInfo( ids, ide, jds, jde, kds, kde, &
1168 ims, ime, jms, jme, kms, kme, &
1169 ips, ipe, jps, jpe, kps, kpe, &
1171 INTEGER, INTENT(OUT) :: ids, ide, jds, jde, kds, kde
1172 INTEGER, INTENT(OUT) :: ims, ime, jms, jme, kms, kme
1173 INTEGER, INTENT(OUT) :: ips, ipe, jps, jpe, kps, kpe
1174 INTEGER, INTENT(OUT) :: domdesc
1175 LOGICAL, INTENT(OUT) :: bdy_mask(4)
1177 ! WRF convenience routine for deducing decomposition information.
1178 !TODO: Note that domdesc is meaningful only for SPMD alternating event loops.
1179 !TODO: For concurrent operation (SPMD or MPMD), we will need to create a new
1180 !TODO: "domdesc" suitable for the task layout of the SST component. For
1181 !TODO: MPMD alternating event loops, we will need to serialize domdesc and
1182 !TODO: store it as metadata within the export state. Similar arguments apply
1183 !TODO: to [ij][mp][se] and bdy_mask.
1185 ! The arguments are:
1186 ! ids, ide, jds, jde, kds, kde Domain extent.
1187 ! ims, ime, jms, jme, kms, kme Memory extent.
1188 ! ips, ipe, jps, jpe, kps, kpe Patch extent.
1189 ! domdesc Domain descriptor for external
1190 ! distributed-memory communication
1191 ! package (opaque to WRF).
1192 ! bdy_mask Boundary mask flags indicating which
1193 ! domain boundaries are on this task.
1195 ! extract decomposition information from head_grid
1196 CALL get_ijk_from_grid( head_grid , &
1197 ids, ide, jds, jde, kds, kde, &
1198 ims, ime, jms, jme, kms, kme, &
1199 ips, ipe, jps, jpe, kps, kpe )
1201 ! with version 3 of ESMF's staggering concepts, WRF's non-staggered grid is equivalent to
1202 ! esmf's 'exclusive' region -- that is the set of points that are owned by the 'DE' (eyeroll)
1203 ! WRF, on the other hand, is returning the 'staggered' dimensions here. So convert to the
1204 ! unstaggered dims before returning.
1205 ! Don't bother with vertical dimension for the time being, since we're only doing 2D coupling.
1208 ide = ide-1 ; ipe = MIN(ide,ipe)
1209 jde = jde-1 ; jpe = MIN(jde,jpe)
1211 domdesc = head_grid%domdesc
1212 bdy_mask = head_grid%bdy_mask
1213 END SUBROUTINE wrf_getDecompInfo
1216 SUBROUTINE wrf_state_populate( ierr )
1218 USE module_domain, ONLY : domain
1219 USE module_io_domain
1221 USE module_configure, ONLY : grid_config_rec_type, model_to_grid_config_rec
1222 USE module_bc_time_utilities
1227 ! Populate WRF import and export states from Registry-generated code.
1228 ! For now, only head_grid can be coupled.
1231 !TODO: Extend later to include child
1232 !TODO: domains, possibly via nested ESMF_State's.
1235 INTEGER, INTENT(OUT) :: ierr
1237 TYPE(domain), POINTER :: grid
1238 TYPE(grid_config_rec_type) :: config_flags
1239 INTEGER :: stream, idum1, idum2, io_form
1240 CHARACTER*80 :: fname, n2
1241 ! external function prototype
1242 INTEGER, EXTERNAL :: use_package
1244 ! for now support coupling to head_grid only
1246 ! TODO: Use actual grid via current_grid%id via something like this...
1247 ! IF ( current_grid_set ) THEN
1248 ! grid => current_grid
1253 CALL model_to_grid_config_rec ( grid%id , model_config_rec , config_flags )
1254 CALL set_scalar_indices_from_config ( grid%id , idum1 , idum2 )
1259 ! "Loop" over auxin streams mucking with io_esmf streams only... Ick.
1260 ! Would need to store function pointers in an array in order to put this
1262 CALL nl_get_io_form_auxinput1( 1, io_form )
1263 IF ( use_package( io_form ) == IO_ESMF ) THEN
1265 CALL open_aux_u( grid, config_flags, stream, AUXINPUT1_ALARM, &
1266 config_flags%auxinput1_inname, grid%auxinput1_oid, &
1267 input_aux_model_input1, ierr )
1268 IF ( ierr /= 0 ) RETURN
1270 CALL nl_get_io_form_auxinput2( 1, io_form )
1271 IF ( use_package( io_form ) == IO_ESMF ) THEN
1273 CALL open_aux_u( grid, config_flags, stream, AUXINPUT2_ALARM, &
1274 config_flags%auxinput2_inname, grid%auxinput2_oid, &
1275 input_aux_model_input2, ierr )
1276 IF ( ierr /= 0 ) RETURN
1278 CALL nl_get_io_form_auxinput3( 1, io_form )
1279 IF ( use_package( io_form ) == IO_ESMF ) THEN
1281 CALL open_aux_u( grid, config_flags, stream, AUXINPUT3_ALARM, &
1282 config_flags%auxinput3_inname, grid%auxinput3_oid, &
1283 input_aux_model_input3, ierr )
1284 IF ( ierr /= 0 ) RETURN
1286 CALL nl_get_io_form_auxinput4( 1, io_form )
1287 IF ( use_package( io_form ) == IO_ESMF ) THEN
1289 CALL open_aux_u( grid, config_flags, stream, AUXINPUT4_ALARM, &
1290 config_flags%auxinput4_inname, grid%auxinput4_oid, &
1291 input_aux_model_input4, ierr )
1292 IF ( ierr /= 0 ) RETURN
1294 CALL nl_get_io_form_auxinput5( 1, io_form )
1295 IF ( use_package( io_form ) == IO_ESMF ) THEN
1297 CALL open_aux_u( grid, config_flags, stream, AUXINPUT5_ALARM, &
1298 config_flags%auxinput5_inname, grid%auxinput5_oid, &
1299 input_aux_model_input5, ierr )
1300 IF ( ierr /= 0 ) RETURN
1302 CALL nl_get_io_form_auxinput6( 1, io_form )
1303 IF ( use_package( io_form ) == IO_ESMF ) THEN
1305 CALL open_aux_u( grid, config_flags, stream, AUXINPUT6_ALARM, &
1306 config_flags%auxinput6_inname, grid%auxinput6_oid, &
1307 input_aux_model_input6, ierr )
1308 IF ( ierr /= 0 ) RETURN
1310 CALL nl_get_io_form_auxinput7( 1, io_form )
1311 IF ( use_package( io_form ) == IO_ESMF ) THEN
1313 CALL open_aux_u( grid, config_flags, stream, AUXINPUT7_ALARM, &
1314 config_flags%auxinput7_inname, grid%auxinput7_oid, &
1315 input_aux_model_input7, ierr )
1316 IF ( ierr /= 0 ) RETURN
1318 CALL nl_get_io_form_auxinput8( 1, io_form )
1319 IF ( use_package( io_form ) == IO_ESMF ) THEN
1321 CALL open_aux_u( grid, config_flags, stream, AUXINPUT8_ALARM, &
1322 config_flags%auxinput8_inname, grid%auxinput8_oid, &
1323 input_aux_model_input8, ierr )
1324 IF ( ierr /= 0 ) RETURN
1326 CALL nl_get_io_form_auxinput9( 1, io_form )
1327 IF ( use_package( io_form ) == IO_ESMF ) THEN
1329 CALL open_aux_u( grid, config_flags, stream, AUXINPUT9_ALARM, &
1330 config_flags%auxinput9_inname, grid%auxinput9_oid, &
1331 input_aux_model_input9, ierr )
1332 IF ( ierr /= 0 ) RETURN
1334 CALL nl_get_io_form_gfdda( 1, io_form )
1335 IF ( use_package( io_form ) == IO_ESMF ) THEN
1337 CALL open_aux_u( grid, config_flags, stream, AUXINPUT10_ALARM, &
1338 config_flags%gfdda_inname, grid%auxinput10_oid, &
1339 input_aux_model_input10, ierr )
1340 IF ( ierr /= 0 ) RETURN
1342 CALL nl_get_io_form_auxinput11( 1, io_form )
1343 IF ( use_package( io_form ) == IO_ESMF ) THEN
1345 CALL open_aux_u( grid, config_flags, stream, AUXINPUT11_ALARM, &
1346 config_flags%auxinput11_inname, grid%auxinput11_oid, &
1347 input_aux_model_input11, ierr )
1348 IF ( ierr /= 0 ) RETURN
1351 ! "Loop" over history streams mucking with io_esmf streams only... Ick.
1352 ! Would need to store function pointers in an array in order to put this
1354 CALL nl_get_io_form_auxhist1( 1, io_form )
1355 IF ( use_package( io_form ) == IO_ESMF ) THEN
1357 CALL open_hist_w( grid, config_flags, stream, AUXHIST1_ALARM, &
1358 config_flags%auxhist1_outname, grid%auxhist1_oid, &
1359 output_aux_hist1, fname, n2, ierr )
1360 IF ( ierr /= 0 ) RETURN
1362 CALL nl_get_io_form_auxhist2( 1, io_form )
1363 IF ( use_package( io_form ) == IO_ESMF ) THEN
1365 CALL open_hist_w( grid, config_flags, stream, AUXHIST2_ALARM, &
1366 config_flags%auxhist2_outname, grid%auxhist2_oid, &
1367 output_aux_hist2, fname, n2, ierr )
1368 IF ( ierr /= 0 ) RETURN
1370 CALL nl_get_io_form_auxhist3( 1, io_form )
1371 IF ( use_package( io_form ) == IO_ESMF ) THEN
1373 CALL open_hist_w( grid, config_flags, stream, AUXHIST3_ALARM, &
1374 config_flags%auxhist3_outname, grid%auxhist3_oid, &
1375 output_aux_hist3, fname, n2, ierr )
1376 IF ( ierr /= 0 ) RETURN
1378 CALL nl_get_io_form_auxhist4( 1, io_form )
1379 IF ( use_package( io_form ) == IO_ESMF ) THEN
1381 CALL open_hist_w( grid, config_flags, stream, AUXHIST4_ALARM, &
1382 config_flags%auxhist4_outname, grid%auxhist4_oid, &
1383 output_aux_hist4, fname, n2, ierr )
1384 IF ( ierr /= 0 ) RETURN
1386 CALL nl_get_io_form_auxhist5( 1, io_form )
1387 IF ( use_package( io_form ) == IO_ESMF ) THEN
1389 CALL open_hist_w( grid, config_flags, stream, AUXHIST5_ALARM, &
1390 config_flags%auxhist5_outname, grid%auxhist5_oid, &
1391 output_aux_hist5, fname, n2, ierr )
1392 IF ( ierr /= 0 ) RETURN
1394 CALL nl_get_io_form_auxhist6( 1, io_form )
1395 IF ( use_package( io_form ) == IO_ESMF ) THEN
1397 CALL open_hist_w( grid, config_flags, stream, AUXHIST6_ALARM, &
1398 config_flags%auxhist6_outname, grid%auxhist6_oid, &
1399 output_aux_hist6, fname, n2, ierr )
1400 IF ( ierr /= 0 ) RETURN
1402 CALL nl_get_io_form_auxhist7( 1, io_form )
1403 IF ( use_package( io_form ) == IO_ESMF ) THEN
1405 CALL open_hist_w( grid, config_flags, stream, AUXHIST7_ALARM, &
1406 config_flags%auxhist7_outname, grid%auxhist7_oid, &
1407 output_aux_hist7, fname, n2, ierr )
1408 IF ( ierr /= 0 ) RETURN
1410 CALL nl_get_io_form_auxhist8( 1, io_form )
1411 IF ( use_package( io_form ) == IO_ESMF ) THEN
1413 CALL open_hist_w( grid, config_flags, stream, AUXHIST8_ALARM, &
1414 config_flags%auxhist8_outname, grid%auxhist8_oid, &
1415 output_aux_hist8, fname, n2, ierr )
1416 IF ( ierr /= 0 ) RETURN
1418 CALL nl_get_io_form_auxhist9( 1, io_form )
1419 IF ( use_package( io_form ) == IO_ESMF ) THEN
1421 CALL open_hist_w( grid, config_flags, stream, AUXHIST9_ALARM, &
1422 config_flags%auxhist9_outname, grid%auxhist9_oid, &
1423 output_aux_hist9, fname, n2, ierr )
1424 IF ( ierr /= 0 ) RETURN
1426 CALL nl_get_io_form_auxhist10( 1, io_form )
1427 IF ( use_package( io_form ) == IO_ESMF ) THEN
1429 CALL open_hist_w( grid, config_flags, stream, AUXHIST10_ALARM, &
1430 config_flags%auxhist10_outname, grid%auxhist10_oid, &
1431 output_aux_hist10, fname, n2, ierr )
1432 IF ( ierr /= 0 ) RETURN
1434 CALL nl_get_io_form_auxhist11( 1, io_form )
1435 IF ( use_package( io_form ) == IO_ESMF ) THEN
1437 CALL open_hist_w( grid, config_flags, stream, AUXHIST11_ALARM, &
1438 config_flags%auxhist11_outname, grid%auxhist11_oid, &
1439 output_aux_hist11, fname, n2, ierr )
1440 IF ( ierr /= 0 ) RETURN
1442 END SUBROUTINE wrf_state_populate
1444 END MODULE module_wrf_component_top
1448 MODULE module_wrf_setservices
1450 ! This module defines WRF "Set Services" method wrf_register()
1451 ! used for ESMF coupling.
1454 USE module_wrf_component_top, ONLY: wrf_component_init1, &
1455 wrf_component_init2, &
1456 wrf_component_run, &
1457 wrf_component_finalize
1462 ! everything is private by default
1465 ! Public entry point for ESMF_GridCompSetServices()
1469 CHARACTER (ESMF_MAXSTR) :: str
1474 SUBROUTINE wrf_register(gcomp, rc)
1475 TYPE(ESMF_GridComp), INTENT(INOUT) :: gcomp
1476 INTEGER, INTENT(OUT) :: rc
1479 ! WRF_register - Externally visible registration routine
1481 ! User-supplied SetServices routine.
1482 ! The Register routine sets the subroutines to be called
1483 ! as the init, run, and finalize routines. Note that these are
1484 ! private to the module.
1486 ! The arguments are:
1488 ! rc Return code; equals ESMF_SUCCESS if there are no errors,
1489 ! otherwise ESMF_FAILURE.
1493 ! Register the callback routines.
1494 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
1495 wrf_component_init1, 1, rc)
1496 IF ( rc /= ESMF_SUCCESS) THEN
1497 CALL wrf_error_fatal ( 'wrf_register: ESMF_GridCompSetEntryPoint(wrf_component_init1) failed' )
1499 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETINIT, &
1500 wrf_component_init2, 2, rc)
1501 IF ( rc /= ESMF_SUCCESS) THEN
1502 CALL wrf_error_fatal ( 'wrf_register: ESMF_GridCompSetEntryPoint(wrf_component_init2) failed' )
1504 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETRUN, &
1505 wrf_component_run, ESMF_SINGLEPHASE, rc)
1506 IF ( rc /= ESMF_SUCCESS) THEN
1507 CALL wrf_error_fatal ( 'wrf_register: ESMF_GridCompSetEntryPoint(wrf_component_run) failed' )
1509 call ESMF_GridCompSetEntryPoint(gcomp, ESMF_SETFINAL, &
1510 wrf_component_finalize, ESMF_SINGLEPHASE, rc)
1511 IF ( rc /= ESMF_SUCCESS) THEN
1512 CALL wrf_error_fatal ( 'wrf_register: ESMF_GridCompSetEntryPoint(wrf_component_finalize) failed' )
1514 PRINT *,'WRF: Registered Initialize, Run, and Finalize routines'
1516 END SUBROUTINE wrf_register
1518 END MODULE module_wrf_setservices