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
21 CALL wrf_open_for_read ( fname , &
23 grid%iocommunicator , &
28 END SUBROUTINE open_r_dataset
30 SUBROUTINE open_w_dataset ( id , fname , grid , config_flags , outsub , sysdepinfo, ierr )
32 CHARACTER*(*) :: fname
33 CHARACTER*(*) :: sysdepinfo
34 INTEGER , INTENT(INOUT) :: id , ierr
35 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
36 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
38 CHARACTER*128 :: DataSet
40 CALL wrf_debug ( 100 , 'calling wrf_open_for_write_begin in open_w_dataset' )
41 CALL wrf_open_for_write_begin ( fname , &
43 grid%iocommunicator , &
47 IF ( ierr .LE. 0 ) THEN
48 CALL wrf_debug ( 100 , 'calling outsub in open_w_dataset' )
49 CALL outsub( id , grid , config_flags , ierr )
50 CALL wrf_debug ( 100 , 'back from outsub in open_w_dataset' )
52 IF ( ierr .LE. 0 ) THEN
53 CALL wrf_debug ( 100 , 'calling wrf_open_for_write_commit in open_w_dataset' )
54 CALL wrf_open_for_write_commit ( id , &
56 CALL wrf_debug ( 100 , 'back from wrf_open_for_write_commit in open_w_dataset' )
58 END SUBROUTINE open_w_dataset
60 SUBROUTINE open_u_dataset ( id , fname , grid , config_flags , insub , sysdepinfo, ierr )
62 CHARACTER*(*) :: fname
63 CHARACTER*(*) :: sysdepinfo
64 INTEGER , INTENT(INOUT) :: id , ierr
65 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
66 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
68 CHARACTER*128 :: DataSet
70 CALL wrf_debug ( 100 , 'calling wrf_open_for_read_begin in open_u_dataset' )
71 CALL wrf_open_for_read_begin ( fname , &
73 grid%iocommunicator , &
77 IF ( ierr .LE. 0 ) THEN
78 CALL wrf_debug ( 100 , 'calling insub in open_u_dataset' )
79 CALL insub( id , grid , config_flags , ierr )
81 IF ( ierr .LE. 0 ) THEN
82 CALL wrf_debug ( 100 , 'calling wrf_open_for_read_commit in open_u_dataset' )
83 CALL wrf_open_for_read_commit ( id , &
85 CALL wrf_debug ( 100 , 'back from wrf_open_for_read_commit in open_u_dataset' )
87 END SUBROUTINE open_u_dataset
89 SUBROUTINE close_dataset( id , config_flags, sysdepinfo )
92 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
93 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
94 CHARACTER*(*) :: sysdepinfo
95 CHARACTER*128 :: DataSet
97 CALL wrf_ioclose( id , ierr )
98 END SUBROUTINE close_dataset
101 ! ------------ Output model input data sets
103 #include "module_io_domain_defs.inc"
105 ! ------------ Input model restart data sets
107 SUBROUTINE input_restart ( fid , grid , config_flags , ierr )
110 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
111 INTEGER, INTENT(IN) :: fid
112 INTEGER, INTENT(INOUT) :: ierr
113 IF ( config_flags%io_form_restart .GT. 0 ) THEN
114 CALL input_wrf ( fid , grid , config_flags , restart_only , ierr )
117 END SUBROUTINE input_restart
119 ! ------------ Input model boundary data sets
121 SUBROUTINE input_boundary ( fid , grid , config_flags , ierr )
124 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
125 INTEGER, INTENT(IN) :: fid
126 INTEGER, INTENT(INOUT) :: ierr
127 IF ( config_flags%io_form_boundary .GT. 0 ) THEN
128 CALL input_wrf ( fid , grid , config_flags , boundary_only , ierr )
131 END SUBROUTINE input_boundary
133 ! ------------ Output model restart data sets
135 SUBROUTINE output_restart ( fid , grid , config_flags , ierr )
138 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
139 INTEGER, INTENT(IN) :: fid
140 INTEGER, INTENT(INOUT) :: ierr
141 IF ( config_flags%io_form_restart .GT. 0 ) THEN
143 !zhang: HWRF for bit reproducibility of random numbers when restarting
144 call random_seed(get=grid%nrnd1)
146 CALL output_wrf ( fid , grid , config_flags , restart_only , ierr )
149 END SUBROUTINE output_restart
151 ! ------------ Output model boundary data sets
153 SUBROUTINE output_boundary ( fid , grid , config_flags , ierr )
156 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
157 INTEGER, INTENT(IN) :: fid
158 INTEGER, INTENT(INOUT) :: ierr
159 IF ( config_flags%io_form_boundary .GT. 0 ) THEN
160 CALL output_wrf ( fid , grid , config_flags , boundary_only , ierr )
163 END SUBROUTINE output_boundary
165 END MODULE module_io_domain
167 ! move outside module so callable without USE of module
168 SUBROUTINE construct_filename1( result , basename , fld1 , len1 )
170 CHARACTER*(*) :: result
171 CHARACTER*(*) :: basename
172 INTEGER , INTENT(IN) :: fld1 , len1
173 CHARACTER*64 :: t1, zeros
175 CALL zero_pad ( t1 , fld1 , len1 )
176 result = TRIM(basename) // "_d" // TRIM(t1)
177 CALL maybe_remove_colons(result)
179 END SUBROUTINE construct_filename1
181 SUBROUTINE construct_filename2( result , basename , fld1 , len1 , date_char )
183 CHARACTER*(*) :: result
184 CHARACTER*(*) :: basename
185 CHARACTER*(*) :: date_char
187 INTEGER , INTENT(IN) :: fld1 , len1
188 CHARACTER*64 :: t1, zeros
189 CALL zero_pad ( t1 , fld1 , len1 )
190 result = TRIM(basename) // ".d" // TRIM(t1) // "." // TRIM(date_char)
191 CALL maybe_remove_colons(result)
193 END SUBROUTINE construct_filename2
195 ! this version looks for <date> and <domain> in the basename and replaces with the arguments
197 SUBROUTINE construct_filename2a( result , basename , fld1 , len1 , date_char )
199 CHARACTER*(*) :: result
200 CHARACTER*(*) :: basename
201 CHARACTER*(*) :: date_char
202 INTEGER , INTENT(IN) :: fld1 , len1
203 CHARACTER*64 :: t1, zeros
207 CALL zero_pad ( t1 , fld1 , len1 )
208 i = index( basename , '<domain>' )
209 l = len(trim(basename))
211 result = basename(1:i-1) // TRIM(t1) // basename(i+8:l)
213 i = index( result , '<date>' )
214 l = len(trim(result))
216 result = result(1:i-1) // TRIM(date_char) // result(i+6:l)
218 CALL maybe_remove_colons(result)
220 END SUBROUTINE construct_filename2a
222 SUBROUTINE construct_filename ( result , basename , fld1 , len1 , fld2 , len2 )
224 CHARACTER*(*) :: result
225 CHARACTER*(*) :: basename
226 INTEGER , INTENT(IN) :: fld1 , len1 , fld2 , len2
227 CHARACTER*64 :: t1, t2, zeros
229 CALL zero_pad ( t1 , fld1 , len1 )
230 CALL zero_pad ( t2 , fld2 , len2 )
231 result = TRIM(basename) // "_d" // TRIM(t1) // "_" // TRIM(t2)
232 CALL maybe_remove_colons(result)
234 END SUBROUTINE construct_filename
236 SUBROUTINE construct_filename3 ( result , basename , fld1 , len1 , fld2 , len2, fld3, len3 )
238 CHARACTER*(*) :: result
239 CHARACTER*(*) :: basename
240 INTEGER , INTENT(IN) :: fld1 , len1 , fld2 , len2, fld3, len3
241 CHARACTER*64 :: t1, t2, t3, zeros
243 CALL zero_pad ( t1 , fld1 , len1 )
244 CALL zero_pad ( t2 , fld2 , len2 )
245 CALL zero_pad ( t3 , fld3 , len3 )
246 result = TRIM(basename) // "_d" // TRIM(t1) // "_" // TRIM(t2) // "_" // TRIM(t3)
247 CALL maybe_remove_colons(result)
249 END SUBROUTINE construct_filename3
251 SUBROUTINE construct_filename4( result , basename , fld1 , len1 , date_char , io_form )
252 USE module_state_description
254 CHARACTER*(*) :: result
255 CHARACTER*(*) :: basename
256 CHARACTER*(*) :: date_char
258 INTEGER, EXTERNAL :: use_package
259 INTEGER , INTENT(IN) :: fld1 , len1 , io_form
260 CHARACTER*64 :: t1, zeros
262 CALL zero_pad ( t1 , fld1 , len1 )
263 IF ( use_package(io_form) .EQ. IO_INTIO ) THEN
265 ELSE IF ( use_package(io_form) .EQ. IO_NETCDF ) THEN
267 ELSE IF ( use_package(io_form) .EQ. IO_PNETCDF ) THEN
269 ELSE IF ( use_package(io_form) .EQ. IO_GRIB1 ) THEN
272 CALL wrf_error_fatal ('improper io_form')
274 result = TRIM(basename) // ".d" // TRIM(t1) // "." // TRIM(date_char) // TRIM(ext)
275 CALL maybe_remove_colons(result)
277 END SUBROUTINE construct_filename4
279 ! this version looks for <date> and <domain> in the basename and replaces with the arguments
281 SUBROUTINE construct_filename4a( result , basename , fld1 , len1 , date_char , io_form )
282 USE module_state_description
284 CHARACTER*(*) :: result
285 CHARACTER*(*) :: basename
286 CHARACTER*(*) :: date_char
288 INTEGER, EXTERNAL :: use_package
289 INTEGER , INTENT(IN) :: fld1 , len1 , io_form
290 CHARACTER*64 :: t1, zeros
294 CALL zero_pad ( t1 , fld1 , len1 )
295 IF ( use_package(io_form) .EQ. IO_INTIO ) THEN
297 ELSE IF ( use_package(io_form) .EQ. IO_NETCDF ) THEN
299 ELSE IF ( use_package(io_form) .EQ. IO_PNETCDF ) THEN
301 ELSE IF ( use_package(io_form) .EQ. IO_GRIB1 ) THEN
304 CALL wrf_error_fatal ('improper io_form')
306 l = len(trim(basename))
307 result = basename(1:l) // TRIM(ext)
308 i = index( result , '<domain>' )
309 l = len(trim(result))
311 result = result(1:i-1) // TRIM(t1) // result(i+8:l)
313 i = index( result , '<date>' )
314 l = len(trim(result))
316 result = result(1:i-1) // TRIM(date_char) // result(i+6:l)
318 CALL maybe_remove_colons(result)
320 END SUBROUTINE construct_filename4a
322 SUBROUTINE append_to_filename ( result , basename , fld1 , len1 )
324 CHARACTER*(*) :: result
325 CHARACTER*(*) :: basename
326 INTEGER , INTENT(IN) :: fld1 , len1
327 CHARACTER*64 :: t1, zeros
329 CALL zero_pad ( t1 , fld1 , len1 )
330 result = TRIM(basename) // "_" // TRIM(t1)
331 CALL maybe_remove_colons(result)
333 END SUBROUTINE append_to_filename
335 SUBROUTINE zero_pad ( result , fld1 , len1 )
337 CHARACTER*(*) :: result
338 INTEGER , INTENT (IN) :: fld1 , len1
340 CHARACTER*64 :: t2, zeros
347 zeros = '0000000000000000000000000000000'
348 result = zeros(1:len1-d) // t2(9-d+1:9)
350 END SUBROUTINE zero_pad
352 SUBROUTINE init_wrfio
353 USE module_io, ONLY : wrf_ioinit
356 CALL wrf_ioinit(ierr)
357 END SUBROUTINE init_wrfio
360 ! This routine figures out the nearest previous time instant
361 ! that corresponds to a multiple of the input time interval.
362 ! Example use is to give the time instant that corresponds to
363 ! an I/O interval, even when the current time is a little bit
364 ! past that time when, for example, the number of model time
365 ! steps does not evenly divide the I/O interval. JM 20051013
368 SUBROUTINE adjust_io_timestr ( TI, CT, ST, timestr )
372 TYPE(WRFU_Time), INTENT(IN) :: ST,CT ! domain start and current time
373 TYPE(WRFU_TimeInterval), INTENT(IN) :: TI ! interval
374 CHARACTER*(*), INTENT(INOUT) :: timestr ! returned string
376 TYPE(WRFU_Time) :: OT
377 TYPE(WRFU_TimeInterval) :: IOI
380 IOI = CT-ST ! length of time since starting
381 n = WRFU_TimeIntervalDIVQuot( IOI , TI ) ! number of whole time intervals
382 IOI = TI * n ! amount of time since starting in whole time intervals
383 OT = ST + IOI ! previous nearest time instant
384 CALL wrf_timetoa( OT, timestr ) ! generate string
386 END SUBROUTINE adjust_io_timestr
388 ! Modify the filename to remove things like ':' from the file name
389 ! unless it is a drive number. Convert to '_' instead.
391 SUBROUTINE maybe_remove_colons( FileName )
392 CHARACTER*(*) FileName
396 l = LEN(TRIM(FileName))
397 ! do not change first two characters (naive way of dealing with
398 ! possiblity of drive name in a microsoft path
399 CALL nl_get_nocolons(1,nocolons)
402 IF ( FileName(i:i) .EQ. ':' ) THEN