8 ! WRF-specific package-independent interface to package-dependent WRF-specific
11 ! These routines have the same names as those specified in the WRF I/O API
13 ! - Routines defined in this file and called by users of this module have
15 ! - Routines defined in the I/O packages and called from routines in this
16 ! file have the "ext_" prefix.
17 ! - Routines called from routines in this file to initiate communication
18 ! with I/O quilt servers have the "wrf_quilt_" prefix.
20 ! See http://www.mmm.ucar.edu/wrf/WG2/software_2.0/IOAPI.doc for the latest
21 ! version of the WRF I/O API. This document includes detailed descriptions
22 ! of subroutines and their arguments that are not duplicated in this file.
24 ! We wish to be able to link to different packages depending on whether
25 ! the I/O is restart, initial, history, or boundary.
31 LOGICAL :: is_inited = .FALSE.
32 INTEGER, PARAMETER, PRIVATE :: MAX_WRF_IO_HANDLE = 1000
33 INTEGER :: wrf_io_handles(MAX_WRF_IO_HANDLE), how_opened(MAX_WRF_IO_HANDLE)
34 LOGICAL :: for_output(MAX_WRF_IO_HANDLE), first_operation(MAX_WRF_IO_HANDLE)
36 LOGICAL, PRIVATE :: bdy_dist_flag = .TRUE. ! false is old style undecomposed boundary data structs,
37 ! true is new style decomposed boundary data structs
38 ! are_bdys_distributed, bdys_are_distributed and
39 ! bdys_not_distributed routines access this flag
44 ! include the file generated from md_calls.m4 using the m4 preprocessor
45 ! note that this file also includes the CONTAINS declaration for the module
49 #include "md_calls.inc"
53 SUBROUTINE wrf_ioinit( Status )
56 ! Initialize the WRF I/O system.
60 INTEGER, INTENT(INOUT) :: Status
62 CHARACTER(len=80) :: SysDepInfo
63 INTEGER :: ierr(10), minerr, maxerr
68 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioinit' )
69 CALL init_io_handles ! defined below
71 CALL ext_ncd_ioinit( SysDepInfo, ierr(1) )
74 CALL ext_int_ioinit( SysDepInfo, ierr(2) )
77 CALL ext_phdf5_ioinit( SysDepInfo, ierr(3) )
80 CALL ext_pnc_ioinit( SysDepInfo, ierr(3) )
83 CALL ext_mcel_ioinit( SysDepInfo, ierr(4) )
86 CALL ext_xxx_ioinit( SysDepInfo, ierr(5) )
89 CALL ext_yyy_ioinit( SysDepInfo, ierr(6) )
92 CALL ext_zzz_ioinit( SysDepInfo, ierr(7) )
95 CALL ext_esmf_ioinit( SysDepInfo, ierr(8) )
98 CALL ext_gr1_ioinit( SysDepInfo, ierr(9) )
101 CALL ext_gr2_ioinit( SysDepInfo, ierr(10) )
103 minerr = MINVAL(ierr)
104 maxerr = MAXVAL(ierr)
105 IF ( minerr < 0 ) THEN
107 ELSE IF ( maxerr > 0 ) THEN
112 END SUBROUTINE wrf_ioinit
116 SUBROUTINE wrf_ioexit( Status )
119 ! Shut down the WRF I/O system.
123 INTEGER, INTENT(INOUT) :: Status
125 LOGICAL, EXTERNAL :: use_output_servers
126 INTEGER :: ierr(11), minerr, maxerr
130 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioexit' )
132 CALL ext_ncd_ioexit( ierr(1) )
135 CALL ext_int_ioexit( ierr(2) )
138 CALL ext_phdf5_ioexit(ierr(3) )
141 CALL ext_pnc_ioexit(ierr(3) )
144 CALL ext_mcel_ioexit( ierr(4) )
147 CALL ext_xxx_ioexit( ierr(5) )
150 CALL ext_yyy_ioexit( ierr(6) )
153 CALL ext_zzz_ioexit( ierr(7) )
156 CALL ext_esmf_ioexit( ierr(8) )
159 CALL ext_gr1_ioexit( ierr(9) )
162 CALL ext_gr2_ioexit( ierr(10) )
165 IF ( use_output_servers() ) CALL wrf_quilt_ioexit( ierr(11) )
166 minerr = MINVAL(ierr)
167 maxerr = MAXVAL(ierr)
168 IF ( minerr < 0 ) THEN
170 ELSE IF ( maxerr > 0 ) THEN
175 END SUBROUTINE wrf_ioexit
177 !--- open_for_write_begin
179 SUBROUTINE wrf_open_for_write_begin( FileName , Comm_compute, Comm_io, SysDepInfo, &
180 DataHandle , Status )
183 ! Begin data definition ("training") phase for writing to WRF dataset
187 USE module_state_description
189 #include "wrf_io_flags.h"
190 CHARACTER*(*) :: FileName
191 INTEGER , INTENT(IN) :: Comm_compute , Comm_io
192 CHARACTER*(*), INTENT(INOUT):: SysDepInfo
193 INTEGER , INTENT(OUT) :: DataHandle
194 INTEGER , INTENT(OUT) :: Status
196 CHARACTER*128 :: DataSet
199 INTEGER, EXTERNAL :: use_package
200 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
201 CHARACTER*128 :: LocFilename ! for appending the process ID if necessary
203 CHARACTER*128 :: mess
204 CHARACTER*1028 :: tstr
206 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_write_begin' )
208 CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
210 IF ( DataSet .eq. 'RESTART' ) THEN
211 CALL nl_get_io_form_restart( 1, io_form )
212 ELSE IF ( DataSet .eq. 'INPUT' ) THEN
213 CALL nl_get_io_form_input( 1, io_form )
214 ELSE IF ( DataSet .eq. 'AUXINPUT1' ) THEN
215 CALL nl_get_io_form_auxinput1( 1, io_form )
216 ELSE IF ( DataSet .eq. 'AUXINPUT2' ) THEN
217 CALL nl_get_io_form_auxinput2( 1, io_form )
218 ELSE IF ( DataSet .eq. 'AUXINPUT3' ) THEN
219 CALL nl_get_io_form_auxinput3( 1, io_form )
220 ELSE IF ( DataSet .eq. 'AUXINPUT4' ) THEN
221 CALL nl_get_io_form_auxinput4( 1, io_form )
222 ELSE IF ( DataSet .eq. 'AUXINPUT5' ) THEN
223 CALL nl_get_io_form_auxinput5( 1, io_form )
224 ELSE IF ( DataSet .eq. 'AUXINPUT6' ) THEN
225 CALL nl_get_io_form_auxinput6( 1, io_form )
226 ELSE IF ( DataSet .eq. 'AUXINPUT7' ) THEN
227 CALL nl_get_io_form_auxinput7( 1, io_form )
228 ELSE IF ( DataSet .eq. 'AUXINPUT8' ) THEN
229 CALL nl_get_io_form_auxinput8( 1, io_form )
230 ELSE IF ( DataSet .eq. 'AUXINPUT9' ) THEN
231 CALL nl_get_io_form_auxinput9( 1, io_form )
232 ELSE IF ( DataSet .eq. 'AUXINPUT10' ) THEN
233 CALL nl_get_io_form_gfdda( 1, io_form )
234 ELSE IF ( DataSet .eq. 'AUXINPUT11' ) THEN
235 CALL nl_get_io_form_auxinput11( 1, io_form )
237 ELSE IF ( DataSet .eq. 'HISTORY' ) THEN
238 CALL nl_get_io_form_history( 1, io_form )
239 ELSE IF ( DataSet .eq. 'AUXHIST1' ) THEN
240 CALL nl_get_io_form_auxhist1( 1, io_form )
241 ELSE IF ( DataSet .eq. 'AUXHIST2' ) THEN
242 CALL nl_get_io_form_auxhist2( 1, io_form )
243 ELSE IF ( DataSet .eq. 'AUXHIST3' ) THEN
244 CALL nl_get_io_form_auxhist3( 1, io_form )
245 ELSE IF ( DataSet .eq. 'AUXHIST4' ) THEN
246 CALL nl_get_io_form_auxhist4( 1, io_form )
247 ELSE IF ( DataSet .eq. 'AUXHIST5' ) THEN
248 CALL nl_get_io_form_auxhist5( 1, io_form )
249 ELSE IF ( DataSet .eq. 'AUXHIST6' ) THEN
250 CALL nl_get_io_form_auxhist6( 1, io_form )
251 ELSE IF ( DataSet .eq. 'AUXHIST7' ) THEN
252 CALL nl_get_io_form_auxhist7( 1, io_form )
253 ELSE IF ( DataSet .eq. 'AUXHIST8' ) THEN
254 CALL nl_get_io_form_auxhist8( 1, io_form )
255 ELSE IF ( DataSet .eq. 'AUXHIST9' ) THEN
256 CALL nl_get_io_form_auxhist9( 1, io_form )
257 ELSE IF ( DataSet .eq. 'AUXHIST10' ) THEN
258 CALL nl_get_io_form_auxhist10( 1, io_form )
259 ELSE IF ( DataSet .eq. 'AUXHIST11' ) THEN
260 CALL nl_get_io_form_auxhist11( 1, io_form )
262 ELSE IF ( DataSet .eq. 'BOUNDARY' ) THEN
263 CALL nl_get_io_form_boundary( 1, io_form )
264 ELSE ! default if nothing is set in SysDepInfo; use history
265 CALL nl_get_io_form_history( 1, io_form )
270 IF ( multi_files( io_form ) .OR. .NOT. use_output_servers() ) THEN
271 SELECT CASE ( use_package(io_form) )
274 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
275 IF ( multi_files(io_form) ) THEN
276 CALL wrf_get_myproc ( myproc )
277 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
279 LocFilename = FileName
281 CALL ext_ncd_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
284 IF ( .NOT. multi_files(io_form) ) THEN
285 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
286 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
291 CALL ext_phdf5_open_for_write_begin( FileName, Comm_compute, Comm_io, SysDepInfo, &
296 CALL ext_pnc_open_for_write_begin( FileName, Comm_compute, Comm_io, SysDepInfo, &
301 CALL ext_xxx_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
306 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
307 IF ( multi_files(io_form) ) THEN
308 CALL wrf_get_myproc ( myproc )
309 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
311 LocFilename = FileName
313 CALL ext_yyy_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
316 IF ( .NOT. multi_files(io_form) ) THEN
317 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
318 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
323 CALL ext_zzz_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
328 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
329 IF ( multi_files(io_form) ) THEN
330 CALL wrf_get_myproc ( myproc )
331 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
333 LocFilename = FileName
335 CALL ext_gr1_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
338 IF ( .NOT. multi_files(io_form) ) THEN
339 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
340 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
345 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
346 IF ( multi_files(io_form) ) THEN
347 CALL wrf_get_myproc ( myproc )
348 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
350 LocFilename = FileName
352 CALL ext_gr2_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
355 IF ( .NOT. multi_files(io_form) ) THEN
356 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
357 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
362 IF ( wrf_dm_on_monitor() ) THEN
363 tstr = TRIM(SysDepInfo) // ',' // 'LAT_R=XLAT,LON_R=XLONG,LANDMASK_I=LU_MASK'
364 CALL ext_mcel_open_for_write_begin ( FileName , Comm_compute, Comm_io, tstr, &
367 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
368 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
372 CALL ext_esmf_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
377 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
378 IF ( multi_files(io_form) ) THEN
379 CALL wrf_get_myproc ( myproc )
380 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
382 LocFilename = FileName
384 CALL ext_int_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
387 IF ( .NOT. multi_files(io_form) ) THEN
388 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
389 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
393 IF ( io_form .NE. 0 ) THEN
394 WRITE(mess,*)'Tried to open ',FileName,' writing: no valid io_form (',io_form,')'
395 CALL wrf_debug(1, mess)
396 Status = WRF_FILE_NOT_OPENED
399 ELSE IF ( use_output_servers() ) THEN
400 IF ( io_form .GT. 0 ) THEN
401 CALL wrf_quilt_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
402 Hndl , io_form, Status )
407 CALL add_new_handle( Hndl, io_form, .TRUE., DataHandle )
408 END SUBROUTINE wrf_open_for_write_begin
410 !--- open_for_write_commit
412 SUBROUTINE wrf_open_for_write_commit( DataHandle , Status )
415 ! This routine switches an internal flag to enable output for the data set
416 ! referenced by DataHandle. The call to wrf_open_for_write_commit() must be
417 ! paired with a call to wrf_open_for_write_begin().
420 USE module_state_description
422 INTEGER , INTENT(IN ) :: DataHandle
423 INTEGER , INTENT(OUT) :: Status
425 CHARACTER (128) :: DataSet
429 INTEGER, EXTERNAL :: use_package
430 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
431 #include "wrf_io_flags.h"
433 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_write_commit' )
436 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
437 CALL set_first_operation( DataHandle )
438 IF ( Hndl .GT. -1 ) THEN
439 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
440 SELECT CASE ( use_package(io_form) )
443 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
444 CALL ext_ncd_open_for_write_commit ( Hndl , Status )
446 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
450 IF ( wrf_dm_on_monitor() ) THEN
451 CALL ext_mcel_open_for_write_commit ( Hndl , Status )
453 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
457 CALL ext_esmf_open_for_write_commit ( Hndl , Status )
461 CALL ext_phdf5_open_for_write_commit ( Hndl , Status )
465 CALL ext_pnc_open_for_write_commit ( Hndl , Status )
469 CALL ext_xxx_open_for_write_commit ( Hndl , Status )
473 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
474 CALL ext_yyy_open_for_write_commit ( Hndl , Status )
476 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
480 CALL ext_zzz_open_for_write_commit ( Hndl , Status )
484 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
485 CALL ext_gr1_open_for_write_commit ( Hndl , Status )
487 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
491 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
492 CALL ext_gr2_open_for_write_commit ( Hndl , Status )
494 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
498 CALL ext_int_open_for_write_commit ( Hndl , Status )
503 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
504 CALL wrf_quilt_open_for_write_commit ( Hndl , Status )
512 END SUBROUTINE wrf_open_for_write_commit
514 !--- open_for_read_begin
516 SUBROUTINE wrf_open_for_read_begin( FileName , Comm_compute, Comm_io, SysDepInfo, &
517 DataHandle , Status )
520 ! Begin data definition ("training") phase for reading from WRF dataset
524 USE module_state_description
526 #include "wrf_io_flags.h"
527 CHARACTER*(*) :: FileName
528 INTEGER , INTENT(IN) :: Comm_compute , Comm_io
529 CHARACTER*(*) :: SysDepInfo
530 INTEGER , INTENT(OUT) :: DataHandle
531 INTEGER , INTENT(OUT) :: Status
533 CHARACTER*128 :: DataSet
536 LOGICAL :: also_for_out
537 INTEGER, EXTERNAL :: use_package
538 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
540 CHARACTER*128 :: LocFilename ! for appending the process ID if necessary
542 CHARACTER*128 :: mess, fhand
543 CHARACTER*1028 :: tstr
545 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read_begin' )
547 CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
548 IF ( DataSet .eq. 'RESTART' ) THEN
549 CALL nl_get_io_form_restart( 1, io_form )
550 ELSE IF ( DataSet .eq. 'INPUT' ) THEN
551 CALL nl_get_io_form_input( 1, io_form )
552 ELSE IF ( DataSet .eq. 'AUXINPUT1' ) THEN
553 CALL nl_get_io_form_auxinput1( 1, io_form )
554 ELSE IF ( DataSet .eq. 'AUXINPUT2' ) THEN
555 CALL nl_get_io_form_auxinput2( 1, io_form )
556 ELSE IF ( DataSet .eq. 'AUXINPUT3' ) THEN
557 CALL nl_get_io_form_auxinput3( 1, io_form )
558 ELSE IF ( DataSet .eq. 'AUXINPUT4' ) THEN
559 CALL nl_get_io_form_auxinput4( 1, io_form )
560 ELSE IF ( DataSet .eq. 'AUXINPUT5' ) THEN
561 CALL nl_get_io_form_auxinput5( 1, io_form )
562 ELSE IF ( DataSet .eq. 'AUXINPUT6' ) THEN
563 CALL nl_get_io_form_auxinput6( 1, io_form )
564 ELSE IF ( DataSet .eq. 'AUXINPUT7' ) THEN
565 CALL nl_get_io_form_auxinput7( 1, io_form )
566 ELSE IF ( DataSet .eq. 'AUXINPUT8' ) THEN
567 CALL nl_get_io_form_auxinput8( 1, io_form )
568 ELSE IF ( DataSet .eq. 'AUXINPUT9' ) THEN
569 CALL nl_get_io_form_auxinput9( 1, io_form )
570 ELSE IF ( DataSet .eq. 'AUXINPUT10' ) THEN
571 CALL nl_get_io_form_gfdda( 1, io_form )
572 ELSE IF ( DataSet .eq. 'AUXINPUT11' ) THEN
573 CALL nl_get_io_form_auxinput11( 1, io_form )
575 ELSE IF ( DataSet .eq. 'HISTORY' ) THEN
576 CALL nl_get_io_form_history( 1, io_form )
577 ELSE IF ( DataSet .eq. 'AUXHIST1' ) THEN
578 CALL nl_get_io_form_auxhist1( 1, io_form )
579 ELSE IF ( DataSet .eq. 'AUXHIST2' ) THEN
580 CALL nl_get_io_form_auxhist2( 1, io_form )
581 ELSE IF ( DataSet .eq. 'AUXHIST3' ) THEN
582 CALL nl_get_io_form_auxhist3( 1, io_form )
583 ELSE IF ( DataSet .eq. 'AUXHIST4' ) THEN
584 CALL nl_get_io_form_auxhist4( 1, io_form )
585 ELSE IF ( DataSet .eq. 'AUXHIST5' ) THEN
586 CALL nl_get_io_form_auxhist5( 1, io_form )
587 ELSE IF ( DataSet .eq. 'AUXHIST6' ) THEN
588 CALL nl_get_io_form_auxhist6( 1, io_form )
589 ELSE IF ( DataSet .eq. 'AUXHIST7' ) THEN
590 CALL nl_get_io_form_auxhist7( 1, io_form )
591 ELSE IF ( DataSet .eq. 'AUXHIST8' ) THEN
592 CALL nl_get_io_form_auxhist8( 1, io_form )
593 ELSE IF ( DataSet .eq. 'AUXHIST9' ) THEN
594 CALL nl_get_io_form_auxhist9( 1, io_form )
595 ELSE IF ( DataSet .eq. 'AUXHIST10' ) THEN
596 CALL nl_get_io_form_auxhist10( 1, io_form )
597 ELSE IF ( DataSet .eq. 'AUXHIST11' ) THEN
598 CALL nl_get_io_form_auxhist11( 1, io_form )
600 ELSE IF ( DataSet .eq. 'BOUNDARY' ) THEN
601 CALL nl_get_io_form_boundary( 1, io_form )
602 ELSE ! default if nothing is set in SysDepInfo; use history
603 CALL nl_get_io_form_history( 1, io_form )
608 also_for_out = .FALSE.
609 ! IF ( .NOT. use_output_servers() ) THEN
610 SELECT CASE ( use_package(io_form) )
613 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
614 IF ( multi_files(io_form) ) THEN
615 CALL wrf_get_myproc ( myproc )
616 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
618 LocFilename = FileName
620 CALL ext_ncd_open_for_read_begin ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
623 IF ( .NOT. multi_files(io_form) ) THEN
624 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
625 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
630 CALL ext_xxx_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
635 CALL ext_yyy_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
640 CALL ext_zzz_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
645 also_for_out = .TRUE.
646 IF ( wrf_dm_on_monitor() ) THEN
648 WRITE(fhand,'(a,i0)')"filter_",filtno
650 tstr = TRIM(SysDepInfo) // ',' // 'READ_MODE=UPDATE,LAT_R=XLAT,LON_R=XLONG,LANDMASK_I=LU_MASK,FILTER_HANDLE=' // TRIM(fhand)
651 CALL ext_mcel_open_for_read_begin ( FileName , Comm_compute, Comm_io, tstr, &
654 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
655 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
659 also_for_out = .TRUE.
660 CALL ext_esmf_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
665 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
666 IF ( multi_files(io_form) ) THEN
667 CALL wrf_get_myproc ( myproc )
668 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
670 LocFilename = FileName
672 CALL ext_gr1_open_for_read_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
675 IF ( .NOT. multi_files(io_form) ) THEN
676 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
677 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
682 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
683 IF ( multi_files(io_form) ) THEN
684 CALL wrf_get_myproc ( myproc )
685 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
687 LocFilename = FileName
689 CALL ext_gr2_open_for_read_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
692 IF ( .NOT. multi_files(io_form) ) THEN
693 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
694 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
701 IF ( io_form .NE. 0 ) THEN
702 WRITE(mess,*)'Tried to open ',FileName,' reading: no valid io_form (',io_form,')'
703 CALL wrf_message(mess)
705 Status = WRF_FILE_NOT_OPENED
710 CALL add_new_handle( Hndl, io_form, also_for_out, DataHandle )
711 END SUBROUTINE wrf_open_for_read_begin
713 !--- open_for_read_commit
715 SUBROUTINE wrf_open_for_read_commit( DataHandle , Status )
718 ! End "training" phase for WRF dataset FileName. The call to
719 ! wrf_open_for_read_commit() must be paired with a call to
720 ! wrf_open_for_read_begin().
723 USE module_state_description
725 INTEGER , INTENT(IN ) :: DataHandle
726 INTEGER , INTENT(OUT) :: Status
728 CHARACTER (128) :: DataSet
732 INTEGER, EXTERNAL :: use_package
733 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
734 #include "wrf_io_flags.h"
736 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read_commit' )
739 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
740 CALL set_first_operation( DataHandle )
741 IF ( Hndl .GT. -1 ) THEN
742 IF ( .NOT. (for_out .AND. use_output_servers()) ) THEN
743 SELECT CASE ( use_package(io_form) )
746 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
747 CALL ext_ncd_open_for_read_commit ( Hndl , Status )
749 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
753 IF ( wrf_dm_on_monitor() ) THEN
754 CALL ext_mcel_open_for_read_commit ( Hndl , Status )
756 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
760 CALL ext_esmf_open_for_read_commit ( Hndl , Status )
764 CALL ext_xxx_open_for_read_commit ( Hndl , Status )
768 CALL ext_yyy_open_for_read_commit ( Hndl , Status )
772 CALL ext_zzz_open_for_read_commit ( Hndl , Status )
776 CALL ext_gr1_open_for_read_commit ( Hndl , Status )
780 CALL ext_gr2_open_for_read_commit ( Hndl , Status )
792 Status = WRF_FILE_NOT_OPENED
795 END SUBROUTINE wrf_open_for_read_commit
799 SUBROUTINE wrf_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
800 DataHandle , Status )
803 ! Opens a WRF dataset for reading.
806 USE module_state_description
808 CHARACTER*(*) :: FileName
809 INTEGER , INTENT(IN) :: Comm_compute , Comm_io
810 CHARACTER*(*) :: SysDepInfo
811 INTEGER , INTENT(OUT) :: DataHandle
812 INTEGER , INTENT(OUT) :: Status
814 CHARACTER (128) :: DataSet, LocFileName
815 INTEGER :: io_form, myproc
817 INTEGER, EXTERNAL :: use_package
818 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
820 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read' )
822 CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
823 IF ( DataSet .eq. 'RESTART' ) THEN
824 CALL nl_get_io_form_restart( 1, io_form )
825 ELSE IF ( DataSet .eq. 'INPUT' ) THEN
826 CALL nl_get_io_form_input( 1, io_form )
827 ELSE IF ( DataSet .eq. 'AUXINPUT1' ) THEN
828 CALL nl_get_io_form_auxinput1( 1, io_form )
829 ELSE IF ( DataSet .eq. 'AUXINPUT2' ) THEN
830 CALL nl_get_io_form_auxinput2( 1, io_form )
831 ELSE IF ( DataSet .eq. 'AUXINPUT3' ) THEN
832 CALL nl_get_io_form_auxinput3( 1, io_form )
833 ELSE IF ( DataSet .eq. 'AUXINPUT4' ) THEN
834 CALL nl_get_io_form_auxinput4( 1, io_form )
835 ELSE IF ( DataSet .eq. 'AUXINPUT5' ) THEN
836 CALL nl_get_io_form_auxinput5( 1, io_form )
837 ELSE IF ( DataSet .eq. 'AUXINPUT6' ) THEN
838 CALL nl_get_io_form_auxinput6( 1, io_form )
839 ELSE IF ( DataSet .eq. 'AUXINPUT7' ) THEN
840 CALL nl_get_io_form_auxinput7( 1, io_form )
841 ELSE IF ( DataSet .eq. 'AUXINPUT8' ) THEN
842 CALL nl_get_io_form_auxinput8( 1, io_form )
843 ELSE IF ( DataSet .eq. 'AUXINPUT9' ) THEN
844 CALL nl_get_io_form_auxinput9( 1, io_form )
845 ELSE IF ( DataSet .eq. 'AUXINPUT10' ) THEN
846 CALL nl_get_io_form_gfdda( 1, io_form )
847 ELSE IF ( DataSet .eq. 'AUXINPUT11' ) THEN
848 CALL nl_get_io_form_auxinput11( 1, io_form )
850 CALL nl_get_io_form_auxinput5( 1, io_form )
851 ELSE IF ( DataSet .eq. 'HISTORY' ) THEN
852 CALL nl_get_io_form_history( 1, io_form )
853 ELSE IF ( DataSet .eq. 'AUXHIST1' ) THEN
854 CALL nl_get_io_form_auxhist1( 1, io_form )
855 ELSE IF ( DataSet .eq. 'AUXHIST2' ) THEN
856 CALL nl_get_io_form_auxhist2( 1, io_form )
857 ELSE IF ( DataSet .eq. 'AUXHIST3' ) THEN
858 CALL nl_get_io_form_auxhist3( 1, io_form )
859 ELSE IF ( DataSet .eq. 'AUXHIST4' ) THEN
860 CALL nl_get_io_form_auxhist4( 1, io_form )
861 ELSE IF ( DataSet .eq. 'AUXHIST5' ) THEN
862 CALL nl_get_io_form_auxhist5( 1, io_form )
863 ELSE IF ( DataSet .eq. 'AUXHIST6' ) THEN
864 CALL nl_get_io_form_auxhist6( 1, io_form )
865 ELSE IF ( DataSet .eq. 'AUXHIST7' ) THEN
866 CALL nl_get_io_form_auxhist7( 1, io_form )
867 ELSE IF ( DataSet .eq. 'AUXHIST8' ) THEN
868 CALL nl_get_io_form_auxhist8( 1, io_form )
869 ELSE IF ( DataSet .eq. 'AUXHIST9' ) THEN
870 CALL nl_get_io_form_auxhist9( 1, io_form )
871 ELSE IF ( DataSet .eq. 'AUXHIST10' ) THEN
872 CALL nl_get_io_form_auxhist10( 1, io_form )
873 ELSE IF ( DataSet .eq. 'AUXHIST11' ) THEN
874 CALL nl_get_io_form_auxhist11( 1, io_form )
876 ELSE IF ( DataSet .eq. 'BOUNDARY' ) THEN
877 CALL nl_get_io_form_boundary( 1, io_form )
878 ELSE ! default if nothing is set in SysDepInfo; use history
879 CALL nl_get_io_form_history( 1, io_form )
884 SELECT CASE ( use_package(io_form) )
887 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
888 IF ( multi_files(io_form) ) THEN
889 CALL wrf_get_myproc ( myproc )
890 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
892 LocFilename = FileName
895 CALL ext_ncd_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
898 IF ( .NOT. multi_files(io_form) ) THEN
899 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
900 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
905 CALL ext_phdf5_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
910 CALL ext_pnc_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
915 CALL ext_xxx_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
920 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
921 IF ( multi_files(io_form) ) THEN
922 CALL wrf_get_myproc ( myproc )
923 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
925 LocFilename = FileName
928 CALL ext_yyy_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
931 IF ( .NOT. multi_files(io_form) ) THEN
932 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
933 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
938 CALL ext_zzz_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
943 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
944 IF ( multi_files(io_form) ) THEN
945 CALL wrf_get_myproc ( myproc )
946 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
948 LocFilename = FileName
951 CALL ext_gr1_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
954 IF ( .NOT. multi_files(io_form) ) THEN
955 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
956 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
961 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
962 IF ( multi_files(io_form) ) THEN
963 CALL wrf_get_myproc ( myproc )
964 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
966 LocFilename = FileName
969 CALL ext_gr2_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
972 IF ( .NOT. multi_files(io_form) ) THEN
973 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
974 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
979 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
980 IF ( multi_files(io_form) ) THEN
981 CALL wrf_get_myproc ( myproc )
982 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
984 LocFilename = FileName
986 CALL ext_int_open_for_read ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
989 IF ( .NOT. multi_files(io_form) ) THEN
990 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
991 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
997 CALL add_new_handle( Hndl, io_form, .FALSE., DataHandle )
999 END SUBROUTINE wrf_open_for_read
1003 SUBROUTINE wrf_inquire_opened ( DataHandle, FileName , FileStatus, Status )
1006 ! Inquire if the dataset referenced by DataHandle is open.
1009 USE module_state_description
1011 INTEGER , INTENT(IN) :: DataHandle
1012 CHARACTER*(*) :: FileName
1013 INTEGER , INTENT(OUT) :: FileStatus
1014 INTEGER , INTENT(OUT) :: Status
1016 INTEGER, EXTERNAL :: use_package
1017 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1018 #include "wrf_io_flags.h"
1019 #include "wrf_status_codes.h"
1021 INTEGER io_form , Hndl
1023 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_inquire_opened' )
1026 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1027 IF ( Hndl .GT. -1 ) THEN
1028 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1029 SELECT CASE ( use_package(io_form) )
1032 IF (wrf_dm_on_monitor()) CALL ext_ncd_inquire_opened ( Hndl, FileName , FileStatus, Status )
1033 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1034 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1038 CALL ext_phdf5_inquire_opened ( Hndl, FileName , FileStatus, Status )
1042 CALL ext_pnc_inquire_opened ( Hndl, FileName , FileStatus, Status )
1046 CALL ext_xxx_inquire_opened ( Hndl, FileName , FileStatus, Status )
1050 IF (wrf_dm_on_monitor()) CALL ext_yyy_inquire_opened ( Hndl, FileName , FileStatus, Status )
1051 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1052 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1056 CALL ext_zzz_inquire_opened ( Hndl, FileName , FileStatus, Status )
1060 IF (wrf_dm_on_monitor()) CALL ext_gr1_inquire_opened ( Hndl, FileName , FileStatus, Status )
1061 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1062 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1066 IF (wrf_dm_on_monitor()) CALL ext_gr2_inquire_opened ( Hndl, FileName , FileStatus, Status )
1067 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1068 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1072 IF (wrf_dm_on_monitor()) CALL ext_int_inquire_opened ( Hndl, FileName , FileStatus, Status )
1073 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1074 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1077 FileStatus = WRF_FILE_NOT_OPENED
1080 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1081 CALL wrf_quilt_inquire_opened ( Hndl, FileName , FileStatus, Status )
1084 FileStatus = WRF_FILE_NOT_OPENED
1088 END SUBROUTINE wrf_inquire_opened
1090 !--- inquire_filename
1093 SUBROUTINE wrf_inquire_filename ( DataHandle, FileName , FileStatus, Status )
1096 ! Returns the Filename and FileStatus associated with DataHandle.
1099 USE module_state_description
1101 INTEGER , INTENT(IN) :: DataHandle
1102 CHARACTER*(*) :: FileName
1103 INTEGER , INTENT(OUT) :: FileStatus
1104 INTEGER , INTENT(OUT) :: Status
1105 #include "wrf_status_codes.h"
1106 INTEGER, EXTERNAL :: use_package
1107 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1110 INTEGER io_form , Hndl
1112 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_inquire_filename' )
1115 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1116 IF ( Hndl .GT. -1 ) THEN
1117 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1118 SELECT CASE ( use_package( io_form ) )
1121 IF (wrf_dm_on_monitor()) CALL ext_ncd_inquire_filename ( Hndl, FileName , FileStatus, Status )
1122 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1123 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1127 CALL ext_phdf5_inquire_filename ( Hndl, FileName , FileStatus, Status )
1131 CALL ext_pnc_inquire_filename ( Hndl, FileName , FileStatus, Status )
1135 CALL ext_xxx_inquire_filename ( Hndl, FileName , FileStatus, Status )
1139 IF (wrf_dm_on_monitor()) CALL ext_yyy_inquire_filename ( Hndl, FileName , FileStatus, Status )
1140 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1141 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1145 CALL ext_zzz_inquire_filename ( Hndl, FileName , FileStatus, Status )
1149 IF (wrf_dm_on_monitor()) CALL ext_gr1_inquire_filename ( Hndl, FileName , FileStatus, Status )
1150 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1151 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1155 IF (wrf_dm_on_monitor()) CALL ext_gr2_inquire_filename ( Hndl, FileName , FileStatus, Status )
1156 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1157 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1161 IF (wrf_dm_on_monitor()) CALL ext_int_inquire_filename ( Hndl, FileName , FileStatus, Status )
1162 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1163 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1168 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1169 CALL wrf_quilt_inquire_filename ( Hndl, FileName , FileStatus, Status )
1176 END SUBROUTINE wrf_inquire_filename
1180 SUBROUTINE wrf_iosync ( DataHandle, Status )
1183 ! Synchronize the disk copy of a dataset with memory buffers.
1186 USE module_state_description
1188 INTEGER , INTENT(IN) :: DataHandle
1189 INTEGER , INTENT(OUT) :: Status
1190 #include "wrf_status_codes.h"
1191 INTEGER, EXTERNAL :: use_package
1192 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1195 INTEGER io_form , Hndl
1197 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_iosync' )
1200 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1201 IF ( Hndl .GT. -1 ) THEN
1202 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1203 SELECT CASE ( use_package(io_form) )
1206 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_iosync( Hndl, Status )
1207 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1211 CALL ext_xxx_iosync( Hndl, Status )
1215 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_iosync( Hndl, Status )
1216 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1220 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_iosync( Hndl, Status )
1221 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1225 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_iosync( Hndl, Status )
1226 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1230 CALL ext_zzz_iosync( Hndl, Status )
1234 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_iosync( Hndl, Status )
1235 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1240 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1241 CALL wrf_quilt_iosync( Hndl, Status )
1246 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1249 END SUBROUTINE wrf_iosync
1253 SUBROUTINE wrf_ioclose ( DataHandle, Status )
1256 ! Close the dataset referenced by DataHandle.
1259 USE module_state_description
1261 INTEGER , INTENT(IN) :: DataHandle
1262 INTEGER , INTENT(OUT) :: Status
1263 #include "wrf_status_codes.h"
1264 INTEGER, EXTERNAL :: use_package
1265 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1266 INTEGER io_form , Hndl
1269 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioclose' )
1272 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1273 IF ( Hndl .GT. -1 ) THEN
1274 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1275 SELECT CASE ( use_package(io_form) )
1278 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_ioclose( Hndl, Status )
1279 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1283 CALL ext_phdf5_ioclose( Hndl, Status )
1287 CALL ext_pnc_ioclose( Hndl, Status )
1291 CALL ext_xxx_ioclose( Hndl, Status )
1295 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_ioclose( Hndl, Status )
1296 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1300 CALL ext_zzz_ioclose( Hndl, Status )
1304 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_ioclose( Hndl, Status )
1305 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1309 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_ioclose( Hndl, Status )
1310 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1314 CALL ext_mcel_ioclose( Hndl, Status )
1318 CALL ext_esmf_ioclose( Hndl, Status )
1322 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_ioclose( Hndl, Status )
1323 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1328 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1329 CALL wrf_quilt_ioclose( Hndl, Status )
1333 CALL free_handle( DataHandle )
1335 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1338 END SUBROUTINE wrf_ioclose
1340 !--- get_next_time (not defined for IntIO )
1342 SUBROUTINE wrf_get_next_time ( DataHandle, DateStr, Status )
1345 ! Returns the next time stamp.
1348 USE module_state_description
1350 INTEGER , INTENT(IN) :: DataHandle
1351 CHARACTER*(*) :: DateStr
1352 INTEGER , INTENT(OUT) :: Status
1353 #include "wrf_status_codes.h"
1355 INTEGER, EXTERNAL :: use_package
1356 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1357 INTEGER io_form , Hndl, len_of_str
1360 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_next_time' )
1363 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1364 IF ( Hndl .GT. -1 ) THEN
1365 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1366 SELECT CASE ( use_package(io_form) )
1369 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_next_time( Hndl, DateStr, Status )
1370 IF ( .NOT. multi_files(io_form) ) THEN
1371 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1372 len_of_str = LEN(DateStr)
1373 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1378 CALL ext_phdf5_get_next_time( Hndl, DateStr, Status )
1382 CALL ext_pnc_get_next_time( Hndl, DateStr, Status )
1386 CALL ext_xxx_get_next_time( Hndl, DateStr, Status )
1390 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_next_time( Hndl, DateStr, Status )
1391 IF ( .NOT. multi_files(io_form) ) THEN
1392 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1393 len_of_str = LEN(DateStr)
1394 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1399 CALL ext_zzz_get_next_time( Hndl, DateStr, Status )
1403 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_next_time( Hndl, DateStr, Status )
1404 IF ( .NOT. multi_files(io_form) ) THEN
1405 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1406 len_of_str = LEN(DateStr)
1407 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1412 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_next_time( Hndl, DateStr, Status )
1413 IF ( .NOT. multi_files(io_form) ) THEN
1414 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1415 len_of_str = LEN(DateStr)
1416 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1421 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_get_next_time( Hndl, DateStr, Status )
1422 IF ( .NOT. multi_files(io_form) ) THEN
1423 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1424 len_of_str = LEN(DateStr)
1425 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1431 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1432 CALL wrf_quilt_get_next_time( Hndl, DateStr, Status )
1437 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1440 END SUBROUTINE wrf_get_next_time
1442 !--- get_previous_time (not defined for IntIO )
1444 SUBROUTINE wrf_get_previous_time ( DataHandle, DateStr, Status )
1447 ! Returns the previous time stamp.
1450 USE module_state_description
1452 INTEGER , INTENT(IN) :: DataHandle
1453 CHARACTER*(*) :: DateStr
1454 INTEGER , INTENT(OUT) :: Status
1455 #include "wrf_status_codes.h"
1457 INTEGER, EXTERNAL :: use_package
1458 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1459 INTEGER io_form , Hndl, len_of_str
1462 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_previous_time' )
1465 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1466 IF ( Hndl .GT. -1 ) THEN
1467 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1468 SELECT CASE ( use_package(io_form) )
1471 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_previous_time( Hndl, DateStr, Status )
1472 IF ( .NOT. multi_files(io_form) ) THEN
1473 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1474 len_of_str = LEN(DateStr)
1475 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1480 CALL ext_phdf5_get_previous_time( Hndl, DateStr, Status )
1484 CALL ext_pnc_get_previous_time( Hndl, DateStr, Status )
1488 CALL ext_xxx_get_previous_time( Hndl, DateStr, Status )
1492 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_previous_time( Hndl, DateStr, Status )
1493 IF ( .NOT. multi_files(io_form) ) THEN
1494 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1495 len_of_str = LEN(DateStr)
1496 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1501 CALL ext_zzz_get_previous_time( Hndl, DateStr, Status )
1505 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_previous_time( Hndl, DateStr, Status )
1506 IF ( .NOT. multi_files(io_form) ) THEN
1507 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1508 len_of_str = LEN(DateStr)
1509 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1514 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_previous_time( Hndl, DateStr, Status )
1515 IF ( .NOT. multi_files(io_form) ) THEN
1516 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1517 len_of_str = LEN(DateStr)
1518 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1526 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1527 CALL wrf_quilt_get_previous_time( Hndl, DateStr, Status )
1532 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1535 END SUBROUTINE wrf_get_previous_time
1539 SUBROUTINE wrf_set_time ( DataHandle, DateStr, Status )
1542 ! Sets the time stamp.
1545 USE module_state_description
1547 INTEGER , INTENT(IN) :: DataHandle
1548 CHARACTER*(*) :: DateStr
1549 INTEGER , INTENT(OUT) :: Status
1550 #include "wrf_status_codes.h"
1552 INTEGER, EXTERNAL :: use_package
1553 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1554 INTEGER io_form , Hndl
1557 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_set_time' )
1560 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1561 IF ( Hndl .GT. -1 ) THEN
1562 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1563 SELECT CASE ( use_package( io_form ) )
1566 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_set_time( Hndl, DateStr, Status )
1567 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1571 CALL ext_phdf5_set_time( Hndl, DateStr, Status )
1575 CALL ext_pnc_set_time( Hndl, DateStr, Status )
1579 CALL ext_xxx_set_time( Hndl, DateStr, Status )
1583 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_set_time( Hndl, DateStr, Status )
1584 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1588 CALL ext_zzz_set_time( Hndl, DateStr, Status )
1592 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_set_time( Hndl, DateStr, Status )
1593 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1597 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_set_time( Hndl, DateStr, Status )
1598 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1602 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_set_time( Hndl, DateStr, Status )
1603 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1608 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1609 CALL wrf_quilt_set_time( Hndl, DateStr, Status )
1614 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1617 END SUBROUTINE wrf_set_time
1619 !--- get_next_var (not defined for IntIO)
1621 SUBROUTINE wrf_get_next_var ( DataHandle, VarName, Status )
1624 ! On reading, this routine returns the name of the next variable in the
1625 ! current time frame.
1628 USE module_state_description
1630 INTEGER , INTENT(IN) :: DataHandle
1631 CHARACTER*(*) :: VarName
1632 INTEGER , INTENT(OUT) :: Status
1633 #include "wrf_status_codes.h"
1635 INTEGER, EXTERNAL :: use_package
1636 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1637 INTEGER io_form , Hndl
1640 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_next_var' )
1643 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1644 IF ( Hndl .GT. -1 ) THEN
1645 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
1646 SELECT CASE ( use_package( io_form ) )
1649 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_next_var( Hndl, VarName, Status )
1650 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1654 CALL ext_xxx_get_next_var( Hndl, VarName, Status )
1658 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_next_var( Hndl, VarName, Status )
1659 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1663 CALL ext_zzz_get_next_var( Hndl, VarName, Status )
1667 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_next_var( Hndl, VarName, Status )
1668 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1672 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_next_var( Hndl, VarName, Status )
1673 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1677 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_get_next_var( Hndl, VarName, Status )
1678 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1683 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1684 CALL wrf_quilt_get_next_var( Hndl, VarName, Status )
1689 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1692 END SUBROUTINE wrf_get_next_var
1695 ! wrf_get_var_info (not implemented for IntIO)
1697 SUBROUTINE wrf_get_var_info ( DataHandle , VarName , NDim , MemoryOrder , Stagger , &
1698 DomainStart , DomainEnd , Status )
1701 ! This routine applies only to a dataset that is open for read. It returns
1702 ! information about a variable.
1705 USE module_state_description
1707 INTEGER ,INTENT(IN) :: DataHandle
1708 CHARACTER*(*) ,INTENT(IN) :: VarName
1709 INTEGER ,INTENT(OUT) :: NDim
1710 CHARACTER*(*) ,INTENT(OUT) :: MemoryOrder
1711 CHARACTER*(*) ,INTENT(OUT) :: Stagger
1712 INTEGER ,dimension(*) ,INTENT(OUT) :: DomainStart, DomainEnd
1713 INTEGER ,INTENT(OUT) :: Status
1714 #include "wrf_status_codes.h"
1715 INTEGER io_form , Hndl
1717 INTEGER, EXTERNAL :: use_package
1718 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
1720 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_var_info' )
1723 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1724 IF ( Hndl .GT. -1 ) THEN
1725 IF (( multi_files(io_form) .OR. wrf_dm_on_monitor() ) .AND. .NOT. (for_out .AND. use_output_servers()) ) THEN
1726 SELECT CASE ( use_package( io_form ) )
1729 CALL ext_ncd_get_var_info ( Hndl , VarName , NDim , &
1730 MemoryOrder , Stagger , &
1731 DomainStart , DomainEnd , &
1736 CALL ext_phdf5_get_var_info ( Hndl , VarName , NDim , &
1737 MemoryOrder , Stagger , &
1738 DomainStart , DomainEnd , &
1743 CALL ext_pnc_get_var_info ( Hndl , VarName , NDim , &
1744 MemoryOrder , Stagger , &
1745 DomainStart , DomainEnd , &
1750 CALL ext_xxx_get_var_info ( Hndl , VarName , NDim , &
1751 MemoryOrder , Stagger , &
1752 DomainStart , DomainEnd , &
1757 CALL ext_yyy_get_var_info ( Hndl , VarName , NDim , &
1758 MemoryOrder , Stagger , &
1759 DomainStart , DomainEnd , &
1764 CALL ext_gr1_get_var_info ( Hndl , VarName , NDim , &
1765 MemoryOrder , Stagger , &
1766 DomainStart , DomainEnd , &
1771 CALL ext_gr2_get_var_info ( Hndl , VarName , NDim , &
1772 MemoryOrder , Stagger , &
1773 DomainStart , DomainEnd , &
1779 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
1780 CALL wrf_quilt_get_var_info ( Hndl , VarName , NDim , &
1781 MemoryOrder , Stagger , &
1782 DomainStart , DomainEnd , &
1788 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1792 END SUBROUTINE wrf_get_var_info
1796 !---------------------------------------------------------------------------------
1799 SUBROUTINE init_io_handles()
1802 ! Initialize all I/O handles.
1807 IF ( .NOT. is_inited ) THEN
1808 DO i = 1, MAX_WRF_IO_HANDLE
1809 wrf_io_handles(i) = -999319
1814 END SUBROUTINE init_io_handles
1816 SUBROUTINE add_new_handle( Hndl, Hopened, for_out, DataHandle )
1819 ! Stash the package-specific I/O handle (Hndl) and return a WRF I/O handle
1821 ! File format ID is passed in via Hopened.
1822 ! for_out will be .TRUE. if this routine was called from an
1823 ! open-for-read/write-begin operation and .FALSE. otherwise.
1827 INTEGER, INTENT(IN) :: Hndl
1828 INTEGER, INTENT(IN) :: Hopened
1829 LOGICAL, INTENT(IN) :: for_out
1830 INTEGER, INTENT(OUT) :: DataHandle
1832 INTEGER, EXTERNAL :: use_package
1833 LOGICAL, EXTERNAL :: multi_files
1834 IF ( .NOT. is_inited ) THEN
1835 CALL wrf_error_fatal( 'add_new_handle: not initialized' )
1837 IF ( multi_files( Hopened ) ) THEN
1838 SELECT CASE ( use_package( Hopened ) )
1840 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for PHDF5' )
1842 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for PNETCDF' )
1845 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for MCEL' )
1849 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for ESMF' )
1854 DO i = 1, MAX_WRF_IO_HANDLE
1855 IF ( wrf_io_handles(i) .EQ. -999319 ) THEN
1857 wrf_io_handles(i) = Hndl
1858 how_opened(i) = Hopened
1859 for_output(DataHandle) = for_out
1860 first_operation(DataHandle) = .TRUE.
1864 IF ( DataHandle .EQ. -1 ) THEN
1865 CALL wrf_error_fatal( 'add_new_handle: no handles left' )
1868 END SUBROUTINE add_new_handle
1870 SUBROUTINE get_handle ( Hndl, Hopened, for_out, DataHandle )
1873 ! Return the package-specific handle (Hndl) from a WRF handle
1875 ! Return file format ID via Hopened.
1876 ! Also, for_out will be set to .TRUE. if the file was opened
1877 ! with an open-for-read/write-begin operation and .FALSE.
1882 INTEGER, INTENT(OUT) :: Hndl
1883 INTEGER, INTENT(OUT) :: Hopened
1884 LOGICAL, INTENT(OUT) :: for_out
1885 INTEGER, INTENT(IN) :: DataHandle
1888 IF ( .NOT. is_inited ) THEN
1889 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
1891 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
1892 Hndl = wrf_io_handles(DataHandle)
1893 Hopened = how_opened(DataHandle)
1894 for_out = for_output(DataHandle)
1899 END SUBROUTINE get_handle
1901 SUBROUTINE set_first_operation( DataHandle )
1904 ! Sets internal flag to indicate that the first read or write has not yet
1905 ! happened for the dataset referenced by DataHandle.
1909 INTEGER, INTENT(IN) :: DataHandle
1910 IF ( .NOT. is_inited ) THEN
1911 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
1913 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
1914 first_operation(DataHandle) = .TRUE.
1917 END SUBROUTINE set_first_operation
1919 SUBROUTINE reset_first_operation( DataHandle )
1922 ! Resets internal flag to indicate that the first read or write has already
1923 ! happened for the dataset referenced by DataHandle.
1927 INTEGER, INTENT(IN) :: DataHandle
1928 IF ( .NOT. is_inited ) THEN
1929 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
1931 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
1932 first_operation(DataHandle) = .FALSE.
1935 END SUBROUTINE reset_first_operation
1937 LOGICAL FUNCTION is_first_operation( DataHandle )
1940 ! Returns .TRUE. the first read or write has not yet happened for the dataset
1941 ! referenced by DataHandle.
1945 INTEGER, INTENT(IN) :: DataHandle
1946 IF ( .NOT. is_inited ) THEN
1947 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
1949 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
1950 is_first_operation = first_operation(DataHandle)
1953 END FUNCTION is_first_operation
1955 SUBROUTINE free_handle ( DataHandle )
1958 ! Trash a handle and return to "unused" pool.
1962 INTEGER, INTENT(IN) :: DataHandle
1964 IF ( .NOT. is_inited ) THEN
1965 CALL wrf_error_fatal( 'free_handle: not initialized' )
1967 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
1968 wrf_io_handles(DataHandle) = -999319
1971 END SUBROUTINE free_handle
1973 !--------------------------------------------------------------
1975 SUBROUTINE init_module_io
1978 ! Initialize this module. Must be called before any other operations are
1982 CALL init_io_handles
1983 END SUBROUTINE init_module_io
1985 SUBROUTINE are_bdys_distributed( res )
1987 LOGICAL, INTENT(OUT) :: res
1989 END SUBROUTINE are_bdys_distributed
1991 SUBROUTINE bdys_not_distributed
1993 bdy_dist_flag = .FALSE.
1994 END SUBROUTINE bdys_not_distributed
1996 SUBROUTINE bdys_are_distributed
1998 bdy_dist_flag = .TRUE.
1999 END SUBROUTINE bdys_are_distributed
2001 END MODULE module_io
2006 ! Remaining routines in this file are defined outside of the module to
2007 ! defeat arg/param type checking.
2010 SUBROUTINE wrf_read_field ( DataHandle , DateStr , VarName , Field , FieldType , &
2012 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2013 DomainStart , DomainEnd , &
2014 MemoryStart , MemoryEnd , &
2015 PatchStart , PatchEnd , &
2019 ! Read the variable named VarName from the dataset pointed to by DataHandle.
2020 ! This routine is a wrapper that ensures uniform treatment of logicals across
2021 ! platforms by reading as integer and then converting to logical.
2024 USE module_state_description
2025 USE module_configure
2027 INTEGER , INTENT(IN) :: DataHandle
2028 CHARACTER*(*) :: DateStr
2029 CHARACTER*(*) :: VarName
2030 LOGICAL , INTENT(INOUT) :: Field(*)
2031 INTEGER ,INTENT(IN) :: FieldType
2032 INTEGER ,INTENT(INOUT) :: Comm
2033 INTEGER ,INTENT(INOUT) :: IOComm
2034 INTEGER ,INTENT(IN) :: DomainDesc
2035 LOGICAL, DIMENSION(4) :: bdy_mask
2036 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2037 CHARACTER*(*) ,INTENT(IN) :: Stagger
2038 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2039 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2040 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2041 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2042 INTEGER ,INTENT(OUT) :: Status
2043 #include "wrf_status_codes.h"
2044 #include "wrf_io_flags.h"
2045 INTEGER, ALLOCATABLE :: ICAST(:)
2046 LOGICAL perturb_input
2047 IF ( FieldType .EQ. WRF_LOGICAL ) THEN
2048 ALLOCATE(ICAST((MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)))
2050 CALL wrf_read_field1 ( DataHandle , DateStr , VarName , ICAST , WRF_INTEGER , &
2052 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2053 DomainStart , DomainEnd , &
2054 MemoryStart , MemoryEnd , &
2055 PatchStart , PatchEnd , &
2057 Field(1:(MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)) = ICAST == 1
2060 CALL wrf_read_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2062 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2063 DomainStart , DomainEnd , &
2064 MemoryStart , MemoryEnd , &
2065 PatchStart , PatchEnd , &
2067 CALL nl_get_perturb_input( 1, perturb_input )
2068 IF ( perturb_input .AND. FieldType .EQ. WRF_FLOAT .AND. TRIM(MemoryOrder) .EQ. 'XZY' ) THEN
2069 CALL perturb_real ( Field, DomainStart, DomainEnd, &
2070 MemoryStart, MemoryEnd, &
2071 PatchStart, PatchEnd )
2074 END SUBROUTINE wrf_read_field
2076 SUBROUTINE wrf_read_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2078 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2079 DomainStart , DomainEnd , &
2080 MemoryStart , MemoryEnd , &
2081 PatchStart , PatchEnd , &
2085 ! Read the variable named VarName from the dataset pointed to by DataHandle.
2086 ! Calls ext_pkg_read_field() via call_pkg_and_dist().
2089 USE module_state_description
2090 USE module_configure
2093 INTEGER , INTENT(IN) :: DataHandle
2094 CHARACTER*(*) :: DateStr
2095 CHARACTER*(*) :: VarName
2096 INTEGER , INTENT(INOUT) :: Field(*)
2097 INTEGER ,INTENT(IN) :: FieldType
2098 INTEGER ,INTENT(INOUT) :: Comm
2099 INTEGER ,INTENT(INOUT) :: IOComm
2100 INTEGER ,INTENT(IN) :: DomainDesc
2101 LOGICAL, DIMENSION(4) :: bdy_mask
2102 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2103 CHARACTER*(*) ,INTENT(IN) :: Stagger
2104 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2105 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2106 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2107 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2108 INTEGER ,INTENT(OUT) :: Status
2109 #include "wrf_status_codes.h"
2110 INTEGER io_form , Hndl
2112 INTEGER, EXTERNAL :: use_package
2113 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers, use_input_servers
2115 EXTERNAL ext_ncd_read_field
2118 EXTERNAL ext_mcel_read_field
2121 EXTERNAL ext_esmf_read_field
2124 EXTERNAL ext_int_read_field
2127 EXTERNAL ext_xxx_read_field
2130 EXTERNAL ext_yyy_read_field
2133 EXTERNAL ext_gr1_read_field
2136 EXTERNAL ext_gr2_read_field
2139 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_read_field' )
2142 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
2143 CALL reset_first_operation( DataHandle )
2144 IF ( Hndl .GT. -1 ) THEN
2145 IF ( .NOT. io_form .GT. 0 ) THEN
2147 ELSE IF ( .NOT. use_input_servers() ) THEN
2148 SELECT CASE ( use_package( io_form ) )
2152 CALL call_pkg_and_dist ( ext_ncd_read_field, multi_files(io_form), .false. , &
2153 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2154 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2155 DomainStart , DomainEnd , &
2156 MemoryStart , MemoryEnd , &
2157 PatchStart , PatchEnd , &
2163 CALL ext_phdf5_read_field ( &
2164 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2165 DomainDesc , MemoryOrder , Stagger , DimNames , &
2166 DomainStart , DomainEnd , &
2167 MemoryStart , MemoryEnd , &
2168 PatchStart , PatchEnd , &
2173 CALL ext_pnc_read_field ( &
2174 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2175 DomainDesc , MemoryOrder , Stagger , DimNames , &
2176 DomainStart , DomainEnd , &
2177 MemoryStart , MemoryEnd , &
2178 PatchStart , PatchEnd , &
2183 CALL call_pkg_and_dist ( ext_mcel_read_field, multi_files(io_form), .true. , &
2184 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2185 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2186 DomainStart , DomainEnd , &
2187 MemoryStart , MemoryEnd , &
2188 PatchStart , PatchEnd , &
2193 CALL ext_esmf_read_field( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2194 DomainDesc , MemoryOrder , Stagger , DimNames , &
2195 DomainStart , DomainEnd , &
2196 MemoryStart , MemoryEnd , &
2197 PatchStart , PatchEnd , &
2202 CALL call_pkg_and_dist ( ext_xxx_read_field, multi_files(io_form), .false., &
2203 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2204 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2205 DomainStart , DomainEnd , &
2206 MemoryStart , MemoryEnd , &
2207 PatchStart , PatchEnd , &
2212 CALL call_pkg_and_dist ( ext_yyy_read_field, multi_files(io_form), .false., &
2213 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2214 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2215 DomainStart , DomainEnd , &
2216 MemoryStart , MemoryEnd , &
2217 PatchStart , PatchEnd , &
2222 CALL call_pkg_and_dist ( ext_int_read_field, multi_files(io_form), .false., &
2223 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2224 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2225 DomainStart , DomainEnd , &
2226 MemoryStart , MemoryEnd , &
2227 PatchStart , PatchEnd , &
2232 CALL call_pkg_and_dist ( ext_gr1_read_field, multi_files(io_form), .false., &
2233 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2234 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2235 DomainStart , DomainEnd , &
2236 MemoryStart , MemoryEnd , &
2237 PatchStart , PatchEnd , &
2242 CALL call_pkg_and_dist ( ext_gr2_read_field, multi_files(io_form), .false., &
2243 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2244 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2245 DomainStart , DomainEnd , &
2246 MemoryStart , MemoryEnd , &
2247 PatchStart , PatchEnd , &
2254 CALL wrf_error_fatal('module_io.F: wrf_read_field: input_servers not implemented yet')
2257 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
2260 END SUBROUTINE wrf_read_field1
2262 SUBROUTINE wrf_write_field ( DataHandle , DateStr , VarName , Field , FieldType , &
2264 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2265 DomainStart , DomainEnd , &
2266 MemoryStart , MemoryEnd , &
2267 PatchStart , PatchEnd , &
2271 ! Write the variable named VarName to the dataset pointed to by DataHandle.
2272 ! This routine is a wrapper that ensures uniform treatment of logicals across
2273 ! platforms by converting to integer before writing.
2276 USE module_state_description
2277 USE module_configure
2279 INTEGER , INTENT(IN) :: DataHandle
2280 CHARACTER*(*) :: DateStr
2281 CHARACTER*(*) :: VarName
2282 LOGICAL , INTENT(IN) :: Field(*)
2283 INTEGER ,INTENT(IN) :: FieldType
2284 INTEGER ,INTENT(INOUT) :: Comm
2285 INTEGER ,INTENT(INOUT) :: IOComm
2286 INTEGER ,INTENT(IN) :: DomainDesc
2287 LOGICAL, DIMENSION(4) ,INTENT(IN) :: bdy_mask
2288 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2289 CHARACTER*(*) ,INTENT(IN) :: Stagger
2290 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2291 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2292 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2293 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2294 INTEGER ,INTENT(OUT) :: Status
2295 #include "wrf_status_codes.h"
2296 #include "wrf_io_flags.h"
2297 INTEGER, ALLOCATABLE :: ICAST(:)
2298 IF ( FieldType .EQ. WRF_LOGICAL ) THEN
2299 ALLOCATE(ICAST((MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)))
2301 WHERE ( Field(1:(MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)) )
2304 CALL wrf_write_field1 ( DataHandle , DateStr , VarName , ICAST , WRF_INTEGER , &
2306 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2307 DomainStart , DomainEnd , &
2308 MemoryStart , MemoryEnd , &
2309 PatchStart , PatchEnd , &
2313 CALL wrf_write_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2315 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2316 DomainStart , DomainEnd , &
2317 MemoryStart , MemoryEnd , &
2318 PatchStart , PatchEnd , &
2321 END SUBROUTINE wrf_write_field
2323 SUBROUTINE wrf_write_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2325 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2326 DomainStart , DomainEnd , &
2327 MemoryStart , MemoryEnd , &
2328 PatchStart , PatchEnd , &
2332 ! Write the variable named VarName to the dataset pointed to by DataHandle.
2333 ! Calls ext_pkg_write_field() via collect_fld_and_call_pkg().
2337 USE module_state_description
2338 USE module_configure
2341 INTEGER , INTENT(IN) :: DataHandle
2342 CHARACTER*(*) :: DateStr
2343 CHARACTER*(*) :: VarName
2344 INTEGER , INTENT(IN) :: Field(*)
2345 INTEGER ,INTENT(IN) :: FieldType
2346 INTEGER ,INTENT(INOUT) :: Comm
2347 INTEGER ,INTENT(INOUT) :: IOComm
2348 INTEGER ,INTENT(IN) :: DomainDesc
2349 LOGICAL, DIMENSION(4) ,INTENT(IN) :: bdy_mask
2350 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2351 CHARACTER*(*) ,INTENT(IN) :: Stagger
2352 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2353 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2354 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2355 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2356 INTEGER ,INTENT(OUT) :: Status
2357 #include "wrf_status_codes.h"
2358 INTEGER, DIMENSION(3) :: starts, ends
2359 INTEGER io_form , Hndl
2361 LOGICAL :: for_out, okay_to_call
2362 INTEGER, EXTERNAL :: use_package
2363 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
2365 EXTERNAL ext_ncd_write_field
2368 EXTERNAL ext_mcel_write_field
2371 EXTERNAL ext_esmf_write_field
2374 EXTERNAL ext_int_write_field
2377 EXTERNAL ext_xxx_write_field
2380 EXTERNAL ext_yyy_write_field
2383 EXTERNAL ext_gr1_write_field
2386 EXTERNAL ext_gr2_write_field
2389 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_write_field' )
2392 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
2393 CALL reset_first_operation ( DataHandle )
2394 IF ( Hndl .GT. -1 ) THEN
2395 IF ( multi_files( io_form ) .OR. .NOT. use_output_servers() ) THEN
2396 SELECT CASE ( use_package( io_form ) )
2399 CALL collect_fld_and_call_pkg ( ext_ncd_write_field, multi_files(io_form), &
2400 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2401 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2402 DomainStart , DomainEnd , &
2403 MemoryStart , MemoryEnd , &
2404 PatchStart , PatchEnd , &
2409 CALL collect_fld_and_call_pkg ( ext_mcel_write_field, multi_files(io_form), &
2410 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2411 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2412 DomainStart , DomainEnd , &
2413 MemoryStart , MemoryEnd , &
2414 PatchStart , PatchEnd , &
2419 CALL ext_esmf_write_field( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2420 DomainDesc , MemoryOrder , Stagger , DimNames , &
2421 DomainStart , DomainEnd , &
2422 MemoryStart , MemoryEnd , &
2423 PatchStart , PatchEnd , &
2428 CALL ext_phdf5_write_field( &
2429 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2430 DomainDesc , MemoryOrder , Stagger , DimNames , &
2431 DomainStart , DomainEnd , &
2432 MemoryStart , MemoryEnd , &
2433 PatchStart , PatchEnd , &
2438 CALL lower_case( MemoryOrder, MemOrd )
2439 okay_to_call = .TRUE.
2440 IF ((TRIM(MemOrd).EQ.'xsz' .OR. TRIM(MemOrd).EQ.'xs').AND. .NOT. bdy_mask(P_XSB)) okay_to_call = .FALSE.
2441 IF ((TRIM(MemOrd).EQ.'xez' .OR. TRIM(MemOrd).EQ.'xe').AND. .NOT. bdy_mask(P_XEB)) okay_to_call = .FALSE.
2442 IF ((TRIM(MemOrd).EQ.'ysz' .OR. TRIM(MemOrd).EQ.'ys').AND. .NOT. bdy_mask(P_YSB)) okay_to_call = .FALSE.
2443 IF ((TRIM(MemOrd).EQ.'yez' .OR. TRIM(MemOrd).EQ.'ye').AND. .NOT. bdy_mask(P_YEB)) okay_to_call = .FALSE.
2444 IF ( okay_to_call ) THEN
2445 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchEnd(1:3)
2447 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchStart(1:3)-1
2450 CALL ext_pnc_write_field( &
2451 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2452 DomainDesc , MemoryOrder , Stagger , DimNames , &
2453 DomainStart , DomainEnd , &
2454 MemoryStart , MemoryEnd , &
2460 CALL collect_fld_and_call_pkg ( ext_xxx_write_field, multi_files(io_form), &
2461 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2462 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2463 DomainStart , DomainEnd , &
2464 MemoryStart , MemoryEnd , &
2465 PatchStart , PatchEnd , &
2470 CALL collect_fld_and_call_pkg ( ext_yyy_write_field, multi_files(io_form), &
2471 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2472 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2473 DomainStart , DomainEnd , &
2474 MemoryStart , MemoryEnd , &
2475 PatchStart , PatchEnd , &
2480 CALL collect_fld_and_call_pkg ( ext_gr1_write_field, multi_files(io_form), &
2481 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2482 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2483 DomainStart , DomainEnd , &
2484 MemoryStart , MemoryEnd , &
2485 PatchStart , PatchEnd , &
2490 CALL collect_fld_and_call_pkg ( ext_gr2_write_field, multi_files(io_form), &
2491 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2492 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2493 DomainStart , DomainEnd , &
2494 MemoryStart , MemoryEnd , &
2495 PatchStart , PatchEnd , &
2500 CALL collect_fld_and_call_pkg ( ext_int_write_field, multi_files(io_form), &
2501 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2502 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2503 DomainStart , DomainEnd , &
2504 MemoryStart , MemoryEnd , &
2505 PatchStart , PatchEnd , &
2511 ELSE IF ( use_output_servers() ) THEN
2512 IF ( io_form .GT. 0 ) THEN
2513 CALL wrf_quilt_write_field ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2514 DomainDesc , MemoryOrder , Stagger , DimNames , &
2515 DomainStart , DomainEnd , &
2516 MemoryStart , MemoryEnd , &
2517 PatchStart , PatchEnd , &
2522 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
2525 END SUBROUTINE wrf_write_field1
2527 SUBROUTINE get_value_from_pairs ( varname , str , retval )
2530 ! parse comma separated list of VARIABLE=VALUE strings and return the
2531 ! value for the matching variable if such exists, otherwise return
2536 CHARACTER*(*) :: varname
2537 CHARACTER*(*) :: str
2538 CHARACTER*(*) :: retval
2540 CHARACTER (128) varstr, tstr
2541 INTEGER i,j,n,varstrn
2542 LOGICAL nobreak, nobreakouter
2544 varstr = TRIM(varname)//"="
2545 varstrn = len(TRIM(varstr))
2549 nobreakouter = .TRUE.
2550 DO WHILE ( nobreakouter )
2554 ! Potential for out of bounds array ref on str(i:i) for i > n; reported by jedwards
2555 ! DO WHILE ( nobreak )
2556 ! IF ( str(i:i) .NE. ',' .AND. i .LE. n ) THEN
2557 ! tstr(j:j) = str(i:i)
2565 DO WHILE ( nobreak )
2567 IF ( i .LE. n ) THEN
2568 IF (str(i:i) .NE. ',' ) THEN
2569 tstr(j:j) = str(i:i)
2576 IF ( i .GT. n ) nobreakouter = .FALSE.
2577 IF ( varstr(1:varstrn) .EQ. tstr(1:varstrn) ) THEN
2578 retval(1:) = TRIM(tstr(varstrn+1:))
2579 nobreakouter = .FALSE.
2583 END SUBROUTINE get_value_from_pairs
2585 LOGICAL FUNCTION multi_files ( io_form )
2588 ! Returns .TRUE. iff io_form is a multi-file format. A multi-file format
2589 ! results in one file for each compute process and can be used with any
2590 ! I/O package. A multi-file dataset can only be read by the same number
2591 ! of tasks that were used to write it. This feature can be useful for
2592 ! speeding up restarts on machines that support efficient parallel I/O.
2593 ! Multi-file formats cannot be used with I/O quilt servers.
2597 INTEGER, INTENT(IN) :: io_form
2599 multi_files = io_form > 99
2601 multi_files = .FALSE.
2603 END FUNCTION multi_files
2605 INTEGER FUNCTION use_package ( io_form )
2608 ! Returns the ID of the external I/O package referenced by io_form.
2612 INTEGER, INTENT(IN) :: io_form
2613 use_package = MOD( io_form, 100 )
2614 END FUNCTION use_package
2617 SUBROUTINE collect_fld_and_call_pkg ( fcn, donotcollect_arg, &
2618 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2619 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2620 DomainStart , DomainEnd , &
2621 MemoryStart , MemoryEnd , &
2622 PatchStart , PatchEnd , &
2626 ! The collect_*_and_call_pkg routines collect a distributed array onto one
2627 ! processor and then call an I/O function to write the result (or in the
2628 ! case of replicated data simply write monitor node's copy of the data)
2629 ! This routine handle cases where collection can be skipped and deals with
2630 ! different data types for Field.
2634 #include "wrf_io_flags.h"
2636 LOGICAL, INTENT(IN) :: donotcollect_arg
2637 INTEGER , INTENT(IN) :: Hndl
2638 CHARACTER*(*) :: DateStr
2639 CHARACTER*(*) :: VarName
2640 INTEGER , INTENT(IN) :: Field(*)
2641 INTEGER ,INTENT(IN) :: FieldType
2642 INTEGER ,INTENT(INOUT) :: Comm
2643 INTEGER ,INTENT(INOUT) :: IOComm
2644 INTEGER ,INTENT(IN) :: DomainDesc
2645 LOGICAL, DIMENSION(4) :: bdy_mask
2646 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2647 CHARACTER*(*) ,INTENT(IN) :: Stagger
2648 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2649 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2650 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2651 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2652 INTEGER ,INTENT(OUT) :: Status
2653 LOGICAL donotcollect
2654 INTEGER ndims, nproc
2656 CALL dim_from_memorder( MemoryOrder , ndims)
2657 CALL wrf_get_nproc( nproc )
2658 donotcollect = donotcollect_arg .OR. (nproc .EQ. 1)
2660 IF ( donotcollect ) THEN
2662 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2663 DomainDesc , MemoryOrder , Stagger , DimNames , &
2664 DomainStart , DomainEnd , &
2665 MemoryStart , MemoryEnd , &
2666 PatchStart , PatchEnd , &
2669 ELSE IF ( FieldType .EQ. WRF_DOUBLE ) THEN
2671 CALL collect_double_and_call_pkg ( fcn, &
2672 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2673 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2674 DomainStart , DomainEnd , &
2675 MemoryStart , MemoryEnd , &
2676 PatchStart , PatchEnd , &
2679 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
2681 CALL collect_real_and_call_pkg ( fcn, &
2682 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2683 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2684 DomainStart , DomainEnd , &
2685 MemoryStart , MemoryEnd , &
2686 PatchStart , PatchEnd , &
2689 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
2691 CALL collect_int_and_call_pkg ( fcn, &
2692 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2693 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2694 DomainStart , DomainEnd , &
2695 MemoryStart , MemoryEnd , &
2696 PatchStart , PatchEnd , &
2699 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
2701 CALL collect_logical_and_call_pkg ( fcn, &
2702 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2703 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2704 DomainStart , DomainEnd , &
2705 MemoryStart , MemoryEnd , &
2706 PatchStart , PatchEnd , &
2711 END SUBROUTINE collect_fld_and_call_pkg
2713 SUBROUTINE collect_real_and_call_pkg ( fcn, &
2714 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2715 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2716 DomainStart , DomainEnd , &
2717 MemoryStart , MemoryEnd , &
2718 PatchStart , PatchEnd , &
2722 ! The collect_*_and_call_pkg routines collect a distributed array onto one
2723 ! processor and then call an I/O function to write the result (or in the
2724 ! case of replicated data simply write monitor node's copy of the data)
2725 ! The sole purpose of this wrapper is to allocate a big real buffer and
2726 ! pass it down to collect_generic_and_call_pkg() to do the actual work.
2729 USE module_state_description
2730 USE module_driver_constants
2733 INTEGER , INTENT(IN) :: Hndl
2734 CHARACTER*(*) :: DateStr
2735 CHARACTER*(*) :: VarName
2736 REAL , INTENT(IN) :: Field(*)
2737 INTEGER ,INTENT(IN) :: FieldType
2738 INTEGER ,INTENT(INOUT) :: Comm
2739 INTEGER ,INTENT(INOUT) :: IOComm
2740 INTEGER ,INTENT(IN) :: DomainDesc
2741 LOGICAL, DIMENSION(4) :: bdy_mask
2742 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2743 CHARACTER*(*) ,INTENT(IN) :: Stagger
2744 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2745 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2746 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2747 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2748 INTEGER ,INTENT(INOUT) :: Status
2749 REAL, ALLOCATABLE :: globbuf (:)
2750 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
2752 IF ( wrf_dm_on_monitor() ) THEN
2753 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
2755 ALLOCATE( globbuf( 1 ) )
2759 # define FRSTELEM (1)
2764 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM, &
2765 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2766 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2767 DomainStart , DomainEnd , &
2768 MemoryStart , MemoryEnd , &
2769 PatchStart , PatchEnd , &
2771 DEALLOCATE ( globbuf )
2774 END SUBROUTINE collect_real_and_call_pkg
2776 SUBROUTINE collect_int_and_call_pkg ( fcn, &
2777 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2778 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2779 DomainStart , DomainEnd , &
2780 MemoryStart , MemoryEnd , &
2781 PatchStart , PatchEnd , &
2785 ! The collect_*_and_call_pkg routines collect a distributed array onto one
2786 ! processor and then call an I/O function to write the result (or in the
2787 ! case of replicated data simply write monitor node's copy of the data)
2788 ! The sole purpose of this wrapper is to allocate a big integer buffer and
2789 ! pass it down to collect_generic_and_call_pkg() to do the actual work.
2792 USE module_state_description
2793 USE module_driver_constants
2796 INTEGER , INTENT(IN) :: Hndl
2797 CHARACTER*(*) :: DateStr
2798 CHARACTER*(*) :: VarName
2799 INTEGER , INTENT(IN) :: Field(*)
2800 INTEGER ,INTENT(IN) :: FieldType
2801 INTEGER ,INTENT(INOUT) :: Comm
2802 INTEGER ,INTENT(INOUT) :: IOComm
2803 INTEGER ,INTENT(IN) :: DomainDesc
2804 LOGICAL, DIMENSION(4) :: bdy_mask
2805 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2806 CHARACTER*(*) ,INTENT(IN) :: Stagger
2807 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2808 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2809 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2810 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2811 INTEGER ,INTENT(INOUT) :: Status
2812 INTEGER, ALLOCATABLE :: globbuf (:)
2813 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
2815 IF ( wrf_dm_on_monitor() ) THEN
2816 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
2818 ALLOCATE( globbuf( 1 ) )
2821 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
2822 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2823 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2824 DomainStart , DomainEnd , &
2825 MemoryStart , MemoryEnd , &
2826 PatchStart , PatchEnd , &
2828 DEALLOCATE ( globbuf )
2831 END SUBROUTINE collect_int_and_call_pkg
2833 SUBROUTINE collect_double_and_call_pkg ( fcn, &
2834 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2835 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2836 DomainStart , DomainEnd , &
2837 MemoryStart , MemoryEnd , &
2838 PatchStart , PatchEnd , &
2842 ! The collect_*_and_call_pkg routines collect a distributed array onto one
2843 ! processor and then call an I/O function to write the result (or in the
2844 ! case of replicated data simply write monitor node's copy of the data)
2845 ! The sole purpose of this wrapper is to allocate a big double precision
2846 ! buffer and pass it down to collect_generic_and_call_pkg() to do the
2850 USE module_state_description
2851 USE module_driver_constants
2854 INTEGER , INTENT(IN) :: Hndl
2855 CHARACTER*(*) :: DateStr
2856 CHARACTER*(*) :: VarName
2857 DOUBLE PRECISION , INTENT(IN) :: Field(*)
2858 INTEGER ,INTENT(IN) :: FieldType
2859 INTEGER ,INTENT(INOUT) :: Comm
2860 INTEGER ,INTENT(INOUT) :: IOComm
2861 INTEGER ,INTENT(IN) :: DomainDesc
2862 LOGICAL, DIMENSION(4) :: bdy_mask
2863 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2864 CHARACTER*(*) ,INTENT(IN) :: Stagger
2865 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2866 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2867 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2868 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2869 INTEGER ,INTENT(INOUT) :: Status
2870 DOUBLE PRECISION, ALLOCATABLE :: globbuf (:)
2871 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
2873 IF ( wrf_dm_on_monitor() ) THEN
2874 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
2876 ALLOCATE( globbuf( 1 ) )
2879 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
2880 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2881 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2882 DomainStart , DomainEnd , &
2883 MemoryStart , MemoryEnd , &
2884 PatchStart , PatchEnd , &
2886 DEALLOCATE ( globbuf )
2889 END SUBROUTINE collect_double_and_call_pkg
2891 SUBROUTINE collect_logical_and_call_pkg ( fcn, &
2892 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2893 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2894 DomainStart , DomainEnd , &
2895 MemoryStart , MemoryEnd , &
2896 PatchStart , PatchEnd , &
2900 ! The collect_*_and_call_pkg routines collect a distributed array onto one
2901 ! processor and then call an I/O function to write the result (or in the
2902 ! case of replicated data simply write monitor node's copy of the data)
2903 ! The sole purpose of this wrapper is to allocate a big logical buffer
2904 ! and pass it down to collect_generic_and_call_pkg() to do the actual work.
2907 USE module_state_description
2908 USE module_driver_constants
2911 INTEGER , INTENT(IN) :: Hndl
2912 CHARACTER*(*) :: DateStr
2913 CHARACTER*(*) :: VarName
2914 LOGICAL , INTENT(IN) :: Field(*)
2915 INTEGER ,INTENT(IN) :: FieldType
2916 INTEGER ,INTENT(INOUT) :: Comm
2917 INTEGER ,INTENT(INOUT) :: IOComm
2918 INTEGER ,INTENT(IN) :: DomainDesc
2919 LOGICAL, DIMENSION(4) :: bdy_mask
2920 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2921 CHARACTER*(*) ,INTENT(IN) :: Stagger
2922 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2923 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2924 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2925 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2926 INTEGER ,INTENT(INOUT) :: Status
2927 LOGICAL, ALLOCATABLE :: globbuf (:)
2928 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
2930 IF ( wrf_dm_on_monitor() ) THEN
2931 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
2933 ALLOCATE( globbuf( 1 ) )
2936 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
2937 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2938 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2939 DomainStart , DomainEnd , &
2940 MemoryStart , MemoryEnd , &
2941 PatchStart , PatchEnd , &
2943 DEALLOCATE ( globbuf )
2946 END SUBROUTINE collect_logical_and_call_pkg
2949 SUBROUTINE collect_generic_and_call_pkg ( fcn, globbuf, &
2950 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2951 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2952 DomainStart , DomainEnd , &
2953 MemoryStart , MemoryEnd , &
2954 PatchStart , PatchEnd , &
2958 ! The collect_*_and_call_pkg routines collect a distributed array onto one
2959 ! processor and then call an I/O function to write the result (or in the
2960 ! case of replicated data simply write monitor node's copy of the data)
2961 ! This routine calls the distributed memory communication routines that
2962 ! collect the array and then calls I/O function fcn to write it to disk.
2965 USE module_state_description
2966 USE module_driver_constants
2968 #include "wrf_io_flags.h"
2969 #if defined( DM_PARALLEL ) && ! defined(STUBMPI)
2973 REAL , DIMENSION(*) , INTENT(INOUT) :: globbuf
2974 INTEGER , INTENT(IN) :: Hndl
2975 CHARACTER*(*) :: DateStr
2976 CHARACTER*(*) :: VarName
2977 REAL , INTENT(IN) :: Field(*)
2978 INTEGER ,INTENT(IN) :: FieldType
2979 INTEGER ,INTENT(INOUT) :: Comm
2980 INTEGER ,INTENT(INOUT) :: IOComm
2981 INTEGER ,INTENT(IN) :: DomainDesc
2982 LOGICAL, DIMENSION(4) :: bdy_mask
2983 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2984 CHARACTER*(*) ,INTENT(IN) :: Stagger
2985 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2986 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2987 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2988 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2989 INTEGER ,INTENT(OUT) :: Status
2991 LOGICAL, EXTERNAL :: has_char
2992 INTEGER ids, ide, jds, jde, kds, kde
2993 INTEGER ims, ime, jms, jme, kms, kme
2994 INTEGER ips, ipe, jps, jpe, kps, kpe
2995 INTEGER, ALLOCATABLE :: counts(:), displs(:)
2996 INTEGER nproc, communicator, mpi_bdyslice_type, ierr, my_displ
2998 INTEGER , dimension(3) :: dom_end_rev
2999 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3000 INTEGER, EXTERNAL :: wrf_dm_monitor_rank
3001 LOGICAL distributed_field
3002 INTEGER i,j,k,idx,lx,idx2,lx2
3003 INTEGER collective_root
3005 CALL wrf_get_nproc( nproc )
3006 CALL wrf_get_dm_communicator ( communicator )
3008 ALLOCATE( counts( nproc ) )
3009 ALLOCATE( displs( nproc ) )
3010 CALL lower_case( MemoryOrder, MemOrd )
3012 collective_root = wrf_dm_monitor_rank()
3014 dom_end_rev(1) = DomainEnd(1)
3015 dom_end_rev(2) = DomainEnd(2)
3016 dom_end_rev(3) = DomainEnd(3)
3018 SELECT CASE (TRIM(MemOrd))
3020 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3021 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3022 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3024 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3025 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3026 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3028 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3029 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3030 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3032 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3033 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3035 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3036 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3037 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3039 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3040 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3042 ! do nothing; the boundary orders and others either dont care or set themselves
3045 SELECT CASE (TRIM(MemOrd))
3047 CASE ( 'xzy','zxy','xyz','yxz','xy','yx' )
3049 distributed_field = .TRUE.
3050 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3051 CALL wrf_patch_to_global_double ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3052 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3053 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3054 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3055 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3056 CALL wrf_patch_to_global_real ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3057 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3058 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3059 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3060 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3061 CALL wrf_patch_to_global_integer ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3062 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3063 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3064 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3065 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
3066 CALL wrf_patch_to_global_logical ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3067 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3068 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3069 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3072 #if defined(DM_PARALLEL) && !defined(STUBMPI)
3073 CASE ( 'xsz', 'xez' )
3074 distributed_field = .FALSE.
3075 IF ( nproc .GT. 1 ) THEN
3076 jds = DomainStart(1) ; jde = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) jde = jde+1 ! ns strip
3077 kds = DomainStart(2) ; kde = DomainEnd(2) ; IF ( .NOT. has_char( Stagger, 'z' ) ) kde = kde+1 ! levels
3078 ids = DomainStart(3) ; ide = DomainEnd(3) ; ! bdy_width
3079 dom_end_rev(1) = jde
3080 dom_end_rev(2) = kde
3081 dom_end_rev(3) = ide
3082 distributed_field = .TRUE.
3083 IF ( (MemOrd .eq. 'xsz' .AND. bdy_mask( P_XSB )) .OR. &
3084 (MemOrd .eq. 'xez' .AND. bdy_mask( P_XEB )) ) THEN
3085 my_displ = PatchStart(1)-1
3086 my_count = PatchEnd(1)-PatchStart(1)+1
3091 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3092 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3093 do i = DomainStart(3),DomainEnd(3) ! bdy_width
3094 do k = DomainStart(2),DomainEnd(2) ! levels
3095 lx = MemoryEnd(1)-MemoryStart(1)+1
3096 lx2 = dom_end_rev(1)-DomainStart(1)+1
3097 idx = lx*((k-1)+(i-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3098 idx2 = lx2*((k-1)+(i-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3099 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3101 CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3102 my_count , & ! sendcount
3103 globbuf, 1+idx2 , & ! recvbuf
3104 counts , & ! recvcounts
3106 collective_root , & ! root
3107 communicator , & ! communicator
3110 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3112 CALL wrf_gatherv_real ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3113 my_count , & ! sendcount
3114 globbuf, 1+idx2 , & ! recvbuf
3115 counts , & ! recvcounts
3117 collective_root , & ! root
3118 communicator , & ! communicator
3121 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3123 CALL wrf_gatherv_integer ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3124 my_count , & ! sendcount
3125 globbuf, 1+idx2 , & ! recvbuf
3126 counts , & ! recvcounts
3128 collective_root , & ! root
3129 communicator , & ! communicator
3137 distributed_field = .FALSE.
3138 IF ( nproc .GT. 1 ) THEN
3139 jds = DomainStart(1) ; jde = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) jde = jde+1 ! ns strip
3140 ids = DomainStart(2) ; ide = DomainEnd(2) ; ! bdy_width
3141 dom_end_rev(1) = jde
3142 dom_end_rev(2) = ide
3143 distributed_field = .TRUE.
3144 IF ( (MemOrd .eq. 'xs' .AND. bdy_mask( P_XSB )) .OR. &
3145 (MemOrd .eq. 'xe' .AND. bdy_mask( P_XEB )) ) THEN
3146 my_displ = PatchStart(1)-1
3147 my_count = PatchEnd(1)-PatchStart(1)+1
3152 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3153 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3154 do i = DomainStart(2),DomainEnd(2) ! bdy_width
3155 lx = MemoryEnd(1)-MemoryStart(1)+1
3157 lx2 = dom_end_rev(1)-DomainStart(1)+1
3159 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3161 CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3162 my_count , & ! sendcount
3163 globbuf, 1+idx2 , & ! recvbuf
3164 counts , & ! recvcounts
3166 collective_root , & ! root
3167 communicator , & ! communicator
3170 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3172 CALL wrf_gatherv_real ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3173 my_count , & ! sendcount
3174 globbuf, 1+idx2 , & ! recvbuf
3175 counts , & ! recvcounts
3177 collective_root , & ! root
3178 communicator , & ! communicator
3181 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3183 CALL wrf_gatherv_integer ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3184 my_count , & ! sendcount
3185 globbuf, 1+idx2 , & ! recvbuf
3186 counts , & ! recvcounts
3188 collective_root , & ! root
3189 communicator , & ! communicator
3195 CASE ( 'ysz', 'yez' )
3196 distributed_field = .FALSE.
3197 IF ( nproc .GT. 1 ) THEN
3198 ids = DomainStart(1) ; ide = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) ide = ide+1 ! ns strip
3199 kds = DomainStart(2) ; kde = DomainEnd(2) ; IF ( .NOT. has_char( Stagger, 'z' ) ) kde = kde+1 ! levels
3200 jds = DomainStart(3) ; jde = DomainEnd(3) ; ! bdy_width
3201 dom_end_rev(1) = ide
3202 dom_end_rev(2) = kde
3203 dom_end_rev(3) = jde
3204 distributed_field = .TRUE.
3205 IF ( (MemOrd .eq. 'ysz' .AND. bdy_mask( P_YSB )) .OR. &
3206 (MemOrd .eq. 'yez' .AND. bdy_mask( P_YEB )) ) THEN
3207 my_displ = PatchStart(1)-1
3208 my_count = PatchEnd(1)-PatchStart(1)+1
3213 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3214 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3215 do j = DomainStart(3),DomainEnd(3) ! bdy_width
3216 do k = DomainStart(2),DomainEnd(2) ! levels
3217 lx = MemoryEnd(1)-MemoryStart(1)+1
3218 lx2 = dom_end_rev(1)-DomainStart(1)+1
3219 idx = lx*((k-1)+(j-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3220 idx2 = lx2*((k-1)+(j-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3222 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3224 CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3225 my_count , & ! sendcount
3226 globbuf, 1+idx2 , & ! recvbuf
3227 counts , & ! recvcounts
3229 collective_root , & ! root
3230 communicator , & ! communicator
3233 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3235 CALL wrf_gatherv_real( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3236 my_count , & ! sendcount
3237 globbuf, 1+idx2 , & ! recvbuf
3238 counts , & ! recvcounts
3240 collective_root , & ! root
3241 communicator , & ! communicator
3244 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3246 CALL wrf_gatherv_integer( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3247 my_count , & ! sendcount
3248 globbuf, 1+idx2 , & ! recvbuf
3249 counts , & ! recvcounts
3251 collective_root , & ! root
3252 communicator , & ! communicator
3260 distributed_field = .FALSE.
3261 IF ( nproc .GT. 1 ) THEN
3262 ids = DomainStart(1) ; ide = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) ide = ide+1 ! ns strip
3263 jds = DomainStart(2) ; jde = DomainEnd(2) ; ! bdy_width
3264 dom_end_rev(1) = ide
3265 dom_end_rev(2) = jde
3266 distributed_field = .TRUE.
3267 IF ( (MemOrd .eq. 'ys' .AND. bdy_mask( P_YSB )) .OR. &
3268 (MemOrd .eq. 'ye' .AND. bdy_mask( P_YEB )) ) THEN
3269 my_displ = PatchStart(1)-1
3270 my_count = PatchEnd(1)-PatchStart(1)+1
3275 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3276 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3277 do j = DomainStart(2),DomainEnd(2) ! bdy_width
3278 lx = MemoryEnd(1)-MemoryStart(1)+1
3280 lx2 = dom_end_rev(1)-DomainStart(1)+1
3283 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3285 CALL wrf_gatherv_double( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3286 my_count , & ! sendcount
3287 globbuf, 1+idx2 , & ! recvbuf
3288 counts , & ! recvcounts
3290 collective_root , & ! root
3291 communicator , & ! communicator
3294 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3296 CALL wrf_gatherv_real( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3297 my_count , & ! sendcount
3298 globbuf, 1+idx2 , & ! recvbuf
3299 counts , & ! recvcounts
3301 collective_root , & ! root
3302 communicator , & ! communicator
3305 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3307 CALL wrf_gatherv_integer( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3308 my_count , & ! sendcount
3309 globbuf, 1+idx2 , & ! recvbuf
3310 counts , & ! recvcounts
3312 collective_root , & ! root
3313 communicator , & ! communicator
3322 distributed_field = .FALSE.
3324 IF ( wrf_dm_on_monitor() ) THEN
3325 IF ( distributed_field ) THEN
3326 CALL fcn ( Hndl , DateStr , VarName , globbuf , FieldType , Comm , IOComm , &
3327 DomainDesc , MemoryOrder , Stagger , DimNames , &
3328 DomainStart , DomainEnd , &
3329 DomainStart , dom_end_rev , & ! memory dims adjust out for unstag
3330 DomainStart , DomainEnd , &
3333 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3334 DomainDesc , MemoryOrder , Stagger , DimNames , &
3335 DomainStart , DomainEnd , &
3336 MemoryStart , MemoryEnd , &
3337 PatchStart , PatchEnd , &
3341 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
3342 DEALLOCATE( counts )
3343 DEALLOCATE( displs )
3345 END SUBROUTINE collect_generic_and_call_pkg
3348 SUBROUTINE call_pkg_and_dist ( fcn, donotdist_arg, update_arg, &
3349 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3350 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3351 DomainStart , DomainEnd , &
3352 MemoryStart , MemoryEnd , &
3353 PatchStart , PatchEnd , &
3357 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3358 ! distribute or replicate the field across compute tasks.
3359 ! This routine handle cases where distribution/replication can be skipped and
3360 ! deals with different data types for Field.
3364 #include "wrf_io_flags.h"
3366 LOGICAL, INTENT(IN) :: donotdist_arg, update_arg ! update means collect old field update it and dist
3367 INTEGER , INTENT(IN) :: Hndl
3368 CHARACTER*(*) :: DateStr
3369 CHARACTER*(*) :: VarName
3371 INTEGER :: FieldType
3374 INTEGER :: DomainDesc
3375 LOGICAL, DIMENSION(4) :: bdy_mask
3376 CHARACTER*(*) :: MemoryOrder
3377 CHARACTER*(*) :: Stagger
3378 CHARACTER*(*) , dimension (*) :: DimNames
3379 INTEGER ,dimension(*) :: DomainStart, DomainEnd
3380 INTEGER ,dimension(*) :: MemoryStart, MemoryEnd
3381 INTEGER ,dimension(*) :: PatchStart, PatchEnd
3384 INTEGER ndims, nproc
3386 CALL dim_from_memorder( MemoryOrder , ndims)
3387 CALL wrf_get_nproc( nproc )
3388 donotdist = donotdist_arg .OR. (nproc .EQ. 1)
3390 IF ( donotdist ) THEN
3391 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3392 DomainDesc , MemoryOrder , Stagger , DimNames , &
3393 DomainStart , DomainEnd , &
3394 MemoryStart , MemoryEnd , &
3395 PatchStart , PatchEnd , &
3398 ELSE IF (FieldType .EQ. WRF_DOUBLE) THEN
3400 CALL call_pkg_and_dist_double ( fcn, update_arg, &
3401 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3402 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3403 DomainStart , DomainEnd , &
3404 MemoryStart , MemoryEnd , &
3405 PatchStart , PatchEnd , &
3408 ELSE IF (FieldType .EQ. WRF_FLOAT) THEN
3410 CALL call_pkg_and_dist_real ( fcn, update_arg, &
3411 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3412 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3413 DomainStart , DomainEnd , &
3414 MemoryStart , MemoryEnd , &
3415 PatchStart , PatchEnd , &
3418 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3420 CALL call_pkg_and_dist_int ( fcn, update_arg, &
3421 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3422 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3423 DomainStart , DomainEnd , &
3424 MemoryStart , MemoryEnd , &
3425 PatchStart , PatchEnd , &
3428 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
3430 CALL call_pkg_and_dist_logical ( fcn, update_arg, &
3431 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3432 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3433 DomainStart , DomainEnd , &
3434 MemoryStart , MemoryEnd , &
3435 PatchStart , PatchEnd , &
3440 END SUBROUTINE call_pkg_and_dist
3442 SUBROUTINE call_pkg_and_dist_real ( fcn, update_arg, &
3443 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3444 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3445 DomainStart , DomainEnd , &
3446 MemoryStart , MemoryEnd , &
3447 PatchStart , PatchEnd , &
3451 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3452 ! distribute or replicate the field across compute tasks.
3453 ! The sole purpose of this wrapper is to allocate a big real buffer and
3454 ! pass it down to call_pkg_and_dist_generic() to do the actual work.
3459 INTEGER , INTENT(IN) :: Hndl
3460 LOGICAL , INTENT(IN) :: update_arg
3461 CHARACTER*(*) :: DateStr
3462 CHARACTER*(*) :: VarName
3463 REAL , INTENT(INOUT) :: Field(*)
3464 INTEGER ,INTENT(IN) :: FieldType
3465 INTEGER ,INTENT(INOUT) :: Comm
3466 INTEGER ,INTENT(INOUT) :: IOComm
3467 INTEGER ,INTENT(IN) :: DomainDesc
3468 LOGICAL, DIMENSION(4) :: bdy_mask
3469 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3470 CHARACTER*(*) ,INTENT(IN) :: Stagger
3471 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3472 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3473 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3474 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3475 INTEGER ,INTENT(INOUT) :: Status
3476 REAL, ALLOCATABLE :: globbuf (:)
3477 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3481 IF ( wrf_dm_on_monitor() ) THEN
3482 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ), &
3484 IF ( test .NE. 0 ) THEN
3485 write(mess,*)"module_io.b",'allocating globbuf ',&
3486 (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3)
3487 CALL wrf_error_fatal(mess)
3490 ALLOCATE( globbuf( 1 ), STAT=test )
3491 IF ( test .NE. 0 ) THEN
3492 write(mess,*)"module_io.b",'allocating globbuf ',1
3493 CALL wrf_error_fatal(mess)
3499 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg, &
3500 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3501 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3502 DomainStart , DomainEnd , &
3503 MemoryStart , MemoryEnd , &
3504 PatchStart , PatchEnd , &
3506 DEALLOCATE ( globbuf )
3508 END SUBROUTINE call_pkg_and_dist_real
3511 SUBROUTINE call_pkg_and_dist_double ( fcn, update_arg , &
3512 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3513 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3514 DomainStart , DomainEnd , &
3515 MemoryStart , MemoryEnd , &
3516 PatchStart , PatchEnd , &
3520 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3521 ! distribute or replicate the field across compute tasks.
3522 ! The sole purpose of this wrapper is to allocate a big double precision buffer
3523 ! and pass it down to call_pkg_and_dist_generic() to do the actual work.
3528 INTEGER , INTENT(IN) :: Hndl
3529 LOGICAL , INTENT(IN) :: update_arg
3530 CHARACTER*(*) :: DateStr
3531 CHARACTER*(*) :: VarName
3532 DOUBLE PRECISION , INTENT(INOUT) :: Field(*)
3533 INTEGER ,INTENT(IN) :: FieldType
3534 INTEGER ,INTENT(INOUT) :: Comm
3535 INTEGER ,INTENT(INOUT) :: IOComm
3536 INTEGER ,INTENT(IN) :: DomainDesc
3537 LOGICAL, DIMENSION(4) :: bdy_mask
3538 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3539 CHARACTER*(*) ,INTENT(IN) :: Stagger
3540 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3541 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3542 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3543 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3544 INTEGER ,INTENT(INOUT) :: Status
3545 DOUBLE PRECISION , ALLOCATABLE :: globbuf (:)
3546 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3548 IF ( wrf_dm_on_monitor() ) THEN
3549 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3551 ALLOCATE( globbuf( 1 ) )
3556 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
3557 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3558 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3559 DomainStart , DomainEnd , &
3560 MemoryStart , MemoryEnd , &
3561 PatchStart , PatchEnd , &
3563 DEALLOCATE ( globbuf )
3565 END SUBROUTINE call_pkg_and_dist_double
3568 SUBROUTINE call_pkg_and_dist_int ( fcn, update_arg , &
3569 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3570 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3571 DomainStart , DomainEnd , &
3572 MemoryStart , MemoryEnd , &
3573 PatchStart , PatchEnd , &
3577 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3578 ! distribute or replicate the field across compute tasks.
3579 ! The sole purpose of this wrapper is to allocate a big integer buffer and
3580 ! pass it down to call_pkg_and_dist_generic() to do the actual work.
3585 INTEGER , INTENT(IN) :: Hndl
3586 LOGICAL , INTENT(IN) :: update_arg
3587 CHARACTER*(*) :: DateStr
3588 CHARACTER*(*) :: VarName
3589 INTEGER , INTENT(INOUT) :: Field(*)
3590 INTEGER ,INTENT(IN) :: FieldType
3591 INTEGER ,INTENT(INOUT) :: Comm
3592 INTEGER ,INTENT(INOUT) :: IOComm
3593 INTEGER ,INTENT(IN) :: DomainDesc
3594 LOGICAL, DIMENSION(4) :: bdy_mask
3595 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3596 CHARACTER*(*) ,INTENT(IN) :: Stagger
3597 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3598 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3599 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3600 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3601 INTEGER ,INTENT(INOUT) :: Status
3602 INTEGER , ALLOCATABLE :: globbuf (:)
3603 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3605 IF ( wrf_dm_on_monitor() ) THEN
3606 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3608 ALLOCATE( globbuf( 1 ) )
3613 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
3614 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3615 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3616 DomainStart , DomainEnd , &
3617 MemoryStart , MemoryEnd , &
3618 PatchStart , PatchEnd , &
3620 DEALLOCATE ( globbuf )
3622 END SUBROUTINE call_pkg_and_dist_int
3625 SUBROUTINE call_pkg_and_dist_logical ( fcn, update_arg , &
3626 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3627 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3628 DomainStart , DomainEnd , &
3629 MemoryStart , MemoryEnd , &
3630 PatchStart , PatchEnd , &
3634 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3635 ! distribute or replicate the field across compute tasks.
3636 ! The sole purpose of this wrapper is to allocate a big logical buffer and
3637 ! pass it down to call_pkg_and_dist_generic() to do the actual work.
3642 INTEGER , INTENT(IN) :: Hndl
3643 LOGICAL , INTENT(IN) :: update_arg
3644 CHARACTER*(*) :: DateStr
3645 CHARACTER*(*) :: VarName
3646 logical , INTENT(INOUT) :: Field(*)
3647 INTEGER ,INTENT(IN) :: FieldType
3648 INTEGER ,INTENT(INOUT) :: Comm
3649 INTEGER ,INTENT(INOUT) :: IOComm
3650 INTEGER ,INTENT(IN) :: DomainDesc
3651 LOGICAL, DIMENSION(4) :: bdy_mask
3652 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3653 CHARACTER*(*) ,INTENT(IN) :: Stagger
3654 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3655 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3656 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3657 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3658 INTEGER ,INTENT(INOUT) :: Status
3659 LOGICAL , ALLOCATABLE :: globbuf (:)
3660 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3662 IF ( wrf_dm_on_monitor() ) THEN
3663 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3665 ALLOCATE( globbuf( 1 ) )
3670 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
3671 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3672 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3673 DomainStart , DomainEnd , &
3674 MemoryStart , MemoryEnd , &
3675 PatchStart , PatchEnd , &
3677 DEALLOCATE ( globbuf )
3679 END SUBROUTINE call_pkg_and_dist_logical
3681 SUBROUTINE call_pkg_and_dist_generic ( fcn, globbuf , update_arg , &
3682 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3683 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3684 DomainStart , DomainEnd , &
3685 MemoryStart , MemoryEnd , &
3686 PatchStart , PatchEnd , &
3691 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3692 ! distribute or replicate the field across compute tasks.
3693 ! This routine calls I/O function fcn to read the field from disk and then calls
3694 ! the distributed memory communication routines that distribute or replicate the
3698 USE module_state_description
3699 USE module_driver_constants
3702 #include "wrf_io_flags.h"
3703 #if defined( DM_PARALLEL ) && ! defined(STUBMPI)
3708 REAL, DIMENSION(*) :: globbuf
3709 INTEGER , INTENT(IN) :: Hndl
3710 LOGICAL , INTENT(IN) :: update_arg
3711 CHARACTER*(*) :: DateStr
3712 CHARACTER*(*) :: VarName
3714 INTEGER ,INTENT(IN) :: FieldType
3715 INTEGER ,INTENT(INOUT) :: Comm
3716 INTEGER ,INTENT(INOUT) :: IOComm
3717 INTEGER ,INTENT(IN) :: DomainDesc
3718 LOGICAL, DIMENSION(4) :: bdy_mask
3719 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3720 CHARACTER*(*) ,INTENT(IN) :: Stagger
3721 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3722 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3723 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3724 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3725 INTEGER ,INTENT(OUT) :: Status
3727 LOGICAL, EXTERNAL :: has_char
3728 INTEGER ids, ide, jds, jde, kds, kde
3729 INTEGER ims, ime, jms, jme, kms, kme
3730 INTEGER ips, ipe, jps, jpe, kps, kpe
3731 INTEGER , dimension(3) :: dom_end_rev
3733 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3734 INTEGER, EXTERNAL :: wrf_dm_monitor_rank
3736 INTEGER lx, lx2, i,j,k ,idx,idx2
3737 INTEGER my_count, nproc, communicator, ierr, my_displ
3739 INTEGER, ALLOCATABLE :: counts(:), displs(:)
3741 LOGICAL distributed_field
3742 INTEGER collective_root
3744 CALL lower_case( MemoryOrder, MemOrd )
3746 collective_root = wrf_dm_monitor_rank()
3748 CALL wrf_get_nproc( nproc )
3749 CALL wrf_get_dm_communicator ( communicator )
3751 ALLOCATE(displs( nproc ))
3752 ALLOCATE(counts( nproc ))
3754 dom_end_rev(1) = DomainEnd(1)
3755 dom_end_rev(2) = DomainEnd(2)
3756 dom_end_rev(3) = DomainEnd(3)
3758 SELECT CASE (TRIM(MemOrd))
3760 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3761 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3762 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3764 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3765 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3766 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3768 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3769 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3770 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3772 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3773 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3775 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3776 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3777 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3779 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3780 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3782 ! do nothing; the boundary orders and others either dont care or set themselves
3785 data_ordering : SELECT CASE ( model_data_order )
3786 CASE ( DATA_ORDER_XYZ )
3787 ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(2); jde=dom_end_rev(2); kds=DomainStart(3); kde=dom_end_rev(3);
3788 ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(2); jme= MemoryEnd(2); kms=MemoryStart(3); kme= MemoryEnd(3);
3789 ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(2); jpe= PatchEnd(2); kps= PatchStart(3); kpe= PatchEnd(3);
3790 CASE ( DATA_ORDER_YXZ )
3791 ids=DomainStart(2); ide=dom_end_rev(2); jds=DomainStart(1); jde=dom_end_rev(1); kds=DomainStart(3); kde=dom_end_rev(3);
3792 ims=MemoryStart(2); ime= MemoryEnd(2); jms=MemoryStart(1); jme= MemoryEnd(1); kms=MemoryStart(3); kme= MemoryEnd(3);
3793 ips= PatchStart(2); ipe= PatchEnd(2); jps= PatchStart(1); jpe= PatchEnd(1); kps= PatchStart(3); kpe= PatchEnd(3);
3794 CASE ( DATA_ORDER_ZXY )
3795 ids=DomainStart(2); ide=dom_end_rev(2); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(1); kde=dom_end_rev(1);
3796 ims=MemoryStart(2); ime= MemoryEnd(2); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(1); kme= MemoryEnd(1);
3797 ips= PatchStart(2); ipe= PatchEnd(2); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(1); kpe= PatchEnd(1);
3798 CASE ( DATA_ORDER_ZYX )
3799 ids=DomainStart(3); ide=dom_end_rev(3); jds=DomainStart(2); jde=dom_end_rev(2); kds=DomainStart(1); kde=dom_end_rev(1);
3800 ims=MemoryStart(3); ime= MemoryEnd(3); jms=MemoryStart(2); jme= MemoryEnd(2); kms=MemoryStart(1); kme= MemoryEnd(1);
3801 ips= PatchStart(3); ipe= PatchEnd(3); jps= PatchStart(2); jpe= PatchEnd(2); kps= PatchStart(1); kpe= PatchEnd(1);
3802 CASE ( DATA_ORDER_XZY )
3803 ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
3804 ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
3805 ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
3806 CASE ( DATA_ORDER_YZX )
3807 ids=DomainStart(3); ide=dom_end_rev(3); jds=DomainStart(1); jde=dom_end_rev(1); kds=DomainStart(2); kde=dom_end_rev(2);
3808 ims=MemoryStart(3); ime= MemoryEnd(3); jms=MemoryStart(1); jme= MemoryEnd(1); kms=MemoryStart(2); kme= MemoryEnd(2);
3809 ips= PatchStart(3); ipe= PatchEnd(3); jps= PatchStart(1); jpe= PatchEnd(1); kps= PatchStart(2); kpe= PatchEnd(2);
3810 END SELECT data_ordering
3813 SELECT CASE (MemOrd)
3815 CASE ( 'xzy', 'yzx', 'xyz', 'yxz', 'zxy', 'zyx', 'xy', 'yx' )
3816 distributed_field = .TRUE.
3817 CASE ( 'xsz', 'xez', 'xs', 'xe' )
3818 CALL are_bdys_distributed( distributed_field )
3819 CASE ( 'ysz', 'yez', 'ys', 'ye' )
3820 CALL are_bdys_distributed( distributed_field )
3823 ! all other memory orders are replicated
3824 distributed_field = .FALSE.
3827 IF ( distributed_field ) THEN
3829 ! added 8/2004 for interfaces, like MCEL, that want the old values so they can be updated
3830 IF ( update_arg ) THEN
3831 SELECT CASE (TRIM(MemOrd))
3832 CASE ( 'xzy','zxy','xyz','yxz','xy','yx' )
3833 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3834 CALL wrf_patch_to_global_double ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3835 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3836 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3837 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3838 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3839 CALL wrf_patch_to_global_real ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3840 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3841 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3842 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3843 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3844 CALL wrf_patch_to_global_integer ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3845 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3846 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3847 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3848 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
3849 CALL wrf_patch_to_global_logical ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3850 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3851 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3852 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3858 IF ( wrf_dm_on_monitor()) THEN
3859 CALL fcn ( Hndl , DateStr , VarName , globbuf , FieldType , Comm , IOComm , &
3860 DomainDesc , MemoryOrder , Stagger , DimNames , &
3861 DomainStart , DomainEnd , &
3862 DomainStart , dom_end_rev , &
3863 DomainStart , DomainEnd , &
3868 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
3870 CALL lower_case( MemoryOrder, MemOrd )
3872 #if defined(DM_PARALLEL) && !defined(STUBMPI)
3873 ! handle boundaries separately
3874 IF ( TRIM(MemOrd) .EQ. 'xsz' .OR. TRIM(MemOrd) .EQ. 'xez' .OR. &
3875 TRIM(MemOrd) .EQ. 'xs' .OR. TRIM(MemOrd) .EQ. 'xe' .OR. &
3876 TRIM(MemOrd) .EQ. 'ysz' .OR. TRIM(MemOrd) .EQ. 'yez' .OR. &
3877 TRIM(MemOrd) .EQ. 'ys' .OR. TRIM(MemOrd) .EQ. 'ye' ) THEN
3879 IF ( TRIM(MemOrd) .EQ. 'xsz' .OR. TRIM(MemOrd) .EQ. 'xez' .OR. &
3880 TRIM(MemOrd) .EQ. 'xs' .OR. TRIM(MemOrd) .EQ. 'xe' ) THEN
3882 jds=DomainStart(1); jde=dom_end_rev(1); ids=DomainStart(3); ide=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
3883 jms=MemoryStart(1); jme= MemoryEnd(1); ims=MemoryStart(3); ime= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
3884 jps= PatchStart(1); jpe= PatchEnd(1); ips= PatchStart(3); ipe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
3886 IF ( nproc .GT. 1 ) THEN
3888 ! Will assume that the i,j, and k dimensions correspond to the model_data_order specified by the registry --
3889 ! eg. i is (1), j is (3), and k is (2) for XZY -- and that when these are passed in for xs/xe boundary arrays (left and right
3890 ! sides of domain) the j is fully dimensioned, i is the bdy_width, and k is k. corresponding arrangement for ys/ye
3891 ! boundaries (bottom and top). Note, however, that for the boundary arrays themselves, the innermost dimension is always
3892 ! the "full" dimension: for xs/xe, dimension 1 of the boundary arrays is j. For ys/ye, it's i. So there's a potential
3893 ! for confusion between the MODEL storage order, and which of the sd31:ed31/sd32:ed32/sd33:ed33 framework dimensions
3894 ! correspond to X/Y/Z as determined by the Registry dimespec definitions and what the storage order of the boundary
3895 ! slab arrays are (which depends on which boundaries they represent). The k memory and domain dimensions must be set
3896 ! properly for 2d (ks=1, ke=1) versus 3d fields.
3898 IF ( (MemOrd(1:2) .EQ. 'xs' .AND. bdy_mask( P_XSB )) .OR. &
3899 (MemOrd(1:2) .EQ. 'xe' .AND. bdy_mask( P_XEB )) ) THEN
3901 my_count = jpe-jps+1
3907 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3908 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3910 do i = ips,ipe ! bdy_width
3911 do k = kds,kde ! levels
3914 idx = lx*((k-1)+(i-1)*(kme-kms+1))
3915 idx2 = lx2*((k-1)+(i-1)*(kde-kds+1))
3916 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3917 CALL wrf_scatterv_double ( &
3918 globbuf, 1+idx2 , & ! recvbuf
3919 counts , & ! recvcounts
3920 Field, jps-jms+1+idx , &
3921 my_count , & ! sendcount
3923 collective_root , & ! root
3924 communicator , & ! communicator
3926 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3928 CALL wrf_scatterv_real ( &
3929 globbuf, 1+idx2 , & ! recvbuf
3930 counts , & ! recvcounts
3931 Field, jps-jms+1+idx , &
3932 my_count , & ! sendcount
3934 collective_root , & ! root
3935 communicator , & ! communicator
3938 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3939 CALL wrf_scatterv_integer ( &
3940 globbuf, 1+idx2 , & ! recvbuf
3941 counts , & ! recvcounts
3942 Field, jps-jms+1+idx , &
3943 my_count , & ! sendcount
3945 collective_root , & ! root
3946 communicator , & ! communicator
3954 IF ( TRIM(MemOrd) .EQ. 'ysz' .OR. TRIM(MemOrd) .EQ. 'yez' .OR. &
3955 TRIM(MemOrd) .EQ. 'ys' .OR. TRIM(MemOrd) .EQ. 'ye' ) THEN
3957 ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
3958 ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
3959 ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
3961 IF ( nproc .GT. 1 ) THEN
3962 IF ( (MemOrd(1:2) .EQ. 'ys' .AND. bdy_mask( P_YSB )) .OR. &
3963 (MemOrd(1:2) .EQ. 'ye' .AND. bdy_mask( P_YEB )) ) THEN
3965 my_count = ipe-ips+1
3971 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3972 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3974 do j = jds,jde ! bdy_width
3975 do k = kds,kde ! levels
3978 idx = lx*((k-1)+(j-1)*(kme-kms+1))
3979 idx2 = lx2*((k-1)+(j-1)*(kde-kds+1))
3981 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3982 CALL wrf_scatterv_double ( &
3983 globbuf, 1+idx2 , & ! recvbuf
3984 counts , & ! recvcounts
3985 Field, ips-ims+1+idx , &
3986 my_count , & ! sendcount
3988 collective_root , & ! root
3989 communicator , & ! communicator
3991 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3992 CALL wrf_scatterv_real ( &
3993 globbuf, 1+idx2 , & ! recvbuf
3994 counts , & ! recvcounts
3995 Field, ips-ims+1+idx , &
3996 my_count , & ! sendcount
3998 collective_root , & ! root
3999 communicator , & ! communicator
4001 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4002 CALL wrf_scatterv_integer ( &
4003 globbuf, 1+idx2 , & ! recvbuf
4004 counts , & ! recvcounts
4005 Field, ips-ims+1+idx , &
4006 my_count , & ! sendcount
4008 collective_root , & ! root
4009 communicator , & ! communicator
4017 ELSE ! not a boundary
4019 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
4021 SELECT CASE (MemOrd)
4022 CASE ( 'xzy','xyz','yxz','zxy' )
4023 CALL wrf_global_to_patch_double ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4024 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4025 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4026 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4028 CALL wrf_global_to_patch_double ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4029 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4030 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4031 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4034 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
4036 SELECT CASE (MemOrd)
4037 CASE ( 'xzy','xyz','yxz','zxy' )
4038 CALL wrf_global_to_patch_real ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4039 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4040 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4041 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4043 CALL wrf_global_to_patch_real ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4044 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4045 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4046 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4049 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4051 SELECT CASE (MemOrd)
4052 CASE ( 'xzy','xyz','yxz','zxy' )
4053 CALL wrf_global_to_patch_integer ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4054 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4055 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4056 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4058 CALL wrf_global_to_patch_integer ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4059 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4060 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4061 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4064 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
4066 SELECT CASE (MemOrd)
4067 CASE ( 'xzy','xyz','yxz','zxy' )
4068 CALL wrf_global_to_patch_logical ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4069 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4070 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4071 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4073 CALL wrf_global_to_patch_logical ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4074 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4075 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4076 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4083 ELSE ! not a distributed field
4085 IF ( wrf_dm_on_monitor()) THEN
4086 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
4087 DomainDesc , MemoryOrder , Stagger , DimNames , &
4088 DomainStart , DomainEnd , &
4089 MemoryStart , MemoryEnd , &
4090 PatchStart , PatchEnd , &
4093 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
4094 memsize = (MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)
4095 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
4096 CALL wrf_dm_bcast_bytes( Field , DWORDSIZE*memsize )
4097 ELSE IF ( FieldType .EQ. WRF_FLOAT) THEN
4098 CALL wrf_dm_bcast_bytes( Field , RWORDSIZE*memsize )
4099 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4100 CALL wrf_dm_bcast_bytes( Field , IWORDSIZE*memsize )
4101 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
4102 CALL wrf_dm_bcast_bytes( Field , LWORDSIZE*memsize )
4110 END SUBROUTINE call_pkg_and_dist_generic
4112 !!!!!! Miscellaneous routines
4114 ! stole these routines from io_netcdf external package; changed names to avoid collisions
4115 SUBROUTINE dim_from_memorder(MemoryOrder,NDim)
4118 ! Decodes array ranks from memory order.
4121 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
4122 INTEGER ,INTENT(OUT) :: NDim
4124 CHARACTER*3 :: MemOrd
4126 CALL Lower_Case(MemoryOrder,MemOrd)
4127 SELECT CASE (MemOrd)
4128 CASE ('xyz','xzy','yxz','yzx','zxy','zyx')
4139 END SUBROUTINE dim_from_memorder
4141 SUBROUTINE lower_case(MemoryOrder,MemOrd)
4144 ! Translates upper-case characters to lower-case.
4147 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
4148 CHARACTER*(*) ,INTENT(OUT) :: MemOrd
4151 INTEGER ,PARAMETER :: upper_to_lower =IACHAR('a')-IACHAR('A')
4155 N = len(MemoryOrder)
4156 MemOrd(1:N) = MemoryOrder(1:N)
4158 c = MemoryOrder(i:i)
4159 if('A'<=c .and. c <='Z') MemOrd(i:i)=achar(iachar(c)+upper_to_lower)
4162 END SUBROUTINE Lower_Case
4164 LOGICAL FUNCTION has_char( str, c )
4167 ! Returns .TRUE. iff string str contains character c. Ignores character case.
4173 CHARACTER*80 str1, str2, str3
4176 CALL lower_case( TRIM(str), str1 )
4179 CALL lower_case( str2, str3 )
4181 DO i = 1, LEN(TRIM(str1))
4182 IF ( str1(i:i) .EQ. d ) THEN
4189 END FUNCTION has_char