22 #include <fms_platform.h> 24 use mpp_mod,
only: mpp_pe, mpp_npes, mpp_root_pe, mpp_init, mpp_exit
30 use mpp_domains_mod,
only: mpp_domains_set_stack_size, mpp_define_io_domain
31 use mpp_io_mod,
only: mpp_open, mpp_close, mpp_ascii, mpp_rdonly
39 integer :: sizex_latlon_grid = 144
40 integer :: sizey_latlon_grid = 90
41 integer :: size_cubic_grid = 48
42 integer :: nz = 10, nt = 2, halo = 1
44 integer :: stackmax =4000000
45 integer :: num_step = 4
47 logical :: do_write=.true.
49 integer :: layout_cubic (2) = (/0,0/)
50 integer :: layout_latlon(2) = (/0,0/)
51 integer :: io_layout(2) = (/0,0/)
53 logical :: read_only = .false.
55 namelist /test_fms_io_nml/ sizex_latlon_grid, sizey_latlon_grid, size_cubic_grid, &
56 nz, nt, halo, num_step, stackmax, do_write, layout_cubic, layout_latlon, io_layout, &
59 integer :: unit, io_status, step
60 character(len=20) :: time_stamp
62 type data_storage_type
63 real,
allocatable,
dimension(:,:,:,:,:) :: data1_r4d, data2_r4d, data1_r4d_read, data2_r4d_read
64 real,
allocatable,
dimension(:,:,:,:) :: data1_r3d, data2_r3d, data1_r3d_read, data2_r3d_read
65 real,
allocatable,
dimension(:,:,:) :: data1_r2d, data2_r2d, data1_r2d_read, data2_r2d_read
66 real,
allocatable,
dimension(:,:) :: data1_r1d, data2_r1d, data1_r1d_read, data2_r1d_read
67 real,
allocatable,
dimension(:) :: data1_r0d, data2_r0d, data1_r0d_read, data2_r0d_read
68 integer,
allocatable,
dimension(:,:,:,:) :: data1_i3d, data2_i3d, data1_i3d_read, data2_i3d_read
69 integer,
allocatable,
dimension(:,:,:) :: data1_i2d, data2_i2d, data1_i2d_read, data2_i2d_read
70 integer,
allocatable,
dimension(:,:) :: data1_i1d, data2_i1d, data1_i1d_read, data2_i1d_read
71 integer,
allocatable,
dimension(:) :: data1_i0d, data2_i0d, data1_i0d_read, data2_i0d_read
72 end type data_storage_type
74 type(data_storage_type),
save :: latlon_data
75 type(data_storage_type),
save :: cubic_data
76 type(domain2d),
save :: domain_latlon
77 type(domain2d),
save :: domain_cubic
78 type(restart_file_type),
save :: restart_latlon
79 type(restart_file_type),
save :: restart_cubic
80 integer :: ntile_latlon = 1
81 integer :: ntile_cubic = 6
84 character(len=128) :: file_latlon, file_cubic
94 #ifdef INTERNAL_FILE_NML 97 if (file_exist(
'input.nml') )
then 98 call mpp_open(unit,
'input.nml',form=mpp_ascii,action=mpp_rdonly)
99 read(unit,test_fms_io_nml,iostat=io_status)
100 call mpp_close (unit)
103 if (io_status > 0)
then 104 call mpp_error(fatal,
'=>test_fms_io: Error reading test_fms_io_nml')
108 if(nt > 2 .OR. nt < 1)
call mpp_error(fatal,
"test_fms_io: nt should be 1 or 2")
111 write(outunit, test_fms_io_nml )
112 call mpp_domains_set_stack_size(stackmax)
114 if(nt > 2)
call mpp_error(fatal,
"test_fms_io: test_fms_io_nml variable nt should be no larger than 2")
116 file_latlon =
"test.res.latlon_grid.save_restore.nc" 117 file_cubic =
"test.res.cubic_grid.save_restore.nc" 119 call setup_test_restart(restart_latlon,
"latlon_grid", ntile_latlon, latlon_data, file_latlon, layout_latlon, domain_latlon)
120 call setup_test_restart(restart_cubic,
"cubic_grid", ntile_cubic, cubic_data, file_cubic, layout_cubic, domain_cubic )
122 if(file_exist(
'INPUT/'//trim(file_latlon), domain_latlon))
then 124 call compare_restart(
"latlon_grid save_restore", latlon_data, .true.)
126 if(file_exist(
'INPUT/'//trim(file_cubic), domain_cubic) )
then 128 call compare_restart(
"cubic_grid save_restore", cubic_data, .true. )
132 if(mod(npes,ntile_latlon) == 0)
call copy_restart_data(latlon_data)
133 if(mod(npes,ntile_cubic) == 0 )
call copy_restart_data(cubic_data)
135 do step = 1, num_step
136 write(time_stamp,
'(a,I4.4)')
"step", step
137 if(mod(npes,ntile_latlon) == 0)
call save_restart(restart_latlon, time_stamp)
138 if(mod(npes,ntile_cubic) == 0 )
call save_restart(restart_cubic, time_stamp)
140 if(mod(npes,ntile_latlon) == 0)
call save_restart(restart_latlon)
141 if(mod(npes,ntile_cubic) == 0)
call save_restart(restart_cubic)
143 if(mod(npes,ntile_latlon) == 0)
call release_storage_memory(latlon_data)
144 if(mod(npes,ntile_cubic) == 0 )
call release_storage_memory(cubic_data)
146 if(mod(npes,ntile_cubic) == 0 )
call mpp_error(note,
"test_fms_io: restart test is done for latlon_grid")
147 if(mod(npes,ntile_cubic) == 0 )
call mpp_error(note,
"test_fms_io: restart test is done for cubic_grid")
150 call mpp_domains_exit
156 subroutine setup_test_restart(restart_data, type, ntiles, storage, file, layout_in, domain)
157 type(restart_file_type),
intent(inout) :: restart_data
158 character(len=*),
intent(in) :: type
159 integer,
intent(in) :: ntiles
160 type(data_storage_type),
intent(inout) :: storage
161 character(len=*),
intent(in) :: file
162 integer,
intent(in) :: layout_in(:)
163 type(domain2d),
intent(inout) :: domain
164 character(len=128) :: file_r
165 character(len=128) :: file_w
166 integer :: pe, npes_per_tile, tile
167 integer :: num_contact
168 integer :: n, layout(2)
169 integer,
allocatable,
dimension(:,:) :: global_indices, layout2D
170 integer,
allocatable,
dimension(:) :: pe_start, pe_end
171 integer,
dimension(1) :: tile1, tile2
172 integer,
dimension(1) :: istart1, iend1, jstart1, jend1
173 integer,
dimension(1) :: istart2, iend2, jstart2, jend2
174 integer :: i, j, k, nx, ny, l
175 integer :: isc, iec, jsc, jec
176 integer :: isd, ied, jsd, jed
177 integer :: id_restart
179 file_r =
"INPUT/test.res."//trim(type)//
".read_write.nc" 180 file_w =
"RESTART/test.res."//trim(type)//
".read_write.nc" 184 nx = sizex_latlon_grid
185 ny = sizey_latlon_grid
190 call mpp_error(fatal,
"test_fms_io: "//type//
" is not a valid option")
194 if(mod(npes,ntiles) .NE. 0)
then 195 call mpp_error(note,
"test_fms_io: npes can not be divided by ntiles, no test will be done for "//trim(type))
198 npes_per_tile = npes/ntiles
199 tile = pe/npes_per_tile + 1
201 if(layout_in(1)*layout_in(2) == npes_per_tile)
then 206 if(io_layout(1) <1 .OR. io_layout(2) <1)
call mpp_error(fatal, &
207 "program test_fms_io: both elements of test_fms_io_nml variable io_layout must be positive integer")
208 if(mod(layout(1), io_layout(1)) .NE. 0 )
call mpp_error(fatal, &
209 "program test_fms_io: layout(1) must be divided by io_layout(1)")
210 if(mod(layout(2), io_layout(2)) .NE. 0 )
call mpp_error(fatal, &
211 "program test_fms_io: layout(2) must be divided by io_layout(2)")
212 allocate(global_indices(4,ntiles), layout2d(2,ntiles), pe_start(ntiles), pe_end(ntiles) )
214 global_indices(:,n) = (/1,nx,1,ny/)
215 layout2d(:,n) = layout
216 pe_start(n) = (n-1)*npes_per_tile
217 pe_end(n) = n*npes_per_tile-1
220 call mpp_define_mosaic(global_indices, layout2d, domain, ntiles, num_contact, tile1, tile2, &
221 istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2, &
222 pe_start, pe_end, whalo=halo, ehalo=halo, shalo=halo, nhalo=halo, name =
type )
223 if(io_layout(1) .NE. 1 .OR. io_layout(2) .NE. 1)
call mpp_define_io_domain(domain, io_layout)
228 allocate(storage%data1_r3d(isd:ied, jsd:jed, nz, nt), storage%data1_r3d_read(isd:ied, jsd:jed, nz, nt) )
229 allocate(storage%data2_r3d(isd:ied, jsd:jed, nz, nt), storage%data2_r3d_read(isd:ied, jsd:jed, nz, nt) )
230 allocate(storage%data1_r4d(isd:ied, jsd:jed, nz, nl, nt) )
231 allocate(storage%data1_r4d_read(isd:ied, jsd:jed, nz, nl, nt) )
232 allocate(storage%data2_r4d(isd:ied, jsd:jed, nz, nl, nt) )
233 allocate(storage%data2_r4d_read(isd:ied, jsd:jed, nz, nl, nt) )
234 allocate(storage%data1_i3d(isd:ied, jsd:jed, nz, nt), storage%data1_i3d_read(isd:ied, jsd:jed, nz, nt) )
235 allocate(storage%data2_i3d(isd:ied, jsd:jed, nz, nt), storage%data2_i3d_read(isd:ied, jsd:jed, nz, nt) )
236 allocate(storage%data1_r2d(isd:ied, jsd:jed, nt), storage%data1_r2d_read(isd:ied, jsd:jed, nt) )
237 allocate(storage%data2_r2d(isd:ied, jsd:jed, nt), storage%data2_r2d_read(isd:ied, jsd:jed, nt) )
238 allocate(storage%data1_i2d(isd:ied, jsd:jed, nt), storage%data1_i2d_read(isd:ied, jsd:jed, nt) )
239 allocate(storage%data2_i2d(isd:ied, jsd:jed, nt), storage%data2_i2d_read(isd:ied, jsd:jed, nt) )
240 allocate(storage%data1_r1d( nz, nt), storage%data1_r1d_read( nz, nt) )
241 allocate(storage%data2_r1d( nz, nt), storage%data2_r1d_read( nz, nt) )
242 allocate(storage%data1_i1d( nz, nt), storage%data1_i1d_read( nz, nt) )
243 allocate(storage%data2_i1d( nz, nt), storage%data2_i1d_read( nz, nt) )
244 allocate(storage%data1_r0d( nt), storage%data1_r0d_read( nt) )
245 allocate(storage%data2_r0d( nt), storage%data2_r0d_read( nt) )
246 allocate(storage%data1_i0d( nt), storage%data1_i0d_read( nt) )
247 allocate(storage%data2_i0d( nt), storage%data2_i0d_read( nt) )
249 storage%data1_r3d = 0; storage%data1_r3d_read = 0; storage%data2_r3d = 0; storage%data2_r3d_read = 0
250 storage%data1_i3d = 0; storage%data1_i3d_read = 0; storage%data2_i3d = 0; storage%data2_i3d_read = 0
251 storage%data1_r2d = 0; storage%data1_r2d_read = 0; storage%data2_r2d = 0; storage%data2_r2d_read = 0
252 storage%data1_i2d = 0; storage%data1_i2d_read = 0; storage%data2_i2d = 0; storage%data2_i2d_read = 0
253 storage%data1_r1d = 0; storage%data1_r1d_read = 0; storage%data2_r1d = 0; storage%data2_r1d_read = 0
254 storage%data1_i1d = 0; storage%data1_i1d_read = 0; storage%data2_i1d = 0; storage%data2_i1d_read = 0
255 storage%data1_r0d = 0; storage%data1_r0d_read = 0; storage%data2_r0d = 0; storage%data2_r0d_read = 0
256 storage%data1_i0d = 0; storage%data1_i0d_read = 0; storage%data2_i0d = 0; storage%data2_i0d_read = 0
257 storage%data1_r4d = 0; storage%data1_r4d_read = 0; storage%data2_r4d = 0; storage%data2_r4d_read = 0
259 storage%data1_r0d(n) = tile + n*1e-3
260 storage%data2_r0d(n) = -tile - n*1e-3
261 storage%data1_i0d(n) = tile*1e3 + n
262 storage%data2_i0d(n) = -tile*1e3 - n
267 storage%data1_r4d(i,j,k,l,n) = l*1e9 + tile*1e6 + n*1e3 + k + i*1e-3 + j*1e-6;
268 storage%data2_r4d(i,j,k,l,n) = -l*1e9 - tile*1e6 - n*1e3 + k - i*1e-3 - j*1e-6;
274 storage%data1_r1d(k,n) = tile*1e3 + n + k*1e-3
275 storage%data2_r1d(k,n) = -tile*1e3 - n - k*1e-3
276 storage%data1_i1d(k,n) = tile*1e6 + n*1e3 + k
277 storage%data2_i1d(k,n) = -tile*1e6 - n*1e3 - k
280 storage%data1_r3d(i,j,k,n) = tile*1e6 + n*1e3 + k + i*1e-3 + j*1e-6;
281 storage%data2_r3d(i,j,k,n) = -tile*1e6 - n*1e3 - k - i*1e-3 - j*1e-6;
282 storage%data1_i3d(i,j,k,n) = (n*ntiles+tile)*1e8 + k*1e6 + i*1e3 + j;
283 storage%data2_i3d(i,j,k,n) = -(n*ntiles+tile)*1e8 - k*1e6 - i*1e3 - j;
290 storage%data1_r2d(i,j,n) = tile*1e1 + n + i*1e-3 + j*1e-6;
291 storage%data2_r2d(i,j,n) = -tile*1e1 - n - i*1e-3 - j*1e-6;
292 storage%data1_i2d(i,j,n) = tile*1e7 + n*1e6 + i*1e3 + j;
293 storage%data2_i2d(i,j,n) = -tile*1e7 - n*1e6 - i*1e3 - j;
297 if(file_exist(file_r, domain))
then 299 call read_data(file_r,
"data1_r3d", storage%data1_r3d_read(:,:,:,n), domain, timelevel = n )
300 call read_data(file_r,
"data2_r3d", storage%data2_r3d_read(:,:,:,n), domain, timelevel = n )
301 call read_data(file_r,
"data1_i3d", storage%data1_i3d_read(:,:,:,n), domain, timelevel = n )
302 call read_data(file_r,
"data2_i3d", storage%data2_i3d_read(:,:,:,n), domain, timelevel = n )
303 call read_data(file_r,
"data1_r2d", storage%data1_r2d_read(:,:, n), domain, timelevel = n )
304 call read_data(file_r,
"data2_r2d", storage%data2_r2d_read(:,:, n), domain, timelevel = n )
305 call read_data(file_r,
"data1_i2d", storage%data1_i2d_read(:,:, n), domain, timelevel = n )
306 call read_data(file_r,
"data2_i2d", storage%data2_i2d_read(:,:, n), domain, timelevel = n )
307 call read_data(file_r,
"data1_r1d", storage%data1_r1d_read(:, n), domain, timelevel = n )
308 call read_data(file_r,
"data2_r1d", storage%data2_r1d_read(:, n), domain, timelevel = n )
309 call read_data(file_r,
"data1_i1d", storage%data1_i1d_read(:, n), domain, timelevel = n )
310 call read_data(file_r,
"data2_i1d", storage%data2_i1d_read(:, n), domain, timelevel = n )
311 call read_data(file_r,
"data1_r0d", storage%data1_r0d_read( n), domain, timelevel = n )
312 call read_data(file_r,
"data2_r0d", storage%data2_r0d_read( n), domain, timelevel = n )
313 call read_data(file_r,
"data1_i0d", storage%data1_i0d_read( n), domain, timelevel = n )
314 call read_data(file_r,
"data2_i0d", storage%data2_i0d_read( n), domain, timelevel = n )
316 call compare_restart(type//
" read_write", storage, .false.)
323 call write_data(file_w,
"data1_r3d", storage%data1_r3d(:,:,:,n), domain )
324 call write_data(file_w,
"data2_r3d", storage%data2_r3d(:,:,:,n), domain )
325 call write_data(file_w,
"data1_i3d", storage%data1_i3d(:,:,:,n), domain )
326 call write_data(file_w,
"data2_i3d", storage%data2_i3d(:,:,:,n), domain )
327 call write_data(file_w,
"data1_r2d", storage%data1_r2d(:,:, n), domain )
328 call write_data(file_w,
"data2_r2d", storage%data2_r2d(:,:, n), domain )
329 call write_data(file_w,
"data1_i2d", storage%data1_i2d(:,:, n), domain )
330 call write_data(file_w,
"data2_i2d", storage%data2_i2d(:,:, n), domain )
331 call write_data(file_w,
"data1_r1d", storage%data1_r1d(:, n), domain )
332 call write_data(file_w,
"data2_r1d", storage%data2_r1d(:, n), domain )
333 call write_data(file_w,
"data1_i1d", storage%data1_i1d(:, n), domain )
334 call write_data(file_w,
"data2_i1d", storage%data2_i1d(:, n), domain )
335 call write_data(file_w,
"data1_r0d", storage%data1_r0d( n), domain )
336 call write_data(file_w,
"data2_r0d", storage%data2_r0d( n), domain )
337 call write_data(file_w,
"data1_i0d", storage%data1_i0d( n), domain )
338 call write_data(file_w,
"data2_i0d", storage%data2_i0d( n), domain )
345 domain, longname=
"first data_r3d",units=
"none", read_only=read_only)
347 domain, longname=
"first data_r3d",units=
"none", read_only=read_only)
349 storage%data2_r3d_read(:,:,:,2), &
350 domain, longname=
"second data_i3d", units=
"none")
353 domain, longname=
"first data_r4d",units=
"none")
355 domain, longname=
"first data_r4d",units=
"none")
357 domain, longname=
"second data_r4d",units=
"none")
360 domain, longname=
"first data_i3d",units=
"none")
362 domain, longname=
"first data_i3d",units=
"none")
364 storage%data2_i3d_read(:,:,:,2), &
365 domain, longname=
"second data_i3d", units=
"none")
368 domain, longname=
"first data_r2d",units=
"none", read_only=read_only)
370 domain, longname=
"first data_r2d",units=
"none", read_only=read_only)
372 storage%data2_r2d_read(:,:,2), &
373 domain, longname=
"second data_i2d", units=
"none")
376 domain, longname=
"first data_i2d",units=
"none", read_only=read_only)
378 domain, longname=
"first data_i2d",units=
"none", read_only=read_only)
380 storage%data2_i2d_read(:,:,2), &
381 domain, longname=
"second data_i2d", units=
"none", read_only=read_only)
384 domain, longname=
"first data_r1d",units=
"none")
386 domain, longname=
"first data_r1d",units=
"none")
388 storage%data2_r1d_read(:, 2), &
389 domain, longname=
"second data_i1d", units=
"none")
392 domain, longname=
"first data_i1d",units=
"none", read_only=read_only)
394 domain, longname=
"first data_i1d",units=
"none", read_only=read_only)
396 storage%data2_i1d_read(:, 2), &
397 domain, longname=
"second data_i1d", units=
"none")
401 domain, longname=
"first data_r0d",units=
"none", read_only=read_only)
403 domain, longname=
"first data_r0d",units=
"none", read_only=read_only)
405 storage%data2_r0d_read( 2), &
406 domain, longname=
"second data_i0d", units=
"none")
409 domain, longname=
"first data_i0d",units=
"none")
411 domain, longname=
"first data_i0d",units=
"none")
413 storage%data2_i0d_read( 2), &
414 domain, longname=
"second data_i0d", units=
"none")
416 end subroutine setup_test_restart
418 subroutine compare_restart(type, storage, compare_r4d)
419 character(len=*),
intent(in) :: type
420 type(data_storage_type),
intent(inout) :: storage
421 logical,
intent(in ) :: compare_r4d
424 call compare_data_r5d(storage%data1_r4d, storage%data1_r4d_read, type//
" data1_r4d")
425 call compare_data_r5d(storage%data2_r4d(:,:,:,:,1:1), storage%data2_r4d_read(:,:,:,:,1:1), type//
" data2_r4d")
427 call compare_data_r4d(storage%data1_r3d, storage%data1_r3d_read, type//
" data1_r3d")
428 call compare_data_r4d(storage%data2_r3d, storage%data2_r3d_read, type//
" data2_r3d")
429 call compare_data_i4d(storage%data1_i3d, storage%data1_i3d_read, type//
" data1_i3d")
430 call compare_data_i4d(storage%data2_i3d, storage%data2_i3d_read, type//
" data2_i3d")
431 call compare_data_r3d(storage%data1_r2d, storage%data1_r2d_read, type//
" data1_r2d")
432 call compare_data_r3d(storage%data2_r2d, storage%data2_r2d_read, type//
" data2_r2d")
433 call compare_data_i3d(storage%data1_i2d, storage%data1_i2d_read, type//
" data1_i2d")
434 call compare_data_i3d(storage%data2_i2d, storage%data2_i2d_read, type//
" data2_i2d")
435 call compare_data_r2d(storage%data1_r1d, storage%data1_r1d_read, type//
" data1_r1d")
436 call compare_data_r2d(storage%data2_r1d, storage%data2_r1d_read, type//
" data2_r1d")
437 call compare_data_i2d(storage%data1_i1d, storage%data1_i1d_read, type//
" data1_i1d")
438 call compare_data_i2d(storage%data2_i1d, storage%data2_i1d_read, type//
" data2_i1d")
439 call compare_data_r1d(storage%data1_r0d, storage%data1_r0d_read, type//
" data1_r0d")
440 call compare_data_r1d(storage%data2_r0d, storage%data2_r0d_read, type//
" data2_r0d")
441 call compare_data_i1d(storage%data1_i0d, storage%data1_i0d_read, type//
" data1_i0d")
442 call compare_data_i1d(storage%data2_i0d, storage%data2_i0d_read, type//
" data2_i0d")
444 end subroutine compare_restart
446 subroutine release_storage_memory(storage)
447 type(data_storage_type),
intent(inout) :: storage
449 deallocate(storage%data1_r3d, storage%data2_r3d, storage%data1_r3d_read, storage%data2_r3d_read)
450 deallocate(storage%data1_i3d, storage%data2_i3d, storage%data1_i3d_read, storage%data2_i3d_read)
451 deallocate(storage%data1_r2d, storage%data2_r2d, storage%data1_r2d_read, storage%data2_r2d_read)
452 deallocate(storage%data1_i2d, storage%data2_i2d, storage%data1_i2d_read, storage%data2_i2d_read)
453 deallocate(storage%data1_r1d, storage%data2_r1d, storage%data1_r1d_read, storage%data2_r1d_read)
454 deallocate(storage%data1_i1d, storage%data2_i1d, storage%data1_i1d_read, storage%data2_i1d_read)
455 deallocate(storage%data1_r0d, storage%data2_r0d, storage%data1_r0d_read, storage%data2_r0d_read)
456 deallocate(storage%data1_i0d, storage%data2_i0d, storage%data1_i0d_read, storage%data2_i0d_read)
457 deallocate(storage%data1_r4d, storage%data2_r4d, storage%data1_r4d_read, storage%data2_r4d_read)
459 end subroutine release_storage_memory
461 subroutine copy_restart_data(storage)
462 type(data_storage_type),
intent(inout) :: storage
465 storage%data1_r3d_read = storage%data1_r3d; storage%data2_r3d_read = storage%data2_r3d
466 storage%data1_i3d_read = storage%data1_i3d; storage%data2_i3d_read = storage%data2_i3d
467 storage%data1_r2d_read = storage%data1_r2d; storage%data2_r2d_read = storage%data2_r2d
468 storage%data1_i2d_read = storage%data1_i2d; storage%data2_i2d_read = storage%data2_i2d
469 storage%data1_r1d_read = storage%data1_r1d; storage%data2_r1d_read = storage%data2_r1d
470 storage%data1_i1d_read = storage%data1_i1d; storage%data2_i1d_read = storage%data2_i1d
471 storage%data1_r0d_read = storage%data1_r0d; storage%data2_r0d_read = storage%data2_r0d
472 storage%data1_i0d_read = storage%data1_i0d; storage%data2_i0d_read = storage%data2_i0d
473 storage%data1_r4d_read = storage%data1_r4d; storage%data2_r4d_read = storage%data2_r4d
477 end subroutine copy_restart_data
479 subroutine compare_data_r5d( a, b, string )
480 real,
intent(in),
dimension(:,:,:,:,:) :: a, b
481 character(len=*),
intent(in) :: string
482 integer(LONG_KIND) :: sum1, sum2
483 integer :: i, j, k, l, n
484 integer,
parameter :: stdunit = 6
486 if(
size(a,1) .ne.
size(b,1) .or.
size(a,2) .ne.
size(b,2) .or.
size(a,3) .ne.
size(b,3) &
487 .or.
size(a,4) .ne.
size(b,4) .or.
size(a,5) .ne.
size(b,5) ) &
488 call mpp_error(fatal,
'compare_data_r5d: size of a and b does not match')
494 if(a(i,j,k,l,n) .ne. b(i,j,k,l,n))
then 495 write(stdunit,
'(a,i3,a,i3,a,i3,a,i3,a,i3,a,i3,a,f18.6,a,f18.6)')
" at pe ", mpp_pe(), &
496 ", at point (",i,
", ", j,
", ", k,
", ", l,
", ", n,
"), a = ", a(i,j,k,l,n),
",& 498 call mpp_error(fatal, trim(
string)//
': point by point comparison are not OK.')
508 if( sum1.EQ.sum2 )
then 509 if( mpp_pe() .EQ. mpp_root_pe() )
call mpp_error( note, trim(
string)//
': OK.' )
516 end subroutine compare_data_r5d
519 subroutine compare_data_r4d( a, b, string )
520 real,
intent(in),
dimension(:,:,:,:) :: a, b
521 character(len=*),
intent(in) :: string
522 integer(LONG_KIND) :: sum1, sum2
523 integer :: i, j, k, l
524 integer,
parameter :: stdunit = 6
526 if(
size(a,1) .ne.
size(b,1) .or.
size(a,2) .ne.
size(b,2) .or.
size(a,3) .ne.
size(b,3) .or.
size(a,4) .ne.
size(b,4) ) &
527 call mpp_error(fatal,
'compare_data_r4d: size of a and b does not match')
533 if(a(i,j,k,l) .ne. b(i,j,k,l))
then 534 write(stdunit,
'(a,i3,a,i3,a,i3,a,i3,a,i3,a,f18.6,a,f18.6)')
" at pe ", mpp_pe(), &
535 ", at point (",i,
", ", j,
", ", k,
", ", l,
"), a = ", a(i,j,k,l),
", b = ", b(i,j,k,l)
536 call mpp_error(fatal, trim(
string)//
': point by point comparison are not OK.')
545 if( sum1.EQ.sum2 )
then 546 if( mpp_pe() .EQ. mpp_root_pe() )
call mpp_error( note, trim(
string)//
': OK.' )
553 end subroutine compare_data_r4d
555 subroutine compare_data_i4d( a, b, string )
556 integer,
intent(in),
dimension(:,:,:,:) :: a, b
557 character(len=*),
intent(in) :: string
558 real :: real_a(size(a,1),size(a,2),size(a,3),size(a,4))
559 real :: real_b(size(b,1),size(b,2),size(b,3),size(b,4))
563 call compare_data_r4d(real_a, real_b,
string)
565 end subroutine compare_data_i4d
568 subroutine compare_data_r3d( a, b, string )
569 real,
intent(in),
dimension(:,:,:) :: a, b
570 character(len=*),
intent(in) :: string
571 integer(LONG_KIND) :: sum1, sum2
573 integer,
parameter :: stdunit = 6
575 if(
size(a,1) .ne.
size(b,1) .or.
size(a,2) .ne.
size(b,2) .or.
size(a,3) .ne.
size(b,3) ) &
576 call mpp_error(fatal,
'compare_data_r3d: size of a and b does not match')
581 if(a(i,j,l) .ne. b(i,j,l))
then 582 write(stdunit,
'(a,i3,a,i3,a,i3,a,i3,a,f16.9,a,f16.9)')
" at pe ", mpp_pe(), &
583 ", at point (",i,
", ", j,
", ", l,
"), a = ", a(i,j,l),
", b = ", b(i,j,l)
584 call mpp_error(fatal, trim(
string)//
': point by point comparison are not OK.')
592 if( sum1.EQ.sum2 )
then 593 if( mpp_pe() .EQ. mpp_root_pe() )
call mpp_error( note, trim(
string)//
': OK.' )
600 end subroutine compare_data_r3d
602 subroutine compare_data_i3d( a, b, string )
603 integer,
intent(in),
dimension(:,:,:) :: a, b
604 character(len=*),
intent(in) :: string
605 real :: real_a(size(a,1),size(a,2),size(a,3))
606 real :: real_b(size(b,1),size(b,2),size(b,3))
610 call compare_data_r3d(real_a, real_b,
string)
612 end subroutine compare_data_i3d
615 subroutine compare_data_r2d( a, b, string )
616 real,
intent(in),
dimension(:,:) :: a, b
617 character(len=*),
intent(in) :: string
618 integer(LONG_KIND) :: sum1, sum2
620 integer,
parameter :: stdunit = 6
622 if(
size(a,1) .ne.
size(b,1) .or.
size(a,2) .ne.
size(b,2) ) &
623 call mpp_error(fatal,
'compare_data_r2d: size of a and b does not match')
627 if(a(i,l) .ne. b(i,l))
then 628 write(stdunit,
'(a,i3,a,i3,a,i3,a,f16.6,a,f16.6)')
" at pe ", mpp_pe(), &
629 ", at point (",i,
", ", l,
"), a = ", a(i,l),
", b = ", b(i,l)
630 call mpp_error(fatal, trim(
string)//
': point by point comparison are not OK.')
637 if( sum1.EQ.sum2 )
then 638 if( mpp_pe() .EQ. mpp_root_pe() )
call mpp_error( note, trim(
string)//
': OK.' )
645 end subroutine compare_data_r2d
647 subroutine compare_data_i2d( a, b, string )
648 integer,
intent(in),
dimension(:,:) :: a, b
649 character(len=*),
intent(in) :: string
650 real :: real_a(size(a,1),size(a,2))
651 real :: real_b(size(b,1),size(b,2))
655 call compare_data_r2d(real_a, real_b,
string)
657 end subroutine compare_data_i2d
659 subroutine compare_data_r1d( a, b, string )
660 real,
intent(in),
dimension(:) :: a, b
661 character(len=*),
intent(in) :: string
662 integer(LONG_KIND) :: sum1, sum2
664 integer,
parameter :: stdunit = 6
666 if(
size(a,1) .ne.
size(b,1) ) &
667 call mpp_error(fatal,
'compare_data_r1d: size of a and b does not match')
670 if(a(l) .ne. b(l))
then 671 write(stdunit,
'(a,i3,a,i3,a,f16.6,a,f16.6)')
" at pe ", mpp_pe(), &
672 ", at point (",l,
"), a = ", a(l),
", b = ", b(l)
673 call mpp_error(fatal, trim(
string)//
': point by point comparison are not OK.')
679 if( sum1.EQ.sum2 )
then 680 if( mpp_pe() .EQ. mpp_root_pe() )
call mpp_error( note, trim(
string)//
': OK.' )
687 end subroutine compare_data_r1d
689 subroutine compare_data_i1d( a, b, string )
690 integer,
intent(in),
dimension(:) :: a, b
691 character(len=*),
intent(in) :: string
692 real :: real_a(size(a(:)))
693 real :: real_b(size(b(:)))
697 call compare_data_r1d(real_a, real_b,
string)
699 end subroutine compare_data_i1d
701 end program fms_io_test
707 #endif /* test_fms_io */
logical function, public file_exist(file_name, domain, no_domain)
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
subroutine, public fms_io_init()
subroutine, public fms_io_exit()
subroutine, public save_restart(fileObj, time_stamp, directory, append, time_level)