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 , &
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, sysdepinfo_tmp
40 CALL wrf_debug ( 100 , 'calling wrf_open_for_write_begin in open_w_dataset' )
42 IF ( grid%id < 10 ) THEN
43 write(sysdepinfo_tmp,'(a,i1)')TRIM(sysdepinfo)//',GRIDID=',grid%id
45 write(sysdepinfo_tmp,'(a,i2)')TRIM(sysdepinfo)//',GRIDID=',grid%id
47 CALL wrf_open_for_write_begin ( fname , &
49 grid%iocommunicator , &
53 IF ( ierr .LE. 0 ) THEN
54 CALL wrf_debug ( 100 , 'calling outsub in open_w_dataset' )
55 CALL outsub( id , grid , config_flags , ierr )
56 CALL wrf_debug ( 100 , 'back from outsub in open_w_dataset' )
58 IF ( ierr .LE. 0 ) THEN
59 CALL wrf_debug ( 100 , 'calling wrf_open_for_write_commit in open_w_dataset' )
60 CALL wrf_open_for_write_commit ( id , &
62 CALL wrf_debug ( 100 , 'back from wrf_open_for_write_commit in open_w_dataset' )
64 END SUBROUTINE open_w_dataset
66 SUBROUTINE open_u_dataset ( id , fname , grid , config_flags , insub , sysdepinfo, ierr )
68 CHARACTER*(*) :: fname
69 CHARACTER*(*) :: sysdepinfo
70 INTEGER , INTENT(INOUT) :: id , ierr
71 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
72 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
74 CHARACTER*128 :: DataSet
76 CALL wrf_debug ( 100 , 'calling wrf_open_for_read_begin in open_u_dataset' )
77 CALL wrf_open_for_read_begin ( fname , &
79 grid%iocommunicator , &
83 IF ( ierr .LE. 0 ) THEN
84 CALL wrf_debug ( 100 , 'calling insub in open_u_dataset' )
85 CALL insub( id , grid , config_flags , ierr )
87 IF ( ierr .LE. 0 ) THEN
88 CALL wrf_debug ( 100 , 'calling wrf_open_for_read_commit in open_u_dataset' )
89 CALL wrf_open_for_read_commit ( id , &
91 CALL wrf_debug ( 100 , 'back from wrf_open_for_read_commit in open_u_dataset' )
93 END SUBROUTINE open_u_dataset
95 SUBROUTINE close_dataset( id , config_flags, sysdepinfo )
98 LOGICAL , EXTERNAL :: wrf_dm_on_monitor
99 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
100 CHARACTER*(*) :: sysdepinfo
101 CHARACTER*128 :: DataSet
103 CALL wrf_ioclose( id , ierr )
104 END SUBROUTINE close_dataset
107 ! ------------ Output model input data sets
109 #include "module_io_domain_defs.inc"
111 ! ------------ Input model restart data sets
113 SUBROUTINE input_restart ( fid , grid , config_flags , ierr )
116 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
117 INTEGER, INTENT(IN) :: fid
118 INTEGER, INTENT(INOUT) :: ierr
119 IF ( config_flags%io_form_restart .GT. 0 ) THEN
120 CALL input_wrf ( fid , grid , config_flags , restart_only , ierr )
123 END SUBROUTINE input_restart
125 ! ------------ Input model boundary data sets
127 SUBROUTINE input_boundary ( fid , grid , config_flags , ierr )
130 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
131 INTEGER, INTENT(IN) :: fid
132 INTEGER, INTENT(INOUT) :: ierr
133 IF ( config_flags%io_form_boundary .GT. 0 ) THEN
134 CALL input_wrf ( fid , grid , config_flags , boundary_only , ierr )
137 END SUBROUTINE input_boundary
139 ! ------------ Output model restart data sets
141 SUBROUTINE output_restart ( fid , grid , config_flags , ierr )
144 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
145 INTEGER, INTENT(IN) :: fid
146 INTEGER, INTENT(INOUT) :: ierr
147 IF ( config_flags%io_form_restart .GT. 0 ) THEN
148 CALL output_wrf ( fid , grid , config_flags , restart_only , ierr )
151 END SUBROUTINE output_restart
153 ! ------------ Output model boundary data sets
155 SUBROUTINE output_boundary ( fid , grid , config_flags , ierr )
158 TYPE(grid_config_rec_type), INTENT(IN ) :: config_flags
159 INTEGER, INTENT(IN) :: fid
160 INTEGER, INTENT(INOUT) :: ierr
161 IF ( config_flags%io_form_boundary .GT. 0 ) THEN
162 CALL output_wrf ( fid , grid , config_flags , boundary_only , ierr )
165 END SUBROUTINE output_boundary
167 END MODULE module_io_domain
169 ! move outside module so callable without USE of module
170 SUBROUTINE construct_filename1( result , basename , fld1 , len1 )
172 CHARACTER*(*) :: result
173 CHARACTER*(*) :: basename
174 INTEGER , INTENT(IN) :: fld1 , len1
175 CHARACTER*64 :: t1, zeros
177 CALL zero_pad ( t1 , fld1 , len1 )
178 result = TRIM(basename) // "_d" // TRIM(t1)
179 CALL maybe_remove_colons(result)
181 END SUBROUTINE construct_filename1
183 SUBROUTINE construct_filename2( result , basename , fld1 , len1 , date_char )
185 CHARACTER*(*) :: result
186 CHARACTER*(*) :: basename
187 CHARACTER*(*) :: date_char
189 INTEGER , INTENT(IN) :: fld1 , len1
190 CHARACTER*64 :: t1, zeros
191 CALL zero_pad ( t1 , fld1 , len1 )
192 result = TRIM(basename) // ".d" // TRIM(t1) // "." // TRIM(date_char)
193 CALL maybe_remove_colons(result)
195 END SUBROUTINE construct_filename2
197 ! this version looks for <date> and <domain> in the basename and replaces with the arguments
199 SUBROUTINE construct_filename2a( result , basename , fld1 , len1 , date_char )
201 CHARACTER*(*) :: result
202 CHARACTER*(*) :: basename
203 CHARACTER*(*) :: date_char
204 INTEGER , INTENT(IN) :: fld1 , len1
205 CHARACTER*64 :: t1, zeros
209 CALL zero_pad ( t1 , fld1 , len1 )
210 i = index( basename , '<domain>' )
211 l = len(trim(basename))
213 result = basename(1:i-1) // TRIM(t1) // basename(i+8:l)
215 i = index( result , '<date>' )
216 l = len(trim(result))
218 result = result(1:i-1) // TRIM(date_char) // result(i+6:l)
220 CALL maybe_remove_colons(result)
222 END SUBROUTINE construct_filename2a
224 SUBROUTINE construct_filename ( result , basename , fld1 , len1 , fld2 , len2 )
226 CHARACTER*(*) :: result
227 CHARACTER*(*) :: basename
228 INTEGER , INTENT(IN) :: fld1 , len1 , fld2 , len2
229 CHARACTER*64 :: t1, t2, zeros
231 CALL zero_pad ( t1 , fld1 , len1 )
232 CALL zero_pad ( t2 , fld2 , len2 )
233 result = TRIM(basename) // "_d" // TRIM(t1) // "_" // TRIM(t2)
234 CALL maybe_remove_colons(result)
236 END SUBROUTINE construct_filename
238 SUBROUTINE construct_filename3 ( result , basename , fld1 , len1 , fld2 , len2, fld3, len3 )
240 CHARACTER*(*) :: result
241 CHARACTER*(*) :: basename
242 INTEGER , INTENT(IN) :: fld1 , len1 , fld2 , len2, fld3, len3
243 CHARACTER*64 :: t1, t2, t3, zeros
245 CALL zero_pad ( t1 , fld1 , len1 )
246 CALL zero_pad ( t2 , fld2 , len2 )
247 CALL zero_pad ( t3 , fld3 , len3 )
248 result = TRIM(basename) // "_d" // TRIM(t1) // "_" // TRIM(t2) // "_" // TRIM(t3)
249 CALL maybe_remove_colons(result)
251 END SUBROUTINE construct_filename3
253 SUBROUTINE construct_filename4( result , basename , fld1 , len1 , date_char , io_form )
254 USE module_state_description
256 CHARACTER*(*) :: result
257 CHARACTER*(*) :: basename
258 CHARACTER*(*) :: date_char
260 INTEGER, EXTERNAL :: use_package
261 INTEGER , INTENT(IN) :: fld1 , len1 , io_form
262 CHARACTER*64 :: t1, zeros
264 CALL zero_pad ( t1 , fld1 , len1 )
265 IF ( use_package(io_form) .EQ. IO_INTIO ) THEN
267 ELSE IF ( use_package(io_form) .EQ. IO_NETCDF ) THEN
269 ELSE IF ( use_package(io_form) .EQ. IO_PNETCDF ) THEN
271 ELSE IF ( use_package(io_form) .EQ. IO_GRIB1 ) THEN
274 CALL wrf_error_fatal ('improper io_form')
276 result = TRIM(basename) // ".d" // TRIM(t1) // "." // TRIM(date_char) // TRIM(ext)
277 CALL maybe_remove_colons(result)
279 END SUBROUTINE construct_filename4
281 ! this version looks for <date> and <domain> in the basename and replaces with the arguments
283 SUBROUTINE construct_filename4a( result , basename , fld1 , len1 , date_char , io_form )
284 USE module_state_description
286 CHARACTER*(*) :: result
287 CHARACTER*(*) :: basename
288 CHARACTER*(*) :: date_char
290 INTEGER, EXTERNAL :: use_package
291 INTEGER , INTENT(IN) :: fld1 , len1 , io_form
292 CHARACTER*64 :: t1, zeros
296 CALL zero_pad ( t1 , fld1 , len1 )
297 IF ( use_package(io_form) .EQ. IO_INTIO ) THEN
299 ELSE IF ( use_package(io_form) .EQ. IO_NETCDF ) THEN
301 ELSE IF ( use_package(io_form) .EQ. IO_PNETCDF ) THEN
303 ELSE IF ( use_package(io_form) .EQ. IO_GRIB1 ) THEN
306 CALL wrf_error_fatal ('improper io_form')
308 l = len(trim(basename))
309 result = basename(1:l) // TRIM(ext)
310 i = index( result , '<domain>' )
311 l = len(trim(result))
313 result = result(1:i-1) // TRIM(t1) // result(i+8:l)
315 i = index( result , '<date>' )
316 l = len(trim(result))
318 result = result(1:i-1) // TRIM(date_char) // result(i+6:l)
320 CALL maybe_remove_colons(result)
322 END SUBROUTINE construct_filename4a
324 SUBROUTINE append_to_filename ( result , basename , fld1 , len1 )
326 CHARACTER*(*) :: result
327 CHARACTER*(*) :: basename
328 INTEGER , INTENT(IN) :: fld1 , len1
329 CHARACTER*64 :: t1, zeros
331 CALL zero_pad ( t1 , fld1 , len1 )
332 result = TRIM(basename) // "_" // TRIM(t1)
333 CALL maybe_remove_colons(result)
335 END SUBROUTINE append_to_filename
337 SUBROUTINE zero_pad ( result , fld1 , len1 )
339 CHARACTER*(*) :: result
340 INTEGER , INTENT (IN) :: fld1 , len1
342 CHARACTER*64 :: t2, zeros
349 zeros = '0000000000000000000000000000000'
350 result = zeros(1:len1-d) // t2(9-d+1:9)
352 END SUBROUTINE zero_pad
354 SUBROUTINE init_wrfio
355 USE module_io, ONLY : wrf_ioinit
358 CALL wrf_ioinit(ierr)
359 END SUBROUTINE init_wrfio
362 ! This routine figures out the nearest previous time instant
363 ! that corresponds to a multiple of the input time interval.
364 ! Example use is to give the time instant that corresponds to
365 ! an I/O interval, even when the current time is a little bit
366 ! past that time when, for example, the number of model time
367 ! steps does not evenly divide the I/O interval. JM 20051013
370 SUBROUTINE adjust_io_timestr ( TI, CT, ST, timestr )
374 TYPE(WRFU_Time), INTENT(IN) :: ST,CT ! domain start and current time
375 TYPE(WRFU_TimeInterval), INTENT(IN) :: TI ! interval
376 CHARACTER*(*), INTENT(INOUT) :: timestr ! returned string
378 TYPE(WRFU_Time) :: OT
379 TYPE(WRFU_TimeInterval) :: IOI
382 IOI = CT-ST ! length of time since starting
383 n = WRFU_TimeIntervalDIVQuot( IOI , TI ) ! number of whole time intervals
384 IOI = TI * n ! amount of time since starting in whole time intervals
385 OT = ST + IOI ! previous nearest time instant
386 CALL wrf_timetoa( OT, timestr ) ! generate string
388 END SUBROUTINE adjust_io_timestr
390 ! Modify the filename to remove things like ':' from the file name
391 ! unless it is a drive number. Convert to '_' instead.
393 SUBROUTINE maybe_remove_colons( FileName )
394 CHARACTER*(*) FileName
398 l = LEN(TRIM(FileName))
399 ! do not change first two characters (naive way of dealing with
400 ! possiblity of drive name in a microsoft path
401 CALL nl_get_nocolons(1,nocolons)
404 IF ( FileName(i:i) .EQ. ':' ) THEN