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)
34 INTEGER :: how_opened(MAX_WRF_IO_HANDLE)
35 LOGICAL :: for_output(MAX_WRF_IO_HANDLE), first_operation(MAX_WRF_IO_HANDLE)
37 LOGICAL, PRIVATE :: bdy_dist_flag = .TRUE. ! false is old style undecomposed boundary data structs,
38 ! true is new style decomposed boundary data structs
39 ! are_bdys_distributed, bdys_are_distributed and
40 ! bdys_not_distributed routines access this flag
41 CHARACTER*256 extradims
46 ! include the file generated from md_calls.m4 using the m4 preprocessor
47 ! note that this file also includes the CONTAINS declaration for the module
51 #include "md_calls.inc"
53 !--- registry-generated routine that gets the io format being used for a dataset
55 INTEGER FUNCTION io_form_for_dataset ( DataSet )
57 CHARACTER*(*), INTENT(IN) :: DataSet
59 #include "io_form_for_dataset.inc"
60 io_form_for_dataset = io_form
62 END FUNCTION io_form_for_dataset
64 INTEGER FUNCTION io_form_for_stream ( stream )
67 INTEGER, INTENT(IN) :: stream
69 #include "io_form_for_stream.inc"
70 io_form_for_stream = io_form
72 END FUNCTION io_form_for_stream
76 SUBROUTINE wrf_ioinit( Status )
79 ! Initialize the WRF I/O system.
83 INTEGER, INTENT(INOUT) :: Status
85 CHARACTER(len=80) :: SysDepInfo
86 INTEGER :: ierr(100), minerr, maxerr
91 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioinit' )
92 CALL init_io_handles ! defined below
94 if ( model_config_rec%use_netcdf_classic ) SysDepInfo="use_netcdf_classic"
95 CALL ext_ncd_ioinit ( SysDepInfo, ierr( 1) )
99 CALL ext_int_ioinit ( SysDepInfo, ierr( 2) )
102 CALL ext_phdf5_ioinit( SysDepInfo, ierr( 3) )
105 CALL ext_xxx_ioinit ( SysDepInfo, ierr( 5) )
108 CALL ext_yyy_ioinit ( SysDepInfo, ierr( 6) )
111 CALL ext_zzz_ioinit ( SysDepInfo, ierr( 7) )
114 CALL ext_esmf_ioinit ( SysDepInfo, ierr( 8) )
117 CALL ext_gr1_ioinit ( SysDepInfo, ierr( 9) )
120 CALL ext_gr2_ioinit ( SysDepInfo, ierr(10) )
123 CALL ext_pnc_ioinit ( SysDepInfo, ierr(11) )
126 CALL ext_pio_ioinit ( SysDepInfo, ierr(12) )
129 CALL ext_ncdpar_ioinit( SysDepInfo, ierr(13) )
132 CALL ext_adios2_ioinit ( SysDepInfo, ierr(14) )
135 minerr = MINVAL(ierr)
136 maxerr = MAXVAL(ierr)
137 IF ( minerr < 0 ) THEN
139 ELSE IF ( maxerr > 0 ) THEN
144 END SUBROUTINE wrf_ioinit
148 SUBROUTINE wrf_ioexit( Status )
151 ! Shut down the WRF I/O system.
155 INTEGER, INTENT(INOUT) :: Status
157 LOGICAL, EXTERNAL :: use_output_servers
158 INTEGER :: ierr(100), minerr, maxerr
162 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioexit' )
164 CALL ext_ncd_ioexit ( ierr( 1) )
167 CALL ext_int_ioexit ( ierr( 2) )
170 CALL ext_phdf5_ioexit( ierr( 3) )
173 CALL ext_xxx_ioexit ( ierr( 5) )
176 CALL ext_yyy_ioexit ( ierr( 6) )
179 CALL ext_zzz_ioexit ( ierr( 7) )
182 CALL ext_esmf_ioexit ( ierr( 8) )
185 CALL ext_gr1_ioexit ( ierr( 9) )
188 CALL ext_gr2_ioexit ( ierr(10) )
191 CALL ext_pnc_ioexit ( ierr(11) )
194 CALL ext_pio_ioexit ( ierr(12) )
197 CALL ext_ncdpar_ioexit ( ierr(13) )
200 CALL ext_adios2_ioexit ( ierr(14) )
203 IF ( use_output_servers() ) THEN
204 CALL wrf_quilt_ioexit( ierr(11) )
206 minerr = MINVAL(ierr)
207 maxerr = MAXVAL(ierr)
208 IF ( minerr < 0 ) THEN
210 ELSE IF ( maxerr > 0 ) THEN
215 END SUBROUTINE wrf_ioexit
217 !--- open_for_write_begin
219 SUBROUTINE wrf_open_for_write_begin( FileName , grid, SysDepInfo, &
220 DataHandle , Status )
223 ! Begin data definition ("training") phase for writing to WRF dataset
227 USE module_state_description
230 USE module_dm, ONLY : ntasks_x, mytask_x, local_communicator_x
233 #include "wrf_io_flags.h"
234 CHARACTER*(*) :: FileName
236 CHARACTER*(*), INTENT(INOUT):: SysDepInfo
237 INTEGER , INTENT(OUT) :: DataHandle
238 INTEGER , INTENT(OUT) :: Status
240 CHARACTER*128 :: DataSet
243 INTEGER, EXTERNAL :: use_package
244 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files
245 LOGICAL, EXTERNAL :: use_output_servers_for
246 CHARACTER*512 :: LocFilename ! for appending the process ID if necessary
248 CHARACTER*512 :: mess
249 CHARACTER (LEN=256) :: message
250 CHARACTER*1028 :: tstr, t1
252 INTEGER :: Comm_compute , Comm_io
255 WRITE(mess,*) 'module_io.F: in wrf_open_for_write_begin, FileName = ',TRIM(FileName)
256 CALL wrf_debug( 100, mess )
258 Comm_compute = grid%communicator
259 Comm_io = grid%iocommunicator
261 CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
263 CALL nl_get_ncd_nofill( 1 , ncd_nofill )
265 io_form = io_form_for_dataset( DataSet )
269 IF ( .not. use_output_servers_for(io_form) ) THEN
270 SELECT CASE ( use_package(io_form) )
273 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
274 IF ( multi_files(io_form) ) THEN
275 CALL wrf_get_myproc ( myproc )
276 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
278 LocFilename = FileName
280 IF ( ncd_nofill ) THEN
281 CALL ext_ncd_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo // ",NOFILL=.TRUE.", &
284 CALL ext_ncd_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
288 IF ( .NOT. multi_files(io_form) ) THEN
289 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
290 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
295 CASE ( IO_NETCDFPAR )
296 IF ( ncd_nofill ) THEN
297 CALL wrf_debug ( 100 , 'calling ext_ncdpar_open_for_write_begin 1' )
299 CALL ext_ncdpar_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo // ",NOFILL=.TRUE.", &
301 WRITE ( message , '("after ext_ncdpar_open_for_write_begin 1: status = ",i8)') status
303 CALL wrf_debug ( 100 , message )
305 CALL wrf_debug ( 100 , 'calling ext_ncdpar_open_for_write_begin 2' )
306 CALL ext_ncdpar_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
308 CALL wrf_debug ( 100 , 'after ext_ncdpar_open_for_write_begin 1' )
314 WRITE(tstr,"(A,',ADIOS ADIOS NTASKS_X=',i10,',MYTASK_X=',i10,',LOCAL_COMMUNICATOR_X=',i10)") &
315 TRIM(SysDepInfo),ntasks_x,mytask_x,local_communicator_x
318 DO i=1,len(TRIM(tstr))
319 IF ( tstr(i:i) .NE. ' ' ) THEN
325 CALL ext_adios2_open_for_write_begin( FileName, tstr, &
326 Dataset, Hndl, Status)
331 CALL ext_phdf5_open_for_write_begin( FileName, Comm_compute, Comm_io, SysDepInfo, &
336 WRITE(tstr,"(A,',NTASKS_X=',i10,',MYTASK_X=',i10,',LOCAL_COMMUNICATOR_X=',i10)") &
337 TRIM(SysDepInfo),ntasks_x,mytask_x,local_communicator_x
340 DO i=1,len(TRIM(tstr))
341 IF ( tstr(i:i) .NE. ' ' ) THEN
347 CALL ext_pnc_open_for_write_begin( FileName, Comm_compute, Comm_io, tstr, &
352 WRITE(tstr,"(A,',NTASKS_X=',i10,',MYTASK_X=',i10,',LOCAL_COMMUNICATOR_X=',i10)") &
353 TRIM(SysDepInfo),ntasks_x,mytask_x,local_communicator_x
356 DO i=1,len(TRIM(tstr))
357 IF ( tstr(i:i) .NE. ' ' ) THEN
363 CALL ext_pio_open_for_write_begin( FileName, grid, tstr, Hndl, Status)
367 CALL ext_xxx_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
372 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
373 IF ( multi_files(io_form) ) THEN
374 CALL wrf_get_myproc ( myproc )
375 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
377 LocFilename = FileName
379 CALL ext_yyy_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
382 IF ( .NOT. multi_files(io_form) ) THEN
383 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
384 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
389 CALL ext_zzz_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
394 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
395 IF ( multi_files(io_form) ) THEN
396 CALL wrf_get_myproc ( myproc )
397 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
399 LocFilename = FileName
401 CALL ext_gr1_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
404 IF ( .NOT. multi_files(io_form) ) THEN
405 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
406 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
411 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
412 IF ( multi_files(io_form) ) THEN
413 CALL wrf_get_myproc ( myproc )
414 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
416 LocFilename = FileName
418 CALL ext_gr2_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
421 IF ( .NOT. multi_files(io_form) ) THEN
422 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
423 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
428 CALL ext_esmf_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
433 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
434 IF ( multi_files(io_form) ) THEN
435 CALL wrf_get_myproc ( myproc )
436 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
438 LocFilename = FileName
440 CALL ext_int_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
443 IF ( .NOT. multi_files(io_form) ) THEN
444 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
445 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
449 IF ( io_form .NE. 0 ) THEN
450 WRITE(mess,*)'Tried to open ',FileName,' writing: no valid io_form (',io_form,')'
451 CALL wrf_debug(1, mess)
452 Status = WRF_FILE_NOT_OPENED
455 ELSE ! use_output_servers_for(io_form)
456 IF ( io_form .GT. 0 ) THEN
457 IF ( ncd_nofill ) THEN
458 CALL wrf_quilt_open_for_write_begin ( FileName , grid%id, Comm_compute, Comm_io, TRIM(SysDepInfo) // ",NOFILL=.TRUE.", &
459 Hndl , io_form, Status )
461 CALL wrf_quilt_open_for_write_begin ( FileName , grid%id, Comm_compute, Comm_io, SysDepInfo, &
462 Hndl , io_form, Status )
466 CALL add_new_handle( Hndl, io_form, .TRUE., DataHandle )
467 END SUBROUTINE wrf_open_for_write_begin
469 !--- open_for_write_commit
471 SUBROUTINE wrf_open_for_write_commit( DataHandle , Status )
474 ! This routine switches an internal flag to enable output for the data set
475 ! referenced by DataHandle. The call to wrf_open_for_write_commit() must be
476 ! paired with a call to wrf_open_for_write_begin().
479 USE module_state_description
481 INTEGER , INTENT(IN ) :: DataHandle
482 INTEGER , INTENT(OUT) :: Status
484 CHARACTER (128) :: DataSet
488 INTEGER, EXTERNAL :: use_package
489 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
490 #include "wrf_io_flags.h"
492 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_write_commit' )
495 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
496 CALL set_first_operation( DataHandle )
497 IF ( Hndl .GT. -1 ) THEN
498 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
499 SELECT CASE ( use_package(io_form) )
502 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
503 CALL ext_ncd_open_for_write_commit ( Hndl , Status )
505 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
508 CASE ( IO_NETCDFPAR )
509 CALL ext_ncdpar_open_for_write_commit ( Hndl , Status )
513 CALL ext_esmf_open_for_write_commit ( Hndl , Status )
517 CALL ext_phdf5_open_for_write_commit ( Hndl , Status )
521 CALL ext_pnc_open_for_write_commit ( Hndl , Status )
525 CALL ext_adios2_open_for_write_commit ( Hndl , Status )
529 CALL ext_pio_open_for_write_commit ( Hndl , Status )
533 CALL ext_xxx_open_for_write_commit ( Hndl , Status )
537 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
538 CALL ext_yyy_open_for_write_commit ( Hndl , Status )
540 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
544 CALL ext_zzz_open_for_write_commit ( Hndl , Status )
548 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
549 CALL ext_gr1_open_for_write_commit ( Hndl , Status )
551 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
555 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
556 CALL ext_gr2_open_for_write_commit ( Hndl , Status )
558 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
562 CALL ext_int_open_for_write_commit ( Hndl , Status )
567 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
568 CALL wrf_quilt_open_for_write_commit ( Hndl , Status )
576 END SUBROUTINE wrf_open_for_write_commit
578 !--- open_for_read_begin
580 SUBROUTINE wrf_open_for_read_begin( FileName , grid, SysDepInfo, &
581 DataHandle , Status )
584 ! Begin data definition ("training") phase for reading from WRF dataset
588 USE module_state_description
591 #include "wrf_io_flags.h"
592 CHARACTER*(*) :: FileName
593 TYPE (domain) :: grid
594 CHARACTER*(*) :: SysDepInfo
595 INTEGER , INTENT(OUT) :: DataHandle
596 INTEGER , INTENT(OUT) :: Status
598 CHARACTER*128 :: DataSet
601 LOGICAL :: also_for_out
602 INTEGER, EXTERNAL :: use_package
603 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
605 CHARACTER*128 :: LocFilename ! for appending the process ID if necessary
607 CHARACTER*128 :: mess, fhand
608 CHARACTER*1028 :: tstr
609 INTEGER :: Comm_compute , Comm_io
611 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read_begin' )
613 Comm_compute = grid%communicator
614 Comm_io = grid%iocommunicator
616 CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
618 io_form = io_form_for_dataset( DataSet )
622 also_for_out = .FALSE.
623 ! IF ( .NOT. use_output_servers_for(io_form) ) THEN
624 SELECT CASE ( use_package(io_form) )
627 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
628 IF ( multi_files(io_form) ) THEN
629 CALL wrf_get_myproc ( myproc )
630 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
632 LocFilename = FileName
634 CALL ext_ncd_open_for_read_begin ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
637 IF ( .NOT. multi_files(io_form) ) THEN
638 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
639 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
643 CASE ( IO_NETCDFPAR )
644 CALL ext_ncdpar_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
649 CALL ext_pnc_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
654 CALL ext_adios2_open_for_read_begin ( FileName , SysDepInfo, &
659 CALL ext_pio_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
664 CALL ext_xxx_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
669 CALL ext_yyy_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
674 CALL ext_zzz_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
679 also_for_out = .TRUE.
680 CALL ext_esmf_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
685 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
686 IF ( multi_files(io_form) ) THEN
687 CALL wrf_get_myproc ( myproc )
688 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
690 LocFilename = FileName
692 CALL ext_gr1_open_for_read_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
695 IF ( .NOT. multi_files(io_form) ) THEN
696 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
697 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
702 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
703 IF ( multi_files(io_form) ) THEN
704 CALL wrf_get_myproc ( myproc )
705 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
707 LocFilename = FileName
709 CALL ext_gr2_open_for_read_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
712 IF ( .NOT. multi_files(io_form) ) THEN
713 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
714 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
721 IF ( io_form .NE. 0 ) THEN
722 WRITE(mess,*)'Tried to open ',FileName,' reading: no valid io_form (',io_form,')'
723 CALL wrf_message(mess)
725 Status = WRF_FILE_NOT_OPENED
730 CALL add_new_handle( Hndl, io_form, also_for_out, DataHandle )
731 END SUBROUTINE wrf_open_for_read_begin
733 !--- open_for_read_commit
735 SUBROUTINE wrf_open_for_read_commit( DataHandle , Status )
738 ! End "training" phase for WRF dataset FileName. The call to
739 ! wrf_open_for_read_commit() must be paired with a call to
740 ! wrf_open_for_read_begin().
743 USE module_state_description
745 INTEGER , INTENT(IN ) :: DataHandle
746 INTEGER , INTENT(OUT) :: Status
748 CHARACTER (128) :: DataSet
752 INTEGER, EXTERNAL :: use_package
753 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
754 #include "wrf_io_flags.h"
756 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read_commit' )
759 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
760 CALL set_first_operation( DataHandle )
761 IF ( Hndl .GT. -1 ) THEN
762 IF ( .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
763 SELECT CASE ( use_package(io_form) )
766 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
767 CALL ext_ncd_open_for_read_commit ( Hndl , Status )
769 IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
773 CALL ext_esmf_open_for_read_commit ( Hndl , Status )
776 CASE ( IO_NETCDFPAR )
777 CALL ext_ncdpar_open_for_read_commit ( Hndl , Status )
781 CALL ext_pnc_open_for_read_commit ( Hndl , Status )
785 CALL ext_adios2_open_for_read_commit ( Hndl , Status )
789 CALL ext_pio_open_for_read_commit ( Hndl , Status )
793 CALL ext_xxx_open_for_read_commit ( Hndl , Status )
797 CALL ext_yyy_open_for_read_commit ( Hndl , Status )
801 CALL ext_zzz_open_for_read_commit ( Hndl , Status )
805 CALL ext_gr1_open_for_read_commit ( Hndl , Status )
809 CALL ext_gr2_open_for_read_commit ( Hndl , Status )
821 Status = WRF_FILE_NOT_OPENED
824 END SUBROUTINE wrf_open_for_read_commit
828 SUBROUTINE wrf_open_for_read ( FileName , grid, SysDepInfo, &
829 DataHandle , Status )
832 ! Opens a WRF dataset for reading.
835 USE module_state_description
838 CHARACTER*(*) :: FileName
839 TYPE (domain) :: grid
840 CHARACTER*(*) :: SysDepInfo
841 INTEGER , INTENT(OUT) :: DataHandle
842 INTEGER , INTENT(OUT) :: Status
844 CHARACTER (128) :: DataSet, LocFileName
845 INTEGER :: io_form, myproc
847 INTEGER, EXTERNAL :: use_package
848 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
849 INTEGER :: Comm_compute, Comm_io
851 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read' )
853 Comm_compute = grid%communicator
854 Comm_io = grid%iocommunicator
856 CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
858 io_form = io_form_for_dataset( DataSet )
862 SELECT CASE ( use_package(io_form) )
865 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
866 IF ( multi_files(io_form) ) THEN
867 CALL wrf_get_myproc ( myproc )
868 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
870 LocFilename = FileName
873 CALL ext_ncd_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
876 IF ( .NOT. multi_files(io_form) ) THEN
877 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
878 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
882 CASE ( IO_NETCDFPAR )
883 CALL ext_ncdpar_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
888 CALL ext_pnc_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
893 CALL ext_adios2_open_for_read ( FileName , SysDepInfo, &
898 CALL ext_pio_open_for_read ( FileName , grid, SysDepInfo, Hndl , Status )
902 CALL ext_phdf5_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
907 CALL ext_xxx_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
912 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
913 IF ( multi_files(io_form) ) THEN
914 CALL wrf_get_myproc ( myproc )
915 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
917 LocFilename = FileName
920 CALL ext_yyy_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
923 IF ( .NOT. multi_files(io_form) ) THEN
924 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
925 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
930 CALL ext_zzz_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
935 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
936 IF ( multi_files(io_form) ) THEN
937 CALL wrf_get_myproc ( myproc )
938 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
940 LocFilename = FileName
943 CALL ext_gr1_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
946 IF ( .NOT. multi_files(io_form) ) THEN
947 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
948 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
953 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
954 IF ( multi_files(io_form) ) THEN
955 CALL wrf_get_myproc ( myproc )
956 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
958 LocFilename = FileName
961 CALL ext_gr2_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
964 IF ( .NOT. multi_files(io_form) ) THEN
965 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
966 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
971 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
972 IF ( multi_files(io_form) ) THEN
973 CALL wrf_get_myproc ( myproc )
974 CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
976 LocFilename = FileName
978 CALL ext_int_open_for_read ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
981 IF ( .NOT. multi_files(io_form) ) THEN
982 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
983 CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
989 CALL add_new_handle( Hndl, io_form, .FALSE., DataHandle )
991 END SUBROUTINE wrf_open_for_read
995 SUBROUTINE wrf_inquire_opened ( DataHandle, FileName , FileStatus, Status )
998 ! Inquire if the dataset referenced by DataHandle is open.
1001 USE module_state_description
1003 INTEGER , INTENT(IN) :: DataHandle
1004 CHARACTER*(*) :: FileName
1005 INTEGER , INTENT(OUT) :: FileStatus
1006 INTEGER , INTENT(OUT) :: Status
1008 INTEGER, EXTERNAL :: use_package
1009 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1010 #include "wrf_io_flags.h"
1011 #include "wrf_status_codes.h"
1016 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_inquire_opened' )
1019 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1020 IF ( Hndl .GT. -1 ) THEN
1021 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1022 SELECT CASE ( use_package(io_form) )
1025 IF (wrf_dm_on_monitor()) CALL ext_ncd_inquire_opened ( Hndl, FileName , FileStatus, Status )
1026 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1027 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1030 CASE ( IO_NETCDFPAR )
1031 CALL ext_ncdpar_inquire_opened ( Hndl, FileName , FileStatus, Status )
1035 CALL ext_phdf5_inquire_opened ( Hndl, FileName , FileStatus, Status )
1039 CALL ext_pnc_inquire_opened ( Hndl, FileName , FileStatus, Status )
1043 CALL ext_adios2_inquire_opened ( Hndl, FileName , FileStatus, Status )
1047 CALL ext_pio_inquire_opened ( Hndl, FileName , FileStatus, Status )
1051 CALL ext_xxx_inquire_opened ( Hndl, FileName , FileStatus, Status )
1055 IF (wrf_dm_on_monitor()) CALL ext_yyy_inquire_opened ( Hndl, FileName , FileStatus, Status )
1056 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1057 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1061 CALL ext_zzz_inquire_opened ( Hndl, FileName , FileStatus, Status )
1065 IF (wrf_dm_on_monitor()) CALL ext_gr1_inquire_opened ( Hndl, FileName , FileStatus, Status )
1066 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1067 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1071 IF (wrf_dm_on_monitor()) CALL ext_gr2_inquire_opened ( Hndl, FileName , FileStatus, Status )
1072 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1073 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1077 IF (wrf_dm_on_monitor()) CALL ext_int_inquire_opened ( Hndl, FileName , FileStatus, Status )
1078 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1079 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1082 FileStatus = WRF_FILE_NOT_OPENED
1085 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1086 CALL wrf_quilt_inquire_opened ( Hndl, FileName , FileStatus, Status )
1089 FileStatus = WRF_FILE_NOT_OPENED
1093 END SUBROUTINE wrf_inquire_opened
1095 !--- inquire_filename
1098 SUBROUTINE wrf_inquire_filename ( DataHandle, FileName , FileStatus, Status )
1101 ! Returns the Filename and FileStatus associated with DataHandle.
1104 USE module_state_description
1106 INTEGER , INTENT(IN) :: DataHandle
1107 CHARACTER*(*) :: FileName
1108 INTEGER , INTENT(OUT) :: FileStatus
1109 INTEGER , INTENT(OUT) :: Status
1110 #include "wrf_status_codes.h"
1111 INTEGER, EXTERNAL :: use_package
1112 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1116 INTEGER :: str_length , str_count
1119 CALL wrf_debug( 300, 'module_io.F: in wrf_inquire_filename' )
1122 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1124 IF ( Hndl .GT. -1 ) THEN
1125 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1126 SELECT CASE ( use_package( io_form ) )
1129 str_length = LEN ( FileName )
1130 DO str_count = 1 , str_length
1131 FileName(str_count:str_count) = ' '
1133 IF (wrf_dm_on_monitor()) CALL ext_ncd_inquire_filename ( Hndl, FileName , FileStatus, Status )
1134 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1135 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1138 CASE ( IO_NETCDFPAR )
1139 CALL ext_ncdpar_inquire_filename ( Hndl, FileName , FileStatus, Status )
1143 CALL ext_phdf5_inquire_filename ( Hndl, FileName , FileStatus, Status )
1147 CALL ext_pnc_inquire_filename ( Hndl, FileName , FileStatus, Status )
1151 CALL ext_adios2_inquire_filename ( Hndl, FileName , FileStatus, Status )
1155 CALL ext_pio_inquire_filename ( Hndl, FileName , FileStatus, Status )
1159 CALL ext_xxx_inquire_filename ( Hndl, FileName , FileStatus, Status )
1163 IF (wrf_dm_on_monitor()) CALL ext_yyy_inquire_filename ( Hndl, FileName , FileStatus, Status )
1164 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1165 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1169 CALL ext_zzz_inquire_filename ( Hndl, FileName , FileStatus, Status )
1173 IF (wrf_dm_on_monitor()) CALL ext_gr1_inquire_filename ( Hndl, FileName , FileStatus, Status )
1174 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1175 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1179 IF (wrf_dm_on_monitor()) CALL ext_gr2_inquire_filename ( Hndl, FileName , FileStatus, Status )
1180 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1181 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1185 IF (wrf_dm_on_monitor()) CALL ext_int_inquire_filename ( Hndl, FileName , FileStatus, Status )
1186 CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
1187 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1192 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1193 CALL wrf_quilt_inquire_filename ( Hndl, FileName , FileStatus, Status )
1200 END SUBROUTINE wrf_inquire_filename
1204 SUBROUTINE wrf_iosync ( DataHandle, Status )
1207 ! Synchronize the disk copy of a dataset with memory buffers.
1210 USE module_state_description
1212 INTEGER , INTENT(IN) :: DataHandle
1213 INTEGER , INTENT(OUT) :: Status
1214 #include "wrf_status_codes.h"
1215 INTEGER, EXTERNAL :: use_package
1216 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1222 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_iosync' )
1225 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1226 IF ( Hndl .GT. -1 ) THEN
1227 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1228 SELECT CASE ( use_package(io_form) )
1231 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_iosync( Hndl, Status )
1232 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1236 CALL ext_xxx_iosync( Hndl, Status )
1240 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_iosync( Hndl, Status )
1241 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1245 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_iosync( Hndl, Status )
1246 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1250 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_iosync( Hndl, Status )
1251 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1255 CALL ext_zzz_iosync( Hndl, Status )
1259 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_iosync( Hndl, Status )
1260 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
1265 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1266 CALL wrf_quilt_iosync( Hndl, Status )
1271 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1274 END SUBROUTINE wrf_iosync
1278 SUBROUTINE wrf_ioclose ( DataHandle, Status )
1281 ! Close the dataset referenced by DataHandle.
1284 USE module_state_description
1286 INTEGER , INTENT(IN) :: DataHandle
1287 INTEGER , INTENT(OUT) :: Status
1288 #include "wrf_status_codes.h"
1289 INTEGER, EXTERNAL :: use_package
1290 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1295 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioclose' )
1298 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1299 CALL free_handle( DataHandle )
1300 IF ( Hndl .GT. -1 ) THEN
1301 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1302 SELECT CASE ( use_package(io_form) )
1305 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_ioclose( Hndl, Status )
1306 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1309 CASE ( IO_NETCDFPAR )
1310 CALL ext_ncdpar_ioclose( Hndl, Status )
1314 CALL ext_phdf5_ioclose( Hndl, Status )
1318 CALL ext_pnc_ioclose( Hndl, Status )
1322 CALL ext_adios2_ioclose( Hndl, Status )
1326 CALL ext_pio_ioclose( Hndl, Status )
1330 CALL ext_xxx_ioclose( Hndl, Status )
1334 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_ioclose( Hndl, Status )
1335 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1339 CALL ext_zzz_ioclose( Hndl, Status )
1343 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_ioclose( Hndl, Status )
1344 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1348 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_ioclose( Hndl, Status )
1349 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1353 CALL ext_esmf_ioclose( Hndl, Status )
1357 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_ioclose( Hndl, Status )
1358 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1363 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1364 CALL wrf_quilt_ioclose( Hndl, Status )
1369 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1372 END SUBROUTINE wrf_ioclose
1374 !--- get_next_time (not defined for IntIO )
1376 SUBROUTINE wrf_get_next_time ( DataHandle, DateStr, Status )
1379 ! Returns the next time stamp.
1382 USE module_state_description
1384 INTEGER , INTENT(IN) :: DataHandle
1385 CHARACTER*(*) :: DateStr
1386 INTEGER , INTENT(OUT) :: Status
1387 #include "wrf_status_codes.h"
1389 INTEGER, EXTERNAL :: use_package
1390 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1391 INTEGER :: io_form, len_of_str
1395 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_next_time' )
1398 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1399 IF ( Hndl .GT. -1 ) THEN
1400 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1401 SELECT CASE ( use_package(io_form) )
1404 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_next_time( Hndl, DateStr, Status )
1405 IF ( .NOT. multi_files(io_form) ) THEN
1406 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1407 len_of_str = LEN(DateStr)
1408 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1413 IF ( multi_files(io_form) ) THEN
1414 CALL ext_pnc_get_next_time( Hndl, DateStr, Status )
1416 IF ( wrf_dm_on_monitor() ) THEN
1417 CALL ext_pnc_get_next_time( Hndl, DateStr, Status )
1420 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1421 len_of_str = LEN(DateStr)
1422 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1427 IF ( multi_files(io_form) ) THEN
1428 CALL ext_pio_get_next_time( Hndl, DateStr, Status )
1430 IF ( wrf_dm_on_monitor() ) THEN
1431 CALL ext_pio_get_next_time( Hndl, DateStr, Status )
1434 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1435 len_of_str = LEN(DateStr)
1436 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1441 CALL ext_adios2_get_next_time( Hndl, DateStr, Status )
1445 CALL ext_phdf5_get_next_time( Hndl, DateStr, Status )
1448 CASE ( IO_NETCDFPAR )
1449 CALL ext_ncdpar_get_next_time( Hndl, DateStr, Status )
1453 CALL ext_xxx_get_next_time( Hndl, DateStr, Status )
1457 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_next_time( Hndl, DateStr, Status )
1458 IF ( .NOT. multi_files(io_form) ) THEN
1459 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1460 len_of_str = LEN(DateStr)
1461 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1466 CALL ext_zzz_get_next_time( Hndl, DateStr, Status )
1470 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_next_time( Hndl, DateStr, Status )
1471 IF ( .NOT. multi_files(io_form) ) THEN
1472 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1473 len_of_str = LEN(DateStr)
1474 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1479 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_next_time( Hndl, DateStr, Status )
1480 IF ( .NOT. multi_files(io_form) ) THEN
1481 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1482 len_of_str = LEN(DateStr)
1483 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1488 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_get_next_time( Hndl, DateStr, Status )
1489 IF ( .NOT. multi_files(io_form) ) THEN
1490 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1491 len_of_str = LEN(DateStr)
1492 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1498 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1499 CALL wrf_quilt_get_next_time( Hndl, DateStr, Status )
1504 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1507 END SUBROUTINE wrf_get_next_time
1509 !--- get_previous_time (not defined for IntIO )
1511 SUBROUTINE wrf_get_previous_time ( DataHandle, DateStr, Status )
1514 ! Returns the previous time stamp.
1517 USE module_state_description
1519 INTEGER , INTENT(IN) :: DataHandle
1520 CHARACTER*(*) :: DateStr
1521 INTEGER , INTENT(OUT) :: Status
1522 #include "wrf_status_codes.h"
1524 INTEGER, EXTERNAL :: use_package
1525 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1526 INTEGER :: io_form, len_of_str
1530 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_previous_time' )
1533 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1534 IF ( Hndl .GT. -1 ) THEN
1535 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1536 SELECT CASE ( use_package(io_form) )
1539 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_previous_time( Hndl, DateStr, Status )
1540 IF ( .NOT. multi_files(io_form) ) THEN
1541 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1542 len_of_str = LEN(DateStr)
1543 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1548 CALL ext_pnc_get_previous_time( Hndl, DateStr, Status )
1552 CALL ext_pio_get_previous_time( Hndl, DateStr, Status )
1556 CALL ext_adios2_get_previous_time( Hndl, DateStr, Status )
1560 CALL ext_phdf5_get_previous_time( Hndl, DateStr, Status )
1563 CASE ( IO_NETCDFPAR )
1564 CALL ext_ncdpar_get_previous_time( Hndl, DateStr, Status )
1568 CALL ext_xxx_get_previous_time( Hndl, DateStr, Status )
1572 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_previous_time( Hndl, DateStr, Status )
1573 IF ( .NOT. multi_files(io_form) ) THEN
1574 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1575 len_of_str = LEN(DateStr)
1576 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1581 CALL ext_zzz_get_previous_time( Hndl, DateStr, Status )
1585 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_previous_time( Hndl, DateStr, Status )
1586 IF ( .NOT. multi_files(io_form) ) THEN
1587 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1588 len_of_str = LEN(DateStr)
1589 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1594 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_previous_time( Hndl, DateStr, Status )
1595 IF ( .NOT. multi_files(io_form) ) THEN
1596 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1597 len_of_str = LEN(DateStr)
1598 CALL wrf_dm_bcast_string ( DateStr , len_of_str )
1606 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1607 CALL wrf_quilt_get_previous_time( Hndl, DateStr, Status )
1612 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1615 END SUBROUTINE wrf_get_previous_time
1619 SUBROUTINE wrf_set_time ( DataHandle, DateStr, Status )
1622 ! Sets the time stamp.
1625 USE module_state_description
1627 INTEGER , INTENT(IN) :: DataHandle
1628 CHARACTER*(*) :: DateStr
1629 INTEGER , INTENT(OUT) :: Status
1630 #include "wrf_status_codes.h"
1632 INTEGER, EXTERNAL :: use_package
1633 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1638 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_set_time' )
1641 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1642 IF ( Hndl .GT. -1 ) THEN
1643 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1644 SELECT CASE ( use_package( io_form ) )
1647 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_set_time( Hndl, DateStr, Status )
1648 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1652 CALL ext_phdf5_set_time( Hndl, DateStr, Status )
1655 CASE ( IO_NETCDFPAR )
1656 CALL ext_ncdpar_set_time( Hndl, DateStr, Status )
1660 CALL ext_pnc_set_time( Hndl, DateStr, Status )
1664 CALL ext_pio_set_time( Hndl, DateStr, Status )
1668 CALL ext_adios2_set_time( Hndl, DateStr, Status )
1672 CALL ext_xxx_set_time( Hndl, DateStr, Status )
1676 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_set_time( Hndl, DateStr, Status )
1677 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1681 CALL ext_zzz_set_time( Hndl, DateStr, Status )
1685 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_set_time( Hndl, DateStr, Status )
1686 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1690 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_set_time( Hndl, DateStr, Status )
1691 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1695 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_set_time( Hndl, DateStr, Status )
1696 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1701 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1702 CALL wrf_quilt_set_time( Hndl, DateStr, Status )
1707 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1710 END SUBROUTINE wrf_set_time
1712 !--- get_next_var (not defined for IntIO)
1714 SUBROUTINE wrf_get_next_var ( DataHandle, VarName, Status )
1717 ! On reading, this routine returns the name of the next variable in the
1718 ! current time frame.
1721 USE module_state_description
1723 INTEGER , INTENT(IN) :: DataHandle
1724 CHARACTER*(*) :: VarName
1725 INTEGER , INTENT(OUT) :: Status
1726 #include "wrf_status_codes.h"
1728 INTEGER, EXTERNAL :: use_package
1729 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1734 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_next_var' )
1737 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1738 IF ( Hndl .GT. -1 ) THEN
1739 IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1740 SELECT CASE ( use_package( io_form ) )
1743 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_next_var( Hndl, VarName, Status )
1744 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1748 CALL ext_xxx_get_next_var( Hndl, VarName, Status )
1752 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_next_var( Hndl, VarName, Status )
1753 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1757 CALL ext_zzz_get_next_var( Hndl, VarName, Status )
1761 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_next_var( Hndl, VarName, Status )
1762 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1766 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_next_var( Hndl, VarName, Status )
1767 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1771 IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_get_next_var( Hndl, VarName, Status )
1772 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
1777 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1778 CALL wrf_quilt_get_next_var( Hndl, VarName, Status )
1783 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1786 END SUBROUTINE wrf_get_next_var
1789 ! wrf_get_var_info (not implemented for IntIO)
1791 SUBROUTINE wrf_get_var_info ( DataHandle , VarName , NDim , MemoryOrder , Stagger , &
1792 DomainStart , DomainEnd , Status )
1795 ! This routine applies only to a dataset that is open for read. It returns
1796 ! information about a variable.
1799 USE module_state_description
1801 INTEGER ,INTENT(IN) :: DataHandle
1802 CHARACTER*(*) ,INTENT(IN) :: VarName
1803 INTEGER ,INTENT(OUT) :: NDim
1804 CHARACTER*(*) ,INTENT(OUT) :: MemoryOrder
1805 CHARACTER*(*) ,INTENT(OUT) :: Stagger
1806 INTEGER ,dimension(*) ,INTENT(OUT) :: DomainStart, DomainEnd
1807 INTEGER ,INTENT(OUT) :: Status
1808 #include "wrf_status_codes.h"
1811 INTEGER, EXTERNAL :: use_package
1812 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers_for
1815 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_var_info' )
1818 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
1819 IF ( Hndl .GT. -1 ) THEN
1820 IF (( multi_files(io_form) .OR. wrf_dm_on_monitor() ) .AND. .NOT. (for_out .AND. use_output_servers_for(io_form)) ) THEN
1821 SELECT CASE ( use_package( io_form ) )
1824 CALL ext_ncd_get_var_info ( Hndl , VarName , NDim , &
1825 MemoryOrder , Stagger , &
1826 DomainStart , DomainEnd , &
1831 CALL ext_phdf5_get_var_info ( Hndl , VarName , NDim , &
1832 MemoryOrder , Stagger , &
1833 DomainStart , DomainEnd , &
1837 CASE ( IO_NETCDFPAR)
1838 CALL ext_ncdpar_get_var_info ( Hndl , VarName , NDim , &
1839 MemoryOrder , Stagger , &
1840 DomainStart , DomainEnd , &
1845 CALL ext_pnc_get_var_info ( Hndl , VarName , NDim , &
1846 MemoryOrder , Stagger , &
1847 DomainStart , DomainEnd , &
1852 CALL ext_pio_get_var_info ( Hndl , VarName , NDim , &
1853 MemoryOrder , Stagger , &
1854 DomainStart , DomainEnd , &
1859 CALL ext_adios2_get_var_info ( Hndl , VarName , NDim , &
1860 MemoryOrder , Stagger , &
1861 DomainStart , DomainEnd , &
1866 CALL ext_xxx_get_var_info ( Hndl , VarName , NDim , &
1867 MemoryOrder , Stagger , &
1868 DomainStart , DomainEnd , &
1873 CALL ext_yyy_get_var_info ( Hndl , VarName , NDim , &
1874 MemoryOrder , Stagger , &
1875 DomainStart , DomainEnd , &
1880 CALL ext_gr1_get_var_info ( Hndl , VarName , NDim , &
1881 MemoryOrder , Stagger , &
1882 DomainStart , DomainEnd , &
1887 CALL ext_gr2_get_var_info ( Hndl , VarName , NDim , &
1888 MemoryOrder , Stagger , &
1889 DomainStart , DomainEnd , &
1895 ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers_for(io_form) ) THEN
1896 CALL wrf_quilt_get_var_info ( Hndl , VarName , NDim , &
1897 MemoryOrder , Stagger , &
1898 DomainStart , DomainEnd , &
1904 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
1908 END SUBROUTINE wrf_get_var_info
1912 !---------------------------------------------------------------------------------
1915 SUBROUTINE init_io_handles()
1918 ! Initialize all I/O handles.
1923 IF ( .NOT. is_inited ) THEN
1924 DO i = 1, MAX_WRF_IO_HANDLE
1925 wrf_io_handles(i) = -999319
1930 END SUBROUTINE init_io_handles
1932 SUBROUTINE add_new_handle( Hndl, Hopened, for_out, DataHandle )
1935 ! Stash the package-specific I/O handle (Hndl) and return a WRF I/O handle
1937 ! File format ID is passed in via Hopened.
1938 ! for_out will be .TRUE. if this routine was called from an
1939 ! open-for-read/write-begin operation and .FALSE. otherwise.
1943 INTEGER, INTENT(IN) :: Hndl
1944 INTEGER, INTENT(IN) :: Hopened
1945 LOGICAL, INTENT(IN) :: for_out
1946 INTEGER, INTENT(OUT) :: DataHandle
1948 INTEGER, EXTERNAL :: use_package
1949 LOGICAL, EXTERNAL :: multi_files
1950 IF ( .NOT. is_inited ) THEN
1951 CALL wrf_error_fatal( 'add_new_handle: not initialized' )
1953 IF ( multi_files( Hopened ) ) THEN
1954 SELECT CASE ( use_package( Hopened ) )
1957 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for PHDF5' )
1960 CASE ( IO_NETCDFPAR )
1961 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for NETCDFPAR' )
1965 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for PNETCDF' )
1969 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for PIO' )
1973 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for ADIOS2' )
1977 CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for ESMF' )
1982 DO i = 1, MAX_WRF_IO_HANDLE
1983 IF ( wrf_io_handles(i) .EQ. -999319 ) THEN
1985 wrf_io_handles(i) = Hndl
1986 how_opened(i) = Hopened
1987 for_output(DataHandle) = for_out
1988 first_operation(DataHandle) = .TRUE.
1992 IF ( DataHandle .EQ. -1 ) THEN
1993 CALL wrf_error_fatal( 'add_new_handle: no handles left' )
1996 END SUBROUTINE add_new_handle
1998 SUBROUTINE get_handle ( Hndl, Hopened, for_out, DataHandle )
2001 ! Return the package-specific handle (Hndl) from a WRF handle
2003 ! Return file format ID via Hopened.
2004 ! Also, for_out will be set to .TRUE. if the file was opened
2005 ! with an open-for-read/write-begin operation and .FALSE.
2010 INTEGER, INTENT(OUT) :: Hndl
2011 INTEGER, INTENT(OUT) :: Hopened
2012 LOGICAL, INTENT(OUT) :: for_out
2013 INTEGER, INTENT(IN) :: DataHandle
2016 IF ( .NOT. is_inited ) THEN
2017 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
2019 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
2020 Hndl = wrf_io_handles(DataHandle)
2021 Hopened = how_opened(DataHandle)
2022 for_out = for_output(DataHandle)
2027 END SUBROUTINE get_handle
2029 SUBROUTINE set_first_operation( DataHandle )
2032 ! Sets internal flag to indicate that the first read or write has not yet
2033 ! happened for the dataset referenced by DataHandle.
2037 INTEGER, INTENT(IN) :: DataHandle
2038 IF ( .NOT. is_inited ) THEN
2039 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
2041 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
2042 first_operation(DataHandle) = .TRUE.
2045 END SUBROUTINE set_first_operation
2047 SUBROUTINE reset_first_operation( DataHandle )
2050 ! Resets internal flag to indicate that the first read or write has already
2051 ! happened for the dataset referenced by DataHandle.
2055 INTEGER, INTENT(IN) :: DataHandle
2056 IF ( .NOT. is_inited ) THEN
2057 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
2059 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
2060 first_operation(DataHandle) = .FALSE.
2063 END SUBROUTINE reset_first_operation
2065 LOGICAL FUNCTION is_first_operation( DataHandle )
2068 ! Returns .TRUE. the first read or write has not yet happened for the dataset
2069 ! referenced by DataHandle.
2073 INTEGER, INTENT(IN) :: DataHandle
2074 IF ( .NOT. is_inited ) THEN
2075 CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
2077 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
2078 is_first_operation = first_operation(DataHandle)
2081 END FUNCTION is_first_operation
2083 SUBROUTINE free_handle ( DataHandle )
2086 ! Trash a handle and return to "unused" pool.
2090 INTEGER, INTENT(IN) :: DataHandle
2092 IF ( .NOT. is_inited ) THEN
2093 CALL wrf_error_fatal( 'free_handle: not initialized' )
2095 IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
2096 wrf_io_handles(DataHandle) = -999319
2099 END SUBROUTINE free_handle
2101 !--------------------------------------------------------------
2103 SUBROUTINE init_module_io
2106 ! Initialize this module. Must be called before any other operations are
2110 CALL init_io_handles
2111 END SUBROUTINE init_module_io
2113 SUBROUTINE are_bdys_distributed( res )
2115 LOGICAL, INTENT(OUT) :: res
2117 END SUBROUTINE are_bdys_distributed
2119 SUBROUTINE bdys_not_distributed
2121 bdy_dist_flag = .FALSE.
2122 END SUBROUTINE bdys_not_distributed
2124 SUBROUTINE bdys_are_distributed
2126 bdy_dist_flag = .TRUE.
2127 END SUBROUTINE bdys_are_distributed
2129 LOGICAL FUNCTION on_stream ( mask , switch )
2131 INTEGER, INTENT(IN) :: mask(*), switch
2133 ! get_mask is a C routine defined in frame/pack_utils.c
2134 ! switch is decremented from its fortran value so it is zero based
2135 CALL get_mask( mask, switch-1, result )
2136 on_stream = ( result .NE. 0 )
2137 END FUNCTION on_stream
2139 SUBROUTINE wrf_start_io_timestep (DataHandle, Status)
2142 ! Signals to I/O library that an I/O time step is starting, and allows the
2143 ! I/O library to partition events into separate logical time steps.
2147 INTEGER, INTENT(IN) :: DataHandle
2148 INTEGER, INTENT(OUT) :: Status
2152 INTEGER, EXTERNAL :: use_package
2153 #include "wrf_status_codes.h"
2154 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
2155 SELECT CASE ( use_package( io_form ) )
2158 CALL ext_adios2_start_io_timestep(Hndl, Status)
2165 SUBROUTINE wrf_end_io_timestep (DataHandle, Status)
2168 ! Signals to I/O library that an I/O time step is ending, and allows the
2169 ! I/O library to partition events into separate logical time steps.
2173 INTEGER, INTENT(IN) :: DataHandle
2174 INTEGER, INTENT(OUT) :: Status
2178 INTEGER, EXTERNAL :: use_package
2179 #include "wrf_status_codes.h"
2180 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
2181 SELECT CASE ( use_package( io_form ) )
2184 CALL ext_adios2_end_io_timestep(Hndl, Status)
2191 END MODULE module_io
2196 ! Remaining routines in this file are defined outside of the module to
2197 ! defeat arg/param type checking.
2200 SUBROUTINE wrf_read_field ( DataHandle , DateStr , VarName , Field , FieldType , &
2202 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2203 DomainStart , DomainEnd , &
2204 MemoryStart , MemoryEnd , &
2205 PatchStart , PatchEnd , &
2209 ! Read the variable named VarName from the dataset pointed to by DataHandle.
2210 ! This routine is a wrapper that ensures uniform treatment of logicals across
2211 ! platforms by reading as integer and then converting to logical.
2214 USE module_state_description
2215 USE module_configure
2218 INTEGER , INTENT(IN) :: DataHandle
2219 CHARACTER*(*) :: DateStr
2220 CHARACTER*(*) :: VarName
2221 LOGICAL , INTENT(INOUT) :: Field(*)
2222 INTEGER ,INTENT(IN) :: FieldType
2223 TYPE(domain) :: grid
2224 INTEGER ,INTENT(IN) :: DomainDesc
2225 LOGICAL, DIMENSION(4) :: bdy_mask
2226 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2227 CHARACTER*(*) ,INTENT(IN) :: Stagger
2228 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2229 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2230 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2231 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2232 INTEGER ,INTENT(OUT) :: Status
2233 #include "wrf_status_codes.h"
2234 #include "wrf_io_flags.h"
2235 INTEGER, ALLOCATABLE :: ICAST(:)
2236 LOGICAL perturb_input
2237 IF ( FieldType .EQ. WRF_LOGICAL ) THEN
2238 ALLOCATE(ICAST((MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)))
2240 CALL wrf_read_field1 ( DataHandle , DateStr , VarName , ICAST , WRF_INTEGER , &
2242 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2243 DomainStart , DomainEnd , &
2244 MemoryStart , MemoryEnd , &
2245 PatchStart , PatchEnd , &
2247 Field(1:(MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)) = ICAST == 1
2250 CALL wrf_read_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2252 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2253 DomainStart , DomainEnd , &
2254 MemoryStart , MemoryEnd , &
2255 PatchStart , PatchEnd , &
2257 CALL nl_get_perturb_input( 1, perturb_input )
2258 IF ( perturb_input .AND. FieldType .EQ. WRF_FLOAT .AND. TRIM(MemoryOrder) .EQ. 'XZY' ) THEN
2259 CALL perturb_real ( Field, DomainStart, DomainEnd, &
2260 MemoryStart, MemoryEnd, &
2261 PatchStart, PatchEnd )
2264 END SUBROUTINE wrf_read_field
2266 SUBROUTINE wrf_read_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2268 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2269 DomainStart , DomainEnd , &
2270 MemoryStart , MemoryEnd , &
2271 PatchStart , PatchEnd , &
2275 ! Read the variable named VarName from the dataset pointed to by DataHandle.
2276 ! Calls ext_pkg_read_field() via call_pkg_and_dist().
2279 USE module_state_description
2280 USE module_configure
2284 INTEGER , INTENT(IN) :: DataHandle
2285 CHARACTER*(*) :: DateStr
2286 CHARACTER*(*) :: VarName
2287 INTEGER , INTENT(INOUT) :: Field(*)
2288 INTEGER ,INTENT(IN) :: FieldType
2289 TYPE(domain) :: grid
2290 INTEGER ,INTENT(IN) :: DomainDesc
2291 LOGICAL, DIMENSION(4) :: bdy_mask
2292 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2293 CHARACTER*(*) ,INTENT(IN) :: Stagger
2294 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2295 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2296 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2297 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2298 INTEGER ,INTENT(OUT) :: Status
2299 #include "wrf_status_codes.h"
2302 INTEGER, EXTERNAL :: use_package
2303 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers, use_input_servers, use_output_servers_for
2305 EXTERNAL ext_ncd_read_field
2308 EXTERNAL ext_ncdpar_read_field
2311 EXTERNAL ext_pnc_read_field
2314 EXTERNAL ext_pio_read_field
2317 EXTERNAL ext_adios2_read_field
2320 EXTERNAL ext_esmf_read_field
2323 EXTERNAL ext_int_read_field
2326 EXTERNAL ext_xxx_read_field
2329 EXTERNAL ext_yyy_read_field
2332 EXTERNAL ext_gr1_read_field
2335 EXTERNAL ext_gr2_read_field
2342 Comm = grid%communicator
2343 IOComm = grid%iocommunicator
2345 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_read_field' )
2348 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
2349 CALL reset_first_operation( DataHandle )
2350 IF ( Hndl .GT. -1 ) THEN
2351 IF ( .NOT. io_form .GT. 0 ) THEN
2353 ELSE IF ( .NOT. use_input_servers() ) THEN
2354 SELECT CASE ( use_package( io_form ) )
2358 CALL call_pkg_and_dist ( ext_ncd_read_field, multi_files(io_form), .false. , &
2359 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2360 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2361 DomainStart , DomainEnd , &
2362 MemoryStart , MemoryEnd , &
2363 PatchStart , PatchEnd , &
2369 CALL ext_phdf5_read_field ( &
2370 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2371 DomainDesc , MemoryOrder , Stagger , DimNames , &
2372 DomainStart , DomainEnd , &
2373 MemoryStart , MemoryEnd , &
2374 PatchStart , PatchEnd , &
2378 CASE ( IO_NETCDFPAR )
2379 CALL ext_ncdpar_read_field ( &
2380 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2381 DomainDesc , MemoryOrder , Stagger , DimNames , &
2382 DomainStart , DomainEnd , &
2383 MemoryStart , MemoryEnd , &
2384 PatchStart , PatchEnd , &
2389 CALL ext_pnc_read_field ( &
2390 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2391 DomainDesc , MemoryOrder , Stagger , DimNames , &
2392 DomainStart , DomainEnd , &
2393 MemoryStart , MemoryEnd , &
2394 PatchStart , PatchEnd , &
2399 CALL ext_pio_read_field(Hndl , DateStr , VarName , Field , FieldType , grid , &
2400 DomainDesc , MemoryOrder , Stagger , DimNames , &
2401 DomainStart , DomainEnd , &
2402 MemoryStart , MemoryEnd , &
2403 PatchStart , PatchEnd , &
2408 CALL ext_adios2_read_field ( &
2409 Hndl , DateStr , VarName , Field , FieldType , &
2410 DomainDesc , MemoryOrder , Stagger , DimNames , &
2411 DomainStart , DomainEnd , &
2412 MemoryStart , MemoryEnd , &
2413 PatchStart , PatchEnd , &
2418 CALL ext_esmf_read_field( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2419 DomainDesc , MemoryOrder , Stagger , DimNames , &
2420 DomainStart , DomainEnd , &
2421 MemoryStart , MemoryEnd , &
2422 PatchStart , PatchEnd , &
2427 CALL call_pkg_and_dist ( ext_xxx_read_field, multi_files(io_form), .false., &
2428 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2429 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2430 DomainStart , DomainEnd , &
2431 MemoryStart , MemoryEnd , &
2432 PatchStart , PatchEnd , &
2437 CALL call_pkg_and_dist ( ext_yyy_read_field, multi_files(io_form), .false., &
2438 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2439 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2440 DomainStart , DomainEnd , &
2441 MemoryStart , MemoryEnd , &
2442 PatchStart , PatchEnd , &
2447 CALL call_pkg_and_dist ( ext_int_read_field, multi_files(io_form), .false., &
2448 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2449 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2450 DomainStart , DomainEnd , &
2451 MemoryStart , MemoryEnd , &
2452 PatchStart , PatchEnd , &
2457 CALL call_pkg_and_dist ( ext_gr1_read_field, multi_files(io_form), .false., &
2458 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2459 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2460 DomainStart , DomainEnd , &
2461 MemoryStart , MemoryEnd , &
2462 PatchStart , PatchEnd , &
2467 CALL call_pkg_and_dist ( ext_gr2_read_field, multi_files(io_form), .false., &
2468 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2469 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2470 DomainStart , DomainEnd , &
2471 MemoryStart , MemoryEnd , &
2472 PatchStart , PatchEnd , &
2479 CALL wrf_error_fatal('module_io.F: wrf_read_field: input_servers not implemented yet')
2482 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
2485 END SUBROUTINE wrf_read_field1
2487 SUBROUTINE wrf_write_field ( DataHandle , DateStr , VarName , Field , FieldType , &
2489 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2490 DomainStart , DomainEnd , &
2491 MemoryStart , MemoryEnd , &
2492 PatchStart , PatchEnd , &
2496 ! Write the variable named VarName to the dataset pointed to by DataHandle.
2497 ! This routine is a wrapper that ensures uniform treatment of logicals across
2498 ! platforms by converting to integer before writing.
2501 USE module_state_description
2502 USE module_configure
2505 INTEGER , INTENT(IN) :: DataHandle
2506 CHARACTER*(*) :: DateStr
2507 CHARACTER*(*) :: VarName
2508 LOGICAL , INTENT(IN) :: Field(*)
2509 INTEGER ,INTENT(IN) :: FieldType
2510 TYPE(domain) :: grid
2511 INTEGER ,INTENT(IN) :: DomainDesc
2512 LOGICAL, DIMENSION(4) ,INTENT(IN) :: bdy_mask
2513 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2514 CHARACTER*(*) ,INTENT(IN) :: Stagger
2515 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2516 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2517 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2518 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2519 INTEGER ,INTENT(OUT) :: Status
2520 #include "wrf_status_codes.h"
2521 #include "wrf_io_flags.h"
2522 INTEGER, ALLOCATABLE :: ICAST(:)
2523 IF ( FieldType .EQ. WRF_LOGICAL ) THEN
2524 ALLOCATE(ICAST((MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)))
2526 WHERE ( Field(1:(MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)) )
2529 CALL wrf_write_field1 ( DataHandle , DateStr , VarName , ICAST , WRF_INTEGER , &
2531 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2532 DomainStart , DomainEnd , &
2533 MemoryStart , MemoryEnd , &
2534 PatchStart , PatchEnd , &
2538 CALL wrf_write_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2540 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2541 DomainStart , DomainEnd , &
2542 MemoryStart , MemoryEnd , &
2543 PatchStart , PatchEnd , &
2546 END SUBROUTINE wrf_write_field
2548 SUBROUTINE wrf_write_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
2550 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2551 DomainStart , DomainEnd , &
2552 MemoryStart , MemoryEnd , &
2553 PatchStart , PatchEnd , &
2557 ! Write the variable named VarName to the dataset pointed to by DataHandle.
2558 ! Calls ext_pkg_write_field() via collect_fld_and_call_pkg().
2562 USE module_state_description
2563 USE module_configure
2567 INTEGER , INTENT(IN) :: DataHandle
2568 CHARACTER*(*) :: DateStr
2569 CHARACTER*(*) :: VarName
2570 INTEGER , INTENT(IN) :: Field(*)
2571 INTEGER ,INTENT(IN) :: FieldType
2572 TYPE(domain) :: grid
2573 INTEGER ,INTENT(IN) :: DomainDesc
2574 LOGICAL, DIMENSION(4) ,INTENT(IN) :: bdy_mask
2575 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2576 CHARACTER*(*) ,INTENT(IN) :: Stagger
2577 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2578 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2579 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2580 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2581 INTEGER ,INTENT(OUT) :: Status
2582 #include "wrf_status_codes.h"
2583 INTEGER, DIMENSION(3) :: starts, ends
2586 LOGICAL :: for_out, okay_to_call
2587 INTEGER, EXTERNAL :: use_package
2588 LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers, use_output_servers_for
2590 EXTERNAL ext_ncd_write_field
2593 EXTERNAL ext_ncdpar_write_field
2596 EXTERNAL ext_pnc_write_field
2599 EXTERNAL ext_pio_write_field
2602 EXTERNAL ext_adios2_write_field
2605 EXTERNAL ext_esmf_write_field
2608 EXTERNAL ext_int_write_field
2611 EXTERNAL ext_xxx_write_field
2614 EXTERNAL ext_yyy_write_field
2617 EXTERNAL ext_gr1_write_field
2620 EXTERNAL ext_gr2_write_field
2627 Comm = grid%communicator
2628 IOComm = grid%iocommunicator
2630 CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_write_field' )
2633 CALL get_handle ( Hndl, io_form , for_out, DataHandle )
2634 CALL reset_first_operation ( DataHandle )
2635 IF ( Hndl .GT. -1 ) THEN
2636 IF ( multi_files( io_form ) .OR. .NOT. use_output_servers_for(io_form) ) THEN
2637 SELECT CASE ( use_package( io_form ) )
2640 CALL collect_fld_and_call_pkg ( ext_ncd_write_field, multi_files(io_form), &
2641 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2642 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2643 DomainStart , DomainEnd , &
2644 MemoryStart , MemoryEnd , &
2645 PatchStart , PatchEnd , &
2650 CALL ext_esmf_write_field( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2651 DomainDesc , MemoryOrder , Stagger , DimNames , &
2652 DomainStart , DomainEnd , &
2653 MemoryStart , MemoryEnd , &
2654 PatchStart , PatchEnd , &
2659 CALL ext_phdf5_write_field( &
2660 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2661 DomainDesc , MemoryOrder , Stagger , DimNames , &
2662 DomainStart , DomainEnd , &
2663 MemoryStart , MemoryEnd , &
2664 PatchStart , PatchEnd , &
2668 CASE ( IO_NETCDFPAR )
2669 CALL ext_ncdpar_write_field( &
2670 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2671 DomainDesc , MemoryOrder , Stagger , DimNames , &
2672 DomainStart , DomainEnd , &
2673 MemoryStart , MemoryEnd , &
2674 PatchStart , PatchEnd , &
2679 CALL lower_case( MemoryOrder, MemOrd )
2680 okay_to_call = .TRUE.
2681 IF ((TRIM(MemOrd).EQ.'xsz' .OR. TRIM(MemOrd).EQ.'xs').AND. .NOT. bdy_mask(P_XSB)) okay_to_call = .FALSE.
2682 IF ((TRIM(MemOrd).EQ.'xez' .OR. TRIM(MemOrd).EQ.'xe').AND. .NOT. bdy_mask(P_XEB)) okay_to_call = .FALSE.
2683 IF ((TRIM(MemOrd).EQ.'ysz' .OR. TRIM(MemOrd).EQ.'ys').AND. .NOT. bdy_mask(P_YSB)) okay_to_call = .FALSE.
2684 IF ((TRIM(MemOrd).EQ.'yez' .OR. TRIM(MemOrd).EQ.'ye').AND. .NOT. bdy_mask(P_YEB)) okay_to_call = .FALSE.
2685 IF ( okay_to_call ) THEN
2686 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchEnd(1:3)
2688 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchStart(1:3)-1
2691 CALL ext_pnc_write_field( &
2692 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2693 DomainDesc , MemoryOrder , Stagger , DimNames , &
2694 DomainStart , DomainEnd , &
2695 MemoryStart , MemoryEnd , &
2701 CALL lower_case( MemoryOrder, MemOrd )
2702 okay_to_call = .TRUE.
2703 IF ((TRIM(MemOrd).EQ.'xsz' .OR. TRIM(MemOrd).EQ.'xs').AND. .NOT. bdy_mask(P_XSB)) okay_to_call = .FALSE.
2704 IF ((TRIM(MemOrd).EQ.'xez' .OR. TRIM(MemOrd).EQ.'xe').AND. .NOT. bdy_mask(P_XEB)) okay_to_call = .FALSE.
2705 IF ((TRIM(MemOrd).EQ.'ysz' .OR. TRIM(MemOrd).EQ.'ys').AND. .NOT. bdy_mask(P_YSB)) okay_to_call = .FALSE.
2706 IF ((TRIM(MemOrd).EQ.'yez' .OR. TRIM(MemOrd).EQ.'ye').AND. .NOT. bdy_mask(P_YEB)) okay_to_call = .FALSE.
2707 IF ( okay_to_call ) THEN
2708 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchEnd(1:3)
2710 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchStart(1:3)-1
2713 CALL ext_adios2_write_field( &
2714 Hndl , DateStr , VarName , Field , FieldType , &
2715 DomainDesc , MemoryOrder , Stagger , DimNames , &
2716 DomainStart , DomainEnd , &
2717 MemoryStart , MemoryEnd , &
2723 CALL lower_case( MemoryOrder, MemOrd )
2724 okay_to_call = .TRUE.
2725 IF ((TRIM(MemOrd).EQ.'xsz' .OR. TRIM(MemOrd).EQ.'xs').AND. .NOT. bdy_mask(P_XSB)) okay_to_call = .FALSE.
2726 IF ((TRIM(MemOrd).EQ.'xez' .OR. TRIM(MemOrd).EQ.'xe').AND. .NOT. bdy_mask(P_XEB)) okay_to_call = .FALSE.
2727 IF ((TRIM(MemOrd).EQ.'ysz' .OR. TRIM(MemOrd).EQ.'ys').AND. .NOT. bdy_mask(P_YSB)) okay_to_call = .FALSE.
2728 IF ((TRIM(MemOrd).EQ.'yez' .OR. TRIM(MemOrd).EQ.'ye').AND. .NOT. bdy_mask(P_YEB)) okay_to_call = .FALSE.
2729 IF ( okay_to_call ) THEN
2730 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchEnd(1:3)
2732 starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchStart(1:3)-1
2735 CALL ext_pio_write_field( Hndl , DateStr , VarName , Field , FieldType , grid , &
2736 DomainDesc , MemoryOrder , Stagger , DimNames , &
2737 DomainStart , DomainEnd , &
2738 MemoryStart , MemoryEnd , &
2739 starts , ends , Status )
2743 CALL collect_fld_and_call_pkg ( ext_xxx_write_field, multi_files(io_form), &
2744 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2745 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2746 DomainStart , DomainEnd , &
2747 MemoryStart , MemoryEnd , &
2748 PatchStart , PatchEnd , &
2753 CALL collect_fld_and_call_pkg ( ext_yyy_write_field, multi_files(io_form), &
2754 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2755 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2756 DomainStart , DomainEnd , &
2757 MemoryStart , MemoryEnd , &
2758 PatchStart , PatchEnd , &
2763 CALL collect_fld_and_call_pkg ( ext_gr1_write_field, multi_files(io_form), &
2764 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2765 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2766 DomainStart , DomainEnd , &
2767 MemoryStart , MemoryEnd , &
2768 PatchStart , PatchEnd , &
2773 CALL collect_fld_and_call_pkg ( ext_gr2_write_field, multi_files(io_form), &
2774 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2775 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2776 DomainStart , DomainEnd , &
2777 MemoryStart , MemoryEnd , &
2778 PatchStart , PatchEnd , &
2783 CALL collect_fld_and_call_pkg ( ext_int_write_field, multi_files(io_form), &
2784 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2785 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2786 DomainStart , DomainEnd , &
2787 MemoryStart , MemoryEnd , &
2788 PatchStart , PatchEnd , &
2794 ELSE IF ( use_output_servers_for(io_form) ) THEN
2795 IF ( io_form .GT. 0 ) THEN
2796 CALL wrf_quilt_write_field ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2797 DomainDesc , MemoryOrder , Stagger , DimNames , &
2798 DomainStart , DomainEnd , &
2799 MemoryStart , MemoryEnd , &
2800 PatchStart , PatchEnd , &
2805 Status = WRF_ERR_FATAL_BAD_FILE_STATUS
2808 END SUBROUTINE wrf_write_field1
2810 SUBROUTINE get_value_from_pairs ( varname , str , retval )
2813 ! parse comma separated list of VARIABLE=VALUE strings and return the
2814 ! value for the matching variable if such exists, otherwise return
2819 CHARACTER*(*) :: varname
2820 CHARACTER*(*) :: str
2821 CHARACTER*(*) :: retval
2823 CHARACTER (256) varstr, tstr
2824 INTEGER i,j,n,varstrn
2825 LOGICAL nobreak, nobreakouter
2827 varstr = TRIM(varname)//"="
2828 varstrn = len(TRIM(varstr))
2832 nobreakouter = .TRUE.
2833 DO WHILE ( nobreakouter )
2837 ! Potential for out of bounds array ref on str(i:i) for i > n; reported by jedwards
2838 ! DO WHILE ( nobreak )
2839 ! IF ( str(i:i) .NE. ',' .AND. i .LE. n ) THEN
2840 ! tstr(j:j) = str(i:i)
2848 DO WHILE ( nobreak )
2850 IF ( i .LE. n ) THEN
2851 IF (str(i:i) .NE. ',' ) THEN
2852 tstr(j:j) = str(i:i)
2859 IF ( i .GT. n ) nobreakouter = .FALSE.
2860 IF ( varstr(1:varstrn) .EQ. tstr(1:varstrn) ) THEN
2861 retval(1:) = TRIM(tstr(varstrn+1:))
2862 nobreakouter = .FALSE.
2866 END SUBROUTINE get_value_from_pairs
2868 LOGICAL FUNCTION multi_files ( io_form )
2871 ! Returns .TRUE. iff io_form is a multi-file format. A multi-file format
2872 ! results in one file for each compute process and can be used with any
2873 ! I/O package. A multi-file dataset can only be read by the same number
2874 ! of tasks that were used to write it. This feature can be useful for
2875 ! speeding up restarts on machines that support efficient parallel I/O.
2876 ! Multi-file formats cannot be used with I/O quilt servers.
2878 ! Note: multi-file is selected by adding 100 to the standard WRF I/O
2879 ! form. If you add 200 instead, then single-file I/O is still done,
2880 ! but without I/O servers.
2884 INTEGER, INTENT(IN) :: io_form
2886 multi_files = ( io_form >= 100 .and. io_form<200 )
2888 multi_files = .FALSE.
2890 END FUNCTION multi_files
2892 INTEGER FUNCTION use_package ( io_form )
2895 ! Returns the ID of the external I/O package referenced by io_form.
2899 INTEGER, INTENT(IN) :: io_form
2900 use_package = MOD( io_form, 100 )
2901 END FUNCTION use_package
2904 SUBROUTINE collect_fld_and_call_pkg ( fcn, donotcollect_arg, &
2905 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2906 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2907 DomainStart , DomainEnd , &
2908 MemoryStart , MemoryEnd , &
2909 PatchStart , PatchEnd , &
2913 ! The collect_*_and_call_pkg routines collect a distributed array onto one
2914 ! processor and then call an I/O function to write the result (or in the
2915 ! case of replicated data simply write monitor node's copy of the data)
2916 ! This routine handle cases where collection can be skipped and deals with
2917 ! different data types for Field.
2921 #include "wrf_io_flags.h"
2923 LOGICAL, INTENT(IN) :: donotcollect_arg
2924 INTEGER , INTENT(IN) :: Hndl
2925 CHARACTER*(*) :: DateStr
2926 CHARACTER*(*) :: VarName
2927 INTEGER , INTENT(IN) :: Field(*)
2928 INTEGER ,INTENT(IN) :: FieldType
2929 INTEGER ,INTENT(INOUT) :: Comm
2930 INTEGER ,INTENT(INOUT) :: IOComm
2931 INTEGER ,INTENT(IN) :: DomainDesc
2932 LOGICAL, DIMENSION(4) :: bdy_mask
2933 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
2934 CHARACTER*(*) ,INTENT(IN) :: Stagger
2935 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
2936 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
2937 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
2938 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
2939 INTEGER ,INTENT(OUT) :: Status
2940 LOGICAL donotcollect
2941 INTEGER ndims, nproc
2943 CALL dim_from_memorder( MemoryOrder , ndims)
2944 CALL wrf_get_nproc( nproc )
2945 donotcollect = donotcollect_arg .OR. (nproc .EQ. 1)
2947 IF ( donotcollect ) THEN
2949 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2950 DomainDesc , MemoryOrder , Stagger , DimNames , &
2951 DomainStart , DomainEnd , &
2952 MemoryStart , MemoryEnd , &
2953 PatchStart , PatchEnd , &
2956 ELSE IF ( FieldType .EQ. WRF_DOUBLE ) THEN
2958 CALL collect_double_and_call_pkg ( fcn, &
2959 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2960 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2961 DomainStart , DomainEnd , &
2962 MemoryStart , MemoryEnd , &
2963 PatchStart , PatchEnd , &
2966 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
2968 CALL collect_real_and_call_pkg ( fcn, &
2969 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2970 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2971 DomainStart , DomainEnd , &
2972 MemoryStart , MemoryEnd , &
2973 PatchStart , PatchEnd , &
2976 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
2978 CALL collect_int_and_call_pkg ( fcn, &
2979 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2980 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2981 DomainStart , DomainEnd , &
2982 MemoryStart , MemoryEnd , &
2983 PatchStart , PatchEnd , &
2986 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
2988 CALL collect_logical_and_call_pkg ( fcn, &
2989 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
2990 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
2991 DomainStart , DomainEnd , &
2992 MemoryStart , MemoryEnd , &
2993 PatchStart , PatchEnd , &
2998 END SUBROUTINE collect_fld_and_call_pkg
3000 SUBROUTINE collect_real_and_call_pkg ( fcn, &
3001 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3002 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3003 DomainStart , DomainEnd , &
3004 MemoryStart , MemoryEnd , &
3005 PatchStart , PatchEnd , &
3009 ! The collect_*_and_call_pkg routines collect a distributed array onto one
3010 ! processor and then call an I/O function to write the result (or in the
3011 ! case of replicated data simply write monitor node's copy of the data)
3012 ! The sole purpose of this wrapper is to allocate a big real buffer and
3013 ! pass it down to collect_generic_and_call_pkg() to do the actual work.
3016 USE module_state_description
3017 USE module_driver_constants
3020 INTEGER , INTENT(IN) :: Hndl
3021 CHARACTER*(*) :: DateStr
3022 CHARACTER*(*) :: VarName
3023 REAL , INTENT(IN) :: Field(*)
3024 INTEGER ,INTENT(IN) :: FieldType
3025 INTEGER ,INTENT(INOUT) :: Comm
3026 INTEGER ,INTENT(INOUT) :: IOComm
3027 INTEGER ,INTENT(IN) :: DomainDesc
3028 LOGICAL, DIMENSION(4) :: bdy_mask
3029 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3030 CHARACTER*(*) ,INTENT(IN) :: Stagger
3031 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3032 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3033 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3034 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3035 INTEGER ,INTENT(INOUT) :: Status
3036 REAL, ALLOCATABLE :: globbuf (:)
3037 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3039 IF ( wrf_dm_on_monitor() ) THEN
3040 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3042 ALLOCATE( globbuf( 1 ) )
3046 # define FRSTELEM (1)
3051 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM, &
3052 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3053 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3054 DomainStart , DomainEnd , &
3055 MemoryStart , MemoryEnd , &
3056 PatchStart , PatchEnd , &
3058 DEALLOCATE ( globbuf )
3061 END SUBROUTINE collect_real_and_call_pkg
3063 SUBROUTINE collect_int_and_call_pkg ( fcn, &
3064 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3065 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3066 DomainStart , DomainEnd , &
3067 MemoryStart , MemoryEnd , &
3068 PatchStart , PatchEnd , &
3072 ! The collect_*_and_call_pkg routines collect a distributed array onto one
3073 ! processor and then call an I/O function to write the result (or in the
3074 ! case of replicated data simply write monitor node's copy of the data)
3075 ! The sole purpose of this wrapper is to allocate a big integer buffer and
3076 ! pass it down to collect_generic_and_call_pkg() to do the actual work.
3079 USE module_state_description
3080 USE module_driver_constants
3083 INTEGER , INTENT(IN) :: Hndl
3084 CHARACTER*(*) :: DateStr
3085 CHARACTER*(*) :: VarName
3086 INTEGER , INTENT(IN) :: Field(*)
3087 INTEGER ,INTENT(IN) :: FieldType
3088 INTEGER ,INTENT(INOUT) :: Comm
3089 INTEGER ,INTENT(INOUT) :: IOComm
3090 INTEGER ,INTENT(IN) :: DomainDesc
3091 LOGICAL, DIMENSION(4) :: bdy_mask
3092 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3093 CHARACTER*(*) ,INTENT(IN) :: Stagger
3094 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3095 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3096 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3097 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3098 INTEGER ,INTENT(INOUT) :: Status
3099 INTEGER, ALLOCATABLE :: globbuf (:)
3100 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3102 IF ( wrf_dm_on_monitor() ) THEN
3103 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3105 ALLOCATE( globbuf( 1 ) )
3108 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
3109 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3110 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3111 DomainStart , DomainEnd , &
3112 MemoryStart , MemoryEnd , &
3113 PatchStart , PatchEnd , &
3115 DEALLOCATE ( globbuf )
3118 END SUBROUTINE collect_int_and_call_pkg
3120 SUBROUTINE collect_double_and_call_pkg ( fcn, &
3121 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3122 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3123 DomainStart , DomainEnd , &
3124 MemoryStart , MemoryEnd , &
3125 PatchStart , PatchEnd , &
3129 ! The collect_*_and_call_pkg routines collect a distributed array onto one
3130 ! processor and then call an I/O function to write the result (or in the
3131 ! case of replicated data simply write monitor node's copy of the data)
3132 ! The sole purpose of this wrapper is to allocate a big double precision
3133 ! buffer and pass it down to collect_generic_and_call_pkg() to do the
3137 USE module_state_description
3138 USE module_driver_constants
3141 INTEGER , INTENT(IN) :: Hndl
3142 CHARACTER*(*) :: DateStr
3143 CHARACTER*(*) :: VarName
3144 DOUBLE PRECISION , INTENT(IN) :: Field(*)
3145 INTEGER ,INTENT(IN) :: FieldType
3146 INTEGER ,INTENT(INOUT) :: Comm
3147 INTEGER ,INTENT(INOUT) :: IOComm
3148 INTEGER ,INTENT(IN) :: DomainDesc
3149 LOGICAL, DIMENSION(4) :: bdy_mask
3150 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3151 CHARACTER*(*) ,INTENT(IN) :: Stagger
3152 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3153 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3154 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3155 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3156 INTEGER ,INTENT(INOUT) :: Status
3157 DOUBLE PRECISION, ALLOCATABLE :: globbuf (:)
3158 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3160 IF ( wrf_dm_on_monitor() ) THEN
3161 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3163 ALLOCATE( globbuf( 1 ) )
3166 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
3167 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3168 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3169 DomainStart , DomainEnd , &
3170 MemoryStart , MemoryEnd , &
3171 PatchStart , PatchEnd , &
3173 DEALLOCATE ( globbuf )
3176 END SUBROUTINE collect_double_and_call_pkg
3178 SUBROUTINE collect_logical_and_call_pkg ( fcn, &
3179 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3180 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3181 DomainStart , DomainEnd , &
3182 MemoryStart , MemoryEnd , &
3183 PatchStart , PatchEnd , &
3187 ! The collect_*_and_call_pkg routines collect a distributed array onto one
3188 ! processor and then call an I/O function to write the result (or in the
3189 ! case of replicated data simply write monitor node's copy of the data)
3190 ! The sole purpose of this wrapper is to allocate a big logical buffer
3191 ! and pass it down to collect_generic_and_call_pkg() to do the actual work.
3194 USE module_state_description
3195 USE module_driver_constants
3198 INTEGER , INTENT(IN) :: Hndl
3199 CHARACTER*(*) :: DateStr
3200 CHARACTER*(*) :: VarName
3201 LOGICAL , INTENT(IN) :: Field(*)
3202 INTEGER ,INTENT(IN) :: FieldType
3203 INTEGER ,INTENT(INOUT) :: Comm
3204 INTEGER ,INTENT(INOUT) :: IOComm
3205 INTEGER ,INTENT(IN) :: DomainDesc
3206 LOGICAL, DIMENSION(4) :: bdy_mask
3207 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3208 CHARACTER*(*) ,INTENT(IN) :: Stagger
3209 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3210 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3211 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3212 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3213 INTEGER ,INTENT(INOUT) :: Status
3214 LOGICAL, ALLOCATABLE :: globbuf (:)
3215 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3217 IF ( wrf_dm_on_monitor() ) THEN
3218 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3220 ALLOCATE( globbuf( 1 ) )
3223 CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
3224 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3225 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3226 DomainStart , DomainEnd , &
3227 MemoryStart , MemoryEnd , &
3228 PatchStart , PatchEnd , &
3230 DEALLOCATE ( globbuf )
3233 END SUBROUTINE collect_logical_and_call_pkg
3236 SUBROUTINE collect_generic_and_call_pkg ( fcn, globbuf, &
3237 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3238 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3239 DomainStart , DomainEnd , &
3240 MemoryStart , MemoryEnd , &
3241 PatchStart , PatchEnd , &
3245 ! The collect_*_and_call_pkg routines collect a distributed array onto one
3246 ! processor and then call an I/O function to write the result (or in the
3247 ! case of replicated data simply write monitor node's copy of the data)
3248 ! This routine calls the distributed memory communication routines that
3249 ! collect the array and then calls I/O function fcn to write it to disk.
3252 USE module_state_description
3253 USE module_driver_constants
3255 #include "wrf_io_flags.h"
3256 #if defined( DM_PARALLEL ) && ! defined(STUBMPI)
3260 REAL , DIMENSION(*) , INTENT(INOUT) :: globbuf
3261 INTEGER , INTENT(IN) :: Hndl
3262 CHARACTER*(*) :: DateStr
3263 CHARACTER*(*) :: VarName
3264 REAL , INTENT(IN) :: Field(*)
3265 INTEGER ,INTENT(IN) :: FieldType
3266 INTEGER ,INTENT(INOUT) :: Comm
3267 INTEGER ,INTENT(INOUT) :: IOComm
3268 INTEGER ,INTENT(IN) :: DomainDesc
3269 LOGICAL, DIMENSION(4) :: bdy_mask
3270 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3271 CHARACTER*(*) ,INTENT(IN) :: Stagger
3272 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3273 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3274 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3275 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3276 INTEGER ,INTENT(OUT) :: Status
3278 LOGICAL, EXTERNAL :: has_char
3279 INTEGER ids, ide, jds, jde, kds, kde
3280 INTEGER ims, ime, jms, jme, kms, kme
3281 INTEGER ips, ipe, jps, jpe, kps, kpe
3282 INTEGER, ALLOCATABLE :: counts(:), displs(:)
3283 INTEGER nproc, communicator, mpi_bdyslice_type, ierr, my_displ
3285 INTEGER , dimension(3) :: dom_end_rev
3286 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3287 INTEGER, EXTERNAL :: wrf_dm_monitor_rank
3288 LOGICAL distributed_field
3289 INTEGER i,j,k,idx,lx,idx2,lx2
3290 INTEGER collective_root
3292 CALL wrf_get_nproc( nproc )
3293 CALL wrf_get_dm_communicator ( communicator )
3295 ALLOCATE( counts( nproc ) )
3296 ALLOCATE( displs( nproc ) )
3297 CALL lower_case( MemoryOrder, MemOrd )
3299 collective_root = wrf_dm_monitor_rank()
3301 dom_end_rev(1) = DomainEnd(1)
3302 dom_end_rev(2) = DomainEnd(2)
3303 dom_end_rev(3) = DomainEnd(3)
3305 SELECT CASE (TRIM(MemOrd))
3307 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3308 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3309 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3311 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3312 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3313 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3315 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3316 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3317 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3319 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3320 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3322 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3323 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3324 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
3326 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
3327 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
3329 ! do nothing; the boundary orders and others either dont care or set themselves
3332 SELECT CASE (TRIM(MemOrd))
3334 CASE ( 'xzy','zxy','xyz','yxz','xy','yx' )
3336 distributed_field = .TRUE.
3337 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3338 CALL wrf_patch_to_global_double ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3339 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3340 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3341 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3342 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3343 CALL wrf_patch_to_global_real ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3344 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3345 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3346 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3347 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3348 CALL wrf_patch_to_global_integer ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3349 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3350 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3351 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3352 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
3353 CALL wrf_patch_to_global_logical ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
3354 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
3355 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
3356 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
3359 #if defined(DM_PARALLEL) && !defined(STUBMPI)
3360 CASE ( 'xsz', 'xez' )
3361 distributed_field = .FALSE.
3362 IF ( nproc .GT. 1 ) THEN
3363 jds = DomainStart(1) ; jde = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) jde = jde+1 ! ns strip
3364 kds = DomainStart(2) ; kde = DomainEnd(2) ; IF ( .NOT. has_char( Stagger, 'z' ) ) kde = kde+1 ! levels
3365 ids = DomainStart(3) ; ide = DomainEnd(3) ; ! bdy_width
3366 dom_end_rev(1) = jde
3367 dom_end_rev(2) = kde
3368 dom_end_rev(3) = ide
3369 distributed_field = .TRUE.
3370 IF ( (MemOrd .eq. 'xsz' .AND. bdy_mask( P_XSB )) .OR. &
3371 (MemOrd .eq. 'xez' .AND. bdy_mask( P_XEB )) ) THEN
3372 my_displ = PatchStart(1)-1
3373 my_count = PatchEnd(1)-PatchStart(1)+1
3378 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3379 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3380 do i = DomainStart(3),DomainEnd(3) ! bdy_width
3381 do k = DomainStart(2),DomainEnd(2) ! levels
3382 lx = MemoryEnd(1)-MemoryStart(1)+1
3383 lx2 = dom_end_rev(1)-DomainStart(1)+1
3384 idx = lx*((k-1)+(i-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3385 idx2 = lx2*((k-1)+(i-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3386 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3388 CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3389 my_count , & ! sendcount
3390 globbuf, 1+idx2 , & ! recvbuf
3391 counts , & ! recvcounts
3393 collective_root , & ! root
3394 communicator , & ! communicator
3397 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3399 CALL wrf_gatherv_real ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3400 my_count , & ! sendcount
3401 globbuf, 1+idx2 , & ! recvbuf
3402 counts , & ! recvcounts
3404 collective_root , & ! root
3405 communicator , & ! communicator
3408 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3410 CALL wrf_gatherv_integer ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3411 my_count , & ! sendcount
3412 globbuf, 1+idx2 , & ! recvbuf
3413 counts , & ! recvcounts
3415 collective_root , & ! root
3416 communicator , & ! communicator
3424 distributed_field = .FALSE.
3425 IF ( nproc .GT. 1 ) THEN
3426 jds = DomainStart(1) ; jde = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) jde = jde+1 ! ns strip
3427 ids = DomainStart(2) ; ide = DomainEnd(2) ; ! bdy_width
3428 dom_end_rev(1) = jde
3429 dom_end_rev(2) = ide
3430 distributed_field = .TRUE.
3431 IF ( (MemOrd .eq. 'xs' .AND. bdy_mask( P_XSB )) .OR. &
3432 (MemOrd .eq. 'xe' .AND. bdy_mask( P_XEB )) ) THEN
3433 my_displ = PatchStart(1)-1
3434 my_count = PatchEnd(1)-PatchStart(1)+1
3439 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3440 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3441 do i = DomainStart(2),DomainEnd(2) ! bdy_width
3442 lx = MemoryEnd(1)-MemoryStart(1)+1
3444 lx2 = dom_end_rev(1)-DomainStart(1)+1
3446 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3448 CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3449 my_count , & ! sendcount
3450 globbuf, 1+idx2 , & ! recvbuf
3451 counts , & ! recvcounts
3453 collective_root , & ! root
3454 communicator , & ! communicator
3457 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3459 CALL wrf_gatherv_real ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3460 my_count , & ! sendcount
3461 globbuf, 1+idx2 , & ! recvbuf
3462 counts , & ! recvcounts
3464 collective_root , & ! root
3465 communicator , & ! communicator
3468 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3470 CALL wrf_gatherv_integer ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
3471 my_count , & ! sendcount
3472 globbuf, 1+idx2 , & ! recvbuf
3473 counts , & ! recvcounts
3475 collective_root , & ! root
3476 communicator , & ! communicator
3482 CASE ( 'ysz', 'yez' )
3483 distributed_field = .FALSE.
3484 IF ( nproc .GT. 1 ) THEN
3485 ids = DomainStart(1) ; ide = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) ide = ide+1 ! ns strip
3486 kds = DomainStart(2) ; kde = DomainEnd(2) ; IF ( .NOT. has_char( Stagger, 'z' ) ) kde = kde+1 ! levels
3487 jds = DomainStart(3) ; jde = DomainEnd(3) ; ! bdy_width
3488 dom_end_rev(1) = ide
3489 dom_end_rev(2) = kde
3490 dom_end_rev(3) = jde
3491 distributed_field = .TRUE.
3492 IF ( (MemOrd .eq. 'ysz' .AND. bdy_mask( P_YSB )) .OR. &
3493 (MemOrd .eq. 'yez' .AND. bdy_mask( P_YEB )) ) THEN
3494 my_displ = PatchStart(1)-1
3495 my_count = PatchEnd(1)-PatchStart(1)+1
3500 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3501 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3502 do j = DomainStart(3),DomainEnd(3) ! bdy_width
3503 do k = DomainStart(2),DomainEnd(2) ! levels
3504 lx = MemoryEnd(1)-MemoryStart(1)+1
3505 lx2 = dom_end_rev(1)-DomainStart(1)+1
3506 idx = lx*((k-1)+(j-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3507 idx2 = lx2*((k-1)+(j-1)*(MemoryEnd(2)-MemoryStart(2)+1))
3509 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3511 CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3512 my_count , & ! sendcount
3513 globbuf, 1+idx2 , & ! recvbuf
3514 counts , & ! recvcounts
3516 collective_root , & ! root
3517 communicator , & ! communicator
3520 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3522 CALL wrf_gatherv_real( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3523 my_count , & ! sendcount
3524 globbuf, 1+idx2 , & ! recvbuf
3525 counts , & ! recvcounts
3527 collective_root , & ! root
3528 communicator , & ! communicator
3531 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3533 CALL wrf_gatherv_integer( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3534 my_count , & ! sendcount
3535 globbuf, 1+idx2 , & ! recvbuf
3536 counts , & ! recvcounts
3538 collective_root , & ! root
3539 communicator , & ! communicator
3547 distributed_field = .FALSE.
3548 IF ( nproc .GT. 1 ) THEN
3549 ids = DomainStart(1) ; ide = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) ide = ide+1 ! ns strip
3550 jds = DomainStart(2) ; jde = DomainEnd(2) ; ! bdy_width
3551 dom_end_rev(1) = ide
3552 dom_end_rev(2) = jde
3553 distributed_field = .TRUE.
3554 IF ( (MemOrd .eq. 'ys' .AND. bdy_mask( P_YSB )) .OR. &
3555 (MemOrd .eq. 'ye' .AND. bdy_mask( P_YEB )) ) THEN
3556 my_displ = PatchStart(1)-1
3557 my_count = PatchEnd(1)-PatchStart(1)+1
3562 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
3563 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
3564 do j = DomainStart(2),DomainEnd(2) ! bdy_width
3565 lx = MemoryEnd(1)-MemoryStart(1)+1
3567 lx2 = dom_end_rev(1)-DomainStart(1)+1
3570 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
3572 CALL wrf_gatherv_double( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3573 my_count , & ! sendcount
3574 globbuf, 1+idx2 , & ! recvbuf
3575 counts , & ! recvcounts
3577 collective_root , & ! root
3578 communicator , & ! communicator
3581 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
3583 CALL wrf_gatherv_real( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3584 my_count , & ! sendcount
3585 globbuf, 1+idx2 , & ! recvbuf
3586 counts , & ! recvcounts
3588 collective_root , & ! root
3589 communicator , & ! communicator
3592 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3594 CALL wrf_gatherv_integer( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
3595 my_count , & ! sendcount
3596 globbuf, 1+idx2 , & ! recvbuf
3597 counts , & ! recvcounts
3599 collective_root , & ! root
3600 communicator , & ! communicator
3609 distributed_field = .FALSE.
3611 IF ( wrf_dm_on_monitor() ) THEN
3612 IF ( distributed_field ) THEN
3613 CALL fcn ( Hndl , DateStr , VarName , globbuf , FieldType , Comm , IOComm , &
3614 DomainDesc , MemoryOrder , Stagger , DimNames , &
3615 DomainStart , DomainEnd , &
3616 DomainStart , dom_end_rev , & ! memory dims adjust out for unstag
3617 DomainStart , DomainEnd , &
3620 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3621 DomainDesc , MemoryOrder , Stagger , DimNames , &
3622 DomainStart , DomainEnd , &
3623 MemoryStart , MemoryEnd , &
3624 PatchStart , PatchEnd , &
3628 CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
3629 DEALLOCATE( counts )
3630 DEALLOCATE( displs )
3632 END SUBROUTINE collect_generic_and_call_pkg
3635 SUBROUTINE call_pkg_and_dist ( fcn, donotdist_arg, update_arg, &
3636 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3637 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3638 DomainStart , DomainEnd , &
3639 MemoryStart , MemoryEnd , &
3640 PatchStart , PatchEnd , &
3644 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3645 ! distribute or replicate the field across compute tasks.
3646 ! This routine handle cases where distribution/replication can be skipped and
3647 ! deals with different data types for Field.
3651 #include "wrf_io_flags.h"
3653 LOGICAL, INTENT(IN) :: donotdist_arg, update_arg ! update means collect old field update it and dist
3654 INTEGER , INTENT(IN) :: Hndl
3655 CHARACTER*(*) :: DateStr
3656 CHARACTER*(*) :: VarName
3658 INTEGER :: FieldType
3661 INTEGER :: DomainDesc
3662 LOGICAL, DIMENSION(4) :: bdy_mask
3663 CHARACTER*(*) :: MemoryOrder
3664 CHARACTER*(*) :: Stagger
3665 CHARACTER*(*) , dimension (*) :: DimNames
3666 INTEGER ,dimension(*) :: DomainStart, DomainEnd
3667 INTEGER ,dimension(*) :: MemoryStart, MemoryEnd
3668 INTEGER ,dimension(*) :: PatchStart, PatchEnd
3671 INTEGER ndims, nproc
3673 CALL dim_from_memorder( MemoryOrder , ndims)
3674 CALL wrf_get_nproc( nproc )
3675 donotdist = donotdist_arg .OR. (nproc .EQ. 1)
3677 IF ( donotdist ) THEN
3678 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3679 DomainDesc , MemoryOrder , Stagger , DimNames , &
3680 DomainStart , DomainEnd , &
3681 MemoryStart , MemoryEnd , &
3682 PatchStart , PatchEnd , &
3685 ELSE IF (FieldType .EQ. WRF_DOUBLE) THEN
3687 CALL call_pkg_and_dist_double ( fcn, update_arg, &
3688 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3689 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3690 DomainStart , DomainEnd , &
3691 MemoryStart , MemoryEnd , &
3692 PatchStart , PatchEnd , &
3695 ELSE IF (FieldType .EQ. WRF_FLOAT) THEN
3697 CALL call_pkg_and_dist_real ( fcn, update_arg, &
3698 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3699 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3700 DomainStart , DomainEnd , &
3701 MemoryStart , MemoryEnd , &
3702 PatchStart , PatchEnd , &
3705 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
3707 CALL call_pkg_and_dist_int ( fcn, update_arg, &
3708 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3709 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3710 DomainStart , DomainEnd , &
3711 MemoryStart , MemoryEnd , &
3712 PatchStart , PatchEnd , &
3715 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
3717 CALL call_pkg_and_dist_logical ( fcn, update_arg, &
3718 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3719 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3720 DomainStart , DomainEnd , &
3721 MemoryStart , MemoryEnd , &
3722 PatchStart , PatchEnd , &
3727 END SUBROUTINE call_pkg_and_dist
3729 SUBROUTINE call_pkg_and_dist_real ( fcn, update_arg, &
3730 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3731 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3732 DomainStart , DomainEnd , &
3733 MemoryStart , MemoryEnd , &
3734 PatchStart , PatchEnd , &
3738 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3739 ! distribute or replicate the field across compute tasks.
3740 ! The sole purpose of this wrapper is to allocate a big real buffer and
3741 ! pass it down to call_pkg_and_dist_generic() to do the actual work.
3746 INTEGER , INTENT(IN) :: Hndl
3747 LOGICAL , INTENT(IN) :: update_arg
3748 CHARACTER*(*) :: DateStr
3749 CHARACTER*(*) :: VarName
3750 REAL , INTENT(INOUT) :: Field(*)
3751 INTEGER ,INTENT(IN) :: FieldType
3752 INTEGER ,INTENT(INOUT) :: Comm
3753 INTEGER ,INTENT(INOUT) :: IOComm
3754 INTEGER ,INTENT(IN) :: DomainDesc
3755 LOGICAL, DIMENSION(4) :: bdy_mask
3756 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3757 CHARACTER*(*) ,INTENT(IN) :: Stagger
3758 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3759 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3760 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3761 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3762 INTEGER ,INTENT(INOUT) :: Status
3763 REAL, ALLOCATABLE :: globbuf (:)
3764 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3768 IF ( wrf_dm_on_monitor() ) THEN
3769 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ), &
3771 IF ( test .NE. 0 ) THEN
3772 write(mess,*)"module_io.b",'allocating globbuf ',&
3773 (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3)
3774 CALL wrf_error_fatal(mess)
3777 ALLOCATE( globbuf( 1 ), STAT=test )
3778 IF ( test .NE. 0 ) THEN
3779 write(mess,*)"module_io.b",'allocating globbuf ',1
3780 CALL wrf_error_fatal(mess)
3786 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg, &
3787 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3788 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3789 DomainStart , DomainEnd , &
3790 MemoryStart , MemoryEnd , &
3791 PatchStart , PatchEnd , &
3793 DEALLOCATE ( globbuf )
3795 END SUBROUTINE call_pkg_and_dist_real
3798 SUBROUTINE call_pkg_and_dist_double ( fcn, update_arg , &
3799 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3800 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3801 DomainStart , DomainEnd , &
3802 MemoryStart , MemoryEnd , &
3803 PatchStart , PatchEnd , &
3807 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3808 ! distribute or replicate the field across compute tasks.
3809 ! The sole purpose of this wrapper is to allocate a big double precision buffer
3810 ! and pass it down to call_pkg_and_dist_generic() to do the actual work.
3815 INTEGER , INTENT(IN) :: Hndl
3816 LOGICAL , INTENT(IN) :: update_arg
3817 CHARACTER*(*) :: DateStr
3818 CHARACTER*(*) :: VarName
3819 DOUBLE PRECISION , INTENT(INOUT) :: Field(*)
3820 INTEGER ,INTENT(IN) :: FieldType
3821 INTEGER ,INTENT(INOUT) :: Comm
3822 INTEGER ,INTENT(INOUT) :: IOComm
3823 INTEGER ,INTENT(IN) :: DomainDesc
3824 LOGICAL, DIMENSION(4) :: bdy_mask
3825 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3826 CHARACTER*(*) ,INTENT(IN) :: Stagger
3827 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3828 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3829 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3830 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3831 INTEGER ,INTENT(INOUT) :: Status
3832 DOUBLE PRECISION , ALLOCATABLE :: globbuf (:)
3833 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3835 IF ( wrf_dm_on_monitor() ) THEN
3836 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3838 ALLOCATE( globbuf( 1 ) )
3843 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
3844 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3845 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3846 DomainStart , DomainEnd , &
3847 MemoryStart , MemoryEnd , &
3848 PatchStart , PatchEnd , &
3850 DEALLOCATE ( globbuf )
3852 END SUBROUTINE call_pkg_and_dist_double
3855 SUBROUTINE call_pkg_and_dist_int ( fcn, update_arg , &
3856 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3857 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3858 DomainStart , DomainEnd , &
3859 MemoryStart , MemoryEnd , &
3860 PatchStart , PatchEnd , &
3864 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3865 ! distribute or replicate the field across compute tasks.
3866 ! The sole purpose of this wrapper is to allocate a big integer buffer and
3867 ! pass it down to call_pkg_and_dist_generic() to do the actual work.
3872 INTEGER , INTENT(IN) :: Hndl
3873 LOGICAL , INTENT(IN) :: update_arg
3874 CHARACTER*(*) :: DateStr
3875 CHARACTER*(*) :: VarName
3876 INTEGER , INTENT(INOUT) :: Field(*)
3877 INTEGER ,INTENT(IN) :: FieldType
3878 INTEGER ,INTENT(INOUT) :: Comm
3879 INTEGER ,INTENT(INOUT) :: IOComm
3880 INTEGER ,INTENT(IN) :: DomainDesc
3881 LOGICAL, DIMENSION(4) :: bdy_mask
3882 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3883 CHARACTER*(*) ,INTENT(IN) :: Stagger
3884 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3885 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3886 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3887 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3888 INTEGER ,INTENT(INOUT) :: Status
3889 INTEGER , ALLOCATABLE :: globbuf (:)
3890 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3892 IF ( wrf_dm_on_monitor() ) THEN
3893 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3895 ALLOCATE( globbuf( 1 ) )
3900 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
3901 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3902 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3903 DomainStart , DomainEnd , &
3904 MemoryStart , MemoryEnd , &
3905 PatchStart , PatchEnd , &
3907 DEALLOCATE ( globbuf )
3909 END SUBROUTINE call_pkg_and_dist_int
3912 SUBROUTINE call_pkg_and_dist_logical ( fcn, update_arg , &
3913 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3914 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3915 DomainStart , DomainEnd , &
3916 MemoryStart , MemoryEnd , &
3917 PatchStart , PatchEnd , &
3921 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3922 ! distribute or replicate the field across compute tasks.
3923 ! The sole purpose of this wrapper is to allocate a big logical buffer and
3924 ! pass it down to call_pkg_and_dist_generic() to do the actual work.
3929 INTEGER , INTENT(IN) :: Hndl
3930 LOGICAL , INTENT(IN) :: update_arg
3931 CHARACTER*(*) :: DateStr
3932 CHARACTER*(*) :: VarName
3933 logical , INTENT(INOUT) :: Field(*)
3934 INTEGER ,INTENT(IN) :: FieldType
3935 INTEGER ,INTENT(INOUT) :: Comm
3936 INTEGER ,INTENT(INOUT) :: IOComm
3937 INTEGER ,INTENT(IN) :: DomainDesc
3938 LOGICAL, DIMENSION(4) :: bdy_mask
3939 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
3940 CHARACTER*(*) ,INTENT(IN) :: Stagger
3941 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
3942 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
3943 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
3944 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
3945 INTEGER ,INTENT(INOUT) :: Status
3946 LOGICAL , ALLOCATABLE :: globbuf (:)
3947 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
3949 IF ( wrf_dm_on_monitor() ) THEN
3950 ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
3952 ALLOCATE( globbuf( 1 ) )
3957 CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
3958 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3959 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3960 DomainStart , DomainEnd , &
3961 MemoryStart , MemoryEnd , &
3962 PatchStart , PatchEnd , &
3964 DEALLOCATE ( globbuf )
3966 END SUBROUTINE call_pkg_and_dist_logical
3968 SUBROUTINE call_pkg_and_dist_generic ( fcn, globbuf , update_arg , &
3969 Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
3970 DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
3971 DomainStart , DomainEnd , &
3972 MemoryStart , MemoryEnd , &
3973 PatchStart , PatchEnd , &
3978 ! The call_pkg_and_dist* routines call an I/O function to read a field and then
3979 ! distribute or replicate the field across compute tasks.
3980 ! This routine calls I/O function fcn to read the field from disk and then calls
3981 ! the distributed memory communication routines that distribute or replicate the
3985 USE module_state_description
3986 USE module_driver_constants
3989 #include "wrf_io_flags.h"
3990 #if defined( DM_PARALLEL ) && ! defined(STUBMPI)
3995 REAL, DIMENSION(*) :: globbuf
3996 INTEGER , INTENT(IN) :: Hndl
3997 LOGICAL , INTENT(IN) :: update_arg
3998 CHARACTER*(*) :: DateStr
3999 CHARACTER*(*) :: VarName
4001 INTEGER ,INTENT(IN) :: FieldType
4002 INTEGER ,INTENT(INOUT) :: Comm
4003 INTEGER ,INTENT(INOUT) :: IOComm
4004 INTEGER ,INTENT(IN) :: DomainDesc
4005 LOGICAL, DIMENSION(4) :: bdy_mask
4006 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
4007 CHARACTER*(*) ,INTENT(IN) :: Stagger
4008 CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
4009 INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
4010 INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
4011 INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
4012 INTEGER ,INTENT(OUT) :: Status
4014 LOGICAL, EXTERNAL :: has_char
4015 INTEGER ids, ide, jds, jde, kds, kde
4016 INTEGER ims, ime, jms, jme, kms, kme
4017 INTEGER ips, ipe, jps, jpe, kps, kpe
4018 INTEGER , dimension(3) :: dom_end_rev
4020 LOGICAL, EXTERNAL :: wrf_dm_on_monitor
4021 INTEGER, EXTERNAL :: wrf_dm_monitor_rank
4023 INTEGER lx, lx2, i,j,k ,idx,idx2
4024 INTEGER my_count, nproc, communicator, ierr, my_displ
4026 INTEGER, ALLOCATABLE :: counts(:), displs(:)
4028 LOGICAL distributed_field
4029 INTEGER collective_root
4031 CALL lower_case( MemoryOrder, MemOrd )
4033 collective_root = wrf_dm_monitor_rank()
4035 CALL wrf_get_nproc( nproc )
4036 CALL wrf_get_dm_communicator ( communicator )
4038 ALLOCATE(displs( nproc ))
4039 ALLOCATE(counts( nproc ))
4041 dom_end_rev(1) = DomainEnd(1)
4042 dom_end_rev(2) = DomainEnd(2)
4043 dom_end_rev(3) = DomainEnd(3)
4045 SELECT CASE (TRIM(MemOrd))
4047 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
4048 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
4049 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
4051 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
4052 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
4053 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
4055 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
4056 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
4057 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
4059 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
4060 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
4062 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
4063 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
4064 IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
4066 IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
4067 IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
4069 ! do nothing; the boundary orders and others either dont care or set themselves
4072 data_ordering : SELECT CASE ( model_data_order )
4073 CASE ( DATA_ORDER_XYZ )
4074 ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(2); jde=dom_end_rev(2); kds=DomainStart(3); kde=dom_end_rev(3);
4075 ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(2); jme= MemoryEnd(2); kms=MemoryStart(3); kme= MemoryEnd(3);
4076 ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(2); jpe= PatchEnd(2); kps= PatchStart(3); kpe= PatchEnd(3);
4077 CASE ( DATA_ORDER_YXZ )
4078 ids=DomainStart(2); ide=dom_end_rev(2); jds=DomainStart(1); jde=dom_end_rev(1); kds=DomainStart(3); kde=dom_end_rev(3);
4079 ims=MemoryStart(2); ime= MemoryEnd(2); jms=MemoryStart(1); jme= MemoryEnd(1); kms=MemoryStart(3); kme= MemoryEnd(3);
4080 ips= PatchStart(2); ipe= PatchEnd(2); jps= PatchStart(1); jpe= PatchEnd(1); kps= PatchStart(3); kpe= PatchEnd(3);
4081 CASE ( DATA_ORDER_ZXY )
4082 ids=DomainStart(2); ide=dom_end_rev(2); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(1); kde=dom_end_rev(1);
4083 ims=MemoryStart(2); ime= MemoryEnd(2); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(1); kme= MemoryEnd(1);
4084 ips= PatchStart(2); ipe= PatchEnd(2); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(1); kpe= PatchEnd(1);
4085 CASE ( DATA_ORDER_ZYX )
4086 ids=DomainStart(3); ide=dom_end_rev(3); jds=DomainStart(2); jde=dom_end_rev(2); kds=DomainStart(1); kde=dom_end_rev(1);
4087 ims=MemoryStart(3); ime= MemoryEnd(3); jms=MemoryStart(2); jme= MemoryEnd(2); kms=MemoryStart(1); kme= MemoryEnd(1);
4088 ips= PatchStart(3); ipe= PatchEnd(3); jps= PatchStart(2); jpe= PatchEnd(2); kps= PatchStart(1); kpe= PatchEnd(1);
4089 CASE ( DATA_ORDER_XZY )
4090 ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
4091 ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
4092 ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
4093 CASE ( DATA_ORDER_YZX )
4094 ids=DomainStart(3); ide=dom_end_rev(3); jds=DomainStart(1); jde=dom_end_rev(1); kds=DomainStart(2); kde=dom_end_rev(2);
4095 ims=MemoryStart(3); ime= MemoryEnd(3); jms=MemoryStart(1); jme= MemoryEnd(1); kms=MemoryStart(2); kme= MemoryEnd(2);
4096 ips= PatchStart(3); ipe= PatchEnd(3); jps= PatchStart(1); jpe= PatchEnd(1); kps= PatchStart(2); kpe= PatchEnd(2);
4097 END SELECT data_ordering
4100 SELECT CASE (MemOrd)
4102 CASE ( 'xzy', 'yzx', 'xyz', 'yxz', 'zxy', 'zyx', 'xy', 'yx' )
4103 distributed_field = .TRUE.
4104 CASE ( 'xsz', 'xez', 'xs', 'xe' )
4105 CALL are_bdys_distributed( distributed_field )
4106 CASE ( 'ysz', 'yez', 'ys', 'ye' )
4107 CALL are_bdys_distributed( distributed_field )
4110 ! all other memory orders are replicated
4111 distributed_field = .FALSE.
4114 IF ( distributed_field ) THEN
4116 ! added 8/2004 for interfaces that want the old values so they can be updated
4117 IF ( update_arg ) THEN
4118 SELECT CASE (TRIM(MemOrd))
4119 CASE ( 'xzy','zxy','xyz','yxz','xy','yx' )
4120 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
4121 CALL wrf_patch_to_global_double ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
4122 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4123 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4124 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4125 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
4126 CALL wrf_patch_to_global_real ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
4127 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4128 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4129 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4130 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4131 CALL wrf_patch_to_global_integer ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
4132 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4133 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4134 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4135 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
4136 CALL wrf_patch_to_global_logical ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
4137 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4138 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4139 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4145 IF ( wrf_dm_on_monitor()) THEN
4146 CALL fcn ( Hndl , DateStr , VarName , globbuf , FieldType , Comm , IOComm , &
4147 DomainDesc , MemoryOrder , Stagger , DimNames , &
4148 DomainStart , DomainEnd , &
4149 DomainStart , dom_end_rev , &
4150 DomainStart , DomainEnd , &
4154 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
4156 CALL lower_case( MemoryOrder, MemOrd )
4158 #if defined(DM_PARALLEL) && !defined(STUBMPI)
4159 ! handle boundaries separately
4160 IF ( TRIM(MemOrd) .EQ. 'xsz' .OR. TRIM(MemOrd) .EQ. 'xez' .OR. &
4161 TRIM(MemOrd) .EQ. 'xs' .OR. TRIM(MemOrd) .EQ. 'xe' .OR. &
4162 TRIM(MemOrd) .EQ. 'ysz' .OR. TRIM(MemOrd) .EQ. 'yez' .OR. &
4163 TRIM(MemOrd) .EQ. 'ys' .OR. TRIM(MemOrd) .EQ. 'ye' ) THEN
4165 IF ( TRIM(MemOrd) .EQ. 'xsz' .OR. TRIM(MemOrd) .EQ. 'xez' .OR. &
4166 TRIM(MemOrd) .EQ. 'xs' .OR. TRIM(MemOrd) .EQ. 'xe' ) THEN
4168 jds=DomainStart(1); jde=dom_end_rev(1); ids=DomainStart(3); ide=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
4169 jms=MemoryStart(1); jme= MemoryEnd(1); ims=MemoryStart(3); ime= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
4170 jps= PatchStart(1); jpe= PatchEnd(1); ips= PatchStart(3); ipe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
4172 IF ( nproc .GT. 1 ) THEN
4174 ! Will assume that the i,j, and k dimensions correspond to the model_data_order specified by the registry --
4175 ! 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
4176 ! sides of domain) the j is fully dimensioned, i is the bdy_width, and k is k. corresponding arrangement for ys/ye
4177 ! boundaries (bottom and top). Note, however, that for the boundary arrays themselves, the innermost dimension is always
4178 ! 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
4179 ! for confusion between the MODEL storage order, and which of the sd31:ed31/sd32:ed32/sd33:ed33 framework dimensions
4180 ! correspond to X/Y/Z as determined by the Registry dimespec definitions and what the storage order of the boundary
4181 ! slab arrays are (which depends on which boundaries they represent). The k memory and domain dimensions must be set
4182 ! properly for 2d (ks=1, ke=1) versus 3d fields.
4185 IF ( (MemOrd(1:2) .EQ. 'xs' .AND. bdy_mask( P_XSB )) .OR. &
4186 (MemOrd(1:2) .EQ. 'xe' .AND. bdy_mask( P_XEB )) ) THEN
4188 my_count = jpe-jps+1
4194 IF ( (MemOrd(1:2) .EQ. 'xs' ) .OR. &
4195 (MemOrd(1:2) .EQ. 'xe' ) ) THEN
4197 my_count = jpe-jps+1
4204 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
4205 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
4207 do i = ips,ipe ! bdy_width
4208 do k = kds,kde ! levels
4211 idx = lx*((k-1)+(i-1)*(kme-kms+1))
4212 idx2 = lx2*((k-1)+(i-1)*(kde-kds+1))
4213 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
4214 CALL wrf_scatterv_double ( &
4215 globbuf, 1+idx2 , & ! sendbuf
4216 counts , & ! sendcounts
4217 Field, jps-jms+1+idx , &
4218 my_count , & ! recvcount
4220 collective_root , & ! root
4221 communicator , & ! communicator
4223 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
4225 CALL wrf_scatterv_real ( &
4226 globbuf, 1+idx2 , & ! sendbuf
4227 counts , & ! sendcounts
4228 Field, jps-jms+1+idx , &
4229 my_count , & ! recvcount
4231 collective_root , & ! root
4232 communicator , & ! communicator
4235 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4236 CALL wrf_scatterv_integer ( &
4237 globbuf, 1+idx2 , & ! sendbuf
4238 counts , & ! sendcounts
4239 Field, jps-jms+1+idx , &
4240 my_count , & ! recvcount
4242 collective_root , & ! root
4243 communicator , & ! communicator
4251 IF ( TRIM(MemOrd) .EQ. 'ysz' .OR. TRIM(MemOrd) .EQ. 'yez' .OR. &
4252 TRIM(MemOrd) .EQ. 'ys' .OR. TRIM(MemOrd) .EQ. 'ye' ) THEN
4255 ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
4256 ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
4257 ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
4259 IF ( nproc .GT. 1 ) THEN
4262 IF ( (MemOrd(1:2) .EQ. 'ys' .AND. bdy_mask( P_YSB )) .OR. &
4263 (MemOrd(1:2) .EQ. 'ye' .AND. bdy_mask( P_YEB )) ) THEN
4265 my_count = ipe-ips+1
4271 IF ( (MemOrd(1:2) .EQ. 'ys' ) .OR. &
4272 (MemOrd(1:2) .EQ. 'ye' ) ) THEN
4274 my_count = ipe-ips+1
4281 CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
4282 CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
4284 do j = jds,jde ! bdy_width
4285 do k = kds,kde ! levels
4288 idx = lx*((k-1)+(j-1)*(kme-kms+1))
4289 idx2 = lx2*((k-1)+(j-1)*(kde-kds+1))
4291 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
4292 CALL wrf_scatterv_double ( &
4293 globbuf, 1+idx2 , & ! sendbuf
4294 counts , & ! sendcounts
4295 Field, ips-ims+1+idx , &
4296 my_count , & ! recvcount
4298 collective_root , & ! root
4299 communicator , & ! communicator
4301 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
4302 CALL wrf_scatterv_real ( &
4303 globbuf, 1+idx2 , & ! sendbuf
4304 counts , & ! sendcounts
4305 Field, ips-ims+1+idx , &
4306 my_count , & ! recvcount
4308 collective_root , & ! root
4309 communicator , & ! communicator
4311 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4312 CALL wrf_scatterv_integer ( &
4313 globbuf, 1+idx2 , & ! sendbuf
4314 counts , & ! sendcounts
4315 Field, ips-ims+1+idx , &
4316 my_count , & ! recvcount
4318 collective_root , & ! root
4319 communicator , & ! communicator
4327 ELSE ! not a boundary
4329 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
4331 SELECT CASE (MemOrd)
4332 CASE ( 'xzy','xyz','yxz','zxy' )
4333 CALL wrf_global_to_patch_double ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4334 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4335 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4336 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4338 CALL wrf_global_to_patch_double ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4339 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4340 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4341 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4344 ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
4346 SELECT CASE (MemOrd)
4347 CASE ( 'xzy','xyz','yxz','zxy' )
4348 CALL wrf_global_to_patch_real ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4349 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4350 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4351 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4353 CALL wrf_global_to_patch_real ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4354 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4355 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4356 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4359 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4361 SELECT CASE (MemOrd)
4362 CASE ( 'xzy','xyz','yxz','zxy' )
4363 CALL wrf_global_to_patch_integer ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4364 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4365 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4366 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4368 CALL wrf_global_to_patch_integer ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4369 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4370 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4371 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4374 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
4376 SELECT CASE (MemOrd)
4377 CASE ( 'xzy','xyz','yxz','zxy' )
4378 CALL wrf_global_to_patch_logical ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4379 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
4380 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
4381 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
4383 CALL wrf_global_to_patch_logical ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
4384 DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
4385 MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
4386 PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
4393 ELSE ! not a distributed field
4395 IF ( wrf_dm_on_monitor()) THEN
4396 CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
4397 DomainDesc , MemoryOrder , Stagger , DimNames , &
4398 DomainStart , DomainEnd , &
4399 MemoryStart , MemoryEnd , &
4400 PatchStart , PatchEnd , &
4403 CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
4404 memsize = (MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)
4405 IF ( FieldType .EQ. WRF_DOUBLE ) THEN
4406 CALL wrf_dm_bcast_bytes( Field , DWORDSIZE*memsize )
4407 ELSE IF ( FieldType .EQ. WRF_FLOAT) THEN
4408 CALL wrf_dm_bcast_bytes( Field , RWORDSIZE*memsize )
4409 ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
4410 CALL wrf_dm_bcast_bytes( Field , IWORDSIZE*memsize )
4411 ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
4412 CALL wrf_dm_bcast_bytes( Field , LWORDSIZE*memsize )
4420 END SUBROUTINE call_pkg_and_dist_generic
4422 !!!!!! Miscellaneous routines
4424 ! stole these routines from io_netcdf external package; changed names to avoid collisions
4425 SUBROUTINE dim_from_memorder(MemoryOrder,NDim)
4428 ! Decodes array ranks from memory order.
4431 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
4432 INTEGER ,INTENT(OUT) :: NDim
4434 CHARACTER*3 :: MemOrd
4436 CALL Lower_Case(MemoryOrder,MemOrd)
4437 SELECT CASE (MemOrd)
4438 CASE ('xyz','xzy','yxz','yzx','zxy','zyx')
4449 END SUBROUTINE dim_from_memorder
4451 SUBROUTINE lower_case(MemoryOrder,MemOrd)
4454 ! Translates upper-case characters to lower-case.
4457 CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
4458 CHARACTER*(*) ,INTENT(OUT) :: MemOrd
4461 INTEGER ,PARAMETER :: upper_to_lower =IACHAR('a')-IACHAR('A')
4465 N = len(MemoryOrder)
4468 MemOrd(1:N) = MemoryOrder(1:N)
4470 c = MemoryOrder(i:i)
4471 if('A'<=c .and. c <='Z') MemOrd(i:i)=achar(iachar(c)+upper_to_lower)
4474 END SUBROUTINE Lower_Case
4476 LOGICAL FUNCTION has_char( str, c )
4479 ! Returns .TRUE. iff string str contains character c. Ignores character case.
4485 CHARACTER*80 str1, str2, str3
4488 CALL lower_case( TRIM(str), str1 )
4491 CALL lower_case( str2, str3 )
4493 DO i = 1, LEN(TRIM(str1))
4494 IF ( str1(i:i) .EQ. d ) THEN
4501 END FUNCTION has_char