PageRenderTime 36ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/frame/module_io.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 4109 lines | 2594 code | 288 blank | 1227 comment | 5 complexity | 9a0c386588802cefdf14e6b9e8dcc79a MD5 | raw file
Possible License(s): AGPL-1.0
  1. !WRF:DRIVER_LAYER:IO
  2. !
  3. #define DEBUG_LVL 500
  4. MODULE module_io
  5. !<DESCRIPTION>
  6. !<PRE>
  7. ! WRF-specific package-independent interface to package-dependent WRF-specific
  8. ! I/O packages.
  9. !
  10. ! These routines have the same names as those specified in the WRF I/O API
  11. ! except that:
  12. ! - Routines defined in this file and called by users of this module have
  13. ! the "wrf_" prefix.
  14. ! - Routines defined in the I/O packages and called from routines in this
  15. ! file have the "ext_" prefix.
  16. ! - Routines called from routines in this file to initiate communication
  17. ! with I/O quilt servers have the "wrf_quilt_" prefix.
  18. !
  19. ! See http://www.mmm.ucar.edu/wrf/WG2/software_2.0/IOAPI.doc for the latest
  20. ! version of the WRF I/O API. This document includes detailed descriptions
  21. ! of subroutines and their arguments that are not duplicated in this file.
  22. !
  23. ! We wish to be able to link to different packages depending on whether
  24. ! the I/O is restart, initial, history, or boundary.
  25. !</PRE>
  26. !</DESCRIPTION>
  27. USE module_configure
  28. LOGICAL :: is_inited = .FALSE.
  29. INTEGER, PARAMETER, PRIVATE :: MAX_WRF_IO_HANDLE = 1000
  30. INTEGER :: wrf_io_handles(MAX_WRF_IO_HANDLE), how_opened(MAX_WRF_IO_HANDLE)
  31. LOGICAL :: for_output(MAX_WRF_IO_HANDLE), first_operation(MAX_WRF_IO_HANDLE)
  32. INTEGER :: filtno = 0
  33. LOGICAL, PRIVATE :: bdy_dist_flag = .TRUE. ! false is old style undecomposed boundary data structs,
  34. ! true is new style decomposed boundary data structs
  35. ! are_bdys_distributed, bdys_are_distributed and
  36. ! bdys_not_distributed routines access this flag
  37. CHARACTER*256 extradims
  38. !<DESCRIPTION>
  39. !<PRE>
  40. !
  41. ! include the file generated from md_calls.m4 using the m4 preprocessor
  42. ! note that this file also includes the CONTAINS declaration for the module
  43. !
  44. !</PRE>
  45. !</DESCRIPTION>
  46. #include "md_calls.inc"
  47. !--- registry-generated routine that gets the io format being used for a dataset
  48. INTEGER FUNCTION io_form_for_dataset ( DataSet )
  49. IMPLICIT NONE
  50. CHARACTER*(*), INTENT(IN) :: DataSet
  51. INTEGER :: io_form
  52. #include "io_form_for_dataset.inc"
  53. io_form_for_dataset = io_form
  54. RETURN
  55. END FUNCTION io_form_for_dataset
  56. INTEGER FUNCTION io_form_for_stream ( stream )
  57. USE module_streams
  58. IMPLICIT NONE
  59. INTEGER, INTENT(IN) :: stream
  60. INTEGER :: io_form
  61. #include "io_form_for_stream.inc"
  62. io_form_for_stream = io_form
  63. RETURN
  64. END FUNCTION io_form_for_stream
  65. !--- ioinit
  66. SUBROUTINE wrf_ioinit( Status )
  67. !<DESCRIPTION>
  68. !<PRE>
  69. ! Initialize the WRF I/O system.
  70. !</PRE>
  71. !</DESCRIPTION>
  72. IMPLICIT NONE
  73. INTEGER, INTENT(INOUT) :: Status
  74. !Local
  75. CHARACTER(len=80) :: SysDepInfo
  76. INTEGER :: ierr(10), minerr, maxerr
  77. !
  78. Status = 0
  79. ierr = 0
  80. SysDepInfo = " "
  81. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioinit' )
  82. CALL init_io_handles ! defined below
  83. #ifdef NETCDF
  84. CALL ext_ncd_ioinit( SysDepInfo, ierr(1) )
  85. #endif
  86. #ifdef INTIO
  87. CALL ext_int_ioinit( SysDepInfo, ierr(2) )
  88. #endif
  89. #ifdef PHDF5
  90. CALL ext_phdf5_ioinit( SysDepInfo, ierr(3) )
  91. #endif
  92. #ifdef PNETCDF
  93. CALL ext_pnc_ioinit( SysDepInfo, ierr(3) )
  94. #endif
  95. #ifdef MCELIO
  96. CALL ext_mcel_ioinit( SysDepInfo, ierr(4) )
  97. #endif
  98. #ifdef XXX
  99. CALL ext_xxx_ioinit( SysDepInfo, ierr(5) )
  100. #endif
  101. #ifdef YYY
  102. CALL ext_yyy_ioinit( SysDepInfo, ierr(6) )
  103. #endif
  104. #ifdef ZZZ
  105. CALL ext_zzz_ioinit( SysDepInfo, ierr(7) )
  106. #endif
  107. #ifdef ESMFIO
  108. CALL ext_esmf_ioinit( SysDepInfo, ierr(8) )
  109. #endif
  110. #ifdef GRIB1
  111. CALL ext_gr1_ioinit( SysDepInfo, ierr(9) )
  112. #endif
  113. #ifdef GRIB2
  114. CALL ext_gr2_ioinit( SysDepInfo, ierr(10) )
  115. #endif
  116. minerr = MINVAL(ierr)
  117. maxerr = MAXVAL(ierr)
  118. IF ( minerr < 0 ) THEN
  119. Status = minerr
  120. ELSE IF ( maxerr > 0 ) THEN
  121. Status = maxerr
  122. ELSE
  123. Status = 0
  124. ENDIF
  125. END SUBROUTINE wrf_ioinit
  126. !--- ioexit
  127. SUBROUTINE wrf_ioexit( Status )
  128. !<DESCRIPTION>
  129. !<PRE>
  130. ! Shut down the WRF I/O system.
  131. !</PRE>
  132. !</DESCRIPTION>
  133. IMPLICIT NONE
  134. INTEGER, INTENT(INOUT) :: Status
  135. !Local
  136. LOGICAL, EXTERNAL :: use_output_servers
  137. INTEGER :: ierr(11), minerr, maxerr
  138. !
  139. Status = 0
  140. ierr = 0
  141. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioexit' )
  142. #ifdef NETCDF
  143. CALL ext_ncd_ioexit( ierr(1) )
  144. #endif
  145. #ifdef INTIO
  146. CALL ext_int_ioexit( ierr(2) )
  147. #endif
  148. #ifdef PHDF5
  149. CALL ext_phdf5_ioexit(ierr(3) )
  150. #endif
  151. #ifdef PNETCDF
  152. CALL ext_pnc_ioexit(ierr(3) )
  153. #endif
  154. #ifdef MCELIO
  155. CALL ext_mcel_ioexit( ierr(4) )
  156. #endif
  157. #ifdef XXX
  158. CALL ext_xxx_ioexit( ierr(5) )
  159. #endif
  160. #ifdef YYY
  161. CALL ext_yyy_ioexit( ierr(6) )
  162. #endif
  163. #ifdef ZZZ
  164. CALL ext_zzz_ioexit( ierr(7) )
  165. #endif
  166. #ifdef ESMFIO
  167. CALL ext_esmf_ioexit( ierr(8) )
  168. #endif
  169. #ifdef GRIB1
  170. CALL ext_gr1_ioexit( ierr(9) )
  171. #endif
  172. #ifdef GRIB2
  173. CALL ext_gr2_ioexit( ierr(10) )
  174. #endif
  175. IF ( use_output_servers() ) CALL wrf_quilt_ioexit( ierr(11) )
  176. minerr = MINVAL(ierr)
  177. maxerr = MAXVAL(ierr)
  178. IF ( minerr < 0 ) THEN
  179. Status = minerr
  180. ELSE IF ( maxerr > 0 ) THEN
  181. Status = maxerr
  182. ELSE
  183. Status = 0
  184. ENDIF
  185. END SUBROUTINE wrf_ioexit
  186. !--- open_for_write_begin
  187. SUBROUTINE wrf_open_for_write_begin( FileName , Comm_compute, Comm_io, SysDepInfo, &
  188. DataHandle , Status )
  189. !<DESCRIPTION>
  190. !<PRE>
  191. ! Begin data definition ("training") phase for writing to WRF dataset
  192. ! FileName.
  193. !</PRE>
  194. !</DESCRIPTION>
  195. USE module_state_description
  196. #ifdef DM_PARALLEL
  197. USE module_dm, ONLY : ntasks_x, mytask_x, local_communicator_x
  198. #endif
  199. IMPLICIT NONE
  200. #include "wrf_io_flags.h"
  201. CHARACTER*(*) :: FileName
  202. INTEGER , INTENT(IN) :: Comm_compute , Comm_io
  203. CHARACTER*(*), INTENT(INOUT):: SysDepInfo
  204. INTEGER , INTENT(OUT) :: DataHandle
  205. INTEGER , INTENT(OUT) :: Status
  206. !Local
  207. CHARACTER*128 :: DataSet
  208. INTEGER :: io_form
  209. INTEGER :: Hndl
  210. INTEGER, EXTERNAL :: use_package
  211. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  212. CHARACTER*128 :: LocFilename ! for appending the process ID if necessary
  213. INTEGER :: myproc
  214. CHARACTER*128 :: mess
  215. CHARACTER*1028 :: tstr, t1
  216. INTEGER i,j
  217. WRITE(mess,*) 'module_io.F: in wrf_open_for_write_begin, FileName = ',TRIM(FileName)
  218. CALL wrf_debug( DEBUG_LVL, mess )
  219. CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
  220. io_form = io_form_for_dataset( DataSet )
  221. Status = 0
  222. Hndl = -1
  223. IF ( multi_files( io_form ) .OR. .NOT. use_output_servers() ) THEN
  224. SELECT CASE ( use_package(io_form) )
  225. #ifdef NETCDF
  226. CASE ( IO_NETCDF )
  227. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  228. IF ( multi_files(io_form) ) THEN
  229. CALL wrf_get_myproc ( myproc )
  230. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  231. ELSE
  232. LocFilename = FileName
  233. ENDIF
  234. CALL ext_ncd_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  235. Hndl , Status )
  236. ENDIF
  237. IF ( .NOT. multi_files(io_form) ) THEN
  238. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  239. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  240. ENDIF
  241. #endif
  242. #ifdef PHDF5
  243. CASE (IO_PHDF5 )
  244. CALL ext_phdf5_open_for_write_begin( FileName, Comm_compute, Comm_io, SysDepInfo, &
  245. Hndl, Status)
  246. #endif
  247. #ifdef PNETCDF
  248. CASE (IO_PNETCDF )
  249. WRITE(tstr,"(A,',NTASKS_X=',i10,',MYTASK_X=',i10,',LOCAL_COMMUNICATOR_X=',i10)") TRIM(SysDepInfo),ntasks_x,mytask_x,local_communicator_x
  250. j=1
  251. t1 = " "
  252. DO i=1,len(TRIM(tstr))
  253. IF ( tstr(i:i) .NE. ' ' ) THEN
  254. t1(j:j) = tstr(i:i)
  255. j = j + 1
  256. ENDIF
  257. ENDDO
  258. tstr = t1
  259. CALL ext_pnc_open_for_write_begin( FileName, Comm_compute, Comm_io, tstr, &
  260. Hndl, Status)
  261. #endif
  262. #ifdef XXX
  263. CASE ( IO_XXX )
  264. CALL ext_xxx_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  265. Hndl , Status )
  266. #endif
  267. #ifdef YYY
  268. CASE ( IO_YYY )
  269. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  270. IF ( multi_files(io_form) ) THEN
  271. CALL wrf_get_myproc ( myproc )
  272. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  273. ELSE
  274. LocFilename = FileName
  275. ENDIF
  276. CALL ext_yyy_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  277. Hndl , Status )
  278. ENDIF
  279. IF ( .NOT. multi_files(io_form) ) THEN
  280. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  281. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  282. ENDIF
  283. #endif
  284. #ifdef ZZZ
  285. CASE ( IO_ZZZ )
  286. CALL ext_zzz_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  287. Hndl , Status )
  288. #endif
  289. #ifdef GRIB1
  290. CASE ( IO_GRIB1 )
  291. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  292. IF ( multi_files(io_form) ) THEN
  293. CALL wrf_get_myproc ( myproc )
  294. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  295. ELSE
  296. LocFilename = FileName
  297. ENDIF
  298. CALL ext_gr1_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  299. Hndl , Status )
  300. ENDIF
  301. IF ( .NOT. multi_files(io_form) ) THEN
  302. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  303. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  304. ENDIF
  305. #endif
  306. #ifdef GRIB2
  307. CASE ( IO_GRIB2 )
  308. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  309. IF ( multi_files(io_form) ) THEN
  310. CALL wrf_get_myproc ( myproc )
  311. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  312. ELSE
  313. LocFilename = FileName
  314. ENDIF
  315. CALL ext_gr2_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  316. Hndl , Status )
  317. ENDIF
  318. IF ( .NOT. multi_files(io_form) ) THEN
  319. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  320. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  321. ENDIF
  322. #endif
  323. #ifdef MCELIO
  324. CASE ( IO_MCEL )
  325. IF ( wrf_dm_on_monitor() ) THEN
  326. tstr = TRIM(SysDepInfo) // ',' // 'LAT_R=XLAT,LON_R=XLONG,LANDMASK_I=LU_MASK'
  327. CALL ext_mcel_open_for_write_begin ( FileName , Comm_compute, Comm_io, tstr, &
  328. Hndl , Status )
  329. ENDIF
  330. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  331. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  332. #endif
  333. #ifdef ESMFIO
  334. CASE ( IO_ESMF )
  335. CALL ext_esmf_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  336. Hndl , Status )
  337. #endif
  338. #ifdef INTIO
  339. CASE ( IO_INTIO )
  340. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  341. IF ( multi_files(io_form) ) THEN
  342. CALL wrf_get_myproc ( myproc )
  343. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  344. ELSE
  345. LocFilename = FileName
  346. ENDIF
  347. CALL ext_int_open_for_write_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  348. Hndl , Status )
  349. ENDIF
  350. IF ( .NOT. multi_files(io_form) ) THEN
  351. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  352. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  353. ENDIF
  354. #endif
  355. CASE DEFAULT
  356. IF ( io_form .NE. 0 ) THEN
  357. WRITE(mess,*)'Tried to open ',FileName,' writing: no valid io_form (',io_form,')'
  358. CALL wrf_debug(1, mess)
  359. Status = WRF_FILE_NOT_OPENED
  360. ENDIF
  361. END SELECT
  362. ELSE IF ( use_output_servers() ) THEN
  363. IF ( io_form .GT. 0 ) THEN
  364. CALL wrf_quilt_open_for_write_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  365. Hndl , io_form, Status )
  366. ENDIF
  367. ELSE
  368. Status = 0
  369. ENDIF
  370. CALL add_new_handle( Hndl, io_form, .TRUE., DataHandle )
  371. END SUBROUTINE wrf_open_for_write_begin
  372. !--- open_for_write_commit
  373. SUBROUTINE wrf_open_for_write_commit( DataHandle , Status )
  374. !<DESCRIPTION>
  375. !<PRE>
  376. ! This routine switches an internal flag to enable output for the data set
  377. ! referenced by DataHandle. The call to wrf_open_for_write_commit() must be
  378. ! paired with a call to wrf_open_for_write_begin().
  379. !</PRE>
  380. !</DESCRIPTION>
  381. USE module_state_description
  382. IMPLICIT NONE
  383. INTEGER , INTENT(IN ) :: DataHandle
  384. INTEGER , INTENT(OUT) :: Status
  385. CHARACTER (128) :: DataSet
  386. INTEGER :: io_form
  387. INTEGER :: Hndl
  388. LOGICAL :: for_out
  389. INTEGER, EXTERNAL :: use_package
  390. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  391. #include "wrf_io_flags.h"
  392. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_write_commit' )
  393. Status = 0
  394. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  395. CALL set_first_operation( DataHandle )
  396. IF ( Hndl .GT. -1 ) THEN
  397. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  398. SELECT CASE ( use_package(io_form) )
  399. #ifdef NETCDF
  400. CASE ( IO_NETCDF )
  401. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  402. CALL ext_ncd_open_for_write_commit ( Hndl , Status )
  403. ENDIF
  404. IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  405. #endif
  406. #ifdef MCELIO
  407. CASE ( IO_MCEL )
  408. IF ( wrf_dm_on_monitor() ) THEN
  409. CALL ext_mcel_open_for_write_commit ( Hndl , Status )
  410. ENDIF
  411. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  412. #endif
  413. #ifdef ESMFIO
  414. CASE ( IO_ESMF )
  415. CALL ext_esmf_open_for_write_commit ( Hndl , Status )
  416. #endif
  417. #ifdef PHDF5
  418. CASE ( IO_PHDF5 )
  419. CALL ext_phdf5_open_for_write_commit ( Hndl , Status )
  420. #endif
  421. #ifdef PNETCDF
  422. CASE ( IO_PNETCDF )
  423. CALL ext_pnc_open_for_write_commit ( Hndl , Status )
  424. #endif
  425. #ifdef XXX
  426. CASE ( IO_XXX )
  427. CALL ext_xxx_open_for_write_commit ( Hndl , Status )
  428. #endif
  429. #ifdef YYY
  430. CASE ( IO_YYY )
  431. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  432. CALL ext_yyy_open_for_write_commit ( Hndl , Status )
  433. ENDIF
  434. IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  435. #endif
  436. #ifdef ZZZ
  437. CASE ( IO_ZZZ )
  438. CALL ext_zzz_open_for_write_commit ( Hndl , Status )
  439. #endif
  440. #ifdef GRIB1
  441. CASE ( IO_GRIB1 )
  442. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  443. CALL ext_gr1_open_for_write_commit ( Hndl , Status )
  444. ENDIF
  445. IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  446. #endif
  447. #ifdef GRIB2
  448. CASE ( IO_GRIB2 )
  449. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  450. CALL ext_gr2_open_for_write_commit ( Hndl , Status )
  451. ENDIF
  452. IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  453. #endif
  454. #ifdef INTIO
  455. CASE ( IO_INTIO )
  456. CALL ext_int_open_for_write_commit ( Hndl , Status )
  457. #endif
  458. CASE DEFAULT
  459. Status = 0
  460. END SELECT
  461. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  462. CALL wrf_quilt_open_for_write_commit ( Hndl , Status )
  463. ELSE
  464. Status = 0
  465. ENDIF
  466. ELSE
  467. Status = 0
  468. ENDIF
  469. RETURN
  470. END SUBROUTINE wrf_open_for_write_commit
  471. !--- open_for_read_begin
  472. SUBROUTINE wrf_open_for_read_begin( FileName , Comm_compute, Comm_io, SysDepInfo, &
  473. DataHandle , Status )
  474. !<DESCRIPTION>
  475. !<PRE>
  476. ! Begin data definition ("training") phase for reading from WRF dataset
  477. ! FileName.
  478. !</PRE>
  479. !</DESCRIPTION>
  480. USE module_state_description
  481. IMPLICIT NONE
  482. #include "wrf_io_flags.h"
  483. CHARACTER*(*) :: FileName
  484. INTEGER , INTENT(IN) :: Comm_compute , Comm_io
  485. CHARACTER*(*) :: SysDepInfo
  486. INTEGER , INTENT(OUT) :: DataHandle
  487. INTEGER , INTENT(OUT) :: Status
  488. CHARACTER*128 :: DataSet
  489. INTEGER :: io_form
  490. INTEGER :: Hndl
  491. LOGICAL :: also_for_out
  492. INTEGER, EXTERNAL :: use_package
  493. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  494. CHARACTER*128 :: LocFilename ! for appending the process ID if necessary
  495. INTEGER myproc
  496. CHARACTER*128 :: mess, fhand
  497. CHARACTER*1028 :: tstr
  498. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read_begin' )
  499. CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
  500. io_form = io_form_for_dataset( DataSet )
  501. Status = 0
  502. Hndl = -1
  503. also_for_out = .FALSE.
  504. ! IF ( .NOT. use_output_servers() ) THEN
  505. SELECT CASE ( use_package(io_form) )
  506. #ifdef NETCDF
  507. CASE ( IO_NETCDF )
  508. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  509. IF ( multi_files(io_form) ) THEN
  510. CALL wrf_get_myproc ( myproc )
  511. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  512. ELSE
  513. LocFilename = FileName
  514. ENDIF
  515. CALL ext_ncd_open_for_read_begin ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
  516. Hndl , Status )
  517. ENDIF
  518. IF ( .NOT. multi_files(io_form) ) THEN
  519. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  520. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  521. ENDIF
  522. #endif
  523. #ifdef PNETCDF
  524. CASE ( IO_PNETCDF )
  525. CALL ext_pnc_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  526. Hndl , Status )
  527. #endif
  528. #ifdef XXX
  529. CASE ( IO_XXX )
  530. CALL ext_xxx_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  531. Hndl , Status )
  532. #endif
  533. #ifdef YYY
  534. CASE ( IO_YYY )
  535. CALL ext_yyy_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  536. Hndl , Status )
  537. #endif
  538. #ifdef ZZZ
  539. CASE ( IO_ZZZ )
  540. CALL ext_zzz_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  541. Hndl , Status )
  542. #endif
  543. #ifdef MCELIO
  544. CASE ( IO_MCEL )
  545. also_for_out = .TRUE.
  546. IF ( wrf_dm_on_monitor() ) THEN
  547. WRITE(fhand,'(a,i0)')"filter_",filtno
  548. filtno = filtno + 1
  549. tstr = TRIM(SysDepInfo) // ',' // 'READ_MODE=UPDATE,LAT_R=XLAT,LON_R=XLONG,LANDMASK_I=LU_MASK,FILTER_HANDLE=' // TRIM(fhand)
  550. CALL ext_mcel_open_for_read_begin ( FileName , Comm_compute, Comm_io, tstr, &
  551. Hndl , Status )
  552. ENDIF
  553. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  554. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  555. #endif
  556. #ifdef ESMFIO
  557. CASE ( IO_ESMF )
  558. also_for_out = .TRUE.
  559. CALL ext_esmf_open_for_read_begin ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  560. Hndl , Status )
  561. #endif
  562. #ifdef GRIB1
  563. CASE ( IO_GRIB1 )
  564. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  565. IF ( multi_files(io_form) ) THEN
  566. CALL wrf_get_myproc ( myproc )
  567. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  568. ELSE
  569. LocFilename = FileName
  570. ENDIF
  571. CALL ext_gr1_open_for_read_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  572. Hndl , Status )
  573. ENDIF
  574. IF ( .NOT. multi_files(io_form) ) THEN
  575. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  576. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  577. ENDIF
  578. #endif
  579. #ifdef GRIB2
  580. CASE ( IO_GRIB2 )
  581. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  582. IF ( multi_files(io_form) ) THEN
  583. CALL wrf_get_myproc ( myproc )
  584. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  585. ELSE
  586. LocFilename = FileName
  587. ENDIF
  588. CALL ext_gr2_open_for_read_begin ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  589. Hndl , Status )
  590. ENDIF
  591. IF ( .NOT. multi_files(io_form) ) THEN
  592. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  593. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  594. ENDIF
  595. #endif
  596. #ifdef INTIO
  597. CASE ( IO_INTIO )
  598. #endif
  599. CASE DEFAULT
  600. IF ( io_form .NE. 0 ) THEN
  601. WRITE(mess,*)'Tried to open ',FileName,' reading: no valid io_form (',io_form,')'
  602. CALL wrf_message(mess)
  603. ENDIF
  604. Status = WRF_FILE_NOT_OPENED
  605. END SELECT
  606. ! ELSE
  607. ! Status = 0
  608. ! ENDIF
  609. CALL add_new_handle( Hndl, io_form, also_for_out, DataHandle )
  610. END SUBROUTINE wrf_open_for_read_begin
  611. !--- open_for_read_commit
  612. SUBROUTINE wrf_open_for_read_commit( DataHandle , Status )
  613. !<DESCRIPTION>
  614. !<PRE>
  615. ! End "training" phase for WRF dataset FileName. The call to
  616. ! wrf_open_for_read_commit() must be paired with a call to
  617. ! wrf_open_for_read_begin().
  618. !</PRE>
  619. !</DESCRIPTION>
  620. USE module_state_description
  621. IMPLICIT NONE
  622. INTEGER , INTENT(IN ) :: DataHandle
  623. INTEGER , INTENT(OUT) :: Status
  624. CHARACTER (128) :: DataSet
  625. INTEGER :: io_form
  626. INTEGER :: Hndl
  627. LOGICAL :: for_out
  628. INTEGER, EXTERNAL :: use_package
  629. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  630. #include "wrf_io_flags.h"
  631. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read_commit' )
  632. Status = 0
  633. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  634. CALL set_first_operation( DataHandle )
  635. IF ( Hndl .GT. -1 ) THEN
  636. IF ( .NOT. (for_out .AND. use_output_servers()) ) THEN
  637. SELECT CASE ( use_package(io_form) )
  638. #ifdef NETCDF
  639. CASE ( IO_NETCDF )
  640. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  641. CALL ext_ncd_open_for_read_commit ( Hndl , Status )
  642. ENDIF
  643. IF ( .NOT. multi_files(io_form) ) CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  644. #endif
  645. #ifdef MCELIO
  646. CASE ( IO_MCEL )
  647. IF ( wrf_dm_on_monitor() ) THEN
  648. CALL ext_mcel_open_for_read_commit ( Hndl , Status )
  649. ENDIF
  650. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  651. #endif
  652. #ifdef ESMFIO
  653. CASE ( IO_ESMF )
  654. CALL ext_esmf_open_for_read_commit ( Hndl , Status )
  655. #endif
  656. #ifdef PNETCDF
  657. CASE ( IO_PNETCDF )
  658. CALL ext_pnc_open_for_read_commit ( Hndl , Status )
  659. #endif
  660. #ifdef XXX
  661. CASE ( IO_XXX )
  662. CALL ext_xxx_open_for_read_commit ( Hndl , Status )
  663. #endif
  664. #ifdef YYY
  665. CASE ( IO_YYY )
  666. CALL ext_yyy_open_for_read_commit ( Hndl , Status )
  667. #endif
  668. #ifdef ZZZ
  669. CASE ( IO_ZZZ )
  670. CALL ext_zzz_open_for_read_commit ( Hndl , Status )
  671. #endif
  672. #ifdef GRIB1
  673. CASE ( IO_GRIB1 )
  674. CALL ext_gr1_open_for_read_commit ( Hndl , Status )
  675. #endif
  676. #ifdef GRIB2
  677. CASE ( IO_GRIB2 )
  678. CALL ext_gr2_open_for_read_commit ( Hndl , Status )
  679. #endif
  680. #ifdef INTIO
  681. CASE ( IO_INTIO )
  682. #endif
  683. CASE DEFAULT
  684. Status = 0
  685. END SELECT
  686. ELSE
  687. Status = 0
  688. ENDIF
  689. ELSE
  690. Status = WRF_FILE_NOT_OPENED
  691. ENDIF
  692. RETURN
  693. END SUBROUTINE wrf_open_for_read_commit
  694. !--- open_for_read
  695. SUBROUTINE wrf_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  696. DataHandle , Status )
  697. !<DESCRIPTION>
  698. !<PRE>
  699. ! Opens a WRF dataset for reading.
  700. !</PRE>
  701. !</DESCRIPTION>
  702. USE module_state_description
  703. IMPLICIT NONE
  704. CHARACTER*(*) :: FileName
  705. INTEGER , INTENT(IN) :: Comm_compute , Comm_io
  706. CHARACTER*(*) :: SysDepInfo
  707. INTEGER , INTENT(OUT) :: DataHandle
  708. INTEGER , INTENT(OUT) :: Status
  709. CHARACTER (128) :: DataSet, LocFileName
  710. INTEGER :: io_form, myproc
  711. INTEGER :: Hndl
  712. INTEGER, EXTERNAL :: use_package
  713. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  714. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_open_for_read' )
  715. CALL get_value_from_pairs ( "DATASET" , SysDepInfo , DataSet )
  716. io_form = io_form_for_dataset( DataSet )
  717. Hndl = -1
  718. Status = 0
  719. SELECT CASE ( use_package(io_form) )
  720. #ifdef NETCDF
  721. CASE ( IO_NETCDF )
  722. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  723. IF ( multi_files(io_form) ) THEN
  724. CALL wrf_get_myproc ( myproc )
  725. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  726. ELSE
  727. LocFilename = FileName
  728. ENDIF
  729. CALL ext_ncd_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
  730. Hndl , Status )
  731. ENDIF
  732. IF ( .NOT. multi_files(io_form) ) THEN
  733. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  734. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  735. ENDIF
  736. #endif
  737. #ifdef PNETCDF
  738. CASE ( IO_PNETCDF )
  739. CALL ext_pnc_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  740. Hndl , Status )
  741. #endif
  742. #ifdef PHDF5
  743. CASE ( IO_PHDF5 )
  744. CALL ext_phdf5_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  745. Hndl , Status )
  746. #endif
  747. #ifdef XXX
  748. CASE ( IO_XXX )
  749. CALL ext_xxx_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  750. Hndl , Status )
  751. #endif
  752. #ifdef YYY
  753. CASE ( IO_YYY )
  754. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  755. IF ( multi_files(io_form) ) THEN
  756. CALL wrf_get_myproc ( myproc )
  757. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  758. ELSE
  759. LocFilename = FileName
  760. ENDIF
  761. CALL ext_yyy_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
  762. Hndl , Status )
  763. ENDIF
  764. IF ( .NOT. multi_files(io_form) ) THEN
  765. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  766. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  767. ENDIF
  768. #endif
  769. #ifdef ZZZ
  770. CASE ( IO_ZZZ )
  771. CALL ext_zzz_open_for_read ( FileName , Comm_compute, Comm_io, SysDepInfo, &
  772. Hndl , Status )
  773. #endif
  774. #ifdef GRIB1
  775. CASE ( IO_GRIB1 )
  776. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  777. IF ( multi_files(io_form) ) THEN
  778. CALL wrf_get_myproc ( myproc )
  779. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  780. ELSE
  781. LocFilename = FileName
  782. ENDIF
  783. CALL ext_gr1_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
  784. Hndl , Status )
  785. ENDIF
  786. IF ( .NOT. multi_files(io_form) ) THEN
  787. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  788. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  789. ENDIF
  790. #endif
  791. #ifdef GRIB2
  792. CASE ( IO_GRIB2 )
  793. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  794. IF ( multi_files(io_form) ) THEN
  795. CALL wrf_get_myproc ( myproc )
  796. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  797. ELSE
  798. LocFilename = FileName
  799. ENDIF
  800. CALL ext_gr2_open_for_read ( LocFilename , Comm_compute, Comm_io, SysDepInfo, &
  801. Hndl , Status )
  802. ENDIF
  803. IF ( .NOT. multi_files(io_form) ) THEN
  804. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  805. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  806. ENDIF
  807. #endif
  808. #ifdef INTIO
  809. CASE ( IO_INTIO )
  810. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) THEN
  811. IF ( multi_files(io_form) ) THEN
  812. CALL wrf_get_myproc ( myproc )
  813. CALL append_to_filename ( LocFilename , FileName , myproc, 4 )
  814. ELSE
  815. LocFilename = FileName
  816. ENDIF
  817. CALL ext_int_open_for_read ( LocFileName , Comm_compute, Comm_io, SysDepInfo, &
  818. Hndl , Status )
  819. ENDIF
  820. IF ( .NOT. multi_files(io_form) ) THEN
  821. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  822. CALL wrf_dm_bcast_bytes( Hndl, IWORDSIZE )
  823. ENDIF
  824. #endif
  825. CASE DEFAULT
  826. Status = 0
  827. END SELECT
  828. CALL add_new_handle( Hndl, io_form, .FALSE., DataHandle )
  829. RETURN
  830. END SUBROUTINE wrf_open_for_read
  831. !--- inquire_opened
  832. SUBROUTINE wrf_inquire_opened ( DataHandle, FileName , FileStatus, Status )
  833. !<DESCRIPTION>
  834. !<PRE>
  835. ! Inquire if the dataset referenced by DataHandle is open.
  836. !</PRE>
  837. !</DESCRIPTION>
  838. USE module_state_description
  839. IMPLICIT NONE
  840. INTEGER , INTENT(IN) :: DataHandle
  841. CHARACTER*(*) :: FileName
  842. INTEGER , INTENT(OUT) :: FileStatus
  843. INTEGER , INTENT(OUT) :: Status
  844. LOGICAL :: for_out
  845. INTEGER, EXTERNAL :: use_package
  846. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  847. #include "wrf_io_flags.h"
  848. #include "wrf_status_codes.h"
  849. INTEGER io_form , Hndl
  850. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_inquire_opened' )
  851. Status = 0
  852. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  853. IF ( Hndl .GT. -1 ) THEN
  854. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  855. SELECT CASE ( use_package(io_form) )
  856. #ifdef NETCDF
  857. CASE ( IO_NETCDF )
  858. IF (wrf_dm_on_monitor()) CALL ext_ncd_inquire_opened ( Hndl, FileName , FileStatus, Status )
  859. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  860. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  861. #endif
  862. #ifdef PHDF5
  863. CASE ( IO_PHDF5 )
  864. CALL ext_phdf5_inquire_opened ( Hndl, FileName , FileStatus, Status )
  865. #endif
  866. #ifdef PNETCDF
  867. CASE ( IO_PNETCDF )
  868. CALL ext_pnc_inquire_opened ( Hndl, FileName , FileStatus, Status )
  869. #endif
  870. #ifdef XXX
  871. CASE ( IO_XXX )
  872. CALL ext_xxx_inquire_opened ( Hndl, FileName , FileStatus, Status )
  873. #endif
  874. #ifdef YYY
  875. CASE ( IO_YYY )
  876. IF (wrf_dm_on_monitor()) CALL ext_yyy_inquire_opened ( Hndl, FileName , FileStatus, Status )
  877. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  878. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  879. #endif
  880. #ifdef ZZZ
  881. CASE ( IO_ZZZ )
  882. CALL ext_zzz_inquire_opened ( Hndl, FileName , FileStatus, Status )
  883. #endif
  884. #ifdef GRIB1
  885. CASE ( IO_GRIB1 )
  886. IF (wrf_dm_on_monitor()) CALL ext_gr1_inquire_opened ( Hndl, FileName , FileStatus, Status )
  887. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  888. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  889. #endif
  890. #ifdef GRIB2
  891. CASE ( IO_GRIB2 )
  892. IF (wrf_dm_on_monitor()) CALL ext_gr2_inquire_opened ( Hndl, FileName , FileStatus, Status )
  893. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  894. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  895. #endif
  896. #ifdef INTIO
  897. CASE ( IO_INTIO )
  898. IF (wrf_dm_on_monitor()) CALL ext_int_inquire_opened ( Hndl, FileName , FileStatus, Status )
  899. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  900. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  901. #endif
  902. CASE DEFAULT
  903. FileStatus = WRF_FILE_NOT_OPENED
  904. Status = 0
  905. END SELECT
  906. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  907. CALL wrf_quilt_inquire_opened ( Hndl, FileName , FileStatus, Status )
  908. ENDIF
  909. ELSE
  910. FileStatus = WRF_FILE_NOT_OPENED
  911. Status = 0
  912. ENDIF
  913. RETURN
  914. END SUBROUTINE wrf_inquire_opened
  915. !--- inquire_filename
  916. SUBROUTINE wrf_inquire_filename ( DataHandle, FileName , FileStatus, Status )
  917. !<DESCRIPTION>
  918. !<PRE>
  919. ! Returns the Filename and FileStatus associated with DataHandle.
  920. !</PRE>
  921. !</DESCRIPTION>
  922. USE module_state_description
  923. IMPLICIT NONE
  924. INTEGER , INTENT(IN) :: DataHandle
  925. CHARACTER*(*) :: FileName
  926. INTEGER , INTENT(OUT) :: FileStatus
  927. INTEGER , INTENT(OUT) :: Status
  928. #include "wrf_status_codes.h"
  929. INTEGER, EXTERNAL :: use_package
  930. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  931. LOGICAL :: for_out
  932. INTEGER io_form , Hndl
  933. INTEGER :: str_length , str_count
  934. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_inquire_filename' )
  935. Status = 0
  936. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  937. IF ( Hndl .GT. -1 ) THEN
  938. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  939. SELECT CASE ( use_package( io_form ) )
  940. #ifdef NETCDF
  941. CASE ( IO_NETCDF )
  942. str_length = LEN ( FileName )
  943. DO str_count = 1 , str_length
  944. FileName(str_count:str_count) = ' '
  945. END DO
  946. IF (wrf_dm_on_monitor()) CALL ext_ncd_inquire_filename ( Hndl, FileName , FileStatus, Status )
  947. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  948. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  949. #endif
  950. #ifdef PHDF5
  951. CASE ( IO_PHDF5 )
  952. CALL ext_phdf5_inquire_filename ( Hndl, FileName , FileStatus, Status )
  953. #endif
  954. #ifdef PNETCDF
  955. CASE ( IO_PNETCDF )
  956. CALL ext_pnc_inquire_filename ( Hndl, FileName , FileStatus, Status )
  957. #endif
  958. #ifdef XXX
  959. CASE ( IO_XXX )
  960. CALL ext_xxx_inquire_filename ( Hndl, FileName , FileStatus, Status )
  961. #endif
  962. #ifdef YYY
  963. CASE ( IO_YYY )
  964. IF (wrf_dm_on_monitor()) CALL ext_yyy_inquire_filename ( Hndl, FileName , FileStatus, Status )
  965. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  966. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  967. #endif
  968. #ifdef ZZZ
  969. CASE ( IO_ZZZ )
  970. CALL ext_zzz_inquire_filename ( Hndl, FileName , FileStatus, Status )
  971. #endif
  972. #ifdef GRIB1
  973. CASE ( IO_GRIB1 )
  974. IF (wrf_dm_on_monitor()) CALL ext_gr1_inquire_filename ( Hndl, FileName , FileStatus, Status )
  975. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  976. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  977. #endif
  978. #ifdef GRIB2
  979. CASE ( IO_GRIB2 )
  980. IF (wrf_dm_on_monitor()) CALL ext_gr2_inquire_filename ( Hndl, FileName , FileStatus, Status )
  981. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  982. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  983. #endif
  984. #ifdef INTIO
  985. CASE ( IO_INTIO )
  986. IF (wrf_dm_on_monitor()) CALL ext_int_inquire_filename ( Hndl, FileName , FileStatus, Status )
  987. CALL wrf_dm_bcast_bytes( FileStatus, IWORDSIZE )
  988. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  989. #endif
  990. CASE DEFAULT
  991. Status = 0
  992. END SELECT
  993. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  994. CALL wrf_quilt_inquire_filename ( Hndl, FileName , FileStatus, Status )
  995. ENDIF
  996. ELSE
  997. FileName = ""
  998. Status = 0
  999. ENDIF
  1000. RETURN
  1001. END SUBROUTINE wrf_inquire_filename
  1002. !--- sync
  1003. SUBROUTINE wrf_iosync ( DataHandle, Status )
  1004. !<DESCRIPTION>
  1005. !<PRE>
  1006. ! Synchronize the disk copy of a dataset with memory buffers.
  1007. !</PRE>
  1008. !</DESCRIPTION>
  1009. USE module_state_description
  1010. IMPLICIT NONE
  1011. INTEGER , INTENT(IN) :: DataHandle
  1012. INTEGER , INTENT(OUT) :: Status
  1013. #include "wrf_status_codes.h"
  1014. INTEGER, EXTERNAL :: use_package
  1015. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  1016. LOGICAL :: for_out
  1017. INTEGER io_form , Hndl
  1018. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_iosync' )
  1019. Status = 0
  1020. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1021. IF ( Hndl .GT. -1 ) THEN
  1022. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  1023. SELECT CASE ( use_package(io_form) )
  1024. #ifdef NETCDF
  1025. CASE ( IO_NETCDF )
  1026. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_iosync( Hndl, Status )
  1027. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  1028. #endif
  1029. #ifdef XXX
  1030. CASE ( IO_XXX )
  1031. CALL ext_xxx_iosync( Hndl, Status )
  1032. #endif
  1033. #ifdef YYY
  1034. CASE ( IO_YYY )
  1035. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_iosync( Hndl, Status )
  1036. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  1037. #endif
  1038. #ifdef GRIB1
  1039. CASE ( IO_GRIB1 )
  1040. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_iosync( Hndl, Status )
  1041. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  1042. #endif
  1043. #ifdef GRIB2
  1044. CASE ( IO_GRIB2 )
  1045. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_iosync( Hndl, Status )
  1046. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  1047. #endif
  1048. #ifdef ZZZ
  1049. CASE ( IO_ZZZ )
  1050. CALL ext_zzz_iosync( Hndl, Status )
  1051. #endif
  1052. #ifdef INTIO
  1053. CASE ( IO_INTIO )
  1054. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_iosync( Hndl, Status )
  1055. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  1056. #endif
  1057. CASE DEFAULT
  1058. Status = 0
  1059. END SELECT
  1060. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  1061. CALL wrf_quilt_iosync( Hndl, Status )
  1062. ELSE
  1063. Status = 0
  1064. ENDIF
  1065. ELSE
  1066. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  1067. ENDIF
  1068. RETURN
  1069. END SUBROUTINE wrf_iosync
  1070. !--- close
  1071. SUBROUTINE wrf_ioclose ( DataHandle, Status )
  1072. !<DESCRIPTION>
  1073. !<PRE>
  1074. ! Close the dataset referenced by DataHandle.
  1075. !</PRE>
  1076. !</DESCRIPTION>
  1077. USE module_state_description
  1078. IMPLICIT NONE
  1079. INTEGER , INTENT(IN) :: DataHandle
  1080. INTEGER , INTENT(OUT) :: Status
  1081. #include "wrf_status_codes.h"
  1082. INTEGER, EXTERNAL :: use_package
  1083. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  1084. INTEGER io_form , Hndl
  1085. LOGICAL :: for_out
  1086. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_ioclose' )
  1087. Status = 0
  1088. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1089. IF ( Hndl .GT. -1 ) THEN
  1090. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  1091. SELECT CASE ( use_package(io_form) )
  1092. #ifdef NETCDF
  1093. CASE ( IO_NETCDF )
  1094. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_ioclose( Hndl, Status )
  1095. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1096. #endif
  1097. #ifdef PHDF5
  1098. CASE ( IO_PHDF5 )
  1099. CALL ext_phdf5_ioclose( Hndl, Status )
  1100. #endif
  1101. #ifdef PNETCDF
  1102. CASE ( IO_PNETCDF )
  1103. CALL ext_pnc_ioclose( Hndl, Status )
  1104. #endif
  1105. #ifdef XXX
  1106. CASE ( IO_XXX )
  1107. CALL ext_xxx_ioclose( Hndl, Status )
  1108. #endif
  1109. #ifdef YYY
  1110. CASE ( IO_YYY )
  1111. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_ioclose( Hndl, Status )
  1112. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1113. #endif
  1114. #ifdef ZZZ
  1115. CASE ( IO_ZZZ )
  1116. CALL ext_zzz_ioclose( Hndl, Status )
  1117. #endif
  1118. #ifdef GRIB1
  1119. CASE ( IO_GRIB1 )
  1120. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_ioclose( Hndl, Status )
  1121. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1122. #endif
  1123. #ifdef GRIB2
  1124. CASE ( IO_GRIB2 )
  1125. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_ioclose( Hndl, Status )
  1126. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1127. #endif
  1128. #ifdef MCELIO
  1129. CASE ( IO_MCEL )
  1130. CALL ext_mcel_ioclose( Hndl, Status )
  1131. #endif
  1132. #ifdef ESMFIO
  1133. CASE ( IO_ESMF )
  1134. CALL ext_esmf_ioclose( Hndl, Status )
  1135. #endif
  1136. #ifdef INTIO
  1137. CASE ( IO_INTIO )
  1138. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_ioclose( Hndl, Status )
  1139. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1140. #endif
  1141. CASE DEFAULT
  1142. Status = 0
  1143. END SELECT
  1144. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  1145. CALL wrf_quilt_ioclose( Hndl, Status )
  1146. ELSE
  1147. Status = 0
  1148. ENDIF
  1149. CALL free_handle( DataHandle )
  1150. ELSE
  1151. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  1152. ENDIF
  1153. RETURN
  1154. END SUBROUTINE wrf_ioclose
  1155. !--- get_next_time (not defined for IntIO )
  1156. SUBROUTINE wrf_get_next_time ( DataHandle, DateStr, Status )
  1157. !<DESCRIPTION>
  1158. !<PRE>
  1159. ! Returns the next time stamp.
  1160. !</PRE>
  1161. !</DESCRIPTION>
  1162. USE module_state_description
  1163. IMPLICIT NONE
  1164. INTEGER , INTENT(IN) :: DataHandle
  1165. CHARACTER*(*) :: DateStr
  1166. INTEGER , INTENT(OUT) :: Status
  1167. #include "wrf_status_codes.h"
  1168. INTEGER, EXTERNAL :: use_package
  1169. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  1170. INTEGER io_form , Hndl, len_of_str
  1171. LOGICAL :: for_out
  1172. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_next_time' )
  1173. Status = 0
  1174. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1175. IF ( Hndl .GT. -1 ) THEN
  1176. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  1177. SELECT CASE ( use_package(io_form) )
  1178. #ifdef NETCDF
  1179. CASE ( IO_NETCDF )
  1180. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_next_time( Hndl, DateStr, Status )
  1181. IF ( .NOT. multi_files(io_form) ) THEN
  1182. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1183. len_of_str = LEN(DateStr)
  1184. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1185. ENDIF
  1186. #endif
  1187. #ifdef PHDF5
  1188. CASE ( IO_PHDF5 )
  1189. CALL ext_phdf5_get_next_time( Hndl, DateStr, Status )
  1190. #endif
  1191. #ifdef PNETCDF
  1192. CASE ( IO_PNETCDF )
  1193. CALL ext_pnc_get_next_time( Hndl, DateStr, Status )
  1194. #endif
  1195. #ifdef XXX
  1196. CASE ( IO_XXX )
  1197. CALL ext_xxx_get_next_time( Hndl, DateStr, Status )
  1198. #endif
  1199. #ifdef YYY
  1200. CASE ( IO_YYY )
  1201. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_next_time( Hndl, DateStr, Status )
  1202. IF ( .NOT. multi_files(io_form) ) THEN
  1203. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1204. len_of_str = LEN(DateStr)
  1205. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1206. ENDIF
  1207. #endif
  1208. #ifdef ZZZ
  1209. CASE ( IO_ZZZ )
  1210. CALL ext_zzz_get_next_time( Hndl, DateStr, Status )
  1211. #endif
  1212. #ifdef GRIB1
  1213. CASE ( IO_GRIB1 )
  1214. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_next_time( Hndl, DateStr, Status )
  1215. IF ( .NOT. multi_files(io_form) ) THEN
  1216. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1217. len_of_str = LEN(DateStr)
  1218. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1219. ENDIF
  1220. #endif
  1221. #ifdef GRIB2
  1222. CASE ( IO_GRIB2 )
  1223. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_next_time( Hndl, DateStr, Status )
  1224. IF ( .NOT. multi_files(io_form) ) THEN
  1225. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1226. len_of_str = LEN(DateStr)
  1227. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1228. ENDIF
  1229. #endif
  1230. #ifdef INTIO
  1231. CASE ( IO_INTIO )
  1232. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_get_next_time( Hndl, DateStr, Status )
  1233. IF ( .NOT. multi_files(io_form) ) THEN
  1234. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1235. len_of_str = LEN(DateStr)
  1236. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1237. ENDIF
  1238. #endif
  1239. CASE DEFAULT
  1240. Status = 0
  1241. END SELECT
  1242. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  1243. CALL wrf_quilt_get_next_time( Hndl, DateStr, Status )
  1244. ELSE
  1245. Status = 0
  1246. ENDIF
  1247. ELSE
  1248. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  1249. ENDIF
  1250. RETURN
  1251. END SUBROUTINE wrf_get_next_time
  1252. !--- get_previous_time (not defined for IntIO )
  1253. SUBROUTINE wrf_get_previous_time ( DataHandle, DateStr, Status )
  1254. !<DESCRIPTION>
  1255. !<PRE>
  1256. ! Returns the previous time stamp.
  1257. !</PRE>
  1258. !</DESCRIPTION>
  1259. USE module_state_description
  1260. IMPLICIT NONE
  1261. INTEGER , INTENT(IN) :: DataHandle
  1262. CHARACTER*(*) :: DateStr
  1263. INTEGER , INTENT(OUT) :: Status
  1264. #include "wrf_status_codes.h"
  1265. INTEGER, EXTERNAL :: use_package
  1266. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  1267. INTEGER io_form , Hndl, len_of_str
  1268. LOGICAL :: for_out
  1269. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_previous_time' )
  1270. Status = 0
  1271. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1272. IF ( Hndl .GT. -1 ) THEN
  1273. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  1274. SELECT CASE ( use_package(io_form) )
  1275. #ifdef NETCDF
  1276. CASE ( IO_NETCDF )
  1277. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_previous_time( Hndl, DateStr, Status )
  1278. IF ( .NOT. multi_files(io_form) ) THEN
  1279. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1280. len_of_str = LEN(DateStr)
  1281. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1282. ENDIF
  1283. #endif
  1284. #ifdef PHDF5
  1285. CASE ( IO_PHDF5 )
  1286. CALL ext_phdf5_get_previous_time( Hndl, DateStr, Status )
  1287. #endif
  1288. #ifdef PNETCDF
  1289. CASE ( IO_PNETCDF )
  1290. CALL ext_pnc_get_previous_time( Hndl, DateStr, Status )
  1291. #endif
  1292. #ifdef XXX
  1293. CASE ( IO_XXX )
  1294. CALL ext_xxx_get_previous_time( Hndl, DateStr, Status )
  1295. #endif
  1296. #ifdef YYY
  1297. CASE ( IO_YYY )
  1298. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_previous_time( Hndl, DateStr, Status )
  1299. IF ( .NOT. multi_files(io_form) ) THEN
  1300. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1301. len_of_str = LEN(DateStr)
  1302. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1303. ENDIF
  1304. #endif
  1305. #ifdef ZZZ
  1306. CASE ( IO_ZZZ )
  1307. CALL ext_zzz_get_previous_time( Hndl, DateStr, Status )
  1308. #endif
  1309. #ifdef GRIB1
  1310. CASE ( IO_GRIB1 )
  1311. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_previous_time( Hndl, DateStr, Status )
  1312. IF ( .NOT. multi_files(io_form) ) THEN
  1313. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1314. len_of_str = LEN(DateStr)
  1315. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1316. ENDIF
  1317. #endif
  1318. #ifdef GRIB2
  1319. CASE ( IO_GRIB2 )
  1320. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_previous_time( Hndl, DateStr, Status )
  1321. IF ( .NOT. multi_files(io_form) ) THEN
  1322. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1323. len_of_str = LEN(DateStr)
  1324. CALL wrf_dm_bcast_string ( DateStr , len_of_str )
  1325. ENDIF
  1326. #endif
  1327. #ifdef INTIO
  1328. #endif
  1329. CASE DEFAULT
  1330. Status = 0
  1331. END SELECT
  1332. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  1333. CALL wrf_quilt_get_previous_time( Hndl, DateStr, Status )
  1334. ELSE
  1335. Status = 0
  1336. ENDIF
  1337. ELSE
  1338. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  1339. ENDIF
  1340. RETURN
  1341. END SUBROUTINE wrf_get_previous_time
  1342. !--- set_time
  1343. SUBROUTINE wrf_set_time ( DataHandle, DateStr, Status )
  1344. !<DESCRIPTION>
  1345. !<PRE>
  1346. ! Sets the time stamp.
  1347. !</PRE>
  1348. !</DESCRIPTION>
  1349. USE module_state_description
  1350. IMPLICIT NONE
  1351. INTEGER , INTENT(IN) :: DataHandle
  1352. CHARACTER*(*) :: DateStr
  1353. INTEGER , INTENT(OUT) :: Status
  1354. #include "wrf_status_codes.h"
  1355. INTEGER, EXTERNAL :: use_package
  1356. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  1357. INTEGER io_form , Hndl
  1358. LOGICAL :: for_out
  1359. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_set_time' )
  1360. Status = 0
  1361. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1362. IF ( Hndl .GT. -1 ) THEN
  1363. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  1364. SELECT CASE ( use_package( io_form ) )
  1365. #ifdef NETCDF
  1366. CASE ( IO_NETCDF )
  1367. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_set_time( Hndl, DateStr, Status )
  1368. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1369. #endif
  1370. #ifdef PHDF5
  1371. CASE ( IO_PHDF5 )
  1372. CALL ext_phdf5_set_time( Hndl, DateStr, Status )
  1373. #endif
  1374. #ifdef PNETCDF
  1375. CASE ( IO_PNETCDF )
  1376. CALL ext_pnc_set_time( Hndl, DateStr, Status )
  1377. #endif
  1378. #ifdef XXX
  1379. CASE ( IO_XXX )
  1380. CALL ext_xxx_set_time( Hndl, DateStr, Status )
  1381. #endif
  1382. #ifdef YYY
  1383. CASE ( IO_YYY )
  1384. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_set_time( Hndl, DateStr, Status )
  1385. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1386. #endif
  1387. #ifdef ZZZ
  1388. CASE ( IO_ZZZ )
  1389. CALL ext_zzz_set_time( Hndl, DateStr, Status )
  1390. #endif
  1391. #ifdef GRIB1
  1392. CASE ( IO_GRIB1 )
  1393. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_set_time( Hndl, DateStr, Status )
  1394. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1395. #endif
  1396. #ifdef GRIB2
  1397. CASE ( IO_GRIB2 )
  1398. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_set_time( Hndl, DateStr, Status )
  1399. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1400. #endif
  1401. #ifdef INTIO
  1402. CASE ( IO_INTIO )
  1403. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_set_time( Hndl, DateStr, Status )
  1404. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1405. #endif
  1406. CASE DEFAULT
  1407. Status = 0
  1408. END SELECT
  1409. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  1410. CALL wrf_quilt_set_time( Hndl, DateStr, Status )
  1411. ELSE
  1412. Status = 0
  1413. ENDIF
  1414. ELSE
  1415. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  1416. ENDIF
  1417. RETURN
  1418. END SUBROUTINE wrf_set_time
  1419. !--- get_next_var (not defined for IntIO)
  1420. SUBROUTINE wrf_get_next_var ( DataHandle, VarName, Status )
  1421. !<DESCRIPTION>
  1422. !<PRE>
  1423. ! On reading, this routine returns the name of the next variable in the
  1424. ! current time frame.
  1425. !</PRE>
  1426. !</DESCRIPTION>
  1427. USE module_state_description
  1428. IMPLICIT NONE
  1429. INTEGER , INTENT(IN) :: DataHandle
  1430. CHARACTER*(*) :: VarName
  1431. INTEGER , INTENT(OUT) :: Status
  1432. #include "wrf_status_codes.h"
  1433. INTEGER, EXTERNAL :: use_package
  1434. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  1435. INTEGER io_form , Hndl
  1436. LOGICAL :: for_out
  1437. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_next_var' )
  1438. Status = 0
  1439. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1440. IF ( Hndl .GT. -1 ) THEN
  1441. IF ( multi_files( io_form ) .OR. .NOT. (for_out .AND. use_output_servers()) ) THEN
  1442. SELECT CASE ( use_package( io_form ) )
  1443. #ifdef NETCDF
  1444. CASE ( IO_NETCDF )
  1445. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_ncd_get_next_var( Hndl, VarName, Status )
  1446. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1447. #endif
  1448. #ifdef XXX
  1449. CASE ( IO_XXX )
  1450. CALL ext_xxx_get_next_var( Hndl, VarName, Status )
  1451. #endif
  1452. #ifdef YYY
  1453. CASE ( IO_YYY )
  1454. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_yyy_get_next_var( Hndl, VarName, Status )
  1455. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1456. #endif
  1457. #ifdef ZZZ
  1458. CASE ( IO_ZZZ )
  1459. CALL ext_zzz_get_next_var( Hndl, VarName, Status )
  1460. #endif
  1461. #ifdef GRIB1
  1462. CASE ( IO_GRIB1 )
  1463. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr1_get_next_var( Hndl, VarName, Status )
  1464. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1465. #endif
  1466. #ifdef GRIB2
  1467. CASE ( IO_GRIB2 )
  1468. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_gr2_get_next_var( Hndl, VarName, Status )
  1469. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1470. #endif
  1471. #ifdef INTIO
  1472. CASE ( IO_INTIO )
  1473. IF ( multi_files(io_form) .OR. wrf_dm_on_monitor() ) CALL ext_int_get_next_var( Hndl, VarName, Status )
  1474. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  1475. #endif
  1476. CASE DEFAULT
  1477. Status = 0
  1478. END SELECT
  1479. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  1480. CALL wrf_quilt_get_next_var( Hndl, VarName, Status )
  1481. ELSE
  1482. Status = 0
  1483. ENDIF
  1484. ELSE
  1485. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  1486. ENDIF
  1487. RETURN
  1488. END SUBROUTINE wrf_get_next_var
  1489. ! wrf_get_var_info (not implemented for IntIO)
  1490. SUBROUTINE wrf_get_var_info ( DataHandle , VarName , NDim , MemoryOrder , Stagger , &
  1491. DomainStart , DomainEnd , Status )
  1492. !<DESCRIPTION>
  1493. !<PRE>
  1494. ! This routine applies only to a dataset that is open for read. It returns
  1495. ! information about a variable.
  1496. !</PRE>
  1497. !</DESCRIPTION>
  1498. USE module_state_description
  1499. IMPLICIT NONE
  1500. INTEGER ,INTENT(IN) :: DataHandle
  1501. CHARACTER*(*) ,INTENT(IN) :: VarName
  1502. INTEGER ,INTENT(OUT) :: NDim
  1503. CHARACTER*(*) ,INTENT(OUT) :: MemoryOrder
  1504. CHARACTER*(*) ,INTENT(OUT) :: Stagger
  1505. INTEGER ,dimension(*) ,INTENT(OUT) :: DomainStart, DomainEnd
  1506. INTEGER ,INTENT(OUT) :: Status
  1507. #include "wrf_status_codes.h"
  1508. INTEGER io_form , Hndl
  1509. LOGICAL :: for_out
  1510. INTEGER, EXTERNAL :: use_package
  1511. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  1512. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_get_var_info' )
  1513. Status = 0
  1514. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1515. IF ( Hndl .GT. -1 ) THEN
  1516. IF (( multi_files(io_form) .OR. wrf_dm_on_monitor() ) .AND. .NOT. (for_out .AND. use_output_servers()) ) THEN
  1517. SELECT CASE ( use_package( io_form ) )
  1518. #ifdef NETCDF
  1519. CASE ( IO_NETCDF )
  1520. CALL ext_ncd_get_var_info ( Hndl , VarName , NDim , &
  1521. MemoryOrder , Stagger , &
  1522. DomainStart , DomainEnd , &
  1523. Status )
  1524. #endif
  1525. #ifdef PHDF5
  1526. CASE ( IO_PHDF5)
  1527. CALL ext_phdf5_get_var_info ( Hndl , VarName , NDim , &
  1528. MemoryOrder , Stagger , &
  1529. DomainStart , DomainEnd , &
  1530. Status )
  1531. #endif
  1532. #ifdef PNETCDF
  1533. CASE ( IO_PNETCDF)
  1534. CALL ext_pnc_get_var_info ( Hndl , VarName , NDim , &
  1535. MemoryOrder , Stagger , &
  1536. DomainStart , DomainEnd , &
  1537. Status )
  1538. #endif
  1539. #ifdef XXX
  1540. CASE ( IO_XXX )
  1541. CALL ext_xxx_get_var_info ( Hndl , VarName , NDim , &
  1542. MemoryOrder , Stagger , &
  1543. DomainStart , DomainEnd , &
  1544. Status )
  1545. #endif
  1546. #ifdef YYY
  1547. CASE ( IO_YYY )
  1548. CALL ext_yyy_get_var_info ( Hndl , VarName , NDim , &
  1549. MemoryOrder , Stagger , &
  1550. DomainStart , DomainEnd , &
  1551. Status )
  1552. #endif
  1553. #ifdef GRIB1
  1554. CASE ( IO_GRIB1 )
  1555. CALL ext_gr1_get_var_info ( Hndl , VarName , NDim , &
  1556. MemoryOrder , Stagger , &
  1557. DomainStart , DomainEnd , &
  1558. Status )
  1559. #endif
  1560. #ifdef GRIB2
  1561. CASE ( IO_GRIB2 )
  1562. CALL ext_gr2_get_var_info ( Hndl , VarName , NDim , &
  1563. MemoryOrder , Stagger , &
  1564. DomainStart , DomainEnd , &
  1565. Status )
  1566. #endif
  1567. CASE DEFAULT
  1568. Status = 0
  1569. END SELECT
  1570. ELSE IF ( io_form .GT. 0 .AND. for_out .AND. use_output_servers() ) THEN
  1571. CALL wrf_quilt_get_var_info ( Hndl , VarName , NDim , &
  1572. MemoryOrder , Stagger , &
  1573. DomainStart , DomainEnd , &
  1574. Status )
  1575. ELSE
  1576. Status = 0
  1577. ENDIF
  1578. ELSE
  1579. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  1580. ENDIF
  1581. RETURN
  1582. END SUBROUTINE wrf_get_var_info
  1583. !---------------------------------------------------------------------------------
  1584. SUBROUTINE init_io_handles()
  1585. !<DESCRIPTION>
  1586. !<PRE>
  1587. ! Initialize all I/O handles.
  1588. !</PRE>
  1589. !</DESCRIPTION>
  1590. IMPLICIT NONE
  1591. INTEGER i
  1592. IF ( .NOT. is_inited ) THEN
  1593. DO i = 1, MAX_WRF_IO_HANDLE
  1594. wrf_io_handles(i) = -999319
  1595. ENDDO
  1596. is_inited = .TRUE.
  1597. ENDIF
  1598. RETURN
  1599. END SUBROUTINE init_io_handles
  1600. SUBROUTINE add_new_handle( Hndl, Hopened, for_out, DataHandle )
  1601. !<DESCRIPTION>
  1602. !<PRE>
  1603. ! Stash the package-specific I/O handle (Hndl) and return a WRF I/O handle
  1604. ! (DataHandle).
  1605. ! File format ID is passed in via Hopened.
  1606. ! for_out will be .TRUE. if this routine was called from an
  1607. ! open-for-read/write-begin operation and .FALSE. otherwise.
  1608. !</PRE>
  1609. !</DESCRIPTION>
  1610. IMPLICIT NONE
  1611. INTEGER, INTENT(IN) :: Hndl
  1612. INTEGER, INTENT(IN) :: Hopened
  1613. LOGICAL, INTENT(IN) :: for_out
  1614. INTEGER, INTENT(OUT) :: DataHandle
  1615. INTEGER i
  1616. INTEGER, EXTERNAL :: use_package
  1617. LOGICAL, EXTERNAL :: multi_files
  1618. IF ( .NOT. is_inited ) THEN
  1619. CALL wrf_error_fatal( 'add_new_handle: not initialized' )
  1620. ENDIF
  1621. IF ( multi_files( Hopened ) ) THEN
  1622. SELECT CASE ( use_package( Hopened ) )
  1623. CASE ( IO_PHDF5 )
  1624. CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for PHDF5' )
  1625. CASE ( IO_PNETCDF )
  1626. CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for PNETCDF' )
  1627. #ifdef MCELIO
  1628. CASE ( IO_MCEL )
  1629. CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for MCEL' )
  1630. #endif
  1631. #ifdef ESMFIO
  1632. CASE ( IO_ESMF )
  1633. CALL wrf_error_fatal( 'add_new_handle: multiple output files not supported for ESMF' )
  1634. #endif
  1635. END SELECT
  1636. ENDIF
  1637. DataHandle = -1
  1638. DO i = 1, MAX_WRF_IO_HANDLE
  1639. IF ( wrf_io_handles(i) .EQ. -999319 ) THEN
  1640. DataHandle = i
  1641. wrf_io_handles(i) = Hndl
  1642. how_opened(i) = Hopened
  1643. for_output(DataHandle) = for_out
  1644. first_operation(DataHandle) = .TRUE.
  1645. EXIT
  1646. ENDIF
  1647. ENDDO
  1648. IF ( DataHandle .EQ. -1 ) THEN
  1649. CALL wrf_error_fatal( 'add_new_handle: no handles left' )
  1650. ENDIF
  1651. RETURN
  1652. END SUBROUTINE add_new_handle
  1653. SUBROUTINE get_handle ( Hndl, Hopened, for_out, DataHandle )
  1654. !<DESCRIPTION>
  1655. !<PRE>
  1656. ! Return the package-specific handle (Hndl) from a WRF handle
  1657. ! (DataHandle).
  1658. ! Return file format ID via Hopened.
  1659. ! Also, for_out will be set to .TRUE. if the file was opened
  1660. ! with an open-for-read/write-begin operation and .FALSE.
  1661. ! otherwise.
  1662. !</PRE>
  1663. !</DESCRIPTION>
  1664. IMPLICIT NONE
  1665. INTEGER, INTENT(OUT) :: Hndl
  1666. INTEGER, INTENT(OUT) :: Hopened
  1667. LOGICAL, INTENT(OUT) :: for_out
  1668. INTEGER, INTENT(IN) :: DataHandle
  1669. CHARACTER*128 mess
  1670. INTEGER i
  1671. IF ( .NOT. is_inited ) THEN
  1672. CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
  1673. ENDIF
  1674. IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
  1675. Hndl = wrf_io_handles(DataHandle)
  1676. Hopened = how_opened(DataHandle)
  1677. for_out = for_output(DataHandle)
  1678. ELSE
  1679. Hndl = -1
  1680. ENDIF
  1681. RETURN
  1682. END SUBROUTINE get_handle
  1683. SUBROUTINE set_first_operation( DataHandle )
  1684. !<DESCRIPTION>
  1685. !<PRE>
  1686. ! Sets internal flag to indicate that the first read or write has not yet
  1687. ! happened for the dataset referenced by DataHandle.
  1688. !</PRE>
  1689. !</DESCRIPTION>
  1690. IMPLICIT NONE
  1691. INTEGER, INTENT(IN) :: DataHandle
  1692. IF ( .NOT. is_inited ) THEN
  1693. CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
  1694. ENDIF
  1695. IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
  1696. first_operation(DataHandle) = .TRUE.
  1697. ENDIF
  1698. RETURN
  1699. END SUBROUTINE set_first_operation
  1700. SUBROUTINE reset_first_operation( DataHandle )
  1701. !<DESCRIPTION>
  1702. !<PRE>
  1703. ! Resets internal flag to indicate that the first read or write has already
  1704. ! happened for the dataset referenced by DataHandle.
  1705. !</PRE>
  1706. !</DESCRIPTION>
  1707. IMPLICIT NONE
  1708. INTEGER, INTENT(IN) :: DataHandle
  1709. IF ( .NOT. is_inited ) THEN
  1710. CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
  1711. ENDIF
  1712. IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
  1713. first_operation(DataHandle) = .FALSE.
  1714. ENDIF
  1715. RETURN
  1716. END SUBROUTINE reset_first_operation
  1717. LOGICAL FUNCTION is_first_operation( DataHandle )
  1718. !<DESCRIPTION>
  1719. !<PRE>
  1720. ! Returns .TRUE. the first read or write has not yet happened for the dataset
  1721. ! referenced by DataHandle.
  1722. !</PRE>
  1723. !</DESCRIPTION>
  1724. IMPLICIT NONE
  1725. INTEGER, INTENT(IN) :: DataHandle
  1726. IF ( .NOT. is_inited ) THEN
  1727. CALL wrf_error_fatal( 'module_io.F: get_handle: not initialized' )
  1728. ENDIF
  1729. IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
  1730. is_first_operation = first_operation(DataHandle)
  1731. ENDIF
  1732. RETURN
  1733. END FUNCTION is_first_operation
  1734. SUBROUTINE free_handle ( DataHandle )
  1735. !<DESCRIPTION>
  1736. !<PRE>
  1737. ! Trash a handle and return to "unused" pool.
  1738. !</PRE>
  1739. !</DESCRIPTION>
  1740. IMPLICIT NONE
  1741. INTEGER, INTENT(IN) :: DataHandle
  1742. INTEGER i
  1743. IF ( .NOT. is_inited ) THEN
  1744. CALL wrf_error_fatal( 'free_handle: not initialized' )
  1745. ENDIF
  1746. IF ( DataHandle .GE. 1 .AND. DataHandle .LE. MAX_WRF_IO_HANDLE ) THEN
  1747. wrf_io_handles(DataHandle) = -999319
  1748. ENDIF
  1749. RETURN
  1750. END SUBROUTINE free_handle
  1751. !--------------------------------------------------------------
  1752. SUBROUTINE init_module_io
  1753. !<DESCRIPTION>
  1754. !<PRE>
  1755. ! Initialize this module. Must be called before any other operations are
  1756. ! attempted.
  1757. !</PRE>
  1758. !</DESCRIPTION>
  1759. CALL init_io_handles
  1760. END SUBROUTINE init_module_io
  1761. SUBROUTINE are_bdys_distributed( res )
  1762. IMPLICIT NONE
  1763. LOGICAL, INTENT(OUT) :: res
  1764. res = bdy_dist_flag
  1765. END SUBROUTINE are_bdys_distributed
  1766. SUBROUTINE bdys_not_distributed
  1767. IMPLICIT NONE
  1768. bdy_dist_flag = .FALSE.
  1769. END SUBROUTINE bdys_not_distributed
  1770. SUBROUTINE bdys_are_distributed
  1771. IMPLICIT NONE
  1772. bdy_dist_flag = .TRUE.
  1773. END SUBROUTINE bdys_are_distributed
  1774. LOGICAL FUNCTION on_stream ( mask , switch )
  1775. IMPLICIT NONE
  1776. INTEGER, INTENT(IN) :: mask(*), switch
  1777. INTEGER :: result
  1778. ! get_mask is a C routine defined in frame/pack_utils.c
  1779. ! switch is decremented from its fortran value so it is zero based
  1780. CALL get_mask( mask, switch-1, result )
  1781. on_stream = ( result .NE. 0 )
  1782. END FUNCTION on_stream
  1783. END MODULE module_io
  1784. !<DESCRIPTION>
  1785. !<PRE>
  1786. ! Remaining routines in this file are defined outside of the module to
  1787. ! defeat arg/param type checking.
  1788. !</PRE>
  1789. !</DESCRIPTION>
  1790. SUBROUTINE wrf_read_field ( DataHandle , DateStr , VarName , Field , FieldType , &
  1791. Comm , IOComm , &
  1792. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1793. DomainStart , DomainEnd , &
  1794. MemoryStart , MemoryEnd , &
  1795. PatchStart , PatchEnd , &
  1796. Status )
  1797. !<DESCRIPTION>
  1798. !<PRE>
  1799. ! Read the variable named VarName from the dataset pointed to by DataHandle.
  1800. ! This routine is a wrapper that ensures uniform treatment of logicals across
  1801. ! platforms by reading as integer and then converting to logical.
  1802. !</PRE>
  1803. !</DESCRIPTION>
  1804. USE module_state_description
  1805. USE module_configure
  1806. IMPLICIT NONE
  1807. INTEGER , INTENT(IN) :: DataHandle
  1808. CHARACTER*(*) :: DateStr
  1809. CHARACTER*(*) :: VarName
  1810. LOGICAL , INTENT(INOUT) :: Field(*)
  1811. INTEGER ,INTENT(IN) :: FieldType
  1812. INTEGER ,INTENT(INOUT) :: Comm
  1813. INTEGER ,INTENT(INOUT) :: IOComm
  1814. INTEGER ,INTENT(IN) :: DomainDesc
  1815. LOGICAL, DIMENSION(4) :: bdy_mask
  1816. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  1817. CHARACTER*(*) ,INTENT(IN) :: Stagger
  1818. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  1819. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  1820. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  1821. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  1822. INTEGER ,INTENT(OUT) :: Status
  1823. #include "wrf_status_codes.h"
  1824. #include "wrf_io_flags.h"
  1825. INTEGER, ALLOCATABLE :: ICAST(:)
  1826. LOGICAL perturb_input
  1827. IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  1828. ALLOCATE(ICAST((MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)))
  1829. CALL wrf_read_field1 ( DataHandle , DateStr , VarName , ICAST , WRF_INTEGER , &
  1830. Comm , IOComm , &
  1831. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1832. DomainStart , DomainEnd , &
  1833. MemoryStart , MemoryEnd , &
  1834. PatchStart , PatchEnd , &
  1835. Status )
  1836. Field(1:(MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)) = ICAST == 1
  1837. DEALLOCATE(ICAST)
  1838. ELSE
  1839. CALL wrf_read_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
  1840. Comm , IOComm , &
  1841. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1842. DomainStart , DomainEnd , &
  1843. MemoryStart , MemoryEnd , &
  1844. PatchStart , PatchEnd , &
  1845. Status )
  1846. CALL nl_get_perturb_input( 1, perturb_input )
  1847. IF ( perturb_input .AND. FieldType .EQ. WRF_FLOAT .AND. TRIM(MemoryOrder) .EQ. 'XZY' ) THEN
  1848. CALL perturb_real ( Field, DomainStart, DomainEnd, &
  1849. MemoryStart, MemoryEnd, &
  1850. PatchStart, PatchEnd )
  1851. ENDIF
  1852. ENDIF
  1853. END SUBROUTINE wrf_read_field
  1854. SUBROUTINE wrf_read_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
  1855. Comm , IOComm , &
  1856. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1857. DomainStart , DomainEnd , &
  1858. MemoryStart , MemoryEnd , &
  1859. PatchStart , PatchEnd , &
  1860. Status )
  1861. !<DESCRIPTION>
  1862. !<PRE>
  1863. ! Read the variable named VarName from the dataset pointed to by DataHandle.
  1864. ! Calls ext_pkg_read_field() via call_pkg_and_dist().
  1865. !</PRE>
  1866. !</DESCRIPTION>
  1867. USE module_state_description
  1868. USE module_configure
  1869. USE module_io
  1870. IMPLICIT NONE
  1871. INTEGER , INTENT(IN) :: DataHandle
  1872. CHARACTER*(*) :: DateStr
  1873. CHARACTER*(*) :: VarName
  1874. INTEGER , INTENT(INOUT) :: Field(*)
  1875. INTEGER ,INTENT(IN) :: FieldType
  1876. INTEGER ,INTENT(INOUT) :: Comm
  1877. INTEGER ,INTENT(INOUT) :: IOComm
  1878. INTEGER ,INTENT(IN) :: DomainDesc
  1879. LOGICAL, DIMENSION(4) :: bdy_mask
  1880. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  1881. CHARACTER*(*) ,INTENT(IN) :: Stagger
  1882. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  1883. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  1884. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  1885. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  1886. INTEGER ,INTENT(OUT) :: Status
  1887. #include "wrf_status_codes.h"
  1888. INTEGER io_form , Hndl
  1889. LOGICAL :: for_out
  1890. INTEGER, EXTERNAL :: use_package
  1891. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers, use_input_servers
  1892. #ifdef NETCDF
  1893. EXTERNAL ext_ncd_read_field
  1894. #endif
  1895. #ifdef MCELIO
  1896. EXTERNAL ext_mcel_read_field
  1897. #endif
  1898. #ifdef ESMFIO
  1899. EXTERNAL ext_esmf_read_field
  1900. #endif
  1901. #ifdef INTIO
  1902. EXTERNAL ext_int_read_field
  1903. #endif
  1904. #ifdef XXX
  1905. EXTERNAL ext_xxx_read_field
  1906. #endif
  1907. #ifdef YYY
  1908. EXTERNAL ext_yyy_read_field
  1909. #endif
  1910. #ifdef GRIB1
  1911. EXTERNAL ext_gr1_read_field
  1912. #endif
  1913. #ifdef GRIB2
  1914. EXTERNAL ext_gr2_read_field
  1915. #endif
  1916. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_read_field' )
  1917. Status = 0
  1918. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  1919. CALL reset_first_operation( DataHandle )
  1920. IF ( Hndl .GT. -1 ) THEN
  1921. IF ( .NOT. io_form .GT. 0 ) THEN
  1922. Status = 0
  1923. ELSE IF ( .NOT. use_input_servers() ) THEN
  1924. SELECT CASE ( use_package( io_form ) )
  1925. #ifdef NETCDF
  1926. CASE ( IO_NETCDF )
  1927. CALL call_pkg_and_dist ( ext_ncd_read_field, multi_files(io_form), .false. , &
  1928. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1929. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1930. DomainStart , DomainEnd , &
  1931. MemoryStart , MemoryEnd , &
  1932. PatchStart , PatchEnd , &
  1933. Status )
  1934. #endif
  1935. #ifdef PHDF5
  1936. CASE ( IO_PHDF5)
  1937. CALL ext_phdf5_read_field ( &
  1938. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1939. DomainDesc , MemoryOrder , Stagger , DimNames , &
  1940. DomainStart , DomainEnd , &
  1941. MemoryStart , MemoryEnd , &
  1942. PatchStart , PatchEnd , &
  1943. Status )
  1944. #endif
  1945. #ifdef PNETCDF
  1946. CASE ( IO_PNETCDF)
  1947. CALL ext_pnc_read_field ( &
  1948. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1949. DomainDesc , MemoryOrder , Stagger , DimNames , &
  1950. DomainStart , DomainEnd , &
  1951. MemoryStart , MemoryEnd , &
  1952. PatchStart , PatchEnd , &
  1953. Status )
  1954. #endif
  1955. #ifdef MCELIO
  1956. CASE ( IO_MCEL )
  1957. CALL call_pkg_and_dist ( ext_mcel_read_field, multi_files(io_form), .true. , &
  1958. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1959. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1960. DomainStart , DomainEnd , &
  1961. MemoryStart , MemoryEnd , &
  1962. PatchStart , PatchEnd , &
  1963. Status )
  1964. #endif
  1965. #ifdef ESMFIO
  1966. CASE ( IO_ESMF )
  1967. CALL ext_esmf_read_field( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1968. DomainDesc , MemoryOrder , Stagger , DimNames , &
  1969. DomainStart , DomainEnd , &
  1970. MemoryStart , MemoryEnd , &
  1971. PatchStart , PatchEnd , &
  1972. Status )
  1973. #endif
  1974. #ifdef XXX
  1975. CASE ( IO_XXX )
  1976. CALL call_pkg_and_dist ( ext_xxx_read_field, multi_files(io_form), .false., &
  1977. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1978. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1979. DomainStart , DomainEnd , &
  1980. MemoryStart , MemoryEnd , &
  1981. PatchStart , PatchEnd , &
  1982. Status )
  1983. #endif
  1984. #ifdef YYY
  1985. CASE ( IO_YYY )
  1986. CALL call_pkg_and_dist ( ext_yyy_read_field, multi_files(io_form), .false., &
  1987. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1988. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1989. DomainStart , DomainEnd , &
  1990. MemoryStart , MemoryEnd , &
  1991. PatchStart , PatchEnd , &
  1992. Status )
  1993. #endif
  1994. #ifdef INTIO
  1995. CASE ( IO_INTIO )
  1996. CALL call_pkg_and_dist ( ext_int_read_field, multi_files(io_form), .false., &
  1997. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  1998. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  1999. DomainStart , DomainEnd , &
  2000. MemoryStart , MemoryEnd , &
  2001. PatchStart , PatchEnd , &
  2002. Status )
  2003. #endif
  2004. #ifdef GRIB1
  2005. CASE ( IO_GRIB1 )
  2006. CALL call_pkg_and_dist ( ext_gr1_read_field, multi_files(io_form), .false., &
  2007. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2008. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2009. DomainStart , DomainEnd , &
  2010. MemoryStart , MemoryEnd , &
  2011. PatchStart , PatchEnd , &
  2012. Status )
  2013. #endif
  2014. #ifdef GRIB2
  2015. CASE ( IO_GRIB2 )
  2016. CALL call_pkg_and_dist ( ext_gr2_read_field, multi_files(io_form), .false., &
  2017. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2018. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2019. DomainStart , DomainEnd , &
  2020. MemoryStart , MemoryEnd , &
  2021. PatchStart , PatchEnd , &
  2022. Status )
  2023. #endif
  2024. CASE DEFAULT
  2025. Status = 0
  2026. END SELECT
  2027. ELSE
  2028. CALL wrf_error_fatal('module_io.F: wrf_read_field: input_servers not implemented yet')
  2029. ENDIF
  2030. ELSE
  2031. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  2032. ENDIF
  2033. RETURN
  2034. END SUBROUTINE wrf_read_field1
  2035. SUBROUTINE wrf_write_field ( DataHandle , DateStr , VarName , Field , FieldType , &
  2036. Comm , IOComm , &
  2037. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2038. DomainStart , DomainEnd , &
  2039. MemoryStart , MemoryEnd , &
  2040. PatchStart , PatchEnd , &
  2041. Status )
  2042. !<DESCRIPTION>
  2043. !<PRE>
  2044. ! Write the variable named VarName to the dataset pointed to by DataHandle.
  2045. ! This routine is a wrapper that ensures uniform treatment of logicals across
  2046. ! platforms by converting to integer before writing.
  2047. !</PRE>
  2048. !</DESCRIPTION>
  2049. USE module_state_description
  2050. USE module_configure
  2051. IMPLICIT NONE
  2052. INTEGER , INTENT(IN) :: DataHandle
  2053. CHARACTER*(*) :: DateStr
  2054. CHARACTER*(*) :: VarName
  2055. LOGICAL , INTENT(IN) :: Field(*)
  2056. INTEGER ,INTENT(IN) :: FieldType
  2057. INTEGER ,INTENT(INOUT) :: Comm
  2058. INTEGER ,INTENT(INOUT) :: IOComm
  2059. INTEGER ,INTENT(IN) :: DomainDesc
  2060. LOGICAL, DIMENSION(4) ,INTENT(IN) :: bdy_mask
  2061. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2062. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2063. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2064. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2065. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2066. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2067. INTEGER ,INTENT(OUT) :: Status
  2068. #include "wrf_status_codes.h"
  2069. #include "wrf_io_flags.h"
  2070. INTEGER, ALLOCATABLE :: ICAST(:)
  2071. IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  2072. ALLOCATE(ICAST((MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)))
  2073. ICAST = 0
  2074. WHERE ( Field(1:(MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)) )
  2075. ICAST = 1
  2076. END WHERE
  2077. CALL wrf_write_field1 ( DataHandle , DateStr , VarName , ICAST , WRF_INTEGER , &
  2078. Comm , IOComm , &
  2079. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2080. DomainStart , DomainEnd , &
  2081. MemoryStart , MemoryEnd , &
  2082. PatchStart , PatchEnd , &
  2083. Status )
  2084. DEALLOCATE(ICAST)
  2085. ELSE
  2086. CALL wrf_write_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
  2087. Comm , IOComm , &
  2088. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2089. DomainStart , DomainEnd , &
  2090. MemoryStart , MemoryEnd , &
  2091. PatchStart , PatchEnd , &
  2092. Status )
  2093. ENDIF
  2094. END SUBROUTINE wrf_write_field
  2095. SUBROUTINE wrf_write_field1 ( DataHandle , DateStr , VarName , Field , FieldType , &
  2096. Comm , IOComm , &
  2097. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2098. DomainStart , DomainEnd , &
  2099. MemoryStart , MemoryEnd , &
  2100. PatchStart , PatchEnd , &
  2101. Status )
  2102. !<DESCRIPTION>
  2103. !<PRE>
  2104. ! Write the variable named VarName to the dataset pointed to by DataHandle.
  2105. ! Calls ext_pkg_write_field() via collect_fld_and_call_pkg().
  2106. !</PRE>
  2107. !</DESCRIPTION>
  2108. USE module_state_description
  2109. USE module_configure
  2110. USE module_io
  2111. IMPLICIT NONE
  2112. INTEGER , INTENT(IN) :: DataHandle
  2113. CHARACTER*(*) :: DateStr
  2114. CHARACTER*(*) :: VarName
  2115. INTEGER , INTENT(IN) :: Field(*)
  2116. INTEGER ,INTENT(IN) :: FieldType
  2117. INTEGER ,INTENT(INOUT) :: Comm
  2118. INTEGER ,INTENT(INOUT) :: IOComm
  2119. INTEGER ,INTENT(IN) :: DomainDesc
  2120. LOGICAL, DIMENSION(4) ,INTENT(IN) :: bdy_mask
  2121. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2122. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2123. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2124. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2125. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2126. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2127. INTEGER ,INTENT(OUT) :: Status
  2128. #include "wrf_status_codes.h"
  2129. INTEGER, DIMENSION(3) :: starts, ends
  2130. INTEGER io_form , Hndl
  2131. CHARACTER*3 MemOrd
  2132. LOGICAL :: for_out, okay_to_call
  2133. INTEGER, EXTERNAL :: use_package
  2134. LOGICAL, EXTERNAL :: wrf_dm_on_monitor, multi_files, use_output_servers
  2135. #ifdef NETCDF
  2136. EXTERNAL ext_ncd_write_field
  2137. #endif
  2138. #ifdef MCELIO
  2139. EXTERNAL ext_mcel_write_field
  2140. #endif
  2141. #ifdef ESMFIO
  2142. EXTERNAL ext_esmf_write_field
  2143. #endif
  2144. #ifdef INTIO
  2145. EXTERNAL ext_int_write_field
  2146. #endif
  2147. #ifdef XXX
  2148. EXTERNAL ext_xxx_write_field
  2149. #endif
  2150. #ifdef YYY
  2151. EXTERNAL ext_yyy_write_field
  2152. #endif
  2153. #ifdef GRIB1
  2154. EXTERNAL ext_gr1_write_field
  2155. #endif
  2156. #ifdef GRIB2
  2157. EXTERNAL ext_gr2_write_field
  2158. #endif
  2159. CALL wrf_debug( DEBUG_LVL, 'module_io.F: in wrf_write_field' )
  2160. Status = 0
  2161. CALL get_handle ( Hndl, io_form , for_out, DataHandle )
  2162. CALL reset_first_operation ( DataHandle )
  2163. IF ( Hndl .GT. -1 ) THEN
  2164. IF ( multi_files( io_form ) .OR. .NOT. use_output_servers() ) THEN
  2165. SELECT CASE ( use_package( io_form ) )
  2166. #ifdef NETCDF
  2167. CASE ( IO_NETCDF )
  2168. CALL collect_fld_and_call_pkg ( ext_ncd_write_field, multi_files(io_form), &
  2169. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2170. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2171. DomainStart , DomainEnd , &
  2172. MemoryStart , MemoryEnd , &
  2173. PatchStart , PatchEnd , &
  2174. Status )
  2175. #endif
  2176. #ifdef MCELIO
  2177. CASE ( IO_MCEL )
  2178. CALL collect_fld_and_call_pkg ( ext_mcel_write_field, multi_files(io_form), &
  2179. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2180. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2181. DomainStart , DomainEnd , &
  2182. MemoryStart , MemoryEnd , &
  2183. PatchStart , PatchEnd , &
  2184. Status )
  2185. #endif
  2186. #ifdef ESMFIO
  2187. CASE ( IO_ESMF )
  2188. CALL ext_esmf_write_field( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2189. DomainDesc , MemoryOrder , Stagger , DimNames , &
  2190. DomainStart , DomainEnd , &
  2191. MemoryStart , MemoryEnd , &
  2192. PatchStart , PatchEnd , &
  2193. Status )
  2194. #endif
  2195. #ifdef PHDF5
  2196. CASE ( IO_PHDF5 )
  2197. CALL ext_phdf5_write_field( &
  2198. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2199. DomainDesc , MemoryOrder , Stagger , DimNames , &
  2200. DomainStart , DomainEnd , &
  2201. MemoryStart , MemoryEnd , &
  2202. PatchStart , PatchEnd , &
  2203. Status )
  2204. #endif
  2205. #ifdef PNETCDF
  2206. CASE ( IO_PNETCDF )
  2207. CALL lower_case( MemoryOrder, MemOrd )
  2208. okay_to_call = .TRUE.
  2209. IF ((TRIM(MemOrd).EQ.'xsz' .OR. TRIM(MemOrd).EQ.'xs').AND. .NOT. bdy_mask(P_XSB)) okay_to_call = .FALSE.
  2210. IF ((TRIM(MemOrd).EQ.'xez' .OR. TRIM(MemOrd).EQ.'xe').AND. .NOT. bdy_mask(P_XEB)) okay_to_call = .FALSE.
  2211. IF ((TRIM(MemOrd).EQ.'ysz' .OR. TRIM(MemOrd).EQ.'ys').AND. .NOT. bdy_mask(P_YSB)) okay_to_call = .FALSE.
  2212. IF ((TRIM(MemOrd).EQ.'yez' .OR. TRIM(MemOrd).EQ.'ye').AND. .NOT. bdy_mask(P_YEB)) okay_to_call = .FALSE.
  2213. IF ( okay_to_call ) THEN
  2214. starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchEnd(1:3)
  2215. ELSE
  2216. starts(1:3) = PatchStart(1:3) ; ends(1:3) = PatchStart(1:3)-1
  2217. ENDIF
  2218. CALL ext_pnc_write_field( &
  2219. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2220. DomainDesc , MemoryOrder , Stagger , DimNames , &
  2221. DomainStart , DomainEnd , &
  2222. MemoryStart , MemoryEnd , &
  2223. starts , ends , &
  2224. Status )
  2225. #endif
  2226. #ifdef XXX
  2227. CASE ( IO_XXX )
  2228. CALL collect_fld_and_call_pkg ( ext_xxx_write_field, multi_files(io_form), &
  2229. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2230. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2231. DomainStart , DomainEnd , &
  2232. MemoryStart , MemoryEnd , &
  2233. PatchStart , PatchEnd , &
  2234. Status )
  2235. #endif
  2236. #ifdef YYY
  2237. CASE ( IO_YYY )
  2238. CALL collect_fld_and_call_pkg ( ext_yyy_write_field, multi_files(io_form), &
  2239. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2240. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2241. DomainStart , DomainEnd , &
  2242. MemoryStart , MemoryEnd , &
  2243. PatchStart , PatchEnd , &
  2244. Status )
  2245. #endif
  2246. #ifdef GRIB1
  2247. CASE ( IO_GRIB1 )
  2248. CALL collect_fld_and_call_pkg ( ext_gr1_write_field, multi_files(io_form), &
  2249. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2250. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2251. DomainStart , DomainEnd , &
  2252. MemoryStart , MemoryEnd , &
  2253. PatchStart , PatchEnd , &
  2254. Status )
  2255. #endif
  2256. #ifdef GRIB2
  2257. CASE ( IO_GRIB2 )
  2258. CALL collect_fld_and_call_pkg ( ext_gr2_write_field, multi_files(io_form), &
  2259. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2260. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2261. DomainStart , DomainEnd , &
  2262. MemoryStart , MemoryEnd , &
  2263. PatchStart , PatchEnd , &
  2264. Status )
  2265. #endif
  2266. #ifdef INTIO
  2267. CASE ( IO_INTIO )
  2268. CALL collect_fld_and_call_pkg ( ext_int_write_field, multi_files(io_form), &
  2269. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2270. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2271. DomainStart , DomainEnd , &
  2272. MemoryStart , MemoryEnd , &
  2273. PatchStart , PatchEnd , &
  2274. Status )
  2275. #endif
  2276. CASE DEFAULT
  2277. Status = 0
  2278. END SELECT
  2279. ELSE IF ( use_output_servers() ) THEN
  2280. IF ( io_form .GT. 0 ) THEN
  2281. CALL wrf_quilt_write_field ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2282. DomainDesc , MemoryOrder , Stagger , DimNames , &
  2283. DomainStart , DomainEnd , &
  2284. MemoryStart , MemoryEnd , &
  2285. PatchStart , PatchEnd , &
  2286. Status )
  2287. ENDIF
  2288. ENDIF
  2289. ELSE
  2290. Status = WRF_ERR_FATAL_BAD_FILE_STATUS
  2291. ENDIF
  2292. RETURN
  2293. END SUBROUTINE wrf_write_field1
  2294. SUBROUTINE get_value_from_pairs ( varname , str , retval )
  2295. !<DESCRIPTION>
  2296. !<PRE>
  2297. ! parse comma separated list of VARIABLE=VALUE strings and return the
  2298. ! value for the matching variable if such exists, otherwise return
  2299. ! the empty string
  2300. !</PRE>
  2301. !</DESCRIPTION>
  2302. IMPLICIT NONE
  2303. CHARACTER*(*) :: varname
  2304. CHARACTER*(*) :: str
  2305. CHARACTER*(*) :: retval
  2306. CHARACTER (128) varstr, tstr
  2307. INTEGER i,j,n,varstrn
  2308. LOGICAL nobreak, nobreakouter
  2309. varstr = TRIM(varname)//"="
  2310. varstrn = len(TRIM(varstr))
  2311. n = len(str)
  2312. retval = ""
  2313. i = 1
  2314. nobreakouter = .TRUE.
  2315. DO WHILE ( nobreakouter )
  2316. j = 1
  2317. nobreak = .TRUE.
  2318. tstr = ""
  2319. ! Potential for out of bounds array ref on str(i:i) for i > n; reported by jedwards
  2320. ! DO WHILE ( nobreak )
  2321. ! IF ( str(i:i) .NE. ',' .AND. i .LE. n ) THEN
  2322. ! tstr(j:j) = str(i:i)
  2323. ! ELSE
  2324. ! nobreak = .FALSE.
  2325. ! ENDIF
  2326. ! j = j + 1
  2327. ! i = i + 1
  2328. ! ENDDO
  2329. ! fix 20021112, JM
  2330. DO WHILE ( nobreak )
  2331. nobreak = .FALSE.
  2332. IF ( i .LE. n ) THEN
  2333. IF (str(i:i) .NE. ',' ) THEN
  2334. tstr(j:j) = str(i:i)
  2335. nobreak = .TRUE.
  2336. ENDIF
  2337. ENDIF
  2338. j = j + 1
  2339. i = i + 1
  2340. ENDDO
  2341. IF ( i .GT. n ) nobreakouter = .FALSE.
  2342. IF ( varstr(1:varstrn) .EQ. tstr(1:varstrn) ) THEN
  2343. retval(1:) = TRIM(tstr(varstrn+1:))
  2344. nobreakouter = .FALSE.
  2345. ENDIF
  2346. ENDDO
  2347. RETURN
  2348. END SUBROUTINE get_value_from_pairs
  2349. LOGICAL FUNCTION multi_files ( io_form )
  2350. !<DESCRIPTION>
  2351. !<PRE>
  2352. ! Returns .TRUE. iff io_form is a multi-file format. A multi-file format
  2353. ! results in one file for each compute process and can be used with any
  2354. ! I/O package. A multi-file dataset can only be read by the same number
  2355. ! of tasks that were used to write it. This feature can be useful for
  2356. ! speeding up restarts on machines that support efficient parallel I/O.
  2357. ! Multi-file formats cannot be used with I/O quilt servers.
  2358. !</PRE>
  2359. !</DESCRIPTION>
  2360. IMPLICIT NONE
  2361. INTEGER, INTENT(IN) :: io_form
  2362. #ifdef DM_PARALLEL
  2363. multi_files = io_form > 99
  2364. #else
  2365. multi_files = .FALSE.
  2366. #endif
  2367. END FUNCTION multi_files
  2368. INTEGER FUNCTION use_package ( io_form )
  2369. !<DESCRIPTION>
  2370. !<PRE>
  2371. ! Returns the ID of the external I/O package referenced by io_form.
  2372. !</PRE>
  2373. !</DESCRIPTION>
  2374. IMPLICIT NONE
  2375. INTEGER, INTENT(IN) :: io_form
  2376. use_package = MOD( io_form, 100 )
  2377. END FUNCTION use_package
  2378. SUBROUTINE collect_fld_and_call_pkg ( fcn, donotcollect_arg, &
  2379. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2380. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2381. DomainStart , DomainEnd , &
  2382. MemoryStart , MemoryEnd , &
  2383. PatchStart , PatchEnd , &
  2384. Status )
  2385. !<DESCRIPTION>
  2386. !<PRE>
  2387. ! The collect_*_and_call_pkg routines collect a distributed array onto one
  2388. ! processor and then call an I/O function to write the result (or in the
  2389. ! case of replicated data simply write monitor node's copy of the data)
  2390. ! This routine handle cases where collection can be skipped and deals with
  2391. ! different data types for Field.
  2392. !</PRE>
  2393. !</DESCRIPTION>
  2394. IMPLICIT NONE
  2395. #include "wrf_io_flags.h"
  2396. EXTERNAL fcn
  2397. LOGICAL, INTENT(IN) :: donotcollect_arg
  2398. INTEGER , INTENT(IN) :: Hndl
  2399. CHARACTER*(*) :: DateStr
  2400. CHARACTER*(*) :: VarName
  2401. INTEGER , INTENT(IN) :: Field(*)
  2402. INTEGER ,INTENT(IN) :: FieldType
  2403. INTEGER ,INTENT(INOUT) :: Comm
  2404. INTEGER ,INTENT(INOUT) :: IOComm
  2405. INTEGER ,INTENT(IN) :: DomainDesc
  2406. LOGICAL, DIMENSION(4) :: bdy_mask
  2407. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2408. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2409. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2410. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2411. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2412. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2413. INTEGER ,INTENT(OUT) :: Status
  2414. LOGICAL donotcollect
  2415. INTEGER ndims, nproc
  2416. CALL dim_from_memorder( MemoryOrder , ndims)
  2417. CALL wrf_get_nproc( nproc )
  2418. donotcollect = donotcollect_arg .OR. (nproc .EQ. 1)
  2419. IF ( donotcollect ) THEN
  2420. CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2421. DomainDesc , MemoryOrder , Stagger , DimNames , &
  2422. DomainStart , DomainEnd , &
  2423. MemoryStart , MemoryEnd , &
  2424. PatchStart , PatchEnd , &
  2425. Status )
  2426. ELSE IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  2427. CALL collect_double_and_call_pkg ( fcn, &
  2428. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2429. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2430. DomainStart , DomainEnd , &
  2431. MemoryStart , MemoryEnd , &
  2432. PatchStart , PatchEnd , &
  2433. Status )
  2434. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  2435. CALL collect_real_and_call_pkg ( fcn, &
  2436. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2437. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2438. DomainStart , DomainEnd , &
  2439. MemoryStart , MemoryEnd , &
  2440. PatchStart , PatchEnd , &
  2441. Status )
  2442. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  2443. CALL collect_int_and_call_pkg ( fcn, &
  2444. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2445. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2446. DomainStart , DomainEnd , &
  2447. MemoryStart , MemoryEnd , &
  2448. PatchStart , PatchEnd , &
  2449. Status )
  2450. ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  2451. CALL collect_logical_and_call_pkg ( fcn, &
  2452. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2453. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2454. DomainStart , DomainEnd , &
  2455. MemoryStart , MemoryEnd , &
  2456. PatchStart , PatchEnd , &
  2457. Status )
  2458. ENDIF
  2459. RETURN
  2460. END SUBROUTINE collect_fld_and_call_pkg
  2461. SUBROUTINE collect_real_and_call_pkg ( fcn, &
  2462. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2463. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2464. DomainStart , DomainEnd , &
  2465. MemoryStart , MemoryEnd , &
  2466. PatchStart , PatchEnd , &
  2467. Status )
  2468. !<DESCRIPTION>
  2469. !<PRE>
  2470. ! The collect_*_and_call_pkg routines collect a distributed array onto one
  2471. ! processor and then call an I/O function to write the result (or in the
  2472. ! case of replicated data simply write monitor node's copy of the data)
  2473. ! The sole purpose of this wrapper is to allocate a big real buffer and
  2474. ! pass it down to collect_generic_and_call_pkg() to do the actual work.
  2475. !</PRE>
  2476. !</DESCRIPTION>
  2477. USE module_state_description
  2478. USE module_driver_constants
  2479. IMPLICIT NONE
  2480. EXTERNAL fcn
  2481. INTEGER , INTENT(IN) :: Hndl
  2482. CHARACTER*(*) :: DateStr
  2483. CHARACTER*(*) :: VarName
  2484. REAL , INTENT(IN) :: Field(*)
  2485. INTEGER ,INTENT(IN) :: FieldType
  2486. INTEGER ,INTENT(INOUT) :: Comm
  2487. INTEGER ,INTENT(INOUT) :: IOComm
  2488. INTEGER ,INTENT(IN) :: DomainDesc
  2489. LOGICAL, DIMENSION(4) :: bdy_mask
  2490. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2491. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2492. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2493. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2494. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2495. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2496. INTEGER ,INTENT(INOUT) :: Status
  2497. REAL, ALLOCATABLE :: globbuf (:)
  2498. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  2499. IF ( wrf_dm_on_monitor() ) THEN
  2500. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
  2501. ELSE
  2502. ALLOCATE( globbuf( 1 ) )
  2503. ENDIF
  2504. #ifdef DEREF_KLUDGE
  2505. # define FRSTELEM (1)
  2506. #else
  2507. # define FRSTELEM
  2508. #endif
  2509. CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM, &
  2510. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2511. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2512. DomainStart , DomainEnd , &
  2513. MemoryStart , MemoryEnd , &
  2514. PatchStart , PatchEnd , &
  2515. Status )
  2516. DEALLOCATE ( globbuf )
  2517. RETURN
  2518. END SUBROUTINE collect_real_and_call_pkg
  2519. SUBROUTINE collect_int_and_call_pkg ( fcn, &
  2520. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2521. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2522. DomainStart , DomainEnd , &
  2523. MemoryStart , MemoryEnd , &
  2524. PatchStart , PatchEnd , &
  2525. Status )
  2526. !<DESCRIPTION>
  2527. !<PRE>
  2528. ! The collect_*_and_call_pkg routines collect a distributed array onto one
  2529. ! processor and then call an I/O function to write the result (or in the
  2530. ! case of replicated data simply write monitor node's copy of the data)
  2531. ! The sole purpose of this wrapper is to allocate a big integer buffer and
  2532. ! pass it down to collect_generic_and_call_pkg() to do the actual work.
  2533. !</PRE>
  2534. !</DESCRIPTION>
  2535. USE module_state_description
  2536. USE module_driver_constants
  2537. IMPLICIT NONE
  2538. EXTERNAL fcn
  2539. INTEGER , INTENT(IN) :: Hndl
  2540. CHARACTER*(*) :: DateStr
  2541. CHARACTER*(*) :: VarName
  2542. INTEGER , INTENT(IN) :: Field(*)
  2543. INTEGER ,INTENT(IN) :: FieldType
  2544. INTEGER ,INTENT(INOUT) :: Comm
  2545. INTEGER ,INTENT(INOUT) :: IOComm
  2546. INTEGER ,INTENT(IN) :: DomainDesc
  2547. LOGICAL, DIMENSION(4) :: bdy_mask
  2548. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2549. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2550. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2551. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2552. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2553. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2554. INTEGER ,INTENT(INOUT) :: Status
  2555. INTEGER, ALLOCATABLE :: globbuf (:)
  2556. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  2557. IF ( wrf_dm_on_monitor() ) THEN
  2558. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
  2559. ELSE
  2560. ALLOCATE( globbuf( 1 ) )
  2561. ENDIF
  2562. CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
  2563. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2564. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2565. DomainStart , DomainEnd , &
  2566. MemoryStart , MemoryEnd , &
  2567. PatchStart , PatchEnd , &
  2568. Status )
  2569. DEALLOCATE ( globbuf )
  2570. RETURN
  2571. END SUBROUTINE collect_int_and_call_pkg
  2572. SUBROUTINE collect_double_and_call_pkg ( fcn, &
  2573. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2574. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2575. DomainStart , DomainEnd , &
  2576. MemoryStart , MemoryEnd , &
  2577. PatchStart , PatchEnd , &
  2578. Status )
  2579. !<DESCRIPTION>
  2580. !<PRE>
  2581. ! The collect_*_and_call_pkg routines collect a distributed array onto one
  2582. ! processor and then call an I/O function to write the result (or in the
  2583. ! case of replicated data simply write monitor node's copy of the data)
  2584. ! The sole purpose of this wrapper is to allocate a big double precision
  2585. ! buffer and pass it down to collect_generic_and_call_pkg() to do the
  2586. ! actual work.
  2587. !</PRE>
  2588. !</DESCRIPTION>
  2589. USE module_state_description
  2590. USE module_driver_constants
  2591. IMPLICIT NONE
  2592. EXTERNAL fcn
  2593. INTEGER , INTENT(IN) :: Hndl
  2594. CHARACTER*(*) :: DateStr
  2595. CHARACTER*(*) :: VarName
  2596. DOUBLE PRECISION , INTENT(IN) :: Field(*)
  2597. INTEGER ,INTENT(IN) :: FieldType
  2598. INTEGER ,INTENT(INOUT) :: Comm
  2599. INTEGER ,INTENT(INOUT) :: IOComm
  2600. INTEGER ,INTENT(IN) :: DomainDesc
  2601. LOGICAL, DIMENSION(4) :: bdy_mask
  2602. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2603. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2604. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2605. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2606. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2607. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2608. INTEGER ,INTENT(INOUT) :: Status
  2609. DOUBLE PRECISION, ALLOCATABLE :: globbuf (:)
  2610. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  2611. IF ( wrf_dm_on_monitor() ) THEN
  2612. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
  2613. ELSE
  2614. ALLOCATE( globbuf( 1 ) )
  2615. ENDIF
  2616. CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
  2617. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2618. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2619. DomainStart , DomainEnd , &
  2620. MemoryStart , MemoryEnd , &
  2621. PatchStart , PatchEnd , &
  2622. Status )
  2623. DEALLOCATE ( globbuf )
  2624. RETURN
  2625. END SUBROUTINE collect_double_and_call_pkg
  2626. SUBROUTINE collect_logical_and_call_pkg ( fcn, &
  2627. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2628. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2629. DomainStart , DomainEnd , &
  2630. MemoryStart , MemoryEnd , &
  2631. PatchStart , PatchEnd , &
  2632. Status )
  2633. !<DESCRIPTION>
  2634. !<PRE>
  2635. ! The collect_*_and_call_pkg routines collect a distributed array onto one
  2636. ! processor and then call an I/O function to write the result (or in the
  2637. ! case of replicated data simply write monitor node's copy of the data)
  2638. ! The sole purpose of this wrapper is to allocate a big logical buffer
  2639. ! and pass it down to collect_generic_and_call_pkg() to do the actual work.
  2640. !</PRE>
  2641. !</DESCRIPTION>
  2642. USE module_state_description
  2643. USE module_driver_constants
  2644. IMPLICIT NONE
  2645. EXTERNAL fcn
  2646. INTEGER , INTENT(IN) :: Hndl
  2647. CHARACTER*(*) :: DateStr
  2648. CHARACTER*(*) :: VarName
  2649. LOGICAL , INTENT(IN) :: Field(*)
  2650. INTEGER ,INTENT(IN) :: FieldType
  2651. INTEGER ,INTENT(INOUT) :: Comm
  2652. INTEGER ,INTENT(INOUT) :: IOComm
  2653. INTEGER ,INTENT(IN) :: DomainDesc
  2654. LOGICAL, DIMENSION(4) :: bdy_mask
  2655. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2656. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2657. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2658. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2659. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2660. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2661. INTEGER ,INTENT(INOUT) :: Status
  2662. LOGICAL, ALLOCATABLE :: globbuf (:)
  2663. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  2664. IF ( wrf_dm_on_monitor() ) THEN
  2665. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
  2666. ELSE
  2667. ALLOCATE( globbuf( 1 ) )
  2668. ENDIF
  2669. CALL collect_generic_and_call_pkg ( fcn, globbuf FRSTELEM , &
  2670. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2671. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2672. DomainStart , DomainEnd , &
  2673. MemoryStart , MemoryEnd , &
  2674. PatchStart , PatchEnd , &
  2675. Status )
  2676. DEALLOCATE ( globbuf )
  2677. RETURN
  2678. END SUBROUTINE collect_logical_and_call_pkg
  2679. SUBROUTINE collect_generic_and_call_pkg ( fcn, globbuf, &
  2680. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  2681. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  2682. DomainStart , DomainEnd , &
  2683. MemoryStart , MemoryEnd , &
  2684. PatchStart , PatchEnd , &
  2685. Status )
  2686. !<DESCRIPTION>
  2687. !<PRE>
  2688. ! The collect_*_and_call_pkg routines collect a distributed array onto one
  2689. ! processor and then call an I/O function to write the result (or in the
  2690. ! case of replicated data simply write monitor node's copy of the data)
  2691. ! This routine calls the distributed memory communication routines that
  2692. ! collect the array and then calls I/O function fcn to write it to disk.
  2693. !</PRE>
  2694. !</DESCRIPTION>
  2695. USE module_state_description
  2696. USE module_driver_constants
  2697. IMPLICIT NONE
  2698. #include "wrf_io_flags.h"
  2699. #if defined( DM_PARALLEL ) && ! defined(STUBMPI)
  2700. include "mpif.h"
  2701. #endif
  2702. EXTERNAL fcn
  2703. REAL , DIMENSION(*) , INTENT(INOUT) :: globbuf
  2704. INTEGER , INTENT(IN) :: Hndl
  2705. CHARACTER*(*) :: DateStr
  2706. CHARACTER*(*) :: VarName
  2707. REAL , INTENT(IN) :: Field(*)
  2708. INTEGER ,INTENT(IN) :: FieldType
  2709. INTEGER ,INTENT(INOUT) :: Comm
  2710. INTEGER ,INTENT(INOUT) :: IOComm
  2711. INTEGER ,INTENT(IN) :: DomainDesc
  2712. LOGICAL, DIMENSION(4) :: bdy_mask
  2713. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  2714. CHARACTER*(*) ,INTENT(IN) :: Stagger
  2715. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  2716. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  2717. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  2718. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  2719. INTEGER ,INTENT(OUT) :: Status
  2720. CHARACTER*3 MemOrd
  2721. LOGICAL, EXTERNAL :: has_char
  2722. INTEGER ids, ide, jds, jde, kds, kde
  2723. INTEGER ims, ime, jms, jme, kms, kme
  2724. INTEGER ips, ipe, jps, jpe, kps, kpe
  2725. INTEGER, ALLOCATABLE :: counts(:), displs(:)
  2726. INTEGER nproc, communicator, mpi_bdyslice_type, ierr, my_displ
  2727. INTEGER my_count
  2728. INTEGER , dimension(3) :: dom_end_rev
  2729. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  2730. INTEGER, EXTERNAL :: wrf_dm_monitor_rank
  2731. LOGICAL distributed_field
  2732. INTEGER i,j,k,idx,lx,idx2,lx2
  2733. INTEGER collective_root
  2734. CALL wrf_get_nproc( nproc )
  2735. CALL wrf_get_dm_communicator ( communicator )
  2736. ALLOCATE( counts( nproc ) )
  2737. ALLOCATE( displs( nproc ) )
  2738. CALL lower_case( MemoryOrder, MemOrd )
  2739. collective_root = wrf_dm_monitor_rank()
  2740. dom_end_rev(1) = DomainEnd(1)
  2741. dom_end_rev(2) = DomainEnd(2)
  2742. dom_end_rev(3) = DomainEnd(3)
  2743. SELECT CASE (TRIM(MemOrd))
  2744. CASE ( 'xzy' )
  2745. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  2746. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  2747. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  2748. CASE ( 'zxy' )
  2749. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  2750. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  2751. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  2752. CASE ( 'xyz' )
  2753. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  2754. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  2755. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  2756. CASE ( 'xy' )
  2757. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  2758. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  2759. CASE ( 'yxz' )
  2760. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  2761. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  2762. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  2763. CASE ( 'yx' )
  2764. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  2765. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  2766. CASE DEFAULT
  2767. ! do nothing; the boundary orders and others either dont care or set themselves
  2768. END SELECT
  2769. SELECT CASE (TRIM(MemOrd))
  2770. #ifndef STUBMPI
  2771. CASE ( 'xzy','zxy','xyz','yxz','xy','yx' )
  2772. distributed_field = .TRUE.
  2773. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  2774. CALL wrf_patch_to_global_double ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  2775. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  2776. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  2777. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  2778. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  2779. CALL wrf_patch_to_global_real ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  2780. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  2781. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  2782. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  2783. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  2784. CALL wrf_patch_to_global_integer ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  2785. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  2786. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  2787. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  2788. ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  2789. CALL wrf_patch_to_global_logical ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  2790. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  2791. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  2792. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  2793. ENDIF
  2794. #if defined(DM_PARALLEL) && !defined(STUBMPI)
  2795. CASE ( 'xsz', 'xez' )
  2796. distributed_field = .FALSE.
  2797. IF ( nproc .GT. 1 ) THEN
  2798. jds = DomainStart(1) ; jde = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) jde = jde+1 ! ns strip
  2799. kds = DomainStart(2) ; kde = DomainEnd(2) ; IF ( .NOT. has_char( Stagger, 'z' ) ) kde = kde+1 ! levels
  2800. ids = DomainStart(3) ; ide = DomainEnd(3) ; ! bdy_width
  2801. dom_end_rev(1) = jde
  2802. dom_end_rev(2) = kde
  2803. dom_end_rev(3) = ide
  2804. distributed_field = .TRUE.
  2805. IF ( (MemOrd .eq. 'xsz' .AND. bdy_mask( P_XSB )) .OR. &
  2806. (MemOrd .eq. 'xez' .AND. bdy_mask( P_XEB )) ) THEN
  2807. my_displ = PatchStart(1)-1
  2808. my_count = PatchEnd(1)-PatchStart(1)+1
  2809. ELSE
  2810. my_displ = 0
  2811. my_count = 0
  2812. ENDIF
  2813. CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2814. CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2815. do i = DomainStart(3),DomainEnd(3) ! bdy_width
  2816. do k = DomainStart(2),DomainEnd(2) ! levels
  2817. lx = MemoryEnd(1)-MemoryStart(1)+1
  2818. lx2 = dom_end_rev(1)-DomainStart(1)+1
  2819. idx = lx*((k-1)+(i-1)*(MemoryEnd(2)-MemoryStart(2)+1))
  2820. idx2 = lx2*((k-1)+(i-1)*(MemoryEnd(2)-MemoryStart(2)+1))
  2821. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  2822. CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
  2823. my_count , & ! sendcount
  2824. globbuf, 1+idx2 , & ! recvbuf
  2825. counts , & ! recvcounts
  2826. displs , & ! displs
  2827. collective_root , & ! root
  2828. communicator , & ! communicator
  2829. ierr )
  2830. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  2831. CALL wrf_gatherv_real ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
  2832. my_count , & ! sendcount
  2833. globbuf, 1+idx2 , & ! recvbuf
  2834. counts , & ! recvcounts
  2835. displs , & ! displs
  2836. collective_root , & ! root
  2837. communicator , & ! communicator
  2838. ierr )
  2839. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  2840. CALL wrf_gatherv_integer ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
  2841. my_count , & ! sendcount
  2842. globbuf, 1+idx2 , & ! recvbuf
  2843. counts , & ! recvcounts
  2844. displs , & ! displs
  2845. collective_root , & ! root
  2846. communicator , & ! communicator
  2847. ierr )
  2848. ENDIF
  2849. enddo
  2850. enddo
  2851. ENDIF
  2852. CASE ( 'xs', 'xe' )
  2853. distributed_field = .FALSE.
  2854. IF ( nproc .GT. 1 ) THEN
  2855. jds = DomainStart(1) ; jde = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) jde = jde+1 ! ns strip
  2856. ids = DomainStart(2) ; ide = DomainEnd(2) ; ! bdy_width
  2857. dom_end_rev(1) = jde
  2858. dom_end_rev(2) = ide
  2859. distributed_field = .TRUE.
  2860. IF ( (MemOrd .eq. 'xs' .AND. bdy_mask( P_XSB )) .OR. &
  2861. (MemOrd .eq. 'xe' .AND. bdy_mask( P_XEB )) ) THEN
  2862. my_displ = PatchStart(1)-1
  2863. my_count = PatchEnd(1)-PatchStart(1)+1
  2864. ELSE
  2865. my_displ = 0
  2866. my_count = 0
  2867. ENDIF
  2868. CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2869. CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2870. do i = DomainStart(2),DomainEnd(2) ! bdy_width
  2871. lx = MemoryEnd(1)-MemoryStart(1)+1
  2872. idx = lx*(i-1)
  2873. lx2 = dom_end_rev(1)-DomainStart(1)+1
  2874. idx2 = lx2*(i-1)
  2875. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  2876. CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
  2877. my_count , & ! sendcount
  2878. globbuf, 1+idx2 , & ! recvbuf
  2879. counts , & ! recvcounts
  2880. displs , & ! displs
  2881. collective_root , & ! root
  2882. communicator , & ! communicator
  2883. ierr )
  2884. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  2885. CALL wrf_gatherv_real ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
  2886. my_count , & ! sendcount
  2887. globbuf, 1+idx2 , & ! recvbuf
  2888. counts , & ! recvcounts
  2889. displs , & ! displs
  2890. collective_root , & ! root
  2891. communicator , & ! communicator
  2892. ierr )
  2893. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  2894. CALL wrf_gatherv_integer ( Field, PatchStart(1)-MemoryStart(1)+1+idx , &
  2895. my_count , & ! sendcount
  2896. globbuf, 1+idx2 , & ! recvbuf
  2897. counts , & ! recvcounts
  2898. displs , & ! displs
  2899. collective_root , & ! root
  2900. communicator , & ! communicator
  2901. ierr )
  2902. ENDIF
  2903. enddo
  2904. ENDIF
  2905. CASE ( 'ysz', 'yez' )
  2906. distributed_field = .FALSE.
  2907. IF ( nproc .GT. 1 ) THEN
  2908. ids = DomainStart(1) ; ide = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) ide = ide+1 ! ns strip
  2909. kds = DomainStart(2) ; kde = DomainEnd(2) ; IF ( .NOT. has_char( Stagger, 'z' ) ) kde = kde+1 ! levels
  2910. jds = DomainStart(3) ; jde = DomainEnd(3) ; ! bdy_width
  2911. dom_end_rev(1) = ide
  2912. dom_end_rev(2) = kde
  2913. dom_end_rev(3) = jde
  2914. distributed_field = .TRUE.
  2915. IF ( (MemOrd .eq. 'ysz' .AND. bdy_mask( P_YSB )) .OR. &
  2916. (MemOrd .eq. 'yez' .AND. bdy_mask( P_YEB )) ) THEN
  2917. my_displ = PatchStart(1)-1
  2918. my_count = PatchEnd(1)-PatchStart(1)+1
  2919. ELSE
  2920. my_displ = 0
  2921. my_count = 0
  2922. ENDIF
  2923. CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2924. CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2925. do j = DomainStart(3),DomainEnd(3) ! bdy_width
  2926. do k = DomainStart(2),DomainEnd(2) ! levels
  2927. lx = MemoryEnd(1)-MemoryStart(1)+1
  2928. lx2 = dom_end_rev(1)-DomainStart(1)+1
  2929. idx = lx*((k-1)+(j-1)*(MemoryEnd(2)-MemoryStart(2)+1))
  2930. idx2 = lx2*((k-1)+(j-1)*(MemoryEnd(2)-MemoryStart(2)+1))
  2931. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  2932. CALL wrf_gatherv_double ( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
  2933. my_count , & ! sendcount
  2934. globbuf, 1+idx2 , & ! recvbuf
  2935. counts , & ! recvcounts
  2936. displs , & ! displs
  2937. collective_root , & ! root
  2938. communicator , & ! communicator
  2939. ierr )
  2940. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  2941. CALL wrf_gatherv_real( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
  2942. my_count , & ! sendcount
  2943. globbuf, 1+idx2 , & ! recvbuf
  2944. counts , & ! recvcounts
  2945. displs , & ! displs
  2946. collective_root , & ! root
  2947. communicator , & ! communicator
  2948. ierr )
  2949. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  2950. CALL wrf_gatherv_integer( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
  2951. my_count , & ! sendcount
  2952. globbuf, 1+idx2 , & ! recvbuf
  2953. counts , & ! recvcounts
  2954. displs , & ! displs
  2955. collective_root , & ! root
  2956. communicator , & ! communicator
  2957. ierr )
  2958. ENDIF
  2959. enddo
  2960. enddo
  2961. ENDIF
  2962. CASE ( 'ys', 'ye' )
  2963. distributed_field = .FALSE.
  2964. IF ( nproc .GT. 1 ) THEN
  2965. ids = DomainStart(1) ; ide = DomainEnd(1) ; IF ( .NOT. has_char( Stagger, 'y' ) ) ide = ide+1 ! ns strip
  2966. jds = DomainStart(2) ; jde = DomainEnd(2) ; ! bdy_width
  2967. dom_end_rev(1) = ide
  2968. dom_end_rev(2) = jde
  2969. distributed_field = .TRUE.
  2970. IF ( (MemOrd .eq. 'ys' .AND. bdy_mask( P_YSB )) .OR. &
  2971. (MemOrd .eq. 'ye' .AND. bdy_mask( P_YEB )) ) THEN
  2972. my_displ = PatchStart(1)-1
  2973. my_count = PatchEnd(1)-PatchStart(1)+1
  2974. ELSE
  2975. my_displ = 0
  2976. my_count = 0
  2977. ENDIF
  2978. CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2979. CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
  2980. do j = DomainStart(2),DomainEnd(2) ! bdy_width
  2981. lx = MemoryEnd(1)-MemoryStart(1)+1
  2982. idx = lx*(j-1)
  2983. lx2 = dom_end_rev(1)-DomainStart(1)+1
  2984. idx2 = lx2*(j-1)
  2985. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  2986. CALL wrf_gatherv_double( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
  2987. my_count , & ! sendcount
  2988. globbuf, 1+idx2 , & ! recvbuf
  2989. counts , & ! recvcounts
  2990. displs , & ! displs
  2991. collective_root , & ! root
  2992. communicator , & ! communicator
  2993. ierr )
  2994. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  2995. CALL wrf_gatherv_real( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
  2996. my_count , & ! sendcount
  2997. globbuf, 1+idx2 , & ! recvbuf
  2998. counts , & ! recvcounts
  2999. displs , & ! displs
  3000. collective_root , & ! root
  3001. communicator , & ! communicator
  3002. ierr )
  3003. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  3004. CALL wrf_gatherv_integer( Field, PatchStart(1)-MemoryStart(1)+1+idx , & ! sendbuf
  3005. my_count , & ! sendcount
  3006. globbuf, 1+idx2 , & ! recvbuf
  3007. counts , & ! recvcounts
  3008. displs , & ! displs
  3009. collective_root , & ! root
  3010. communicator , & ! communicator
  3011. ierr )
  3012. ENDIF
  3013. enddo
  3014. ENDIF
  3015. #endif
  3016. #endif
  3017. CASE DEFAULT
  3018. distributed_field = .FALSE.
  3019. END SELECT
  3020. IF ( wrf_dm_on_monitor() ) THEN
  3021. IF ( distributed_field ) THEN
  3022. CALL fcn ( Hndl , DateStr , VarName , globbuf , FieldType , Comm , IOComm , &
  3023. DomainDesc , MemoryOrder , Stagger , DimNames , &
  3024. DomainStart , DomainEnd , &
  3025. DomainStart , dom_end_rev , & ! memory dims adjust out for unstag
  3026. DomainStart , DomainEnd , &
  3027. Status )
  3028. ELSE
  3029. CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3030. DomainDesc , MemoryOrder , Stagger , DimNames , &
  3031. DomainStart , DomainEnd , &
  3032. MemoryStart , MemoryEnd , &
  3033. PatchStart , PatchEnd , &
  3034. Status )
  3035. ENDIF
  3036. ENDIF
  3037. CALL wrf_dm_bcast_bytes( Status , IWORDSIZE )
  3038. DEALLOCATE( counts )
  3039. DEALLOCATE( displs )
  3040. RETURN
  3041. END SUBROUTINE collect_generic_and_call_pkg
  3042. SUBROUTINE call_pkg_and_dist ( fcn, donotdist_arg, update_arg, &
  3043. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3044. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3045. DomainStart , DomainEnd , &
  3046. MemoryStart , MemoryEnd , &
  3047. PatchStart , PatchEnd , &
  3048. Status )
  3049. !<DESCRIPTION>
  3050. !<PRE>
  3051. ! The call_pkg_and_dist* routines call an I/O function to read a field and then
  3052. ! distribute or replicate the field across compute tasks.
  3053. ! This routine handle cases where distribution/replication can be skipped and
  3054. ! deals with different data types for Field.
  3055. !</PRE>
  3056. !</DESCRIPTION>
  3057. IMPLICIT NONE
  3058. #include "wrf_io_flags.h"
  3059. EXTERNAL fcn
  3060. LOGICAL, INTENT(IN) :: donotdist_arg, update_arg ! update means collect old field update it and dist
  3061. INTEGER , INTENT(IN) :: Hndl
  3062. CHARACTER*(*) :: DateStr
  3063. CHARACTER*(*) :: VarName
  3064. INTEGER :: Field(*)
  3065. INTEGER :: FieldType
  3066. INTEGER :: Comm
  3067. INTEGER :: IOComm
  3068. INTEGER :: DomainDesc
  3069. LOGICAL, DIMENSION(4) :: bdy_mask
  3070. CHARACTER*(*) :: MemoryOrder
  3071. CHARACTER*(*) :: Stagger
  3072. CHARACTER*(*) , dimension (*) :: DimNames
  3073. INTEGER ,dimension(*) :: DomainStart, DomainEnd
  3074. INTEGER ,dimension(*) :: MemoryStart, MemoryEnd
  3075. INTEGER ,dimension(*) :: PatchStart, PatchEnd
  3076. INTEGER :: Status
  3077. LOGICAL donotdist
  3078. INTEGER ndims, nproc
  3079. CALL dim_from_memorder( MemoryOrder , ndims)
  3080. CALL wrf_get_nproc( nproc )
  3081. donotdist = donotdist_arg .OR. (nproc .EQ. 1)
  3082. IF ( donotdist ) THEN
  3083. CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3084. DomainDesc , MemoryOrder , Stagger , DimNames , &
  3085. DomainStart , DomainEnd , &
  3086. MemoryStart , MemoryEnd , &
  3087. PatchStart , PatchEnd , &
  3088. Status )
  3089. ELSE IF (FieldType .EQ. WRF_DOUBLE) THEN
  3090. CALL call_pkg_and_dist_double ( fcn, update_arg, &
  3091. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3092. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3093. DomainStart , DomainEnd , &
  3094. MemoryStart , MemoryEnd , &
  3095. PatchStart , PatchEnd , &
  3096. Status )
  3097. ELSE IF (FieldType .EQ. WRF_FLOAT) THEN
  3098. CALL call_pkg_and_dist_real ( fcn, update_arg, &
  3099. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3100. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3101. DomainStart , DomainEnd , &
  3102. MemoryStart , MemoryEnd , &
  3103. PatchStart , PatchEnd , &
  3104. Status )
  3105. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  3106. CALL call_pkg_and_dist_int ( fcn, update_arg, &
  3107. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3108. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3109. DomainStart , DomainEnd , &
  3110. MemoryStart , MemoryEnd , &
  3111. PatchStart , PatchEnd , &
  3112. Status )
  3113. ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  3114. CALL call_pkg_and_dist_logical ( fcn, update_arg, &
  3115. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3116. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3117. DomainStart , DomainEnd , &
  3118. MemoryStart , MemoryEnd , &
  3119. PatchStart , PatchEnd , &
  3120. Status )
  3121. ENDIF
  3122. RETURN
  3123. END SUBROUTINE call_pkg_and_dist
  3124. SUBROUTINE call_pkg_and_dist_real ( fcn, update_arg, &
  3125. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3126. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3127. DomainStart , DomainEnd , &
  3128. MemoryStart , MemoryEnd , &
  3129. PatchStart , PatchEnd , &
  3130. Status )
  3131. !<DESCRIPTION>
  3132. !<PRE>
  3133. ! The call_pkg_and_dist* routines call an I/O function to read a field and then
  3134. ! distribute or replicate the field across compute tasks.
  3135. ! The sole purpose of this wrapper is to allocate a big real buffer and
  3136. ! pass it down to call_pkg_and_dist_generic() to do the actual work.
  3137. !</PRE>
  3138. !</DESCRIPTION>
  3139. IMPLICIT NONE
  3140. EXTERNAL fcn
  3141. INTEGER , INTENT(IN) :: Hndl
  3142. LOGICAL , INTENT(IN) :: update_arg
  3143. CHARACTER*(*) :: DateStr
  3144. CHARACTER*(*) :: VarName
  3145. REAL , INTENT(INOUT) :: Field(*)
  3146. INTEGER ,INTENT(IN) :: FieldType
  3147. INTEGER ,INTENT(INOUT) :: Comm
  3148. INTEGER ,INTENT(INOUT) :: IOComm
  3149. INTEGER ,INTENT(IN) :: DomainDesc
  3150. LOGICAL, DIMENSION(4) :: bdy_mask
  3151. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  3152. CHARACTER*(*) ,INTENT(IN) :: Stagger
  3153. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  3154. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  3155. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  3156. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  3157. INTEGER ,INTENT(INOUT) :: Status
  3158. REAL, ALLOCATABLE :: globbuf (:)
  3159. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  3160. INTEGER test
  3161. CHARACTER*128 mess
  3162. IF ( wrf_dm_on_monitor() ) THEN
  3163. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ), &
  3164. STAT=test )
  3165. IF ( test .NE. 0 ) THEN
  3166. write(mess,*)"module_io.b",'allocating globbuf ',&
  3167. (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3)
  3168. CALL wrf_error_fatal(mess)
  3169. ENDIF
  3170. ELSE
  3171. ALLOCATE( globbuf( 1 ), STAT=test )
  3172. IF ( test .NE. 0 ) THEN
  3173. write(mess,*)"module_io.b",'allocating globbuf ',1
  3174. CALL wrf_error_fatal(mess)
  3175. ENDIF
  3176. ENDIF
  3177. globbuf = 0.
  3178. CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg, &
  3179. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3180. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3181. DomainStart , DomainEnd , &
  3182. MemoryStart , MemoryEnd , &
  3183. PatchStart , PatchEnd , &
  3184. Status )
  3185. DEALLOCATE ( globbuf )
  3186. RETURN
  3187. END SUBROUTINE call_pkg_and_dist_real
  3188. SUBROUTINE call_pkg_and_dist_double ( fcn, update_arg , &
  3189. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3190. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3191. DomainStart , DomainEnd , &
  3192. MemoryStart , MemoryEnd , &
  3193. PatchStart , PatchEnd , &
  3194. Status )
  3195. !<DESCRIPTION>
  3196. !<PRE>
  3197. ! The call_pkg_and_dist* routines call an I/O function to read a field and then
  3198. ! distribute or replicate the field across compute tasks.
  3199. ! The sole purpose of this wrapper is to allocate a big double precision buffer
  3200. ! and pass it down to call_pkg_and_dist_generic() to do the actual work.
  3201. !</PRE>
  3202. !</DESCRIPTION>
  3203. IMPLICIT NONE
  3204. EXTERNAL fcn
  3205. INTEGER , INTENT(IN) :: Hndl
  3206. LOGICAL , INTENT(IN) :: update_arg
  3207. CHARACTER*(*) :: DateStr
  3208. CHARACTER*(*) :: VarName
  3209. DOUBLE PRECISION , INTENT(INOUT) :: Field(*)
  3210. INTEGER ,INTENT(IN) :: FieldType
  3211. INTEGER ,INTENT(INOUT) :: Comm
  3212. INTEGER ,INTENT(INOUT) :: IOComm
  3213. INTEGER ,INTENT(IN) :: DomainDesc
  3214. LOGICAL, DIMENSION(4) :: bdy_mask
  3215. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  3216. CHARACTER*(*) ,INTENT(IN) :: Stagger
  3217. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  3218. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  3219. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  3220. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  3221. INTEGER ,INTENT(INOUT) :: Status
  3222. DOUBLE PRECISION , ALLOCATABLE :: globbuf (:)
  3223. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  3224. IF ( wrf_dm_on_monitor() ) THEN
  3225. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
  3226. ELSE
  3227. ALLOCATE( globbuf( 1 ) )
  3228. ENDIF
  3229. globbuf = 0
  3230. CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
  3231. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3232. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3233. DomainStart , DomainEnd , &
  3234. MemoryStart , MemoryEnd , &
  3235. PatchStart , PatchEnd , &
  3236. Status )
  3237. DEALLOCATE ( globbuf )
  3238. RETURN
  3239. END SUBROUTINE call_pkg_and_dist_double
  3240. SUBROUTINE call_pkg_and_dist_int ( fcn, update_arg , &
  3241. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3242. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3243. DomainStart , DomainEnd , &
  3244. MemoryStart , MemoryEnd , &
  3245. PatchStart , PatchEnd , &
  3246. Status )
  3247. !<DESCRIPTION>
  3248. !<PRE>
  3249. ! The call_pkg_and_dist* routines call an I/O function to read a field and then
  3250. ! distribute or replicate the field across compute tasks.
  3251. ! The sole purpose of this wrapper is to allocate a big integer buffer and
  3252. ! pass it down to call_pkg_and_dist_generic() to do the actual work.
  3253. !</PRE>
  3254. !</DESCRIPTION>
  3255. IMPLICIT NONE
  3256. EXTERNAL fcn
  3257. INTEGER , INTENT(IN) :: Hndl
  3258. LOGICAL , INTENT(IN) :: update_arg
  3259. CHARACTER*(*) :: DateStr
  3260. CHARACTER*(*) :: VarName
  3261. INTEGER , INTENT(INOUT) :: Field(*)
  3262. INTEGER ,INTENT(IN) :: FieldType
  3263. INTEGER ,INTENT(INOUT) :: Comm
  3264. INTEGER ,INTENT(INOUT) :: IOComm
  3265. INTEGER ,INTENT(IN) :: DomainDesc
  3266. LOGICAL, DIMENSION(4) :: bdy_mask
  3267. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  3268. CHARACTER*(*) ,INTENT(IN) :: Stagger
  3269. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  3270. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  3271. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  3272. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  3273. INTEGER ,INTENT(INOUT) :: Status
  3274. INTEGER , ALLOCATABLE :: globbuf (:)
  3275. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  3276. IF ( wrf_dm_on_monitor() ) THEN
  3277. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
  3278. ELSE
  3279. ALLOCATE( globbuf( 1 ) )
  3280. ENDIF
  3281. globbuf = 0
  3282. CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
  3283. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3284. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3285. DomainStart , DomainEnd , &
  3286. MemoryStart , MemoryEnd , &
  3287. PatchStart , PatchEnd , &
  3288. Status )
  3289. DEALLOCATE ( globbuf )
  3290. RETURN
  3291. END SUBROUTINE call_pkg_and_dist_int
  3292. SUBROUTINE call_pkg_and_dist_logical ( fcn, update_arg , &
  3293. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3294. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3295. DomainStart , DomainEnd , &
  3296. MemoryStart , MemoryEnd , &
  3297. PatchStart , PatchEnd , &
  3298. Status )
  3299. !<DESCRIPTION>
  3300. !<PRE>
  3301. ! The call_pkg_and_dist* routines call an I/O function to read a field and then
  3302. ! distribute or replicate the field across compute tasks.
  3303. ! The sole purpose of this wrapper is to allocate a big logical buffer and
  3304. ! pass it down to call_pkg_and_dist_generic() to do the actual work.
  3305. !</PRE>
  3306. !</DESCRIPTION>
  3307. IMPLICIT NONE
  3308. EXTERNAL fcn
  3309. INTEGER , INTENT(IN) :: Hndl
  3310. LOGICAL , INTENT(IN) :: update_arg
  3311. CHARACTER*(*) :: DateStr
  3312. CHARACTER*(*) :: VarName
  3313. logical , INTENT(INOUT) :: Field(*)
  3314. INTEGER ,INTENT(IN) :: FieldType
  3315. INTEGER ,INTENT(INOUT) :: Comm
  3316. INTEGER ,INTENT(INOUT) :: IOComm
  3317. INTEGER ,INTENT(IN) :: DomainDesc
  3318. LOGICAL, DIMENSION(4) :: bdy_mask
  3319. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  3320. CHARACTER*(*) ,INTENT(IN) :: Stagger
  3321. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  3322. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  3323. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  3324. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  3325. INTEGER ,INTENT(INOUT) :: Status
  3326. LOGICAL , ALLOCATABLE :: globbuf (:)
  3327. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  3328. IF ( wrf_dm_on_monitor() ) THEN
  3329. ALLOCATE( globbuf( (DomainEnd(1)-DomainStart(1)+3)*(DomainEnd(2)-DomainStart(2)+3)*(DomainEnd(3)-DomainStart(3)+3) ) )
  3330. ELSE
  3331. ALLOCATE( globbuf( 1 ) )
  3332. ENDIF
  3333. globbuf = .false.
  3334. CALL call_pkg_and_dist_generic ( fcn, globbuf FRSTELEM , update_arg , &
  3335. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3336. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3337. DomainStart , DomainEnd , &
  3338. MemoryStart , MemoryEnd , &
  3339. PatchStart , PatchEnd , &
  3340. Status )
  3341. DEALLOCATE ( globbuf )
  3342. RETURN
  3343. END SUBROUTINE call_pkg_and_dist_logical
  3344. SUBROUTINE call_pkg_and_dist_generic ( fcn, globbuf , update_arg , &
  3345. Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3346. DomainDesc , bdy_mask, MemoryOrder , Stagger , DimNames , &
  3347. DomainStart , DomainEnd , &
  3348. MemoryStart , MemoryEnd , &
  3349. PatchStart , PatchEnd , &
  3350. Status )
  3351. !<DESCRIPTION>
  3352. !<PRE>
  3353. ! The call_pkg_and_dist* routines call an I/O function to read a field and then
  3354. ! distribute or replicate the field across compute tasks.
  3355. ! This routine calls I/O function fcn to read the field from disk and then calls
  3356. ! the distributed memory communication routines that distribute or replicate the
  3357. ! array.
  3358. !</PRE>
  3359. !</DESCRIPTION>
  3360. USE module_state_description
  3361. USE module_driver_constants
  3362. USE module_io
  3363. IMPLICIT NONE
  3364. #include "wrf_io_flags.h"
  3365. #if defined( DM_PARALLEL ) && ! defined(STUBMPI)
  3366. include "mpif.h"
  3367. #endif
  3368. EXTERNAL fcn
  3369. REAL, DIMENSION(*) :: globbuf
  3370. INTEGER , INTENT(IN) :: Hndl
  3371. LOGICAL , INTENT(IN) :: update_arg
  3372. CHARACTER*(*) :: DateStr
  3373. CHARACTER*(*) :: VarName
  3374. REAL :: Field(*)
  3375. INTEGER ,INTENT(IN) :: FieldType
  3376. INTEGER ,INTENT(INOUT) :: Comm
  3377. INTEGER ,INTENT(INOUT) :: IOComm
  3378. INTEGER ,INTENT(IN) :: DomainDesc
  3379. LOGICAL, DIMENSION(4) :: bdy_mask
  3380. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  3381. CHARACTER*(*) ,INTENT(IN) :: Stagger
  3382. CHARACTER*(*) , dimension (*) ,INTENT(IN) :: DimNames
  3383. INTEGER ,dimension(*) ,INTENT(IN) :: DomainStart, DomainEnd
  3384. INTEGER ,dimension(*) ,INTENT(IN) :: MemoryStart, MemoryEnd
  3385. INTEGER ,dimension(*) ,INTENT(IN) :: PatchStart, PatchEnd
  3386. INTEGER ,INTENT(OUT) :: Status
  3387. CHARACTER*3 MemOrd
  3388. LOGICAL, EXTERNAL :: has_char
  3389. INTEGER ids, ide, jds, jde, kds, kde
  3390. INTEGER ims, ime, jms, jme, kms, kme
  3391. INTEGER ips, ipe, jps, jpe, kps, kpe
  3392. INTEGER , dimension(3) :: dom_end_rev
  3393. INTEGER memsize
  3394. LOGICAL, EXTERNAL :: wrf_dm_on_monitor
  3395. INTEGER, EXTERNAL :: wrf_dm_monitor_rank
  3396. INTEGER lx, lx2, i,j,k ,idx,idx2
  3397. INTEGER my_count, nproc, communicator, ierr, my_displ
  3398. INTEGER, ALLOCATABLE :: counts(:), displs(:)
  3399. LOGICAL distributed_field
  3400. INTEGER collective_root
  3401. CALL lower_case( MemoryOrder, MemOrd )
  3402. collective_root = wrf_dm_monitor_rank()
  3403. CALL wrf_get_nproc( nproc )
  3404. CALL wrf_get_dm_communicator ( communicator )
  3405. ALLOCATE(displs( nproc ))
  3406. ALLOCATE(counts( nproc ))
  3407. dom_end_rev(1) = DomainEnd(1)
  3408. dom_end_rev(2) = DomainEnd(2)
  3409. dom_end_rev(3) = DomainEnd(3)
  3410. SELECT CASE (TRIM(MemOrd))
  3411. CASE ( 'xzy' )
  3412. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  3413. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  3414. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  3415. CASE ( 'zxy' )
  3416. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  3417. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  3418. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  3419. CASE ( 'xyz' )
  3420. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  3421. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  3422. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  3423. CASE ( 'xy' )
  3424. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  3425. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  3426. CASE ( 'yxz' )
  3427. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  3428. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  3429. IF ( .NOT. has_char( Stagger, 'z' ) ) dom_end_rev(3) = dom_end_rev(3) + 1
  3430. CASE ( 'yx' )
  3431. IF ( .NOT. has_char( Stagger, 'y' ) ) dom_end_rev(1) = dom_end_rev(1) + 1
  3432. IF ( .NOT. has_char( Stagger, 'x' ) ) dom_end_rev(2) = dom_end_rev(2) + 1
  3433. CASE DEFAULT
  3434. ! do nothing; the boundary orders and others either dont care or set themselves
  3435. END SELECT
  3436. data_ordering : SELECT CASE ( model_data_order )
  3437. CASE ( DATA_ORDER_XYZ )
  3438. ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(2); jde=dom_end_rev(2); kds=DomainStart(3); kde=dom_end_rev(3);
  3439. ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(2); jme= MemoryEnd(2); kms=MemoryStart(3); kme= MemoryEnd(3);
  3440. ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(2); jpe= PatchEnd(2); kps= PatchStart(3); kpe= PatchEnd(3);
  3441. CASE ( DATA_ORDER_YXZ )
  3442. ids=DomainStart(2); ide=dom_end_rev(2); jds=DomainStart(1); jde=dom_end_rev(1); kds=DomainStart(3); kde=dom_end_rev(3);
  3443. ims=MemoryStart(2); ime= MemoryEnd(2); jms=MemoryStart(1); jme= MemoryEnd(1); kms=MemoryStart(3); kme= MemoryEnd(3);
  3444. ips= PatchStart(2); ipe= PatchEnd(2); jps= PatchStart(1); jpe= PatchEnd(1); kps= PatchStart(3); kpe= PatchEnd(3);
  3445. CASE ( DATA_ORDER_ZXY )
  3446. ids=DomainStart(2); ide=dom_end_rev(2); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(1); kde=dom_end_rev(1);
  3447. ims=MemoryStart(2); ime= MemoryEnd(2); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(1); kme= MemoryEnd(1);
  3448. ips= PatchStart(2); ipe= PatchEnd(2); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(1); kpe= PatchEnd(1);
  3449. CASE ( DATA_ORDER_ZYX )
  3450. ids=DomainStart(3); ide=dom_end_rev(3); jds=DomainStart(2); jde=dom_end_rev(2); kds=DomainStart(1); kde=dom_end_rev(1);
  3451. ims=MemoryStart(3); ime= MemoryEnd(3); jms=MemoryStart(2); jme= MemoryEnd(2); kms=MemoryStart(1); kme= MemoryEnd(1);
  3452. ips= PatchStart(3); ipe= PatchEnd(3); jps= PatchStart(2); jpe= PatchEnd(2); kps= PatchStart(1); kpe= PatchEnd(1);
  3453. CASE ( DATA_ORDER_XZY )
  3454. ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
  3455. ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
  3456. ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
  3457. CASE ( DATA_ORDER_YZX )
  3458. ids=DomainStart(3); ide=dom_end_rev(3); jds=DomainStart(1); jde=dom_end_rev(1); kds=DomainStart(2); kde=dom_end_rev(2);
  3459. ims=MemoryStart(3); ime= MemoryEnd(3); jms=MemoryStart(1); jme= MemoryEnd(1); kms=MemoryStart(2); kme= MemoryEnd(2);
  3460. ips= PatchStart(3); ipe= PatchEnd(3); jps= PatchStart(1); jpe= PatchEnd(1); kps= PatchStart(2); kpe= PatchEnd(2);
  3461. END SELECT data_ordering
  3462. SELECT CASE (MemOrd)
  3463. #ifndef STUBMPI
  3464. CASE ( 'xzy', 'yzx', 'xyz', 'yxz', 'zxy', 'zyx', 'xy', 'yx' )
  3465. distributed_field = .TRUE.
  3466. CASE ( 'xsz', 'xez', 'xs', 'xe' )
  3467. CALL are_bdys_distributed( distributed_field )
  3468. CASE ( 'ysz', 'yez', 'ys', 'ye' )
  3469. CALL are_bdys_distributed( distributed_field )
  3470. #endif
  3471. CASE DEFAULT
  3472. ! all other memory orders are replicated
  3473. distributed_field = .FALSE.
  3474. END SELECT
  3475. IF ( distributed_field ) THEN
  3476. ! added 8/2004 for interfaces, like MCEL, that want the old values so they can be updated
  3477. IF ( update_arg ) THEN
  3478. SELECT CASE (TRIM(MemOrd))
  3479. CASE ( 'xzy','zxy','xyz','yxz','xy','yx' )
  3480. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  3481. CALL wrf_patch_to_global_double ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  3482. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3483. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3484. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3485. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  3486. CALL wrf_patch_to_global_real ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  3487. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3488. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3489. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3490. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  3491. CALL wrf_patch_to_global_integer ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  3492. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3493. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3494. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3495. ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  3496. CALL wrf_patch_to_global_logical ( Field , globbuf , DomainDesc, Stagger, MemOrd , &
  3497. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3498. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3499. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3500. ENDIF
  3501. CASE DEFAULT
  3502. END SELECT
  3503. ENDIF
  3504. IF ( wrf_dm_on_monitor()) THEN
  3505. CALL fcn ( Hndl , DateStr , VarName , globbuf , FieldType , Comm , IOComm , &
  3506. DomainDesc , MemoryOrder , Stagger , DimNames , &
  3507. DomainStart , DomainEnd , &
  3508. DomainStart , dom_end_rev , &
  3509. DomainStart , DomainEnd , &
  3510. Status )
  3511. ENDIF
  3512. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  3513. CALL lower_case( MemoryOrder, MemOrd )
  3514. #if defined(DM_PARALLEL) && !defined(STUBMPI)
  3515. ! handle boundaries separately
  3516. IF ( TRIM(MemOrd) .EQ. 'xsz' .OR. TRIM(MemOrd) .EQ. 'xez' .OR. &
  3517. TRIM(MemOrd) .EQ. 'xs' .OR. TRIM(MemOrd) .EQ. 'xe' .OR. &
  3518. TRIM(MemOrd) .EQ. 'ysz' .OR. TRIM(MemOrd) .EQ. 'yez' .OR. &
  3519. TRIM(MemOrd) .EQ. 'ys' .OR. TRIM(MemOrd) .EQ. 'ye' ) THEN
  3520. IF ( TRIM(MemOrd) .EQ. 'xsz' .OR. TRIM(MemOrd) .EQ. 'xez' .OR. &
  3521. TRIM(MemOrd) .EQ. 'xs' .OR. TRIM(MemOrd) .EQ. 'xe' ) THEN
  3522. jds=DomainStart(1); jde=dom_end_rev(1); ids=DomainStart(3); ide=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
  3523. jms=MemoryStart(1); jme= MemoryEnd(1); ims=MemoryStart(3); ime= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
  3524. jps= PatchStart(1); jpe= PatchEnd(1); ips= PatchStart(3); ipe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
  3525. IF ( nproc .GT. 1 ) THEN
  3526. ! Will assume that the i,j, and k dimensions correspond to the model_data_order specified by the registry --
  3527. ! 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
  3528. ! sides of domain) the j is fully dimensioned, i is the bdy_width, and k is k. corresponding arrangement for ys/ye
  3529. ! boundaries (bottom and top). Note, however, that for the boundary arrays themselves, the innermost dimension is always
  3530. ! 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
  3531. ! for confusion between the MODEL storage order, and which of the sd31:ed31/sd32:ed32/sd33:ed33 framework dimensions
  3532. ! correspond to X/Y/Z as determined by the Registry dimespec definitions and what the storage order of the boundary
  3533. ! slab arrays are (which depends on which boundaries they represent). The k memory and domain dimensions must be set
  3534. ! properly for 2d (ks=1, ke=1) versus 3d fields.
  3535. #if 1
  3536. IF ( (MemOrd(1:2) .EQ. 'xs' .AND. bdy_mask( P_XSB )) .OR. &
  3537. (MemOrd(1:2) .EQ. 'xe' .AND. bdy_mask( P_XEB )) ) THEN
  3538. my_displ = jps-1
  3539. my_count = jpe-jps+1
  3540. ELSE
  3541. my_displ = 0
  3542. my_count = 0
  3543. ENDIF
  3544. #else
  3545. IF ( (MemOrd(1:2) .EQ. 'xs' ) .OR. &
  3546. (MemOrd(1:2) .EQ. 'xe' ) ) THEN
  3547. my_displ = jps-1
  3548. my_count = jpe-jps+1
  3549. ELSE
  3550. my_displ = 0
  3551. my_count = 0
  3552. ENDIF
  3553. #endif
  3554. CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
  3555. CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
  3556. do i = ips,ipe ! bdy_width
  3557. do k = kds,kde ! levels
  3558. lx = jme-jms+1
  3559. lx2 = jde-jds+1
  3560. idx = lx*((k-1)+(i-1)*(kme-kms+1))
  3561. idx2 = lx2*((k-1)+(i-1)*(kde-kds+1))
  3562. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  3563. CALL wrf_scatterv_double ( &
  3564. globbuf, 1+idx2 , & ! sendbuf
  3565. counts , & ! sendcounts
  3566. Field, jps-jms+1+idx , &
  3567. my_count , & ! recvcount
  3568. displs , & ! displs
  3569. collective_root , & ! root
  3570. communicator , & ! communicator
  3571. ierr )
  3572. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  3573. CALL wrf_scatterv_real ( &
  3574. globbuf, 1+idx2 , & ! sendbuf
  3575. counts , & ! sendcounts
  3576. Field, jps-jms+1+idx , &
  3577. my_count , & ! recvcount
  3578. displs , & ! displs
  3579. collective_root , & ! root
  3580. communicator , & ! communicator
  3581. ierr )
  3582. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  3583. CALL wrf_scatterv_integer ( &
  3584. globbuf, 1+idx2 , & ! sendbuf
  3585. counts , & ! sendcounts
  3586. Field, jps-jms+1+idx , &
  3587. my_count , & ! recvcount
  3588. displs , & ! displs
  3589. collective_root , & ! root
  3590. communicator , & ! communicator
  3591. ierr )
  3592. ENDIF
  3593. enddo
  3594. enddo
  3595. ENDIF
  3596. ENDIF
  3597. IF ( TRIM(MemOrd) .EQ. 'ysz' .OR. TRIM(MemOrd) .EQ. 'yez' .OR. &
  3598. TRIM(MemOrd) .EQ. 'ys' .OR. TRIM(MemOrd) .EQ. 'ye' ) THEN
  3599. ids=DomainStart(1); ide=dom_end_rev(1); jds=DomainStart(3); jde=dom_end_rev(3); kds=DomainStart(2); kde=dom_end_rev(2);
  3600. ims=MemoryStart(1); ime= MemoryEnd(1); jms=MemoryStart(3); jme= MemoryEnd(3); kms=MemoryStart(2); kme= MemoryEnd(2);
  3601. ips= PatchStart(1); ipe= PatchEnd(1); jps= PatchStart(3); jpe= PatchEnd(3); kps= PatchStart(2); kpe= PatchEnd(2);
  3602. IF ( nproc .GT. 1 ) THEN
  3603. #if 1
  3604. IF ( (MemOrd(1:2) .EQ. 'ys' .AND. bdy_mask( P_YSB )) .OR. &
  3605. (MemOrd(1:2) .EQ. 'ye' .AND. bdy_mask( P_YEB )) ) THEN
  3606. my_displ = ips-1
  3607. my_count = ipe-ips+1
  3608. ELSE
  3609. my_displ = 0
  3610. my_count = 0
  3611. ENDIF
  3612. #else
  3613. IF ( (MemOrd(1:2) .EQ. 'ys' ) .OR. &
  3614. (MemOrd(1:2) .EQ. 'ye' ) ) THEN
  3615. my_displ = ips-1
  3616. my_count = ipe-ips+1
  3617. ELSE
  3618. my_displ = 0
  3619. my_count = 0
  3620. ENDIF
  3621. #endif
  3622. CALL mpi_gather( my_displ, 1, MPI_INTEGER, displs, 1, MPI_INTEGER, collective_root, communicator, ierr )
  3623. CALL mpi_gather( my_count, 1, MPI_INTEGER, counts, 1, MPI_INTEGER, collective_root, communicator, ierr )
  3624. do j = jds,jde ! bdy_width
  3625. do k = kds,kde ! levels
  3626. lx = ime-ims+1
  3627. lx2 = ide-ids+1
  3628. idx = lx*((k-1)+(j-1)*(kme-kms+1))
  3629. idx2 = lx2*((k-1)+(j-1)*(kde-kds+1))
  3630. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  3631. CALL wrf_scatterv_double ( &
  3632. globbuf, 1+idx2 , & ! sendbuf
  3633. counts , & ! sendcounts
  3634. Field, ips-ims+1+idx , &
  3635. my_count , & ! recvcount
  3636. displs , & ! displs
  3637. collective_root , & ! root
  3638. communicator , & ! communicator
  3639. ierr )
  3640. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  3641. CALL wrf_scatterv_real ( &
  3642. globbuf, 1+idx2 , & ! sendbuf
  3643. counts , & ! sendcounts
  3644. Field, ips-ims+1+idx , &
  3645. my_count , & ! recvcount
  3646. displs , & ! displs
  3647. collective_root , & ! root
  3648. communicator , & ! communicator
  3649. ierr )
  3650. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  3651. CALL wrf_scatterv_integer ( &
  3652. globbuf, 1+idx2 , & ! sendbuf
  3653. counts , & ! sendcounts
  3654. Field, ips-ims+1+idx , &
  3655. my_count , & ! recvcount
  3656. displs , & ! displs
  3657. collective_root , & ! root
  3658. communicator , & ! communicator
  3659. ierr )
  3660. ENDIF
  3661. enddo
  3662. enddo
  3663. ENDIF
  3664. ENDIF
  3665. ELSE ! not a boundary
  3666. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  3667. SELECT CASE (MemOrd)
  3668. CASE ( 'xzy','xyz','yxz','zxy' )
  3669. CALL wrf_global_to_patch_double ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3670. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3671. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3672. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3673. CASE ( 'xy','yx' )
  3674. CALL wrf_global_to_patch_double ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3675. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
  3676. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
  3677. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
  3678. END SELECT
  3679. ELSE IF ( FieldType .EQ. WRF_FLOAT ) THEN
  3680. SELECT CASE (MemOrd)
  3681. CASE ( 'xzy','xyz','yxz','zxy' )
  3682. CALL wrf_global_to_patch_real ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3683. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3684. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3685. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3686. CASE ( 'xy','yx' )
  3687. CALL wrf_global_to_patch_real ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3688. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
  3689. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
  3690. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
  3691. END SELECT
  3692. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  3693. SELECT CASE (MemOrd)
  3694. CASE ( 'xzy','xyz','yxz','zxy' )
  3695. CALL wrf_global_to_patch_integer ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3696. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3697. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3698. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3699. CASE ( 'xy','yx' )
  3700. CALL wrf_global_to_patch_integer ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3701. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
  3702. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
  3703. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
  3704. END SELECT
  3705. ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  3706. SELECT CASE (MemOrd)
  3707. CASE ( 'xzy','xyz','yxz','zxy' )
  3708. CALL wrf_global_to_patch_logical ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3709. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), DomainStart(3), DomainEnd(3), &
  3710. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), MemoryStart(3), MemoryEnd(3), &
  3711. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , PatchStart(3) , PatchEnd(3) )
  3712. CASE ( 'xy','yx' )
  3713. CALL wrf_global_to_patch_logical ( globbuf, Field , DomainDesc, Stagger, MemOrd , &
  3714. DomainStart(1), DomainEnd(1), DomainStart(2), DomainEnd(2), 1 , 1 , &
  3715. MemoryStart(1), MemoryEnd(1), MemoryStart(2), MemoryEnd(2), 1 , 1 , &
  3716. PatchStart(1) , PatchEnd(1) , PatchStart(2) , PatchEnd(2) , 1 , 1 )
  3717. END SELECT
  3718. ENDIF
  3719. ENDIF
  3720. #endif
  3721. ELSE ! not a distributed field
  3722. IF ( wrf_dm_on_monitor()) THEN
  3723. CALL fcn ( Hndl , DateStr , VarName , Field , FieldType , Comm , IOComm , &
  3724. DomainDesc , MemoryOrder , Stagger , DimNames , &
  3725. DomainStart , DomainEnd , &
  3726. MemoryStart , MemoryEnd , &
  3727. PatchStart , PatchEnd , &
  3728. Status )
  3729. ENDIF
  3730. CALL wrf_dm_bcast_bytes( Status, IWORDSIZE )
  3731. memsize = (MemoryEnd(1)-MemoryStart(1)+1)*(MemoryEnd(2)-MemoryStart(2)+1)*(MemoryEnd(3)-MemoryStart(3)+1)
  3732. IF ( FieldType .EQ. WRF_DOUBLE ) THEN
  3733. CALL wrf_dm_bcast_bytes( Field , DWORDSIZE*memsize )
  3734. ELSE IF ( FieldType .EQ. WRF_FLOAT) THEN
  3735. CALL wrf_dm_bcast_bytes( Field , RWORDSIZE*memsize )
  3736. ELSE IF ( FieldType .EQ. WRF_INTEGER ) THEN
  3737. CALL wrf_dm_bcast_bytes( Field , IWORDSIZE*memsize )
  3738. ELSE IF ( FieldType .EQ. WRF_LOGICAL ) THEN
  3739. CALL wrf_dm_bcast_bytes( Field , LWORDSIZE*memsize )
  3740. ENDIF
  3741. ENDIF
  3742. DEALLOCATE(displs)
  3743. DEALLOCATE(counts)
  3744. RETURN
  3745. END SUBROUTINE call_pkg_and_dist_generic
  3746. !!!!!! Miscellaneous routines
  3747. ! stole these routines from io_netcdf external package; changed names to avoid collisions
  3748. SUBROUTINE dim_from_memorder(MemoryOrder,NDim)
  3749. !<DESCRIPTION>
  3750. !<PRE>
  3751. ! Decodes array ranks from memory order.
  3752. !</PRE>
  3753. !</DESCRIPTION>
  3754. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  3755. INTEGER ,INTENT(OUT) :: NDim
  3756. !Local
  3757. CHARACTER*3 :: MemOrd
  3758. !
  3759. CALL Lower_Case(MemoryOrder,MemOrd)
  3760. SELECT CASE (MemOrd)
  3761. CASE ('xyz','xzy','yxz','yzx','zxy','zyx')
  3762. NDim = 3
  3763. CASE ('xy','yx')
  3764. NDim = 2
  3765. CASE ('z','c','0')
  3766. NDim = 1
  3767. CASE DEFAULT
  3768. NDim = 0
  3769. RETURN
  3770. END SELECT
  3771. RETURN
  3772. END SUBROUTINE dim_from_memorder
  3773. SUBROUTINE lower_case(MemoryOrder,MemOrd)
  3774. !<DESCRIPTION>
  3775. !<PRE>
  3776. ! Translates upper-case characters to lower-case.
  3777. !</PRE>
  3778. !</DESCRIPTION>
  3779. CHARACTER*(*) ,INTENT(IN) :: MemoryOrder
  3780. CHARACTER*(*) ,INTENT(OUT) :: MemOrd
  3781. !Local
  3782. CHARACTER*1 :: c
  3783. INTEGER ,PARAMETER :: upper_to_lower =IACHAR('a')-IACHAR('A')
  3784. INTEGER :: i,n,n1
  3785. !
  3786. MemOrd = ' '
  3787. N = len(MemoryOrder)
  3788. N1 = len(MemOrd)
  3789. N = MIN(N,N1)
  3790. MemOrd(1:N) = MemoryOrder(1:N)
  3791. DO i=1,N
  3792. c = MemoryOrder(i:i)
  3793. if('A'<=c .and. c <='Z') MemOrd(i:i)=achar(iachar(c)+upper_to_lower)
  3794. ENDDO
  3795. RETURN
  3796. END SUBROUTINE Lower_Case
  3797. LOGICAL FUNCTION has_char( str, c )
  3798. !<DESCRIPTION>
  3799. !<PRE>
  3800. ! Returns .TRUE. iff string str contains character c. Ignores character case.
  3801. !</PRE>
  3802. !</DESCRIPTION>
  3803. IMPLICIT NONE
  3804. CHARACTER*(*) str
  3805. CHARACTER c, d
  3806. CHARACTER*80 str1, str2, str3
  3807. INTEGER i
  3808. CALL lower_case( TRIM(str), str1 )
  3809. str2 = ""
  3810. str2(1:1) = c
  3811. CALL lower_case( str2, str3 )
  3812. d = str3(1:1)
  3813. DO i = 1, LEN(TRIM(str1))
  3814. IF ( str1(i:i) .EQ. d ) THEN
  3815. has_char = .TRUE.
  3816. RETURN
  3817. ENDIF
  3818. ENDDO
  3819. has_char = .FALSE.
  3820. RETURN
  3821. END FUNCTION has_char