1 !WRF:MEDIATION_LAYER:IO
4 MODULE module_io_domain
7 USE module_configure, ONLY : grid_config_rec_type
8 USE module_domain, ONLY : domain
12 SUBROUTINE open_r_dataset ( id , fname , grid , config_flags , sysdepinfo, ierr )
14 CHARACTER*(*) :: fname
15 CHARACTER*(*) :: sysdepinfo
16 INTEGER , INTENT(INOUT) :: id , ierr
17 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
18 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
19 CHARACTER*128 :: DataSet, tmp
21 CALL wrf_open_for_read ( fname , &
27 END SUBROUTINE open_r_dataset
29 SUBROUTINE open_w_dataset ( id , fname , grid , config_flags , outsub , sysdepinfo, ierr )
31 CHARACTER*(*) :: fname
32 CHARACTER*(*) :: sysdepinfo
33 INTEGER , INTENT(INOUT) :: id , ierr
34 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
35 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
37 CHARACTER*128 :: DataSet, sysdepinfo_tmp
39 CALL wrf_debug ( 100 , 'calling wrf_open_for_write_begin in open_w_dataset' )
41 IF ( grid%id < 10 ) THEN
42 write(sysdepinfo_tmp,'(a,i1)')TRIM(sysdepinfo)//',GRIDID=',grid%id
44 write(sysdepinfo_tmp,'(a,i2)')TRIM(sysdepinfo)//',GRIDID=',grid%id
46 CALL wrf_open_for_write_begin ( fname , &
51 IF ( ierr .LE. 0 ) THEN
52 CALL wrf_debug ( 100 , 'calling outsub in open_w_dataset' )
53 CALL outsub( id , grid , config_flags , ierr )
54 CALL wrf_debug ( 100 , 'back from outsub in open_w_dataset' )
56 IF ( ierr .LE. 0 ) THEN
57 CALL wrf_debug ( 100 , 'calling wrf_open_for_write_commit in open_w_dataset' )
58 CALL wrf_open_for_write_commit ( id , ierr )
59 CALL wrf_debug ( 100 , 'back from wrf_open_for_write_commit in open_w_dataset' )
61 END SUBROUTINE open_w_dataset
63 SUBROUTINE open_u_dataset ( id , fname , grid , config_flags , insub , sysdepinfo, ierr )
65 CHARACTER*(*) :: fname
66 CHARACTER*(*) :: sysdepinfo
67 INTEGER , INTENT(INOUT) :: id , ierr
68 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
69 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
71 CHARACTER*128 :: DataSet
73 CALL wrf_debug ( 100 , 'calling wrf_open_for_read_begin in open_u_dataset' )
74 CALL wrf_open_for_read_begin ( fname , &
79 IF ( ierr .LE. 0 ) THEN
80 CALL wrf_debug ( 100 , 'calling insub in open_u_dataset' )
81 CALL insub( id , grid , config_flags , ierr )
83 IF ( ierr .LE. 0 ) THEN
84 CALL wrf_debug ( 100 , 'calling wrf_open_for_read_commit in open_u_dataset' )
85 CALL wrf_open_for_read_commit ( id , ierr )
86 CALL wrf_debug ( 100 , 'back from wrf_open_for_read_commit in open_u_dataset' )
88 END SUBROUTINE open_u_dataset
90 SUBROUTINE close_dataset( id , config_flags, sysdepinfo )
93 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
94 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
95 CHARACTER*(*) :: sysdepinfo
96 CHARACTER*128 :: DataSet
98 CALL wrf_ioclose( id , ierr )
99 END SUBROUTINE close_dataset
102 ! ------------ Output model input data sets
104 #include "module_io_domain_defs.inc"
106 ! ------------ Input model restart data sets
108 SUBROUTINE input_restart ( fid , grid , config_flags , ierr )
111 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
112 INTEGER, INTENT(IN) :: fid
113 INTEGER, INTENT(INOUT) :: ierr
114 IF ( config_flags%io_form_restart .GT. 0 ) THEN
115 CALL input_wrf ( fid , grid , config_flags , restart_only , ierr )
118 END SUBROUTINE input_restart
120 ! ------------ Input model boundary data sets
122 SUBROUTINE input_boundary ( fid , grid , config_flags , ierr )
125 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
126 INTEGER, INTENT(IN) :: fid
127 INTEGER, INTENT(INOUT) :: ierr
128 IF ( config_flags%io_form_boundary .GT. 0 ) THEN
129 CALL input_wrf ( fid , grid , config_flags , boundary_only , ierr )
132 END SUBROUTINE input_boundary
134 ! ------------ Output model restart data sets
136 SUBROUTINE output_restart ( fid , grid , config_flags , ierr )
139 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
140 INTEGER, INTENT(IN) :: fid
141 INTEGER, INTENT(INOUT) :: ierr
142 IF ( config_flags%io_form_restart .GT. 0 ) THEN
143 CALL output_wrf ( fid , grid , config_flags , restart_only , ierr )
146 END SUBROUTINE output_restart
148 ! ------------ Output model boundary data sets
150 SUBROUTINE output_boundary ( fid , grid , config_flags , ierr )
153 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
154 INTEGER, INTENT(IN) :: fid
155 INTEGER, INTENT(INOUT) :: ierr
156 IF ( config_flags%io_form_boundary .GT. 0 ) THEN
157 CALL output_wrf ( fid , grid , config_flags , boundary_only , ierr )
160 END SUBROUTINE output_boundary
162 END MODULE module_io_domain
164 ! move outside module so callable without USE of module
165 SUBROUTINE construct_filename1( result , basename , fld1 , len1 )
167 CHARACTER*(*) :: result
168 CHARACTER*(*) :: basename
169 INTEGER , INTENT(IN) :: fld1 , len1
170 CHARACTER*64 :: t1, zeros
172 CALL zero_pad ( t1 , fld1 , len1 )
173 result = TRIM(basename) // "_d" // TRIM(t1)
174 CALL maybe_remove_colons(result)
176 END SUBROUTINE construct_filename1
178 SUBROUTINE construct_filename2( result , basename , fld1 , len1 , date_char )
180 CHARACTER*(*) :: result
181 CHARACTER*(*) :: basename
182 CHARACTER*(*) :: date_char
184 INTEGER , INTENT(IN) :: fld1 , len1
185 CHARACTER*64 :: t1, zeros
186 CALL zero_pad ( t1 , fld1 , len1 )
187 result = TRIM(basename) // ".d" // TRIM(t1) // "." // TRIM(date_char)
188 CALL maybe_remove_colons(result)
190 END SUBROUTINE construct_filename2
192 ! this version looks for <date> and <domain> in the basename and replaces with the arguments
194 SUBROUTINE construct_filename2a( result , basename , fld1 , len1 , date_char )
196 CHARACTER*(*) :: result
197 CHARACTER*(*) :: basename
198 CHARACTER*(*) :: date_char
199 INTEGER , INTENT(IN) :: fld1 , len1
200 CHARACTER*64 :: t1, zeros
204 CALL zero_pad ( t1 , fld1 , len1 )
207 ! The string name length 12345678 including < > ----|
209 i = index( result , '<domain>' ) ! is this |
210 DO WHILE ( i .GT. 0 ) ! value |
211 l = len(trim(result)) ! \/
212 result = result (1:i-1) // TRIM(t1) // result(i+8:l)
213 i = index( result , '<domain>' )
216 i = index( result , '<date>' )
217 DO WHILE ( i .GT. 0 )
218 l = len(trim(result))
219 result = result(1:i-1) // TRIM(date_char) // result(i+6:l)
220 i = index( result , '<date>' )
223 i = index( result , '<year>' )
224 DO WHILE ( i .GT. 0 )
225 l = len(trim(result))
226 result = result(1:i-1) // TRIM(date_char( 1: 4)) // result(i+6:l)
227 i = index( result , '<year>' )
230 i = index( result , '<month>' )
231 DO WHILE ( i .GT. 0 )
232 l = len(trim(result))
233 result = result(1:i-1) // TRIM(date_char( 6: 7)) // result(i+7:l)
234 i = index( result , '<month>' )
237 i = index( result , '<day>' )
238 DO WHILE ( i .GT. 0 )
239 l = len(trim(result))
240 result = result(1:i-1) // TRIM(date_char( 9:10)) // result(i+5:l)
241 i = index( result , '<day>' )
244 i = index( result , '<hour>' )
245 DO WHILE ( i .GT. 0 )
246 l = len(trim(result))
247 result = result(1:i-1) // TRIM(date_char(12:13)) // result(i+6:l)
248 i = index( result , '<hour>' )
251 CALL maybe_remove_colons(result)
253 END SUBROUTINE construct_filename2a
255 SUBROUTINE construct_filename ( result , basename , fld1 , len1 , fld2 , len2 )
257 CHARACTER*(*) :: result
258 CHARACTER*(*) :: basename
259 INTEGER , INTENT(IN) :: fld1 , len1 , fld2 , len2
260 CHARACTER*64 :: t1, t2, zeros
262 CALL zero_pad ( t1 , fld1 , len1 )
263 CALL zero_pad ( t2 , fld2 , len2 )
264 result = TRIM(basename) // "_d" // TRIM(t1) // "_" // TRIM(t2)
265 CALL maybe_remove_colons(result)
267 END SUBROUTINE construct_filename
269 SUBROUTINE construct_filename3 ( result , basename , fld1 , len1 , fld2 , len2, fld3, len3 )
271 CHARACTER*(*) :: result
272 CHARACTER*(*) :: basename
273 INTEGER , INTENT(IN) :: fld1 , len1 , fld2 , len2, fld3, len3
274 CHARACTER*64 :: t1, t2, t3, zeros
276 CALL zero_pad ( t1 , fld1 , len1 )
277 CALL zero_pad ( t2 , fld2 , len2 )
278 CALL zero_pad ( t3 , fld3 , len3 )
279 result = TRIM(basename) // "_d" // TRIM(t1) // "_" // TRIM(t2) // "_" // TRIM(t3)
280 CALL maybe_remove_colons(result)
282 END SUBROUTINE construct_filename3
284 SUBROUTINE construct_filename4( result , basename , fld1 , len1 , date_char , io_form )
285 USE module_state_description
287 CHARACTER*(*) :: result
288 CHARACTER*(*) :: basename
289 CHARACTER*(*) :: date_char
291 INTEGER, EXTERNAL :: use_package
292 INTEGER , INTENT(IN) :: fld1 , len1 , io_form
293 CHARACTER*64 :: t1, zeros
295 CALL zero_pad ( t1 , fld1 , len1 )
296 IF ( use_package(io_form) .EQ. IO_INTIO ) THEN
298 ELSE IF ( use_package(io_form) .EQ. IO_NETCDF ) THEN
300 ELSE IF ( use_package(io_form) .EQ. IO_NETCDFPAR ) THEN
302 ELSE IF ( use_package(io_form) .EQ. IO_PNETCDF ) THEN
304 ELSE IF ( use_package(io_form) .EQ. IO_PIO ) THEN
306 ELSE IF ( use_package(io_form) .EQ. IO_GRIB1 ) THEN
309 CALL wrf_error_fatal ('improper io_form')
311 result = TRIM(basename) // ".d" // TRIM(t1) // "." // TRIM(date_char) // TRIM(ext)
312 CALL maybe_remove_colons(result)
314 END SUBROUTINE construct_filename4
316 ! this version looks for <date> and <domain> in the basename and replaces with the arguments
318 SUBROUTINE construct_filename4a( result , basename , fld1 , len1 , date_char , io_form )
319 USE module_state_description
321 CHARACTER*(*) :: result
322 CHARACTER*(*) :: basename
323 CHARACTER*(*) :: date_char
325 INTEGER, EXTERNAL :: use_package
326 INTEGER , INTENT(IN) :: fld1 , len1 , io_form
327 CHARACTER*64 :: t1, zeros
331 CALL zero_pad ( t1 , fld1 , len1 )
332 IF ( use_package(io_form) .EQ. IO_INTIO ) THEN
334 ELSE IF ( use_package(io_form) .EQ. IO_NETCDF ) THEN
336 ELSE IF ( use_package(io_form) .EQ. IO_PNETCDF ) THEN
338 ELSE IF ( use_package(io_form) .EQ. IO_PIO ) THEN
340 ELSE IF ( use_package(io_form) .EQ. IO_GRIB1 ) THEN
343 CALL wrf_error_fatal ('improper io_form')
345 l = len(trim(basename))
346 result = basename(1:l) // TRIM(ext)
348 ! The string name length 12345678 including < > ----|
350 i = index( result , '<domain>' ) ! is this |
351 DO WHILE ( i .GT. 0 ) ! value |
352 l = len(trim(result )) ! \/
353 result = result (1:i-1) // TRIM(t1) // result (i+8:l)
354 i = index( result , '<domain>' )
357 i = index( result , '<date>' )
358 DO WHILE ( i .GT. 0 )
359 l = len(trim(result))
360 result = result(1:i-1) // TRIM(date_char) // result(i+6:l)
361 i = index( result , '<date>' )
364 i = index( result , '<year>' )
365 DO WHILE ( i .GT. 0 )
366 l = len(trim(result))
367 result = result(1:i-1) // TRIM(date_char( 1: 4)) // result(i+6:l)
368 i = index( result , '<year>' )
371 i = index( result , '<month>' )
372 DO WHILE ( i .GT. 0 )
373 l = len(trim(result))
374 result = result(1:i-1) // TRIM(date_char( 6: 7)) // result(i+7:l)
375 i = index( result , '<month>' )
378 i = index( result , '<day>' )
379 DO WHILE ( i .GT. 0 )
380 l = len(trim(result))
381 result = result(1:i-1) // TRIM(date_char( 9:10)) // result(i+5:l)
382 i = index( result , '<day>' )
385 i = index( result , '<hour>' )
386 DO WHILE ( i .GT. 0 )
387 l = len(trim(result))
388 result = result(1:i-1) // TRIM(date_char(12:13)) // result(i+6:l)
389 i = index( result , '<hour>' )
391 CALL maybe_remove_colons(result)
394 END SUBROUTINE construct_filename4a
396 SUBROUTINE append_to_filename ( result , basename , fld1 , len1 )
398 CHARACTER*(*) :: result
399 CHARACTER*(*) :: basename
400 INTEGER , INTENT(IN) :: fld1 , len1
401 CHARACTER*64 :: t1, zeros
403 CALL zero_pad ( t1 , fld1 , len1 )
404 result = TRIM(basename) // "_" // TRIM(t1)
405 CALL maybe_remove_colons(result)
407 END SUBROUTINE append_to_filename
409 SUBROUTINE zero_pad ( result , fld1 , len1 )
411 CHARACTER*(*) :: result
412 INTEGER , INTENT (IN) :: fld1 , len1
414 CHARACTER*64 :: t2, zeros
421 zeros = '0000000000000000000000000000000'
422 result = zeros(1:len1-d) // t2(9-d+1:9)
424 END SUBROUTINE zero_pad
426 SUBROUTINE init_wrfio
427 USE module_io, ONLY : wrf_ioinit
430 CALL wrf_ioinit(ierr)
431 END SUBROUTINE init_wrfio
434 ! This routine figures out the nearest previous time instant
435 ! that corresponds to a multiple of the input time interval.
436 ! Example use is to give the time instant that corresponds to
437 ! an I/O interval, even when the current time is a little bit
438 ! past that time when, for example, the number of model time
439 ! steps does not evenly divide the I/O interval. JM 20051013
442 SUBROUTINE adjust_io_timestr ( TI, CT, ST, timestr )
446 TYPE(WRFU_Time), INTENT(IN) :: ST,CT ! domain start and current time
447 TYPE(WRFU_TimeInterval), INTENT(IN) :: TI ! interval
448 CHARACTER*(*), INTENT(INOUT) :: timestr ! returned string
450 TYPE(WRFU_Time) :: OT
451 TYPE(WRFU_TimeInterval) :: IOI
454 IOI = CT-ST ! length of time since starting
455 n = WRFU_TimeIntervalDIVQuot( IOI , TI ) ! number of whole time intervals
456 IOI = TI * n ! amount of time since starting in whole time intervals
457 OT = ST + IOI ! previous nearest time instant
458 CALL wrf_timetoa( OT, timestr ) ! generate string
460 END SUBROUTINE adjust_io_timestr
462 ! Modify the filename to remove things like ':' from the file name
463 ! unless it is a drive number. Convert to '_' instead.
465 SUBROUTINE maybe_remove_colons( FileName )
466 CHARACTER*(*) FileName
470 l = LEN(TRIM(FileName))
471 ! do not change first two characters (naive way of dealing with
472 ! possiblity of drive name in a microsoft path
473 CALL nl_get_nocolons(1,nocolons)
476 IF ( FileName(i:i) .EQ. ':' ) THEN
478 ! Remove this modification to filename - dashes are OK
479 ! ELSE IF ( FileName(i:i) .EQ. '-' ) THEN
480 ! FileName(i:i) = '_'