Line data Source code
1 : #ifdef ncdf
2 : #define USE_NETCDF
3 : #endif
4 : !=======================================================================
5 :
6 : ! Routines for opening, reading and writing external files
7 : !
8 : ! author: Tony Craig, NCAR
9 : !
10 : ! 2004: Block structure added by William Lipscomb, LANL
11 : ! 2006: Converted to free source form (F90) by Elizabeth Hunke
12 : ! 2007: netcdf versions added by Alison McLaren & Ann Keen, Met Office
13 :
14 : module ice_read_write
15 :
16 : use ice_kinds_mod
17 : use ice_constants, only: c0, spval_dbl, &
18 : field_loc_noupdate, field_type_noupdate
19 : use ice_communicate, only: my_task, master_task
20 : use ice_broadcast, only: broadcast_scalar
21 : use ice_domain, only: distrb_info, orca_halogrid
22 : use ice_domain_size, only: max_blocks, nx_global, ny_global, ncat
23 : use ice_blocks, only: nx_block, ny_block, nghost
24 : use ice_exit, only: abort_ice
25 : use ice_fileunits, only: nu_diag
26 :
27 : #ifdef USE_NETCDF
28 : use netcdf
29 : #endif
30 :
31 : implicit none
32 :
33 : private
34 :
35 : integer (kind=int_kind), parameter, private :: &
36 : bits_per_byte = 8 ! number of bits per byte.
37 : ! used to determine RecSize in ice_open
38 :
39 : public :: ice_open, &
40 : ice_open_ext, & ! LCOV_EXCL_LINE
41 : ice_open_nc, & ! LCOV_EXCL_LINE
42 : ice_read, & ! LCOV_EXCL_LINE
43 : ice_read_ext, & ! LCOV_EXCL_LINE
44 : ice_read_nc, & ! LCOV_EXCL_LINE
45 : ice_read_global, & ! LCOV_EXCL_LINE
46 : ice_read_global_nc, & ! LCOV_EXCL_LINE
47 : ice_read_nc_uv, & ! LCOV_EXCL_LINE
48 : ice_read_nc_xyf, & ! LCOV_EXCL_LINE
49 : ice_write, & ! LCOV_EXCL_LINE
50 : ice_write_nc, & ! LCOV_EXCL_LINE
51 : ice_write_ext, & ! LCOV_EXCL_LINE
52 : ice_read_vec_nc, & ! LCOV_EXCL_LINE
53 : ice_get_ncvarsize, & ! LCOV_EXCL_LINE
54 : ice_close_nc
55 :
56 : interface ice_write
57 : module procedure ice_write_xyt, &
58 : ice_write_xyzt
59 : end interface
60 :
61 : interface ice_read
62 : module procedure ice_read_xyt, &
63 : ice_read_xyzt
64 : end interface
65 :
66 : interface ice_read_nc
67 : module procedure ice_read_nc_xy, &
68 : ice_read_nc_xyz, & ! LCOV_EXCL_LINE
69 : !ice_read_nc_xyf, & ! LCOV_EXCL_LINE
70 : ice_read_nc_point, & ! LCOV_EXCL_LINE
71 : ice_read_nc_1D, & ! LCOV_EXCL_LINE
72 : ice_read_nc_2D, & ! LCOV_EXCL_LINE
73 : ice_read_nc_3D, & ! LCOV_EXCL_LINE
74 : ice_read_nc_z
75 : end interface
76 :
77 : interface ice_write_nc
78 : module procedure ice_write_nc_xy, &
79 : ice_write_nc_xyz
80 : end interface
81 :
82 : !=======================================================================
83 :
84 : contains
85 :
86 : !=======================================================================
87 :
88 : ! Opens an unformatted file for reading.
89 : ! nbits indicates whether the file is sequential or direct access.
90 : !
91 : ! author: Tony Craig, NCAR
92 :
93 84 : subroutine ice_open(nu, filename, nbits, algn)
94 :
95 : integer (kind=int_kind), intent(in) :: &
96 : nu , & ! unit number ! LCOV_EXCL_LINE
97 : nbits ! no. of bits per variable (0 for sequential access)
98 :
99 : integer (kind=int_kind), intent(in), optional :: algn
100 : integer (kind=int_kind) :: RecSize, Remnant, nbytes
101 :
102 : character (*) :: filename
103 :
104 : character(len=*), parameter :: subname = '(ice_open)'
105 :
106 84 : if (my_task == master_task) then
107 :
108 20 : if (nbits == 0) then ! sequential access
109 :
110 0 : open(nu,file=filename,form='unformatted')
111 :
112 : else ! direct access
113 :
114 : ! use nbytes to compute RecSize.
115 : ! this prevents integer overflow with large global grids using nbits
116 : ! nx*ny*nbits > 2^31 -1 (i.e., global grid 9000x7054x64)
117 20 : nbytes = nbits/bits_per_byte
118 20 : RecSize = nx_global*ny_global*nbytes
119 :
120 20 : if (present(algn)) then
121 : ! If data is keept in blocks using given sizes (=algn)
122 : ! Used in eg. HYCOM binary files, which are stored as "blocks" dividable by 16384 bit (=algn)
123 0 : if (algn /= 0) then
124 0 : Remnant = modulo(RecSize,algn)
125 0 : if (Remnant /= 0) then
126 0 : RecSize = RecSize + (algn - Remnant)
127 : endif
128 : endif
129 : endif
130 : open(nu,file=filename,recl=RecSize, &
131 20 : form='unformatted',access='direct')
132 : endif ! nbits = 0
133 :
134 : endif ! my_task = master_task
135 :
136 84 : end subroutine ice_open
137 :
138 : !=======================================================================
139 :
140 : ! Opens an unformatted file for reading, incl ghost cells (direct access).
141 : ! nbits indicates whether the file is sequential or direct access.
142 : !
143 : ! authors: Tony Craig, NCAR
144 : ! David Hebert, NRLSSC
145 :
146 0 : subroutine ice_open_ext(nu, filename, nbits)
147 :
148 : integer (kind=int_kind), intent(in) :: &
149 : nu , & ! unit number ! LCOV_EXCL_LINE
150 : nbits ! no. of bits per variable (0 for sequential access)
151 :
152 : integer (kind=int_kind) :: RecSize, nbytes
153 :
154 : character (*) :: filename
155 :
156 : integer (kind=int_kind) :: &
157 : nx, ny ! grid dimensions including ghost cells
158 :
159 : character(len=*), parameter :: subname = '(ice_open_ext)'
160 :
161 0 : if (my_task == master_task) then
162 :
163 0 : if (nbits == 0) then ! sequential access
164 :
165 0 : open(nu,file=filename,form='unformatted')
166 :
167 : else ! direct access
168 :
169 0 : nx = nx_global + 2*nghost
170 0 : ny = ny_global + 2*nghost
171 :
172 : ! use nbytes to compute RecSize.
173 : ! this prevents integer overflow with large global grids using nbits
174 : ! nx*ny*nbits > 2^31 -1 (i.e., global grid 9000x7054x64)
175 0 : nbytes = nbits/bits_per_byte
176 0 : RecSize = nx*ny*nbytes
177 : open(nu,file=filename,recl=RecSize, &
178 0 : form='unformatted',access='direct')
179 : endif ! nbits = 0
180 :
181 : endif ! my_task = master_task
182 :
183 0 : end subroutine ice_open_ext
184 :
185 : !=======================================================================
186 :
187 : ! Read an unformatted file and scatter to processors.
188 : ! work is a real array, atype indicates the format of the data.
189 : ! If the optional variables field_loc and field_type are present,
190 : ! the ghost cells are filled using values from the global array.
191 : ! This prevents them from being filled with zeroes in land cells
192 : ! (subroutine ice_HaloUpdate need not be called).
193 : !
194 : ! author: Tony Craig, NCAR
195 :
196 13 : subroutine ice_read_xyt(nu, nrec, work, atype, diag, &
197 : field_loc, field_type, & ! LCOV_EXCL_LINE
198 : ignore_eof, hit_eof)
199 :
200 : use ice_gather_scatter, only: scatter_global
201 :
202 : integer (kind=int_kind), intent(in) :: &
203 : nu , & ! unit number ! LCOV_EXCL_LINE
204 : nrec ! record number (0 for sequential access)
205 :
206 : real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), intent(out) :: &
207 : work ! output array (real, 8-byte)
208 :
209 : character (len=4), intent(in) :: &
210 : atype ! format for input array
211 : ! (real/integer, 4-byte/8-byte)
212 :
213 : logical (kind=log_kind), intent(in) :: &
214 : diag ! if true, write diagnostic output
215 :
216 : integer (kind=int_kind), optional, intent(in) :: &
217 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
218 : field_type ! type of field (scalar, vector, angle)
219 :
220 : logical (kind=log_kind), optional, intent(in) :: ignore_eof
221 : logical (kind=log_kind), optional, intent(out) :: hit_eof
222 :
223 : ! local variables
224 :
225 : integer (kind=int_kind) :: i, j, ios
226 :
227 : real (kind=dbl_kind) :: &
228 8 : amin, amax, asum ! min, max values and sum of input array
229 :
230 : logical (kind=log_kind) :: ignore_eof_use
231 :
232 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
233 21 : work_g1
234 :
235 : real (kind=real_kind), dimension(:,:), allocatable :: &
236 21 : work_gr
237 :
238 : integer(kind=int_kind), dimension(:,:), allocatable :: &
239 21 : work_gi4
240 :
241 : integer(selected_int_kind(13)), dimension(:,:), allocatable :: &
242 21 : work_gi8
243 :
244 : character(len=*), parameter :: subname = '(ice_read_xyt)'
245 :
246 21 : if (my_task == master_task) then
247 5 : allocate(work_g1(nx_global,ny_global))
248 : else
249 16 : allocate(work_g1(1,1)) ! to save memory
250 : endif
251 :
252 21 : if (my_task == master_task) then
253 :
254 : !-------------------------------------------------------------------
255 : ! Read global array according to format atype
256 : !-------------------------------------------------------------------
257 5 : if (present(hit_eof)) hit_eof = .false.
258 :
259 5 : if (atype == 'ida4') then
260 5 : allocate(work_gi4(nx_global,ny_global))
261 5 : read(nu,rec=nrec) work_gi4
262 58590 : work_g1 = real(work_gi4,kind=dbl_kind)
263 5 : deallocate(work_gi4)
264 0 : elseif (atype == 'ida8') then
265 0 : allocate(work_gi8(nx_global,ny_global))
266 0 : read(nu,rec=nrec) work_gi8
267 0 : work_g1 = real(work_gi8,kind=dbl_kind)
268 0 : deallocate(work_gi8)
269 0 : elseif (atype == 'rda4') then
270 0 : allocate(work_gr(nx_global,ny_global))
271 0 : read(nu,rec=nrec) work_gr
272 0 : work_g1 = work_gr
273 0 : deallocate(work_gr)
274 0 : elseif (atype == 'rda8') then
275 0 : read(nu,rec=nrec) work_g1
276 0 : elseif (atype == 'ruf8') then
277 0 : if (present(ignore_eof)) then
278 0 : ignore_eof_use = ignore_eof
279 : else
280 0 : ignore_eof_use = .false.
281 : endif
282 0 : if (ignore_eof_use) then
283 : ! Read line from file, checking for end-of-file
284 0 : read(nu, iostat=ios) ((work_g1(i,j),i=1,nx_global), &
285 0 : j=1,ny_global)
286 0 : if (present(hit_eof)) hit_eof = ios < 0
287 : else
288 0 : read(nu) ((work_g1(i,j),i=1,nx_global),j=1,ny_global)
289 : endif
290 : else
291 0 : write(nu_diag,*) subname,' ERROR: reading unknown atype ',atype
292 : endif
293 : endif ! my_task = master_task
294 :
295 21 : if (present(hit_eof)) then
296 0 : call broadcast_scalar(hit_eof,master_task)
297 0 : if (hit_eof) then
298 0 : deallocate(work_g1)
299 0 : return
300 : endif
301 : endif
302 :
303 : !-------------------------------------------------------------------
304 : ! optional diagnostics
305 : !-------------------------------------------------------------------
306 21 : if (my_task==master_task .and. diag) then
307 58585 : amin = minval(work_g1)
308 58585 : amax = maxval(work_g1, mask = work_g1 /= spval_dbl)
309 58585 : asum = sum(work_g1, mask = work_g1 /= spval_dbl)
310 5 : write(nu_diag,*) subname,' read_global ',nu, nrec, amin, amax, asum
311 : endif
312 :
313 : !-------------------------------------------------------------------
314 : ! Scatter data to individual processors.
315 : ! NOTE: Ghost cells are not updated unless field_loc is present.
316 : !-------------------------------------------------------------------
317 :
318 21 : if (present(field_loc)) then
319 0 : call scatter_global(work, work_g1, master_task, distrb_info, &
320 21 : field_loc, field_type)
321 : else
322 0 : call scatter_global(work, work_g1, master_task, distrb_info, &
323 0 : field_loc_noupdate, field_type_noupdate)
324 : endif
325 :
326 21 : deallocate(work_g1)
327 :
328 21 : end subroutine ice_read_xyt
329 :
330 : !=======================================================================
331 : ! Read an unformatted file and scatter to processors.
332 : ! work is a real array, atype indicates the format of the data.
333 : ! If the optional variables field_loc and field_type are present,
334 : ! the ghost cells are filled using values from the global array.
335 : ! This prevents them from being filled with zeroes in land cells
336 : ! (subroutine ice_HaloUpdate need not be called).
337 : !
338 : ! author: Tony Craig, NCAR
339 :
340 0 : subroutine ice_read_xyzt(nu, nrec, work, atype, diag, &
341 : field_loc, field_type, & ! LCOV_EXCL_LINE
342 : ignore_eof, hit_eof)
343 :
344 : use ice_gather_scatter, only: scatter_global
345 : use ice_domain_size, only: nblyr
346 :
347 : integer (kind=int_kind), intent(in) :: &
348 : nu , & ! unit number ! LCOV_EXCL_LINE
349 : nrec ! record number (0 for sequential access)
350 :
351 : real (kind=dbl_kind), dimension(nx_block,ny_block,nblyr+2,max_blocks), intent(out) :: &
352 : work ! output array (real, 8-byte)
353 :
354 : character (len=4), intent(in) :: &
355 : atype ! format for input array
356 : ! (real/integer, 4-byte/8-byte)
357 :
358 : logical (kind=log_kind), intent(in) :: &
359 : diag ! if true, write diagnostic output
360 :
361 : integer (kind=int_kind), optional, intent(in) :: &
362 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
363 : field_type ! type of field (scalar, vector, angle)
364 :
365 : logical (kind=log_kind), optional, intent(in) :: ignore_eof
366 : logical (kind=log_kind), optional, intent(out) :: hit_eof
367 :
368 : ! local variables
369 :
370 : integer (kind=int_kind) :: i, j, k, ios
371 :
372 : real (kind=dbl_kind) :: &
373 0 : amin, amax, asum ! min, max values and sum of input array
374 :
375 : logical (kind=log_kind) :: ignore_eof_use
376 :
377 :
378 : real (kind=dbl_kind), dimension(:,:,:), allocatable :: &
379 0 : work_g4
380 :
381 : integer(kind=int_kind), dimension(:,:,:), allocatable :: &
382 0 : work_gi5
383 :
384 : integer(selected_int_kind(13)), dimension(:,:,:), allocatable :: &
385 0 : work_gi9
386 :
387 : real (kind=real_kind), dimension(:,:,:), allocatable :: &
388 0 : work_gr3
389 :
390 : character(len=*), parameter :: subname = '(ice_read_xyzt)'
391 :
392 0 : if (my_task == master_task) then
393 0 : allocate(work_g4(nx_global,ny_global,nblyr+2))
394 : else
395 0 : allocate(work_g4(1,1,nblyr+2)) ! to save memory
396 : endif
397 :
398 0 : if (my_task == master_task) then
399 :
400 : !-------------------------------------------------------------------
401 : ! Read global array according to format atype
402 : !-------------------------------------------------------------------
403 0 : if (present(hit_eof)) hit_eof = .false.
404 :
405 0 : if (atype == 'ida4') then
406 0 : allocate(work_gi5(nx_global,ny_global,nblyr+2))
407 0 : read(nu,rec=nrec) work_gi5
408 0 : work_g4 = real(work_gi5,kind=dbl_kind)
409 0 : deallocate(work_gi5)
410 0 : elseif (atype == 'ida8') then
411 0 : allocate(work_gi9(nx_global,ny_global,nblyr+2))
412 0 : read(nu,rec=nrec) work_gi9
413 0 : work_g4 = real(work_gi9,kind=dbl_kind)
414 0 : deallocate(work_gi9)
415 0 : elseif (atype == 'rda4') then
416 0 : allocate(work_gr3(nx_global,ny_global,nblyr+2))
417 0 : read(nu,rec=nrec) work_gr3
418 0 : work_g4 = work_gr3
419 0 : deallocate(work_gr3)
420 0 : elseif (atype == 'rda8') then
421 0 : read(nu,rec=nrec) work_g4
422 0 : elseif (atype == 'ruf8') then
423 0 : if (present(ignore_eof)) then
424 0 : ignore_eof_use = ignore_eof
425 : else
426 0 : ignore_eof_use = .false.
427 : endif
428 0 : if (ignore_eof_use) then
429 : ! Read line from file, checking for end-of-file
430 0 : read(nu, iostat=ios) (((work_g4(i,j,k),i=1,nx_global), &
431 : j=1,ny_global), & ! LCOV_EXCL_LINE
432 0 : k=1,nblyr+2)
433 0 : if (present(hit_eof)) hit_eof = ios < 0
434 : else
435 0 : read(nu) (((work_g4(i,j,k),i=1,nx_global),j=1,ny_global),&
436 0 : k=1,nblyr+2)
437 : endif
438 : else
439 0 : write(nu_diag,*) subname,' ERROR: reading unknown atype ',atype
440 : endif
441 : endif ! my_task = master_task
442 :
443 0 : if (present(hit_eof)) then
444 0 : call broadcast_scalar(hit_eof,master_task)
445 0 : if (hit_eof) then
446 0 : deallocate(work_g4)
447 0 : return
448 : endif
449 : endif
450 :
451 : !-------------------------------------------------------------------
452 : ! optional diagnostics
453 : !-------------------------------------------------------------------
454 0 : if (my_task==master_task .and. diag) then
455 0 : amin = minval(work_g4)
456 0 : amax = maxval(work_g4, mask = work_g4 /= spval_dbl)
457 0 : asum = sum (work_g4, mask = work_g4 /= spval_dbl)
458 0 : write(nu_diag,*) subname,' read_global ',nu, nrec, amin, amax, asum
459 : endif
460 :
461 : !-------------------------------------------------------------------
462 : ! Scatter data to individual processors.
463 : ! NOTE: Ghost cells are not updated unless field_loc is present.
464 : !-------------------------------------------------------------------
465 :
466 0 : do k = 1, nblyr+2
467 :
468 0 : if (present(field_loc)) then
469 0 : call scatter_global(work(:,:,k,:), work_g4(:,:,k), master_task, distrb_info, &
470 0 : field_loc, field_type)
471 :
472 : else
473 :
474 0 : call scatter_global(work(:,:,k,:), work_g4(:,:,k), master_task, distrb_info, &
475 0 : field_loc_noupdate, field_type_noupdate)
476 : endif
477 :
478 : enddo !k
479 0 : deallocate(work_g4)
480 :
481 0 : end subroutine ice_read_xyzt
482 :
483 : !=======================================================================
484 :
485 : ! Read an unformatted file
486 : ! Just like ice_read except that it returns a global array.
487 : ! work_g is a real array, atype indicates the format of the data
488 : !
489 : ! Adapted by William Lipscomb, LANL, from ice_read
490 :
491 91 : subroutine ice_read_global (nu, nrec, work_g, atype, diag, &
492 : ignore_eof, hit_eof)
493 :
494 : integer (kind=int_kind), intent(in) :: &
495 : nu , & ! unit number ! LCOV_EXCL_LINE
496 : nrec ! record number (0 for sequential access)
497 :
498 : real (kind=dbl_kind), dimension(nx_global,ny_global), intent(out) :: &
499 : work_g ! output array (real, 8-byte)
500 :
501 : character (len=4) :: &
502 : atype ! format for input array
503 : ! (real/integer, 4-byte/8-byte)
504 :
505 : logical (kind=log_kind) :: &
506 : diag ! if true, write diagnostic output
507 :
508 : logical (kind=log_kind), optional, intent(in) :: ignore_eof
509 : logical (kind=log_kind), optional, intent(out) :: hit_eof
510 :
511 : ! local variables
512 :
513 : integer (kind=int_kind) :: i, j, ios
514 :
515 : real (kind=dbl_kind) :: &
516 56 : amin, amax, asum ! min, max values and sum of input array
517 :
518 : logical (kind=log_kind) :: ignore_eof_use
519 :
520 : real (kind=real_kind), dimension(:,:), allocatable :: &
521 147 : work_gr
522 :
523 : integer(kind=int_kind), dimension(:,:), allocatable :: &
524 147 : work_gi4
525 :
526 : integer(selected_int_kind(13)), dimension(:,:), allocatable :: &
527 147 : work_gi8
528 :
529 : character(len=*), parameter :: subname = '(ice_read_global)'
530 :
531 1722399 : work_g(:,:) = c0
532 :
533 147 : if (my_task == master_task) then
534 :
535 : !-------------------------------------------------------------------
536 : ! Read global array according to format atype
537 : !-------------------------------------------------------------------
538 35 : if (present(hit_eof)) hit_eof = .false.
539 :
540 35 : if (atype == 'ida4') then
541 5 : allocate(work_gi4(nx_global,ny_global))
542 5 : read(nu,rec=nrec) work_gi4
543 58585 : work_g = real(work_gi4,kind=dbl_kind)
544 5 : deallocate(work_gi4)
545 30 : elseif (atype == 'ida8') then
546 0 : allocate(work_gi8(nx_global,ny_global))
547 0 : read(nu,rec=nrec) work_gi8
548 0 : work_g = real(work_gi8,kind=dbl_kind)
549 0 : deallocate(work_gi8)
550 30 : elseif (atype == 'rda4') then
551 0 : allocate(work_gr(nx_global,ny_global))
552 0 : read(nu,rec=nrec) work_gr
553 0 : work_g = work_gr
554 0 : deallocate(work_gr)
555 30 : elseif (atype == 'rda8') then
556 30 : read(nu,rec=nrec) work_g
557 0 : elseif (atype == 'ruf8') then
558 0 : if (present(ignore_eof)) then
559 0 : ignore_eof_use = ignore_eof
560 : else
561 0 : ignore_eof_use = .false.
562 : endif
563 0 : if (ignore_eof_use) then
564 : ! Read line from file, checking for end-of-file
565 0 : read(nu, iostat=ios) ((work_g(i,j),i=1,nx_global), &
566 0 : j=1,ny_global)
567 0 : if (present(hit_eof)) hit_eof = ios < 0
568 : else
569 0 : read(nu) ((work_g(i,j),i=1,nx_global),j=1,ny_global)
570 : endif
571 : else
572 0 : write(nu_diag,*) subname,' ERROR: reading unknown atype ',atype
573 : endif
574 : endif ! my_task = master_task
575 :
576 147 : if (present(hit_eof)) then
577 0 : call broadcast_scalar(hit_eof,master_task)
578 0 : if (hit_eof) return
579 : endif
580 :
581 : !-------------------------------------------------------------------
582 : ! optional diagnostics
583 : !-------------------------------------------------------------------
584 147 : if (my_task == master_task .and. diag) then
585 410095 : amin = minval(work_g)
586 410095 : amax = maxval(work_g, mask = work_g /= spval_dbl)
587 410095 : asum = sum (work_g, mask = work_g /= spval_dbl)
588 35 : write(nu_diag,*) subname,' read_global ',nu, nrec, amin, amax,asum
589 : endif
590 :
591 147 : end subroutine ice_read_global
592 :
593 : !=======================================================================
594 :
595 : ! Read an unformatted file and scatter to processors, incl ghost cells.
596 : ! work is a real array, atype indicates the format of the data.
597 : ! (subroutine ice_HaloUpdate need not be called).
598 :
599 0 : subroutine ice_read_ext(nu, nrec, work, atype, diag, &
600 : ignore_eof, hit_eof)
601 :
602 : use ice_gather_scatter, only: scatter_global_ext
603 :
604 : integer (kind=int_kind), intent(in) :: &
605 : nu , & ! unit number ! LCOV_EXCL_LINE
606 : nrec ! record number (0 for sequential access)
607 :
608 : real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), intent(out) :: &
609 : work ! output array (real, 8-byte)
610 :
611 : character (len=4), intent(in) :: &
612 : atype ! format for input array
613 : ! (real/integer, 4-byte/8-byte)
614 :
615 : logical (kind=log_kind), intent(in) :: &
616 : diag ! if true, write diagnostic output
617 :
618 : logical (kind=log_kind), optional, intent(in) :: ignore_eof
619 : logical (kind=log_kind), optional, intent(out) :: hit_eof
620 :
621 : ! local variables
622 :
623 : integer (kind=int_kind) :: i, j, ios, nx, ny
624 :
625 : real (kind=dbl_kind) :: &
626 0 : amin, amax, asum ! min, max values and sum of input array
627 :
628 : logical (kind=log_kind) :: ignore_eof_use
629 :
630 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
631 0 : work_g1
632 :
633 : real (kind=real_kind), dimension(:,:), allocatable :: &
634 0 : work_gr
635 :
636 : integer(kind=int_kind), dimension(:,:), allocatable :: &
637 0 : work_gi4
638 :
639 : integer(selected_int_kind(13)), dimension(:,:), allocatable :: &
640 0 : work_gi8
641 :
642 : character(len=*), parameter :: subname = '(ice_read_ext)'
643 :
644 0 : nx = nx_global + 2*nghost
645 0 : ny = ny_global + 2*nghost
646 :
647 0 : if (my_task == master_task) then
648 0 : allocate(work_g1(nx,ny))
649 : else
650 0 : allocate(work_g1(1,1)) ! to save memory
651 : endif
652 :
653 0 : if (my_task == master_task) then
654 :
655 : !-------------------------------------------------------------------
656 : ! Read global array according to format atype
657 : !-------------------------------------------------------------------
658 0 : if (present(hit_eof)) hit_eof = .false.
659 :
660 0 : if (atype == 'ida4') then
661 0 : allocate(work_gi4(nx,ny))
662 0 : read(nu,rec=nrec) work_gi4
663 0 : work_g1 = real(work_gi4,kind=dbl_kind)
664 0 : deallocate(work_gi4)
665 0 : elseif (atype == 'ida8') then
666 0 : allocate(work_gi8(nx,ny))
667 0 : read(nu,rec=nrec) work_gi8
668 0 : work_g1 = real(work_gi8,kind=dbl_kind)
669 0 : deallocate(work_gi8)
670 0 : elseif (atype == 'rda4') then
671 0 : allocate(work_gr(nx,ny))
672 0 : read(nu,rec=nrec) work_gr
673 0 : work_g1 = work_gr
674 0 : deallocate(work_gr)
675 0 : elseif (atype == 'rda8') then
676 0 : read(nu,rec=nrec) work_g1
677 0 : elseif (atype == 'ruf8') then
678 0 : if (present(ignore_eof)) then
679 0 : ignore_eof_use = ignore_eof
680 : else
681 0 : ignore_eof_use = .false.
682 : endif
683 0 : if (ignore_eof_use) then
684 : ! Read line from file, checking for end-of-file
685 0 : read(nu, iostat=ios) ((work_g1(i,j),i=1,nx), &
686 0 : j=1,ny)
687 0 : if (present(hit_eof)) hit_eof = ios < 0
688 : else
689 0 : read(nu) ((work_g1(i,j),i=1,nx),j=1,ny)
690 : endif
691 : else
692 0 : write(nu_diag,*) subname,' ERROR: reading unknown atype ',atype
693 : endif
694 : endif ! my_task = master_task
695 :
696 0 : if (present(hit_eof)) then
697 0 : call broadcast_scalar(hit_eof,master_task)
698 0 : if (hit_eof) then
699 0 : deallocate(work_g1)
700 0 : return
701 : endif
702 : endif
703 :
704 : !-------------------------------------------------------------------
705 : ! optional diagnostics
706 : !-------------------------------------------------------------------
707 0 : if (my_task==master_task .and. diag) then
708 0 : amin = minval(work_g1)
709 0 : amax = maxval(work_g1, mask = work_g1 /= spval_dbl)
710 0 : asum = sum (work_g1, mask = work_g1 /= spval_dbl)
711 0 : write(nu_diag,*) subname,' read_global ',nu, nrec, amin, amax, asum
712 : endif
713 :
714 : !-------------------------------------------------------------------
715 : ! Scatter data to individual processors.
716 : ! NOTE: Ghost cells are always updated
717 : !-------------------------------------------------------------------
718 :
719 0 : call scatter_global_ext(work, work_g1, master_task, distrb_info)
720 :
721 0 : deallocate(work_g1)
722 :
723 0 : end subroutine ice_read_ext
724 :
725 : !=======================================================================
726 :
727 : ! Writes an unformatted file
728 : ! work is a real array, atype indicates the format of the data
729 :
730 0 : subroutine ice_write_xyt(nu, nrec, work, atype, diag)
731 :
732 : use ice_gather_scatter, only: gather_global
733 :
734 : integer (kind=int_kind), intent(in) :: &
735 : nu , & ! unit number ! LCOV_EXCL_LINE
736 : nrec ! record number (0 for sequential access)
737 :
738 : real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), intent(in) :: &
739 : work ! input array (real, 8-byte)
740 :
741 : character (len=4), intent(in) :: &
742 : atype ! format for output array
743 : ! (real/integer, 4-byte/8-byte)
744 :
745 : logical (kind=log_kind), intent(in) :: &
746 : diag ! if true, write diagnostic output
747 :
748 : ! local variables
749 :
750 : integer (kind=int_kind) :: i, j
751 :
752 : real (kind=dbl_kind) :: &
753 0 : amin, amax, asum ! min, max values and sum of input array
754 :
755 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
756 0 : work_g1
757 :
758 : real (kind=real_kind), dimension(:,:), allocatable :: &
759 0 : work_gr
760 :
761 : integer(kind=int_kind), dimension(:,:), allocatable :: &
762 0 : work_gi4
763 :
764 : integer(selected_int_kind(13)), dimension(:,:), allocatable :: &
765 0 : work_gi8
766 :
767 : character(len=*), parameter :: subname = '(ice_write_xyt)'
768 :
769 : !-------------------------------------------------------------------
770 : ! Gather data from individual processors
771 : !-------------------------------------------------------------------
772 :
773 0 : if (my_task == master_task) then
774 0 : allocate(work_g1(nx_global,ny_global))
775 : else
776 0 : allocate(work_g1(1,1)) ! to save memory
777 : endif
778 :
779 0 : call gather_global(work_g1, work, master_task, distrb_info, spc_val=c0)
780 :
781 0 : if (my_task == master_task) then
782 :
783 : !-------------------------------------------------------------------
784 : ! Write global array according to format atype
785 : !-------------------------------------------------------------------
786 0 : if (atype == 'ida4') then
787 0 : allocate(work_gi4(nx_global,ny_global))
788 0 : work_gi4 = nint(work_g1)
789 0 : write(nu,rec=nrec) work_gi4
790 0 : deallocate(work_gi4)
791 0 : elseif (atype == 'ida8') then
792 0 : allocate(work_gi8(nx_global,ny_global))
793 0 : work_gi8 = nint(work_g1)
794 0 : write(nu,rec=nrec) work_gi8
795 0 : deallocate(work_gi8)
796 0 : elseif (atype == 'rda4') then
797 0 : allocate(work_gr(nx_global,ny_global))
798 0 : work_gr = real(work_g1,real_kind)
799 0 : write(nu,rec=nrec) work_gr
800 0 : deallocate(work_gr)
801 0 : elseif (atype == 'rda8') then
802 0 : write(nu,rec=nrec) work_g1
803 0 : elseif (atype == 'ruf8') then
804 0 : write(nu) ((work_g1(i,j),i=1,nx_global),j=1,ny_global)
805 : else
806 0 : write(nu_diag,*) subname,' ERROR: writing unknown atype ',atype
807 : endif
808 :
809 : !-------------------------------------------------------------------
810 : ! diagnostics
811 : !-------------------------------------------------------------------
812 0 : if (diag) then
813 0 : amin = minval(work_g1)
814 0 : amax = maxval(work_g1, mask = work_g1 /= spval_dbl)
815 0 : asum = sum (work_g1, mask = work_g1 /= spval_dbl)
816 0 : write(nu_diag,*) subname,' write_global ', nu, nrec, amin, amax, asum
817 : endif
818 :
819 : endif ! my_task = master_task
820 :
821 0 : deallocate(work_g1)
822 :
823 0 : end subroutine ice_write_xyt
824 :
825 : !=======================================================================
826 :
827 : ! Writes an unformatted file
828 : ! work is a real array, atype indicates the format of the data
829 :
830 0 : subroutine ice_write_xyzt(nu, nrec, work, atype, diag)
831 :
832 : use ice_gather_scatter, only: gather_global
833 : use ice_domain_size, only: nblyr
834 :
835 : integer (kind=int_kind), intent(in) :: &
836 : nu , & ! unit number ! LCOV_EXCL_LINE
837 : nrec ! record number (0 for sequential access)
838 :
839 : real (kind=dbl_kind), dimension(nx_block,ny_block,nblyr+2,max_blocks), &
840 : intent(in) :: & ! LCOV_EXCL_LINE
841 : work ! input array (real, 8-byte)
842 :
843 : character (len=4), intent(in) :: &
844 : atype ! format for output array
845 : ! (real/integer, 4-byte/8-byte)
846 :
847 : logical (kind=log_kind), intent(in) :: &
848 : diag ! if true, write diagnostic output
849 :
850 : ! local variables
851 :
852 : integer (kind=int_kind) :: i, j, k
853 :
854 : real (kind=dbl_kind) :: &
855 0 : amin, amax, asum ! min, max values and sum of input array
856 :
857 : real (kind=dbl_kind), dimension(:,:,:), allocatable :: &
858 0 : work_g4
859 :
860 : real (kind=real_kind), dimension(:,:,:), allocatable :: &
861 0 : work_gr3
862 :
863 : integer(kind=int_kind), dimension(:,:,:), allocatable :: &
864 0 : work_gi5
865 :
866 : integer(selected_int_kind(13)), dimension(:,:,:), allocatable :: &
867 0 : work_gi9
868 :
869 : character(len=*), parameter :: subname = '(ice_write_xyzt)'
870 :
871 : !-------------------------------------------------------------------
872 : ! Gather data from individual processors
873 : !-------------------------------------------------------------------
874 :
875 0 : if (my_task == master_task) then
876 0 : allocate(work_g4(nx_global,ny_global,nblyr+2))
877 : else
878 0 : allocate(work_g4(1,1,nblyr+2)) ! to save memory
879 : endif
880 0 : do k = 1,nblyr+2
881 0 : call gather_global(work_g4(:,:,k), work(:,:,k,:), master_task, &
882 0 : distrb_info, spc_val=c0)
883 : enddo !k
884 :
885 0 : if (my_task == master_task) then
886 :
887 : !-------------------------------------------------------------------
888 : ! Write global array according to format atype
889 : !-------------------------------------------------------------------
890 0 : if (atype == 'ida4') then
891 0 : allocate(work_gi5(nx_global,ny_global,nblyr+2))
892 0 : work_gi5 = nint(work_g4)
893 0 : write(nu,rec=nrec) work_gi5
894 0 : deallocate(work_gi5)
895 0 : elseif (atype == 'ida8') then
896 0 : allocate(work_gi9(nx_global,ny_global,nblyr+2))
897 0 : work_gi9 = nint(work_g4)
898 0 : write(nu,rec=nrec) work_gi9
899 0 : deallocate(work_gi9)
900 0 : elseif (atype == 'rda4') then
901 0 : allocate(work_gr3(nx_global,ny_global,nblyr+2))
902 0 : work_gr3 = real(work_g4,real_kind)
903 0 : write(nu,rec=nrec) work_gr3
904 0 : deallocate(work_gr3)
905 0 : elseif (atype == 'rda8') then
906 0 : write(nu,rec=nrec) work_g4
907 0 : elseif (atype == 'ruf8') then
908 0 : write(nu)(((work_g4(i,j,k),i=1,nx_global),j=1,ny_global), &
909 0 : k=1,nblyr+2)
910 : else
911 0 : write(nu_diag,*) subname,' ERROR: writing unknown atype ',atype
912 : endif
913 :
914 : !-------------------------------------------------------------------
915 : ! diagnostics
916 : !-------------------------------------------------------------------
917 0 : if (diag) then
918 0 : amin = minval(work_g4)
919 0 : amax = maxval(work_g4, mask = work_g4 /= spval_dbl)
920 0 : asum = sum (work_g4, mask = work_g4 /= spval_dbl)
921 0 : write(nu_diag,*) subname,' write_global ', nu, nrec, amin, amax, asum
922 : endif
923 :
924 : endif ! my_task = master_task
925 :
926 0 : deallocate(work_g4)
927 :
928 0 : end subroutine ice_write_xyzt
929 :
930 : !=======================================================================
931 : !
932 : ! Writes an unformatted file, including ghost cells
933 : ! work is a real array, atype indicates the format of the data
934 : !
935 : ! author: Tony Craig, NCAR
936 :
937 0 : subroutine ice_write_ext(nu, nrec, work, atype, diag)
938 :
939 : use ice_gather_scatter, only: gather_global_ext
940 :
941 : integer (kind=int_kind), intent(in) :: &
942 : nu , & ! unit number ! LCOV_EXCL_LINE
943 : nrec ! record number (0 for sequential access)
944 :
945 : real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), &
946 : intent(in) :: & ! LCOV_EXCL_LINE
947 : work ! input array (real, 8-byte)
948 :
949 : character (len=4), intent(in) :: &
950 : atype ! format for output array
951 : ! (real/integer, 4-byte/8-byte)
952 :
953 : logical (kind=log_kind), intent(in) :: &
954 : diag ! if true, write diagnostic output
955 :
956 : ! local variables
957 :
958 : integer (kind=int_kind) :: i, j, nx, ny
959 :
960 : real (kind=dbl_kind) :: &
961 0 : amin, amax, asum ! min, max values and sum of input array
962 :
963 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
964 0 : work_g1
965 :
966 : real (kind=real_kind), dimension(:,:), allocatable :: &
967 0 : work_gr
968 :
969 : integer(kind=int_kind), dimension(:,:), allocatable :: &
970 0 : work_gi4
971 :
972 : integer(selected_int_kind(13)), dimension(:,:), allocatable :: &
973 0 : work_gi8
974 :
975 : character(len=*), parameter :: subname = '(ice_write_ext)'
976 :
977 : !-------------------------------------------------------------------
978 : ! Gather data from individual processors
979 : !-------------------------------------------------------------------
980 :
981 0 : nx = nx_global + 2*nghost
982 0 : ny = ny_global + 2*nghost
983 :
984 0 : if (my_task == master_task) then
985 0 : allocate(work_g1(nx,ny))
986 : else
987 0 : allocate(work_g1(1,1)) ! to save memory
988 : endif
989 :
990 0 : call gather_global_ext(work_g1, work, master_task, distrb_info, spc_val=c0)
991 :
992 0 : if (my_task == master_task) then
993 :
994 : !-------------------------------------------------------------------
995 : ! Write global array according to format atype
996 : !-------------------------------------------------------------------
997 0 : if (atype == 'ida4') then
998 0 : allocate(work_gi4(nx,ny))
999 0 : work_gi4 = nint(work_g1)
1000 0 : write(nu,rec=nrec) work_gi4
1001 0 : deallocate(work_gi4)
1002 0 : elseif (atype == 'ida8') then
1003 0 : allocate(work_gi8(nx,ny))
1004 0 : work_gi8 = nint(work_g1)
1005 0 : write(nu,rec=nrec) work_gi8
1006 0 : deallocate(work_gi8)
1007 0 : elseif (atype == 'rda4') then
1008 0 : allocate(work_gr(nx,ny))
1009 0 : work_gr = real(work_g1,real_kind)
1010 0 : write(nu,rec=nrec) work_gr
1011 0 : deallocate(work_gr)
1012 0 : elseif (atype == 'rda8') then
1013 0 : write(nu,rec=nrec) work_g1
1014 0 : elseif (atype == 'ruf8') then
1015 0 : write(nu) ((work_g1(i,j),i=1,nx),j=1,ny)
1016 : else
1017 0 : write(nu_diag,*) subname,' ERROR: writing unknown atype ',atype
1018 : endif
1019 :
1020 : !-------------------------------------------------------------------
1021 : ! diagnostics
1022 : !-------------------------------------------------------------------
1023 0 : if (diag) then
1024 0 : amin = minval(work_g1)
1025 0 : amax = maxval(work_g1, mask = work_g1 /= spval_dbl)
1026 0 : asum = sum (work_g1, mask = work_g1 /= spval_dbl)
1027 0 : write(nu_diag,*) subname,' write_global ', nu, nrec, amin, amax, asum
1028 : endif
1029 :
1030 : endif ! my_task = master_task
1031 :
1032 0 : deallocate(work_g1)
1033 :
1034 0 : end subroutine ice_write_ext
1035 :
1036 : !=======================================================================
1037 :
1038 : ! Opens a netCDF file for reading
1039 : ! Adapted by Alison McLaren, Met Office from ice_open
1040 :
1041 2904 : subroutine ice_open_nc(filename, fid)
1042 :
1043 : character (char_len_long), intent(in) :: &
1044 : filename ! netCDF filename
1045 :
1046 : integer (kind=int_kind), intent(out) :: &
1047 : fid ! unit number
1048 :
1049 : ! local variables
1050 :
1051 : character(len=*), parameter :: subname = '(ice_open_nc)'
1052 :
1053 : #ifdef USE_NETCDF
1054 : integer (kind=int_kind) :: &
1055 : status ! status variable from netCDF routine
1056 :
1057 2904 : if (my_task == master_task) then
1058 :
1059 624 : status = nf90_open(filename, NF90_NOWRITE, fid)
1060 624 : if (status /= nf90_noerr) then
1061 : !write(nu_diag,*) subname,' NF90_STRERROR = ',trim(nf90_strerror(status))
1062 : call abort_ice(subname//' ERROR: Cannot open '//trim(filename), &
1063 0 : file=__FILE__, line=__LINE__)
1064 : endif
1065 :
1066 : endif ! my_task = master_task
1067 :
1068 : #else
1069 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined for '//trim(filename), &
1070 : file=__FILE__, line=__LINE__)
1071 : fid = -999 ! to satisfy intent(out) attribute
1072 : #endif
1073 2904 : end subroutine ice_open_nc
1074 :
1075 : !=======================================================================
1076 :
1077 : ! Read a netCDF file and scatter to processors.
1078 : ! If the optional variables field_loc and field_type are present,
1079 : ! the ghost cells are filled using values from the global array.
1080 : ! This prevents them from being filled with zeroes in land cells
1081 : ! (subroutine ice_HaloUpdate need not be called).
1082 : !
1083 : ! Adapted by Alison McLaren, Met Office from ice_read
1084 :
1085 7790 : subroutine ice_read_nc_xy(fid, nrec, varname, work, diag, &
1086 : field_loc, field_type, restart_ext)
1087 :
1088 : use ice_gather_scatter, only: scatter_global, scatter_global_ext
1089 :
1090 : integer (kind=int_kind), intent(in) :: &
1091 : fid , & ! file id ! LCOV_EXCL_LINE
1092 : nrec ! record number
1093 :
1094 : logical (kind=log_kind), intent(in) :: &
1095 : diag ! if true, write diagnostic output
1096 :
1097 : character (len=*), intent(in) :: &
1098 : varname ! field name in netcdf file
1099 :
1100 : real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), intent(out) :: &
1101 : work ! output array (real, 8-byte)
1102 :
1103 : logical (kind=log_kind), optional, intent(in) :: &
1104 : restart_ext ! if true, read extended grid
1105 :
1106 : integer (kind=int_kind), optional, intent(in) :: &
1107 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
1108 : field_type ! type of field (scalar, vector, angle)
1109 :
1110 : ! local variables
1111 :
1112 : character(len=*), parameter :: subname = '(ice_read_nc_xy)'
1113 :
1114 : #ifdef USE_NETCDF
1115 : ! netCDF file diagnostics:
1116 : integer (kind=int_kind) :: &
1117 : varid , & ! variable id ! LCOV_EXCL_LINE
1118 : status , & ! status output from netcdf routines ! LCOV_EXCL_LINE
1119 : ndims , & ! number of dimensions ! LCOV_EXCL_LINE
1120 : dimlen ! dimension size
1121 :
1122 : integer (kind=int_kind), dimension(10) :: &
1123 : dimids ! generic size dimids
1124 :
1125 : real (kind=dbl_kind) :: &
1126 : missingvalue, & ! LCOV_EXCL_LINE
1127 3672 : amin, amax, asum ! min, max values and sum of input array
1128 :
1129 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
1130 7790 : work_g1
1131 :
1132 : integer (kind=int_kind) :: nx, ny
1133 :
1134 : integer (kind=int_kind) :: lnrec ! local value of nrec
1135 :
1136 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
1137 7790 : work_g2
1138 :
1139 7790 : lnrec = nrec
1140 :
1141 7790 : if (orca_halogrid .and. .not. present(restart_ext)) then
1142 0 : if (my_task == master_task) then
1143 0 : allocate(work_g2(nx_global+2,ny_global+1))
1144 : else
1145 0 : allocate(work_g2(1,1)) ! to save memory
1146 : endif
1147 0 : work_g2(:,:) = c0
1148 : endif
1149 :
1150 7790 : nx = nx_global
1151 7790 : ny = ny_global
1152 :
1153 25165720 : work = c0 ! to satisfy intent(out) attribute
1154 :
1155 7790 : if (present(restart_ext)) then
1156 0 : if (restart_ext) then
1157 0 : nx = nx_global + 2*nghost
1158 0 : ny = ny_global + 2*nghost
1159 : endif
1160 : endif
1161 :
1162 7790 : if (my_task == master_task) then
1163 1674 : allocate(work_g1(nx,ny))
1164 : else
1165 6116 : allocate(work_g1(1,1)) ! to save memory
1166 : endif
1167 :
1168 7790 : if (my_task == master_task) then
1169 :
1170 : !-------------------------------------------------------------
1171 : ! Find out ID of required variable
1172 : !-------------------------------------------------------------
1173 :
1174 1674 : status = nf90_inq_varid(fid, trim(varname), varid)
1175 1674 : if (status /= nf90_noerr) then
1176 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
1177 0 : file=__FILE__, line=__LINE__)
1178 : endif
1179 :
1180 : !-------------------------------------------------------------
1181 : ! Check nrec axis size
1182 : !-------------------------------------------------------------
1183 :
1184 1674 : status = nf90_inquire_variable(fid, varid, ndims=ndims, dimids=dimids)
1185 1674 : if (status /= nf90_noerr) then
1186 : call abort_ice(subname//' ERROR: inquire variable dimids '//trim(varname), &
1187 0 : file=__FILE__, line=__LINE__)
1188 : endif
1189 1674 : if (ndims > 2) then
1190 1526 : status = nf90_inquire_dimension(fid, dimids(3), len=dimlen)
1191 1526 : if (status /= nf90_noerr) then
1192 : call abort_ice(subname//' ERROR: inquire dimension size 3 '//trim(varname), &
1193 0 : file=__FILE__, line=__LINE__)
1194 : endif
1195 1526 : if (lnrec > dimlen) then
1196 0 : write(nu_diag,*) subname,' ERROR not enough records, ',trim(varname),lnrec,dimlen
1197 : call abort_ice(subname//' ERROR: not enough records '//trim(varname), &
1198 0 : file=__FILE__, line=__LINE__)
1199 : endif
1200 : endif
1201 :
1202 : !--------------------------------------------------------------
1203 : ! Read global array
1204 : !--------------------------------------------------------------
1205 :
1206 1674 : if (orca_halogrid .and. .not. present(restart_ext)) then
1207 : status = nf90_get_var( fid, varid, work_g2, &
1208 : start=(/1,1,lnrec/), & ! LCOV_EXCL_LINE
1209 0 : count=(/nx_global+2,ny_global+1,1/))
1210 0 : if (status /= nf90_noerr) then
1211 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
1212 0 : file=__FILE__, line=__LINE__)
1213 : endif
1214 0 : work_g1 = work_g2(2:nx_global+1,1:ny_global)
1215 : else
1216 : status = nf90_get_var( fid, varid, work_g1, &
1217 : start=(/1,1,lnrec/), & ! LCOV_EXCL_LINE
1218 11718 : count=(/nx,ny,1/))
1219 1674 : if (status /= nf90_noerr) then
1220 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
1221 0 : file=__FILE__, line=__LINE__)
1222 : endif
1223 : endif
1224 :
1225 1674 : status = nf90_get_att(fid, varid, "_FillValue", missingvalue)
1226 : endif ! my_task = master_task
1227 :
1228 : !-------------------------------------------------------------------
1229 : ! optional diagnostics
1230 : !-------------------------------------------------------------------
1231 :
1232 7790 : if (my_task==master_task .and. diag) then
1233 : write(nu_diag,'(2a,i8,a,i8,2a)') &
1234 : subname,' fid= ',fid, ', lnrec = ',lnrec, & ! LCOV_EXCL_LINE
1235 296 : ', varname = ',trim(varname)
1236 : ! status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
1237 : ! write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
1238 : ! do id=1,ndim
1239 : ! status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
1240 : ! write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
1241 : ! enddo
1242 1858812 : amin = minval(work_g1)
1243 1858812 : amax = maxval(work_g1, mask = work_g1 /= missingvalue)
1244 1858812 : asum = sum (work_g1, mask = work_g1 /= missingvalue)
1245 148 : write(nu_diag,*) subname,' min, max, sum =', amin, amax, asum, trim(varname)
1246 : endif
1247 :
1248 : !-------------------------------------------------------------------
1249 : ! Scatter data to individual processors.
1250 : ! NOTE: Ghost cells are not updated unless field_loc is present.
1251 : !-------------------------------------------------------------------
1252 :
1253 7790 : if (present(restart_ext)) then
1254 0 : if (restart_ext) then
1255 0 : call scatter_global_ext(work, work_g1, master_task, distrb_info)
1256 : endif
1257 : else
1258 7790 : if (present(field_loc)) then
1259 0 : call scatter_global(work, work_g1, master_task, distrb_info, &
1260 7790 : field_loc, field_type)
1261 : else
1262 0 : call scatter_global(work, work_g1, master_task, distrb_info, &
1263 0 : field_loc_noupdate, field_type_noupdate)
1264 : endif
1265 : endif
1266 :
1267 7790 : deallocate(work_g1)
1268 :
1269 : ! echmod: this should not be necessary if fill/missing are only on land
1270 25165720 : where (work > 1.0e+30_dbl_kind) work = c0
1271 :
1272 7790 : if (orca_halogrid .and. .not. present(restart_ext)) deallocate(work_g2)
1273 :
1274 : #else
1275 : work = c0 ! to satisfy intent(out) attribute
1276 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
1277 : file=__FILE__, line=__LINE__)
1278 : #endif
1279 15580 : end subroutine ice_read_nc_xy
1280 :
1281 : !=======================================================================
1282 :
1283 : ! Read a netCDF file and scatter to processors.
1284 : ! If the optional variables field_loc and field_type are present,
1285 : ! the ghost cells are filled using values from the global array.
1286 : ! This prevents them from being filled with zeroes in land cells
1287 : ! (subroutine ice_HaloUpdate need not be called).
1288 : !
1289 : ! Adapted by David Bailey, NCAR from ice_read_nc_xy
1290 :
1291 659 : subroutine ice_read_nc_xyz(fid, nrec, varname, work, diag, &
1292 : field_loc, field_type, restart_ext)
1293 :
1294 : use ice_gather_scatter, only: scatter_global, scatter_global_ext
1295 :
1296 : integer (kind=int_kind), intent(in) :: &
1297 : fid , & ! file id ! LCOV_EXCL_LINE
1298 : nrec ! record number
1299 :
1300 : character (len=*), intent(in) :: &
1301 : varname ! field name in netcdf file
1302 :
1303 : logical (kind=log_kind), intent(in) :: &
1304 : diag ! if true, write diagnostic output
1305 :
1306 : real (kind=dbl_kind), dimension(nx_block,ny_block,ncat,max_blocks), intent(out) :: &
1307 : work ! output array (real, 8-byte)
1308 :
1309 : logical (kind=log_kind), optional, intent(in) :: &
1310 : restart_ext ! if true, read extended grid
1311 :
1312 : integer (kind=int_kind), optional, intent(in) :: &
1313 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
1314 : field_type ! type of field (scalar, vector, angle)
1315 :
1316 : ! local variables
1317 :
1318 : character(len=*), parameter :: subname = '(ice_read_nc_xyz)'
1319 :
1320 : #ifdef USE_NETCDF
1321 : ! netCDF file diagnostics:
1322 : integer (kind=int_kind) :: &
1323 : n, & ! ncat index ! LCOV_EXCL_LINE
1324 : varid , & ! variable id ! LCOV_EXCL_LINE
1325 : status , & ! status output from netcdf routines ! LCOV_EXCL_LINE
1326 : ndims , & ! number of dimensions ! LCOV_EXCL_LINE
1327 : dimlen ! dimension size
1328 :
1329 : integer (kind=int_kind), dimension(10) :: &
1330 : dimids ! generic size dimids
1331 :
1332 : real (kind=dbl_kind) :: &
1333 : missingvalue, & ! missing value ! LCOV_EXCL_LINE
1334 188 : amin, amax, asum ! min, max values and sum of input array
1335 :
1336 : ! character (char_len) :: &
1337 : ! dimname ! dimension name
1338 :
1339 : real (kind=dbl_kind), dimension(:,:,:), allocatable :: &
1340 659 : work_g1
1341 :
1342 : integer (kind=int_kind) :: nx, ny
1343 :
1344 : integer (kind=int_kind) :: lnrec ! local value of nrec
1345 :
1346 : real (kind=dbl_kind), dimension(:,:,:), allocatable :: &
1347 659 : work_g2
1348 :
1349 659 : lnrec = nrec
1350 :
1351 659 : if (orca_halogrid .and. .not. present(restart_ext)) then
1352 0 : if (my_task == master_task) then
1353 0 : allocate(work_g2(nx_global+2,ny_global+1,ncat))
1354 : else
1355 0 : allocate(work_g2(1,1,ncat)) ! to save memory
1356 : endif
1357 0 : work_g2(:,:,:) = c0
1358 : endif
1359 :
1360 659 : nx = nx_global
1361 659 : ny = ny_global
1362 :
1363 659 : if (present(restart_ext)) then
1364 0 : if (restart_ext) then
1365 0 : nx = nx_global + 2*nghost
1366 0 : ny = ny_global + 2*nghost
1367 : endif
1368 : endif
1369 :
1370 659 : if (my_task == master_task) then
1371 132 : allocate(work_g1(nx,ny,ncat))
1372 : else
1373 527 : allocate(work_g1(1,1,ncat)) ! to save memory
1374 : endif
1375 :
1376 659 : if (my_task == master_task) then
1377 :
1378 : !-------------------------------------------------------------
1379 : ! Find out ID of required variable
1380 : !-------------------------------------------------------------
1381 :
1382 132 : status = nf90_inq_varid(fid, trim(varname), varid)
1383 132 : if (status /= nf90_noerr) then
1384 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
1385 0 : file=__FILE__, line=__LINE__)
1386 : endif
1387 :
1388 : !-------------------------------------------------------------
1389 : ! Check nrec axis size
1390 : !-------------------------------------------------------------
1391 :
1392 132 : status = nf90_inquire_variable(fid, varid, ndims=ndims, dimids=dimids)
1393 132 : if (status /= nf90_noerr) then
1394 : call abort_ice(subname//' ERROR: inquire variable dimids '//trim(varname), &
1395 0 : file=__FILE__, line=__LINE__)
1396 : endif
1397 132 : if (ndims > 3) then
1398 0 : status = nf90_inquire_dimension(fid, dimids(4), len=dimlen)
1399 0 : if (status /= nf90_noerr) then
1400 : call abort_ice(subname//' ERROR: inquire dimension size 4 '//trim(varname), &
1401 0 : file=__FILE__, line=__LINE__)
1402 : endif
1403 0 : if (lnrec > dimlen) then
1404 0 : write(nu_diag,*) subname,' ERROR not enough records, ',trim(varname),lnrec,dimlen
1405 : call abort_ice(subname//' ERROR: not enough records '//trim(varname), &
1406 0 : file=__FILE__, line=__LINE__)
1407 : endif
1408 : endif
1409 :
1410 : !--------------------------------------------------------------
1411 : ! Read global array
1412 : !--------------------------------------------------------------
1413 :
1414 132 : if (orca_halogrid .and. .not. present(restart_ext)) then
1415 : status = nf90_get_var( fid, varid, work_g2, &
1416 : start=(/1,1,1,lnrec/), & ! LCOV_EXCL_LINE
1417 0 : count=(/nx_global+2,ny_global+1,ncat,1/))
1418 0 : if (status /= nf90_noerr) then
1419 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
1420 0 : file=__FILE__, line=__LINE__)
1421 : endif
1422 0 : work_g1 = work_g2(2:nx_global+1,1:ny_global,:)
1423 : else
1424 : status = nf90_get_var( fid, varid, work_g1, &
1425 : start=(/1,1,1,lnrec/), & ! LCOV_EXCL_LINE
1426 1188 : count=(/nx,ny,ncat,1/))
1427 132 : if (status /= nf90_noerr) then
1428 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
1429 0 : file=__FILE__, line=__LINE__)
1430 : endif
1431 : endif
1432 :
1433 132 : status = nf90_get_att(fid, varid, "_FillValue", missingvalue)
1434 : endif ! my_task = master_task
1435 :
1436 : !-------------------------------------------------------------------
1437 : ! optional diagnostics
1438 : !-------------------------------------------------------------------
1439 :
1440 659 : if (my_task==master_task .and. diag) then
1441 : write(nu_diag,'(2a,i8,a,i8,2a)') &
1442 : subname,' fid= ',fid, ', lnrec = ',lnrec, & ! LCOV_EXCL_LINE
1443 264 : ', varname = ',trim(varname)
1444 : ! status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
1445 : ! write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
1446 : ! do id=1,ndim
1447 : ! status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
1448 : ! write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
1449 : ! enddo
1450 792 : do n=1,ncat
1451 8404660 : amin = minval(work_g1(:,:,n))
1452 8404660 : amax = maxval(work_g1(:,:,n), mask = work_g1(:,:,n) /= missingvalue)
1453 8404660 : asum = sum (work_g1(:,:,n), mask = work_g1(:,:,n) /= missingvalue)
1454 792 : write(nu_diag,*) subname,' min, max, sum =', amin, amax, asum, trim(varname)
1455 : enddo
1456 : endif
1457 :
1458 : !-------------------------------------------------------------------
1459 : ! Scatter data to individual processors.
1460 : ! NOTE: Ghost cells are not updated unless field_loc is present.
1461 : !-------------------------------------------------------------------
1462 :
1463 659 : if (present(restart_ext)) then
1464 0 : if (restart_ext) then
1465 0 : do n=1,ncat
1466 0 : call scatter_global_ext(work(:,:,n,:), work_g1(:,:,n), &
1467 0 : master_task, distrb_info)
1468 : enddo
1469 : endif
1470 : else
1471 659 : if (present(field_loc)) then
1472 3954 : do n=1,ncat
1473 0 : call scatter_global(work(:,:,n,:), work_g1(:,:,n), master_task, &
1474 3954 : distrb_info, field_loc, field_type)
1475 : enddo
1476 : else
1477 0 : do n=1,ncat
1478 0 : call scatter_global(work(:,:,n,:), work_g1(:,:,n), master_task, &
1479 0 : distrb_info, field_loc_noupdate, field_type_noupdate)
1480 : enddo
1481 : endif
1482 : endif
1483 :
1484 659 : deallocate(work_g1)
1485 659 : if (orca_halogrid .and. .not. present(restart_ext)) deallocate(work_g2)
1486 :
1487 : #else
1488 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
1489 : file=__FILE__, line=__LINE__)
1490 : work = c0 ! to satisfy intent(out) attribute
1491 : #endif
1492 1318 : end subroutine ice_read_nc_xyz
1493 :
1494 : !=======================================================================
1495 :
1496 : ! Read a netCDF file and scatter to processors.
1497 : ! If the optional variables field_loc and field_type are present,
1498 : ! the ghost cells are filled using values from the global array.
1499 : ! This prevents them from being filled with zeroes in land cells
1500 : ! (subroutine ice_HaloUpdate need not be called).
1501 : !
1502 : ! Adapted by David Bailey, NCAR from ice_read_nc_xy
1503 : ! Adapted by Lettie Roach, NIWA to read nfreq
1504 : ! by changing all occurrences of ncat to nfreq
1505 :
1506 0 : subroutine ice_read_nc_xyf(fid, nrec, varname, work, diag, &
1507 : field_loc, field_type, restart_ext)
1508 :
1509 : use ice_fileunits, only: nu_diag
1510 : use ice_domain_size, only: nfreq
1511 : use ice_gather_scatter, only: scatter_global, scatter_global_ext
1512 :
1513 : integer (kind=int_kind), intent(in) :: &
1514 : fid , & ! file id ! LCOV_EXCL_LINE
1515 : nrec ! record number
1516 :
1517 : character (len=*), intent(in) :: &
1518 : varname ! field name in netcdf file
1519 :
1520 : logical (kind=log_kind), intent(in) :: &
1521 : diag ! if true, write diagnostic output
1522 :
1523 : real (kind=dbl_kind), dimension(nx_block,ny_block,nfreq,1,max_blocks), &
1524 : intent(out) :: & ! LCOV_EXCL_LINE
1525 : work ! output array (real, 8-byte)
1526 :
1527 : logical (kind=log_kind), optional, intent(in) :: &
1528 : restart_ext ! if true, read extended grid
1529 :
1530 : integer (kind=int_kind), optional, intent(in) :: &
1531 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
1532 : field_type ! type of field (scalar, vector, angle)
1533 :
1534 : ! local variables
1535 :
1536 : ! netCDF file diagnostics:
1537 : integer (kind=int_kind) :: &
1538 : varid, & ! variable id ! LCOV_EXCL_LINE
1539 : status, & ! status output from netcdf routines ! LCOV_EXCL_LINE
1540 : ndim, nvar, & ! sizes of netcdf file ! LCOV_EXCL_LINE
1541 : id, & ! dimension index ! LCOV_EXCL_LINE
1542 : n, & ! ncat index ! LCOV_EXCL_LINE
1543 : ndims, & ! number of dimensions ! LCOV_EXCL_LINE
1544 : dimlen ! dimension size
1545 :
1546 : integer (kind=int_kind), dimension(10) :: &
1547 : dimids ! generic size dimids
1548 :
1549 : real (kind=dbl_kind) :: &
1550 : missingvalue, & ! missing value ! LCOV_EXCL_LINE
1551 0 : amin, amax, asum ! min, max values and sum of input array
1552 :
1553 : character (char_len) :: &
1554 : dimname ! dimension name
1555 :
1556 : real (kind=dbl_kind), dimension(:,:,:), allocatable :: &
1557 0 : work_g1
1558 :
1559 : integer (kind=int_kind) :: nx, ny
1560 :
1561 : integer (kind=int_kind) :: lnrec ! local value of nrec
1562 :
1563 : character(len=*), parameter :: subname = '(ice_read_nc_xyf)'
1564 :
1565 : #ifdef USE_NETCDF
1566 : real (kind=dbl_kind), dimension(:,:,:), allocatable :: &
1567 0 : work_g2
1568 :
1569 0 : lnrec = nrec
1570 :
1571 0 : if (orca_halogrid .and. .not. present(restart_ext)) then
1572 0 : if (my_task == master_task) then
1573 0 : allocate(work_g2(nx_global+2,ny_global+1,nfreq))
1574 : else
1575 0 : allocate(work_g2(1,1,nfreq)) ! to save memory
1576 : endif
1577 0 : work_g2(:,:,:) = c0
1578 : endif
1579 :
1580 0 : nx = nx_global
1581 0 : ny = ny_global
1582 :
1583 0 : if (present(restart_ext)) then
1584 0 : if (restart_ext) then
1585 0 : nx = nx_global + 2*nghost
1586 0 : ny = ny_global + 2*nghost
1587 : endif
1588 : endif
1589 :
1590 0 : if (my_task == master_task) then
1591 0 : allocate(work_g1(nx,ny,nfreq))
1592 : else
1593 0 : allocate(work_g1(1,1,nfreq)) ! to save memory
1594 : endif
1595 :
1596 0 : if (my_task == master_task) then
1597 :
1598 : !-------------------------------------------------------------
1599 : ! Find out ID of required variable
1600 : !-------------------------------------------------------------
1601 :
1602 0 : status = nf90_inq_varid(fid, trim(varname), varid)
1603 0 : if (status /= nf90_noerr) then
1604 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
1605 0 : file=__FILE__, line=__LINE__)
1606 : endif
1607 :
1608 : !-------------------------------------------------------------
1609 : ! Check nrec axis size
1610 : !-------------------------------------------------------------
1611 :
1612 0 : status = nf90_inquire_variable(fid, varid, ndims=ndims, dimids=dimids)
1613 0 : if (status /= nf90_noerr) then
1614 : call abort_ice(subname//' ERROR: inquire variable dimids '//trim(varname), &
1615 0 : file=__FILE__, line=__LINE__)
1616 : endif
1617 0 : if (ndims > 3) then
1618 0 : status = nf90_inquire_dimension(fid, dimids(4), len=dimlen)
1619 0 : if (status /= nf90_noerr) then
1620 : call abort_ice(subname//' ERROR: inquire dimension size 4 '//trim(varname), &
1621 0 : file=__FILE__, line=__LINE__)
1622 : endif
1623 0 : if (lnrec > dimlen) then
1624 0 : write(nu_diag,*) subname,' ERROR not enough records, ',trim(varname),lnrec,dimlen
1625 : call abort_ice(subname//' ERROR: not enough records '//trim(varname), &
1626 0 : file=__FILE__, line=__LINE__)
1627 : endif
1628 : endif
1629 :
1630 : !--------------------------------------------------------------
1631 : ! Read global array
1632 : !--------------------------------------------------------------
1633 :
1634 0 : if (orca_halogrid .and. .not. present(restart_ext)) then
1635 : status = nf90_get_var( fid, varid, work_g2, &
1636 : start=(/1,1,1,lnrec/), & ! LCOV_EXCL_LINE
1637 0 : count=(/nx_global+2,ny_global+1,nfreq,1/))
1638 0 : if (status /= nf90_noerr) then
1639 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
1640 0 : file=__FILE__, line=__LINE__)
1641 : endif
1642 0 : work_g1 = work_g2(2:nx_global+1,1:ny_global,:)
1643 : else
1644 : status = nf90_get_var( fid, varid, work_g1, &
1645 : start=(/1,1,1,lnrec/), & ! LCOV_EXCL_LINE
1646 0 : count=(/nx,ny,nfreq,1/))
1647 0 : if (status /= nf90_noerr) then
1648 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
1649 0 : file=__FILE__, line=__LINE__)
1650 : endif
1651 : endif
1652 :
1653 0 : status = nf90_get_att(fid, varid, "missing_value", missingvalue)
1654 : endif ! my_task = master_task
1655 :
1656 : !-------------------------------------------------------------------
1657 : ! optional diagnostics
1658 : !-------------------------------------------------------------------
1659 :
1660 0 : if (my_task==master_task .and. diag) then
1661 : write(nu_diag,'(2a,i8,a,i8,2a)') &
1662 : subname,' fid= ',fid, ', lnrec = ',lnrec, & ! LCOV_EXCL_LINE
1663 0 : ', varname = ',trim(varname)
1664 0 : status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
1665 0 : write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
1666 0 : do id=1,ndim
1667 0 : status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
1668 0 : write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
1669 : enddo
1670 0 : write(nu_diag,*) subname,' missingvalue= ',missingvalue
1671 0 : do n = 1, nfreq
1672 0 : amin = minval(work_g1(:,:,n))
1673 0 : amax = maxval(work_g1(:,:,n), mask = work_g1(:,:,n) /= missingvalue)
1674 0 : asum = sum (work_g1(:,:,n), mask = work_g1(:,:,n) /= missingvalue)
1675 0 : write(nu_diag,*) subname,' min, max, sum =', amin, amax, asum, trim(varname)
1676 : enddo
1677 : endif
1678 :
1679 : !-------------------------------------------------------------------
1680 : ! Scatter data to individual processors.
1681 : ! NOTE: Ghost cells are not updated unless field_loc is present.
1682 : !-------------------------------------------------------------------
1683 :
1684 0 : if (present(restart_ext)) then
1685 0 : if (restart_ext) then
1686 0 : do n = 1, nfreq
1687 0 : call scatter_global_ext(work(:,:,n,1,:), work_g1(:,:,n), &
1688 0 : master_task, distrb_info)
1689 : enddo
1690 : endif
1691 : else
1692 0 : if (present(field_loc)) then
1693 0 : do n = 1, nfreq
1694 0 : call scatter_global(work(:,:,n,1,:), work_g1(:,:,n), master_task, &
1695 0 : distrb_info, field_loc, field_type)
1696 : enddo
1697 : else
1698 0 : do n = 1, nfreq
1699 0 : call scatter_global(work(:,:,n,1,:), work_g1(:,:,n), master_task, &
1700 0 : distrb_info, field_loc_noupdate, field_type_noupdate)
1701 : enddo
1702 : endif
1703 : endif
1704 :
1705 : ! echmod: this should not be necessary if fill/missing are only on land
1706 0 : where (work > 1.0e+30_dbl_kind) work = c0
1707 :
1708 0 : deallocate(work_g1)
1709 0 : if (orca_halogrid .and. .not. present(restart_ext)) deallocate(work_g2)
1710 :
1711 : #else
1712 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
1713 : file=__FILE__, line=__LINE__)
1714 : work = c0 ! to satisfy intent(out) attribute
1715 : #endif
1716 :
1717 0 : end subroutine ice_read_nc_xyf
1718 :
1719 : !=======================================================================
1720 :
1721 : ! Read a netCDF file
1722 : ! Adapted by Alison McLaren, Met Office from ice_read
1723 :
1724 0 : subroutine ice_read_nc_point(fid, nrec, varname, work, diag, &
1725 : field_loc, field_type)
1726 :
1727 : integer (kind=int_kind), intent(in) :: &
1728 : fid , & ! file id ! LCOV_EXCL_LINE
1729 : nrec ! record number
1730 :
1731 : logical (kind=log_kind), intent(in) :: &
1732 : diag ! if true, write diagnostic output
1733 :
1734 : character (char_len), intent(in) :: &
1735 : varname ! field name in netcdf file
1736 :
1737 : integer (kind=int_kind), optional, intent(in) :: &
1738 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
1739 : field_type ! type of field (scalar, vector, angle)
1740 :
1741 : real (kind=dbl_kind), intent(out) :: &
1742 : work ! output variable (real, 8-byte)
1743 :
1744 : ! local variables
1745 :
1746 : character(len=*), parameter :: subname = '(ice_read_nc_point)'
1747 :
1748 : #ifdef USE_NETCDF
1749 : ! netCDF file diagnostics:
1750 : integer (kind=int_kind) :: &
1751 : varid, & ! netcdf id for field ! LCOV_EXCL_LINE
1752 : status, & ! status output from netcdf routines ! LCOV_EXCL_LINE
1753 : ndim, nvar, & ! sizes of netcdf file ! LCOV_EXCL_LINE
1754 : id, & ! dimension index ! LCOV_EXCL_LINE
1755 : ndims, & ! number of dimensions ! LCOV_EXCL_LINE
1756 : dimlen ! dimension size
1757 :
1758 : integer (kind=int_kind), dimension(10) :: &
1759 : dimids ! generic size dimids
1760 :
1761 : real (kind=dbl_kind), dimension(1) :: &
1762 0 : workg ! temporary work variable
1763 :
1764 : integer (kind=int_kind) :: lnrec ! local value of nrec
1765 :
1766 : character (char_len) :: &
1767 : dimname ! dimension name
1768 :
1769 0 : lnrec = nrec
1770 :
1771 0 : if (my_task == master_task) then
1772 :
1773 : !-------------------------------------------------------------
1774 : ! Find out ID of required variable
1775 : !-------------------------------------------------------------
1776 :
1777 0 : status = nf90_inq_varid(fid, trim(varname), varid)
1778 0 : if (status /= nf90_noerr) then
1779 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
1780 0 : file=__FILE__, line=__LINE__)
1781 : endif
1782 :
1783 : !-------------------------------------------------------------
1784 : ! Check nrec axis size
1785 : !-------------------------------------------------------------
1786 :
1787 0 : status = nf90_inquire_variable(fid, varid, ndims=ndims, dimids=dimids)
1788 0 : if (status /= nf90_noerr) then
1789 : call abort_ice(subname//' ERROR: inquire variable dimids '//trim(varname), &
1790 0 : file=__FILE__, line=__LINE__)
1791 : endif
1792 0 : if (ndims > 0) then
1793 0 : status = nf90_inquire_dimension(fid, dimids(1), len=dimlen)
1794 0 : if (status /= nf90_noerr) then
1795 : call abort_ice(subname//' ERROR: inquire dimension size 1 '//trim(varname), &
1796 0 : file=__FILE__, line=__LINE__)
1797 : endif
1798 0 : if (lnrec > dimlen) then
1799 0 : write(nu_diag,*) subname,' ERROR not enough records, ',trim(varname),lnrec,dimlen
1800 : call abort_ice(subname//' ERROR: not enough records '//trim(varname), &
1801 0 : file=__FILE__, line=__LINE__)
1802 : endif
1803 : endif
1804 :
1805 : !--------------------------------------------------------------
1806 : ! Read point variable
1807 : !--------------------------------------------------------------
1808 :
1809 : status = nf90_get_var(fid, varid, workg, &
1810 : start= (/ lnrec /), & ! LCOV_EXCL_LINE
1811 0 : count=(/ 1 /))
1812 0 : if (status /= nf90_noerr) then
1813 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
1814 0 : file=__FILE__, line=__LINE__)
1815 : endif
1816 : endif ! my_task = master_task
1817 :
1818 : !-------------------------------------------------------------------
1819 : ! optional diagnostics
1820 : !-------------------------------------------------------------------
1821 :
1822 0 : if (my_task==master_task .and. diag) then
1823 : write(nu_diag,'(2a,i8,a,i8,2a)') &
1824 : subname,' fid= ',fid, ', lnrec = ',lnrec, & ! LCOV_EXCL_LINE
1825 0 : ', varname = ',trim(varname)
1826 0 : status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
1827 0 : write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
1828 0 : do id=1,ndim
1829 0 : status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
1830 0 : write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
1831 : enddo
1832 : endif
1833 :
1834 0 : work = workg(1)
1835 :
1836 : #else
1837 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
1838 : file=__FILE__, line=__LINE__)
1839 : work = c0 ! to satisfy intent(out) attribute
1840 : #endif
1841 0 : end subroutine ice_read_nc_point
1842 :
1843 : !=======================================================================
1844 :
1845 : ! Written by T. Craig
1846 :
1847 0 : subroutine ice_read_nc_1D(fid, varname, work, diag, &
1848 : xdim)
1849 :
1850 : use ice_fileunits, only: nu_diag
1851 :
1852 : integer (kind=int_kind), intent(in) :: &
1853 : fid , & ! file id ! LCOV_EXCL_LINE
1854 : xdim ! field dimensions
1855 :
1856 : logical (kind=log_kind), intent(in) :: &
1857 : diag ! if true, write diagnostic output
1858 :
1859 : character (char_len), intent(in) :: &
1860 : varname ! field name in netcdf file
1861 :
1862 : real (kind=dbl_kind), dimension(:), intent(out) :: &
1863 : work ! output array
1864 :
1865 : ! local variables
1866 :
1867 : character(len=*), parameter :: subname = '(ice_read_nc_1D)'
1868 :
1869 : #ifdef USE_NETCDF
1870 : ! netCDF file diagnostics:
1871 : integer (kind=int_kind) :: &
1872 : varid, & ! netcdf id for field ! LCOV_EXCL_LINE
1873 : status, & ! status output from netcdf routines ! LCOV_EXCL_LINE
1874 : ndim, nvar ! sizes of netcdf file
1875 :
1876 : real (kind=dbl_kind), dimension(xdim) :: &
1877 0 : workg ! output array (real, 8-byte)
1878 :
1879 : !--------------------------------------------------------------
1880 :
1881 0 : if (my_task == master_task) then
1882 :
1883 0 : if (size(work,dim=1) < xdim) then
1884 0 : write(nu_diag,*) subname,' work, dim=1 ',size(work,dim=1),xdim
1885 : call abort_ice (subname//' ERROR: work array wrong size '//trim(varname), &
1886 0 : file=__FILE__, line=__LINE__ )
1887 : endif
1888 : !-------------------------------------------------------------
1889 : ! Find out ID of required variable
1890 : !-------------------------------------------------------------
1891 :
1892 0 : status = nf90_inq_varid(fid, trim(varname), varid)
1893 :
1894 0 : if (status /= nf90_noerr) then
1895 : call abort_ice (subname//' ERROR: Cannot find variable '//trim(varname), &
1896 0 : file=__FILE__, line=__LINE__ )
1897 : endif
1898 :
1899 : !--------------------------------------------------------------
1900 : ! Read array
1901 : !--------------------------------------------------------------
1902 0 : status = nf90_get_var( fid, varid, workg, &
1903 : start=(/1/), & ! LCOV_EXCL_LINE
1904 0 : count=(/xdim/) )
1905 0 : work(1:xdim) = workg(1:xdim)
1906 :
1907 : !-------------------------------------------------------------------
1908 : ! optional diagnostics
1909 : !-------------------------------------------------------------------
1910 :
1911 0 : if (diag) then
1912 0 : write(nu_diag,*) subname, &
1913 : ' fid= ',fid, ', xdim = ',xdim, & ! LCOV_EXCL_LINE
1914 0 : ' varname = ',trim(varname)
1915 0 : status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
1916 0 : write(nu_diag,*) 'ndim= ',ndim,', nvar= ',nvar
1917 : endif
1918 : endif
1919 : #else
1920 : call abort_ice(subname//'ERROR: USE_NETCDF cpp not defined', &
1921 : file=__FILE__, line=__LINE__)
1922 : work = c0 ! to satisfy intent(out) attribute
1923 : #endif
1924 :
1925 0 : end subroutine ice_read_nc_1D
1926 :
1927 : !=======================================================================
1928 :
1929 : ! Written by T. Craig
1930 :
1931 0 : subroutine ice_read_nc_2D(fid, varname, work, diag, &
1932 : xdim, ydim)
1933 :
1934 : use ice_fileunits, only: nu_diag
1935 :
1936 : integer (kind=int_kind), intent(in) :: &
1937 : fid , & ! file id ! LCOV_EXCL_LINE
1938 : xdim, ydim ! field dimensions
1939 :
1940 : logical (kind=log_kind), intent(in) :: &
1941 : diag ! if true, write diagnostic output
1942 :
1943 : character (char_len), intent(in) :: &
1944 : varname ! field name in netcdf file
1945 :
1946 : real (kind=dbl_kind), dimension(:,:), intent(out) :: &
1947 : work ! output array
1948 :
1949 : ! local variables
1950 :
1951 : character(len=*), parameter :: subname = '(ice_read_nc_2D)'
1952 :
1953 : #ifdef USE_NETCDF
1954 : ! netCDF file diagnostics:
1955 : integer (kind=int_kind) :: &
1956 : varid, & ! netcdf id for field ! LCOV_EXCL_LINE
1957 : status, & ! status output from netcdf routines ! LCOV_EXCL_LINE
1958 : ndim, nvar ! sizes of netcdf file
1959 :
1960 : real (kind=dbl_kind), dimension(xdim,ydim) :: &
1961 0 : workg ! output array (real, 8-byte)
1962 :
1963 : !--------------------------------------------------------------
1964 :
1965 0 : if (my_task == master_task) then
1966 :
1967 0 : if (size(work,dim=1) < xdim .or. &
1968 0 : size(work,dim=2) < ydim) then
1969 0 : write(nu_diag,*) subname,' work, dim=1 ',size(work,dim=1),xdim
1970 0 : write(nu_diag,*) subname,' work, dim=2 ',size(work,dim=2),ydim
1971 : call abort_ice (subname//' ERROR: work array wrong size '//trim(varname), &
1972 0 : file=__FILE__, line=__LINE__ )
1973 : endif
1974 : !-------------------------------------------------------------
1975 : ! Find out ID of required variable
1976 : !-------------------------------------------------------------
1977 :
1978 0 : status = nf90_inq_varid(fid, trim(varname), varid)
1979 :
1980 0 : if (status /= nf90_noerr) then
1981 : call abort_ice (subname//' ERROR: Cannot find variable '//trim(varname), &
1982 0 : file=__FILE__, line=__LINE__ )
1983 : endif
1984 :
1985 : !--------------------------------------------------------------
1986 : ! Read array
1987 : !--------------------------------------------------------------
1988 0 : status = nf90_get_var( fid, varid, workg, &
1989 : start=(/1,1/), & ! LCOV_EXCL_LINE
1990 0 : count=(/xdim,ydim/) )
1991 0 : work(1:xdim,1:ydim) = workg(1:xdim, 1:ydim)
1992 :
1993 : !-------------------------------------------------------------------
1994 : ! optional diagnostics
1995 : !-------------------------------------------------------------------
1996 :
1997 0 : if (diag) then
1998 0 : write(nu_diag,*) subname, &
1999 : ' fid= ',fid, ', xdim = ',xdim, & ! LCOV_EXCL_LINE
2000 0 : ' ydim= ', ydim, ' varname = ',trim(varname)
2001 0 : status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
2002 0 : write(nu_diag,*) 'ndim= ',ndim,', nvar= ',nvar
2003 : endif
2004 : endif
2005 : #else
2006 : call abort_ice(subname//'ERROR: USE_NETCDF cpp not defined', &
2007 : file=__FILE__, line=__LINE__)
2008 : work = c0 ! to satisfy intent(out) attribute
2009 : #endif
2010 :
2011 0 : end subroutine ice_read_nc_2D
2012 :
2013 : !=======================================================================
2014 : !=======================================================================
2015 :
2016 : ! Written by T. Craig
2017 :
2018 0 : subroutine ice_read_nc_3D(fid, varname, work, diag, &
2019 : xdim, ydim, zdim)
2020 :
2021 : use ice_fileunits, only: nu_diag
2022 :
2023 : integer (kind=int_kind), intent(in) :: &
2024 : fid , & ! file id ! LCOV_EXCL_LINE
2025 : xdim, ydim,zdim ! field dimensions
2026 :
2027 : logical (kind=log_kind), intent(in) :: &
2028 : diag ! if true, write diagnostic output
2029 :
2030 : character (char_len), intent(in) :: &
2031 : varname ! field name in netcdf file
2032 :
2033 : real (kind=dbl_kind), dimension(:,:,:), intent(out) :: &
2034 : work ! output array
2035 :
2036 : ! local variables
2037 :
2038 : character(len=*), parameter :: subname = '(ice_read_nc_3D)'
2039 :
2040 : #ifdef USE_NETCDF
2041 : ! netCDF file diagnostics:
2042 : integer (kind=int_kind) :: &
2043 : varid, & ! netcdf id for field ! LCOV_EXCL_LINE
2044 : status, & ! status output from netcdf routines ! LCOV_EXCL_LINE
2045 : ndim, nvar ! sizes of netcdf file
2046 :
2047 : real (kind=dbl_kind), dimension(xdim,ydim,zdim) :: &
2048 0 : workg ! output array (real, 8-byte)
2049 :
2050 : !--------------------------------------------------------------
2051 :
2052 0 : if (my_task == master_task) then
2053 :
2054 0 : if (size(work,dim=1) < xdim .or. &
2055 : size(work,dim=2) < ydim .or. & ! LCOV_EXCL_LINE
2056 0 : size(work,dim=3) < zdim ) then
2057 0 : write(nu_diag,*) subname,' work, dim=1 ',size(work,dim=1),xdim
2058 0 : write(nu_diag,*) subname,' work, dim=2 ',size(work,dim=2),ydim
2059 0 : write(nu_diag,*) subname,' work, dim=3 ',size(work,dim=3),zdim
2060 : call abort_ice (subname//' ERROR: work array wrong size '//trim(varname), &
2061 0 : file=__FILE__, line=__LINE__ )
2062 : endif
2063 : !-------------------------------------------------------------
2064 : ! Find out ID of required variable
2065 : !-------------------------------------------------------------
2066 :
2067 0 : status = nf90_inq_varid(fid, trim(varname), varid)
2068 :
2069 0 : if (status /= nf90_noerr) then
2070 : call abort_ice (subname//' ERROR: Cannot find variable '//trim(varname), &
2071 0 : file=__FILE__, line=__LINE__ )
2072 : endif
2073 :
2074 : !--------------------------------------------------------------
2075 : ! Read array
2076 : !--------------------------------------------------------------
2077 0 : status = nf90_get_var( fid, varid, workg, &
2078 : start=(/1,1,1/), & ! LCOV_EXCL_LINE
2079 0 : count=(/xdim,ydim,zdim/) )
2080 0 : work(1:xdim,1:ydim,1:zdim) = workg(1:xdim, 1:ydim, 1:zdim)
2081 :
2082 : !-------------------------------------------------------------------
2083 : ! optional diagnostics
2084 : !-------------------------------------------------------------------
2085 :
2086 0 : if (diag) then
2087 0 : write(nu_diag,*) subname, &
2088 : ' fid= ',fid, ', xdim = ',xdim, & ! LCOV_EXCL_LINE
2089 0 : ' ydim= ', ydim,' zdim = ',zdim, ' varname = ',trim(varname)
2090 0 : status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
2091 0 : write(nu_diag,*) 'ndim= ',ndim,', nvar= ',nvar
2092 : endif
2093 : endif
2094 : #else
2095 : call abort_ice(subname//'ERROR: USE_NETCDF cpp not defined', &
2096 : file=__FILE__, line=__LINE__)
2097 : work = c0 ! to satisfy intent(out) attribute
2098 : #endif
2099 :
2100 0 : end subroutine ice_read_nc_3D
2101 :
2102 : !=======================================================================
2103 :
2104 : ! Adapted by Nicole Jeffery, LANL
2105 :
2106 0 : subroutine ice_read_nc_z(fid, nrec, varname, work, diag, &
2107 : field_loc, field_type)
2108 :
2109 : use ice_domain_size, only: nilyr
2110 :
2111 : integer (kind=int_kind), intent(in) :: &
2112 : fid , & ! file id ! LCOV_EXCL_LINE
2113 : nrec ! record number
2114 :
2115 : logical (kind=log_kind), intent(in) :: &
2116 : diag ! if true, write diagnostic output
2117 :
2118 : character (char_len), intent(in) :: &
2119 : varname ! field name in netcdf file
2120 :
2121 : integer (kind=int_kind), optional, intent(in) :: &
2122 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
2123 : field_type ! type of field (scalar, vector, angle)
2124 :
2125 : real (kind=dbl_kind), dimension(nilyr), intent(out) :: &
2126 : work ! output array (real, 8-byte)
2127 :
2128 : ! local variables
2129 :
2130 : #ifdef USE_NETCDF
2131 : real (kind=dbl_kind), dimension(:), allocatable :: &
2132 0 : work_z
2133 :
2134 : ! netCDF file diagnostics:
2135 : integer (kind=int_kind) :: &
2136 : varid, & ! netcdf id for field ! LCOV_EXCL_LINE
2137 : status, & ! status output from netcdf routines ! LCOV_EXCL_LINE
2138 : ndim, nvar, & ! sizes of netcdf file ! LCOV_EXCL_LINE
2139 : id, & ! dimension index ! LCOV_EXCL_LINE
2140 : ndims, & ! number of dimensions ! LCOV_EXCL_LINE
2141 : dimlen ! dimension size
2142 :
2143 : integer (kind=int_kind), dimension(10) :: &
2144 : dimids ! generic size dimids
2145 :
2146 : character (char_len) :: &
2147 : dimname ! dimension name
2148 :
2149 : integer (kind=int_kind) :: lnrec ! local value of nrec
2150 :
2151 : #endif
2152 :
2153 : character(len=*), parameter :: subname = '(ice_read_nc_z)'
2154 :
2155 : #ifdef USE_NETCDF
2156 :
2157 0 : lnrec = nrec
2158 :
2159 0 : allocate(work_z(nilyr))
2160 :
2161 0 : if (my_task == master_task) then
2162 :
2163 : !-------------------------------------------------------------
2164 : ! Find out ID of required variable
2165 : !-------------------------------------------------------------
2166 :
2167 0 : status = nf90_inq_varid(fid, trim(varname), varid)
2168 0 : if (status /= nf90_noerr) then
2169 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
2170 0 : file=__FILE__, line=__LINE__)
2171 : endif
2172 :
2173 : !-------------------------------------------------------------
2174 : ! Check nrec axis size
2175 : !-------------------------------------------------------------
2176 :
2177 0 : status = nf90_inquire_variable(fid, varid, ndims=ndims, dimids=dimids)
2178 0 : if (status /= nf90_noerr) then
2179 : call abort_ice(subname//' ERROR: inquire variable dimids '//trim(varname), &
2180 0 : file=__FILE__, line=__LINE__)
2181 : endif
2182 0 : if (ndims > 1) then
2183 0 : status = nf90_inquire_dimension(fid, dimids(2), len=dimlen)
2184 0 : if (status /= nf90_noerr) then
2185 : call abort_ice(subname//' ERROR: inquire dimension size 2 '//trim(varname), &
2186 0 : file=__FILE__, line=__LINE__)
2187 : endif
2188 0 : if (lnrec > dimlen) then
2189 0 : write(nu_diag,*) subname,' ERROR not enough records, ',trim(varname),lnrec,dimlen
2190 : call abort_ice(subname//' ERROR: not enough records '//trim(varname), &
2191 0 : file=__FILE__, line=__LINE__)
2192 : endif
2193 : endif
2194 :
2195 : !--------------------------------------------------------------
2196 : ! Read global array
2197 : !--------------------------------------------------------------
2198 :
2199 : status = nf90_get_var( fid, varid, work_z, &
2200 : start=(/1,lnrec/), & ! LCOV_EXCL_LINE
2201 0 : count=(/nilyr,1/))
2202 0 : if (status /= nf90_noerr) then
2203 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
2204 0 : file=__FILE__, line=__LINE__)
2205 : endif
2206 : endif ! my_task = master_task
2207 :
2208 : !-------------------------------------------------------------------
2209 : ! optional diagnostics
2210 : !-------------------------------------------------------------------
2211 :
2212 0 : if (my_task==master_task .and. diag) then
2213 : write(nu_diag,'(2a,i8,a,i8,2a)') &
2214 : subname,' fid= ',fid, ', lnrec = ',lnrec, & ! LCOV_EXCL_LINE
2215 0 : ', varname = ',trim(varname)
2216 0 : status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
2217 0 : write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
2218 0 : do id=1,ndim
2219 0 : status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
2220 0 : write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
2221 : enddo
2222 : endif
2223 :
2224 0 : work(:) = work_z(:)
2225 0 : deallocate(work_z)
2226 :
2227 : #else
2228 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2229 : file=__FILE__, line=__LINE__)
2230 : work = c0 ! to satisfy intent(out) attribute
2231 : #endif
2232 0 : end subroutine ice_read_nc_z
2233 :
2234 : !=======================================================================
2235 :
2236 : ! Write a netCDF file.
2237 : !
2238 : ! Adapted by David Bailey, NCAR
2239 :
2240 1274 : subroutine ice_write_nc_xy(fid, nrec, varid, work, diag, &
2241 : restart_ext, varname)
2242 :
2243 : use ice_gather_scatter, only: gather_global, gather_global_ext
2244 :
2245 : integer (kind=int_kind), intent(in) :: &
2246 : fid , & ! file id ! LCOV_EXCL_LINE
2247 : varid , & ! variable id ! LCOV_EXCL_LINE
2248 : nrec ! record number
2249 :
2250 : logical (kind=log_kind), intent(in) :: &
2251 : diag ! if true, write diagnostic output
2252 :
2253 : logical (kind=log_kind), optional, intent(in) :: &
2254 : restart_ext ! if true, write extended grid
2255 :
2256 : real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), intent(in) :: &
2257 : work ! output array (real, 8-byte)
2258 :
2259 : character (len=*), optional, intent(in) :: &
2260 : varname ! variable name
2261 :
2262 : ! local variables
2263 :
2264 : character(len=*), parameter :: subname = '(ice_write_nc_xy)'
2265 :
2266 : #ifdef USE_NETCDF
2267 : ! netCDF file diagnostics:
2268 : integer (kind=int_kind) :: &
2269 : status ! status output from netcdf routines
2270 : ! ndim, nvar, & ! sizes of netcdf file
2271 : ! id, & ! dimension index ! LCOV_EXCL_LINE
2272 : ! dimlen ! size of dimension
2273 :
2274 : real (kind=dbl_kind) :: &
2275 312 : amin, amax, asum ! min, max values and sum of input array
2276 :
2277 : character (char_len) :: &
2278 : lvarname ! variable name
2279 : ! dimname ! dimension name
2280 :
2281 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
2282 1274 : work_g1
2283 :
2284 : integer (kind=int_kind) :: nx, ny
2285 :
2286 1274 : nx = nx_global
2287 1274 : ny = ny_global
2288 :
2289 1274 : if (present(restart_ext)) then
2290 0 : if (restart_ext) then
2291 0 : nx = nx_global + 2*nghost
2292 0 : ny = ny_global + 2*nghost
2293 : endif
2294 : endif
2295 :
2296 1274 : if (present(varname)) then
2297 1274 : lvarname = trim(varname)
2298 : else
2299 0 : lvarname = ' '
2300 : endif
2301 :
2302 1274 : if (my_task == master_task) then
2303 234 : allocate(work_g1(nx,ny))
2304 : else
2305 1040 : allocate(work_g1(1,1)) ! to save memory
2306 : endif
2307 :
2308 1274 : if (present(restart_ext)) then
2309 0 : if (restart_ext) then
2310 0 : call gather_global_ext(work_g1, work, master_task, distrb_info, spc_val=c0)
2311 : endif
2312 : else
2313 1274 : call gather_global(work_g1, work, master_task, distrb_info, spc_val=c0)
2314 : endif
2315 :
2316 1274 : if (my_task == master_task) then
2317 :
2318 : !--------------------------------------------------------------
2319 : ! Write global array
2320 : !--------------------------------------------------------------
2321 :
2322 : status = nf90_put_var( fid, varid, work_g1, &
2323 : start=(/1,1,nrec/), & ! LCOV_EXCL_LINE
2324 1638 : count=(/nx,ny,1/))
2325 :
2326 : endif ! my_task = master_task
2327 :
2328 : !-------------------------------------------------------------------
2329 : ! optional diagnostics
2330 : !-------------------------------------------------------------------
2331 :
2332 1274 : if (my_task==master_task .and. diag) then
2333 : ! write(nu_diag,*) &
2334 : ! subname,' fid= ',fid, ', nrec = ',nrec, & ! LCOV_EXCL_LINE
2335 : ! ', varid = ',varid
2336 : ! status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
2337 : ! write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
2338 : ! do id=1,ndim
2339 : ! status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
2340 : ! write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
2341 : ! enddo
2342 3115866 : amin = minval(work_g1)
2343 3115866 : amax = maxval(work_g1, mask = work_g1 /= spval_dbl)
2344 3115866 : asum = sum (work_g1, mask = work_g1 /= spval_dbl)
2345 234 : write(nu_diag,*) subname,' min, max, sum =', amin, amax, asum, trim(lvarname)
2346 : endif
2347 :
2348 1274 : deallocate(work_g1)
2349 :
2350 : #else
2351 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2352 : file=__FILE__, line=__LINE__)
2353 : #endif
2354 :
2355 2548 : end subroutine ice_write_nc_xy
2356 :
2357 : !=======================================================================
2358 :
2359 : ! Write a netCDF file.
2360 : !
2361 : ! Adapted by David Bailey, NCAR
2362 :
2363 1372 : subroutine ice_write_nc_xyz(fid, nrec, varid, work, diag, &
2364 : restart_ext, varname)
2365 :
2366 : use ice_gather_scatter, only: gather_global, gather_global_ext
2367 :
2368 : integer (kind=int_kind), intent(in) :: &
2369 : fid , & ! file id ! LCOV_EXCL_LINE
2370 : varid , & ! variable id ! LCOV_EXCL_LINE
2371 : nrec ! record number
2372 :
2373 : logical (kind=log_kind), intent(in) :: &
2374 : diag ! if true, write diagnostic output
2375 :
2376 : logical (kind=log_kind), optional, intent(in) :: &
2377 : restart_ext ! if true, read extended grid
2378 :
2379 : real (kind=dbl_kind), dimension(nx_block,ny_block,ncat,max_blocks), intent(in) :: &
2380 : work ! output array (real, 8-byte)
2381 :
2382 : character (len=*), optional, intent(in) :: &
2383 : varname ! variable name
2384 :
2385 : ! local variables
2386 :
2387 : character(len=*), parameter :: subname = '(ice_write_nc_xyz)'
2388 :
2389 : #ifdef USE_NETCDF
2390 : ! netCDF file diagnostics:
2391 : integer (kind=int_kind) :: &
2392 : n, & ! ncat index ! LCOV_EXCL_LINE
2393 : status ! status output from netcdf routines
2394 : ! ndim, nvar, & ! sizes of netcdf file
2395 : ! id, & ! dimension index ! LCOV_EXCL_LINE
2396 : ! dimlen ! size of dimension
2397 :
2398 : real (kind=dbl_kind) :: &
2399 336 : amin, amax, asum ! min, max values and sum of input array
2400 :
2401 : character (char_len) :: &
2402 : lvarname ! variable name
2403 : ! dimname ! dimension name
2404 :
2405 : real (kind=dbl_kind), dimension(:,:,:), allocatable :: &
2406 1372 : work_g1
2407 :
2408 : integer (kind=int_kind) :: nx, ny
2409 :
2410 1372 : nx = nx_global
2411 1372 : ny = ny_global
2412 :
2413 1372 : if (present(restart_ext)) then
2414 0 : if (restart_ext) then
2415 0 : nx = nx_global + 2*nghost
2416 0 : ny = ny_global + 2*nghost
2417 : endif
2418 : endif
2419 :
2420 1372 : if (my_task == master_task) then
2421 252 : allocate(work_g1(nx,ny,ncat))
2422 : else
2423 1120 : allocate(work_g1(1,1,ncat)) ! to save memory
2424 : endif
2425 :
2426 1372 : if (present(restart_ext)) then
2427 0 : if (restart_ext) then
2428 0 : do n=1,ncat
2429 0 : call gather_global_ext(work_g1(:,:,n), work(:,:,n,:), &
2430 0 : master_task, distrb_info, spc_val=c0)
2431 : enddo
2432 : endif
2433 : else
2434 8232 : do n=1,ncat
2435 0 : call gather_global(work_g1(:,:,n), work(:,:,n,:), &
2436 8232 : master_task, distrb_info, spc_val=c0)
2437 : enddo
2438 : endif
2439 :
2440 1372 : if (present(varname)) then
2441 1372 : lvarname = trim(varname)
2442 : else
2443 0 : lvarname = ' '
2444 : endif
2445 :
2446 1372 : if (my_task == master_task) then
2447 :
2448 : !--------------------------------------------------------------
2449 : ! Read global array
2450 : !--------------------------------------------------------------
2451 :
2452 : status = nf90_put_var( fid, varid, work_g1, &
2453 : start=(/1,1,1,nrec/), & ! LCOV_EXCL_LINE
2454 2268 : count=(/nx,ny,ncat,1/))
2455 :
2456 : endif ! my_task = master_task
2457 :
2458 : !-------------------------------------------------------------------
2459 : ! optional diagnostics
2460 : !-------------------------------------------------------------------
2461 :
2462 1372 : if (my_task==master_task .and. diag) then
2463 : ! write(nu_diag,*) &
2464 : ! subname,' fid= ',fid, ', nrec = ',nrec, & ! LCOV_EXCL_LINE
2465 : ! ', varid = ',varid
2466 : ! status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
2467 : ! write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
2468 : ! do id=1,ndim
2469 : ! status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
2470 : ! write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
2471 : ! enddo
2472 252 : amin = 10000._dbl_kind
2473 252 : amax = -10000._dbl_kind
2474 1512 : do n=1,ncat
2475 16777740 : amin = minval(work_g1(:,:,n))
2476 16777740 : amax = maxval(work_g1(:,:,n), mask = work_g1(:,:,n) /= spval_dbl)
2477 16777740 : asum = sum (work_g1(:,:,n), mask = work_g1(:,:,n) /= spval_dbl)
2478 1512 : write(nu_diag,*) subname,' min, max, sum =', amin, amax, asum, trim(lvarname)
2479 : enddo
2480 : endif
2481 :
2482 1372 : deallocate(work_g1)
2483 :
2484 : #else
2485 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2486 : file=__FILE__, line=__LINE__)
2487 : #endif
2488 :
2489 2744 : end subroutine ice_write_nc_xyz
2490 :
2491 : !=======================================================================
2492 :
2493 : ! Read a netcdf file.
2494 : ! Just like ice_read_nc except that it returns a global array.
2495 : ! work_g is a real array
2496 : !
2497 : ! Adapted by William Lipscomb, LANL, from ice_read
2498 : ! Adapted by Ann Keen, Met Office, to read from a netcdf file
2499 :
2500 0 : subroutine ice_read_global_nc (fid, nrec, varname, work_g, diag)
2501 :
2502 : integer (kind=int_kind), intent(in) :: &
2503 : fid , & ! file id ! LCOV_EXCL_LINE
2504 : nrec ! record number
2505 :
2506 : character (char_len), intent(in) :: &
2507 : varname ! field name in netcdf file
2508 :
2509 : real (kind=dbl_kind), dimension(nx_global,ny_global), intent(out) :: &
2510 : work_g ! output array (real, 8-byte)
2511 :
2512 : logical (kind=log_kind) :: &
2513 : diag ! if true, write diagnostic output
2514 :
2515 : ! local variables
2516 :
2517 : character(len=*), parameter :: subname = '(ice_read_global_nc)'
2518 :
2519 : #ifdef USE_NETCDF
2520 : ! netCDF file diagnostics:
2521 : integer (kind=int_kind) :: &
2522 : varid, & ! netcdf id for field ! LCOV_EXCL_LINE
2523 : status ! status output from netcdf routines
2524 : ! ndim, nvar, & ! sizes of netcdf file
2525 : ! id, & ! dimension index ! LCOV_EXCL_LINE
2526 : ! dimlen ! size of dimension
2527 :
2528 : real (kind=dbl_kind) :: &
2529 0 : amin, amax, asum ! min, max values and sum of input array
2530 :
2531 : ! character (char_len) :: &
2532 : ! dimname ! dimension name
2533 : !
2534 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
2535 0 : work_g3
2536 :
2537 0 : if (orca_halogrid) then
2538 0 : if (my_task == master_task) then
2539 0 : allocate(work_g3(nx_global+2,ny_global+1))
2540 : else
2541 0 : allocate(work_g3(1,1)) ! to save memory
2542 : endif
2543 0 : work_g3(:,:) = c0
2544 : endif
2545 :
2546 0 : work_g(:,:) = c0
2547 :
2548 0 : if (my_task == master_task) then
2549 :
2550 : !-------------------------------------------------------------
2551 : ! Find out ID of required variable
2552 : !-------------------------------------------------------------
2553 :
2554 0 : status = nf90_inq_varid(fid, trim(varname), varid)
2555 0 : if (status /= nf90_noerr) then
2556 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
2557 0 : file=__FILE__, line=__LINE__)
2558 : endif
2559 :
2560 : !--------------------------------------------------------------
2561 : ! Read global array
2562 : !--------------------------------------------------------------
2563 :
2564 0 : if (orca_halogrid) then
2565 : status = nf90_get_var( fid, varid, work_g3, &
2566 : start=(/1,1,nrec/), & ! LCOV_EXCL_LINE
2567 0 : count=(/nx_global+2,ny_global+1,1/))
2568 0 : if (status /= nf90_noerr) then
2569 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
2570 0 : file=__FILE__, line=__LINE__)
2571 : endif
2572 0 : work_g=work_g3(2:nx_global+1,1:ny_global)
2573 : else
2574 0 : status = nf90_get_var( fid, varid, work_g, &
2575 : start=(/1,1,nrec/), & ! LCOV_EXCL_LINE
2576 0 : count=(/nx_global,ny_global,1/))
2577 0 : if (status /= nf90_noerr) then
2578 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
2579 0 : file=__FILE__, line=__LINE__)
2580 : endif
2581 : endif
2582 : endif ! my_task = master_task
2583 :
2584 : !-------------------------------------------------------------------
2585 : ! optional diagnostics
2586 : !-------------------------------------------------------------------
2587 :
2588 0 : if (my_task == master_task .and. diag) then
2589 : ! write(nu_diag,*) &
2590 : ! subname,' fid= ',fid, ', nrec = ',nrec, & ! LCOV_EXCL_LINE
2591 : ! ', varname = ',trim(varname)
2592 : ! status = nf90_inquire(fid, nDimensions=ndim, nVariables=nvar)
2593 : ! write(nu_diag,*) subname,' ndim= ',ndim,', nvar= ',nvar
2594 : ! do id=1,ndim
2595 : ! status = nf90_inquire_dimension(fid,id,name=dimname,len=dimlen)
2596 : ! write(nu_diag,*) subname,' Dim name = ',trim(dimname),', size = ',dimlen
2597 : ! enddo
2598 0 : amin = minval(work_g)
2599 0 : amax = maxval(work_g, mask = work_g /= spval_dbl)
2600 0 : asum = sum (work_g, mask = work_g /= spval_dbl)
2601 0 : write(nu_diag,*) subname,' min, max, sum = ', amin, amax, asum, trim(varname)
2602 : endif
2603 :
2604 0 : if (orca_halogrid) deallocate(work_g3)
2605 :
2606 : #else
2607 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2608 : file=__FILE__, line=__LINE__)
2609 : work_g = c0 ! to satisfy intent(out) attribute
2610 : #endif
2611 :
2612 0 : end subroutine ice_read_global_nc
2613 :
2614 : !=======================================================================
2615 :
2616 : ! Closes a netCDF file
2617 : ! author: Alison McLaren, Met Office
2618 :
2619 2904 : subroutine ice_close_nc(fid)
2620 :
2621 : integer (kind=int_kind), intent(in) :: &
2622 : fid ! unit number
2623 :
2624 : ! local variables
2625 :
2626 : character(len=*), parameter :: subname = '(ice_close_nc)'
2627 :
2628 : #ifdef USE_NETCDF
2629 : integer (kind=int_kind) :: &
2630 : status ! status variable from netCDF routine
2631 :
2632 2904 : if (my_task == master_task) then
2633 624 : status = nf90_close(fid)
2634 : endif
2635 : #else
2636 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2637 : file=__FILE__, line=__LINE__)
2638 : #endif
2639 :
2640 2904 : end subroutine ice_close_nc
2641 :
2642 : !=======================================================================
2643 :
2644 : ! Read a netCDF file and scatter to processors.
2645 : ! If the optional variables field_loc and field_type are present,
2646 : ! the ghost cells are filled using values from the global array.
2647 : ! This prevents them from being filled with zeroes in land cells
2648 : ! (subroutine ice_HaloUpdate need not be called).
2649 : !
2650 : ! Adapted by Elizabeth Hunke for reading 3D ocean currents
2651 :
2652 0 : subroutine ice_read_nc_uv(fid, nrec, nzlev, varname, work, diag, &
2653 : field_loc, field_type, restart_ext)
2654 :
2655 : use ice_gather_scatter, only: scatter_global, scatter_global_ext
2656 :
2657 : integer (kind=int_kind), intent(in) :: &
2658 : fid , & ! file id ! LCOV_EXCL_LINE
2659 : nrec , & ! record number ! LCOV_EXCL_LINE
2660 : nzlev ! z level
2661 :
2662 : logical (kind=log_kind), intent(in) :: &
2663 : diag ! if true, write diagnostic output
2664 :
2665 : character (len=*), intent(in) :: &
2666 : varname ! field name in netcdf file
2667 :
2668 : real (kind=dbl_kind), dimension(nx_block,ny_block,max_blocks), intent(out) :: &
2669 : work ! output array (real, 8-byte)
2670 :
2671 : logical (kind=log_kind), optional, intent(in) :: &
2672 : restart_ext ! if true, read extended grid
2673 :
2674 : integer (kind=int_kind), optional, intent(in) :: &
2675 : field_loc, & ! location of field on staggered grid ! LCOV_EXCL_LINE
2676 : field_type ! type of field (scalar, vector, angle)
2677 :
2678 : ! local variables
2679 :
2680 : character(len=*), parameter :: subname = '(ice_read_nc_uv)'
2681 :
2682 : #ifdef USE_NETCDF
2683 : ! netCDF file diagnostics:
2684 : integer (kind=int_kind) :: &
2685 : varid , & ! variable id ! LCOV_EXCL_LINE
2686 : status ! status output from netcdf routines
2687 : ! ndim, nvar, & ! sizes of netcdf file
2688 : ! id, & ! dimension index ! LCOV_EXCL_LINE
2689 : ! dimlen ! size of dimension
2690 :
2691 : real (kind=dbl_kind) :: &
2692 0 : amin, amax, asum ! min, max values and sum of input array
2693 :
2694 : ! character (char_len) :: &
2695 : ! dimname ! dimension name
2696 :
2697 : real (kind=dbl_kind), dimension(:,:), allocatable :: &
2698 0 : work_g1
2699 :
2700 : integer (kind=int_kind) :: nx, ny
2701 :
2702 0 : nx = nx_global
2703 0 : ny = ny_global
2704 :
2705 0 : if (present(restart_ext)) then
2706 0 : if (restart_ext) then
2707 0 : nx = nx_global + 2*nghost
2708 0 : ny = ny_global + 2*nghost
2709 : endif
2710 : endif
2711 :
2712 0 : if (my_task == master_task) then
2713 0 : allocate(work_g1(nx,ny))
2714 : else
2715 0 : allocate(work_g1(1,1)) ! to save memory
2716 : endif
2717 :
2718 0 : if (my_task == master_task) then
2719 :
2720 : !-------------------------------------------------------------
2721 : ! Find out ID of required variable
2722 : !-------------------------------------------------------------
2723 :
2724 0 : status = nf90_inq_varid(fid, trim(varname), varid)
2725 0 : if (status /= nf90_noerr) then
2726 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
2727 0 : file=__FILE__, line=__LINE__)
2728 : endif
2729 :
2730 : !--------------------------------------------------------------
2731 : ! Read global array
2732 : !--------------------------------------------------------------
2733 :
2734 : status = nf90_get_var( fid, varid, work_g1, &
2735 : start=(/1,1,nzlev,nrec/), & ! LCOV_EXCL_LINE
2736 0 : count=(/nx,ny,1,1/))
2737 0 : if (status /= nf90_noerr) then
2738 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
2739 0 : file=__FILE__, line=__LINE__)
2740 : endif
2741 :
2742 : endif ! my_task = master_task
2743 :
2744 : !-------------------------------------------------------------------
2745 : ! optional diagnostics
2746 : !-------------------------------------------------------------------
2747 :
2748 0 : if (my_task==master_task .and. diag) then
2749 0 : amin = minval(work_g1)
2750 0 : amax = maxval(work_g1, mask = work_g1 /= spval_dbl)
2751 0 : asum = sum (work_g1, mask = work_g1 /= spval_dbl)
2752 0 : write(nu_diag,*) subname,' min, max, sum =', amin, amax, asum, trim(varname)
2753 : endif
2754 :
2755 : !-------------------------------------------------------------------
2756 : ! Scatter data to individual processors.
2757 : ! NOTE: Ghost cells are not updated unless field_loc is present.
2758 : !-------------------------------------------------------------------
2759 :
2760 0 : if (present(restart_ext)) then
2761 0 : if (restart_ext) then
2762 0 : call scatter_global_ext(work, work_g1, master_task, distrb_info)
2763 : endif
2764 : else
2765 0 : if (present(field_loc)) then
2766 0 : call scatter_global(work, work_g1, master_task, distrb_info, &
2767 0 : field_loc, field_type)
2768 : else
2769 0 : call scatter_global(work, work_g1, master_task, distrb_info, &
2770 0 : field_loc_noupdate, field_type_noupdate)
2771 : endif
2772 : endif
2773 :
2774 0 : deallocate(work_g1)
2775 :
2776 : #else
2777 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2778 : file=__FILE__, line=__LINE__)
2779 : work = c0 ! to satisfy intent(out) attribute
2780 : #endif
2781 :
2782 0 : end subroutine ice_read_nc_uv
2783 :
2784 : !=======================================================================
2785 : ! Read a vector in a netcdf file.
2786 : ! Just like ice_read_global_nc except that it returns a vector.
2787 : ! work_g is a real vector
2788 : !
2789 : ! Adapted by William Lipscomb, LANL, from ice_read
2790 : ! Adapted by Ann Keen, Met Office, to read from a netcdf file
2791 :
2792 0 : subroutine ice_read_vec_nc (fid, nrec, varname, work_g, diag)
2793 :
2794 : integer (kind=int_kind), intent(in) :: &
2795 : fid , & ! file id ! LCOV_EXCL_LINE
2796 : nrec ! record number
2797 :
2798 : character (char_len), intent(in) :: &
2799 : varname ! field name in netcdf file
2800 :
2801 : real (kind=dbl_kind), dimension(nrec), &
2802 : intent(out) :: & ! LCOV_EXCL_LINE
2803 : work_g ! output array (real, 8-byte)
2804 :
2805 : logical (kind=log_kind) :: &
2806 : diag ! if true, write diagnostic output
2807 :
2808 : ! local variables
2809 :
2810 : character(len=*), parameter :: subname = '(ice_read_vec_nc)'
2811 :
2812 : #ifdef USE_NETCDF
2813 : ! netCDF file diagnostics:
2814 : integer (kind=int_kind) :: &
2815 : varid, & ! netcdf id for field ! LCOV_EXCL_LINE
2816 : status ! status output from netcdf routines
2817 :
2818 : real (kind=dbl_kind) :: &
2819 0 : amin, amax ! min, max values of input vector
2820 :
2821 0 : work_g(:) = c0
2822 :
2823 0 : if (my_task == master_task) then
2824 :
2825 : !-------------------------------------------------------------
2826 : ! Find out ID of required variable
2827 : !-------------------------------------------------------------
2828 :
2829 0 : status = nf90_inq_varid(fid, trim(varname), varid)
2830 0 : if (status /= nf90_noerr) then
2831 : call abort_ice(subname//' ERROR: Cannot find variable '//trim(varname), &
2832 0 : file=__FILE__, line=__LINE__)
2833 : endif
2834 :
2835 : !--------------------------------------------------------------
2836 : ! Read global array
2837 : !--------------------------------------------------------------
2838 :
2839 0 : status = nf90_get_var( fid, varid, work_g, &
2840 : start=(/1/), & ! LCOV_EXCL_LINE
2841 0 : count=(/nrec/))
2842 0 : if (status /= nf90_noerr) then
2843 : call abort_ice(subname//' ERROR: Cannot get variable '//trim(varname), &
2844 0 : file=__FILE__, line=__LINE__)
2845 : endif
2846 :
2847 : endif ! my_task = master_task
2848 :
2849 : !-------------------------------------------------------------------
2850 : ! optional diagnostics
2851 : !-------------------------------------------------------------------
2852 :
2853 0 : if (my_task == master_task .and. diag) then
2854 0 : amin = minval(work_g)
2855 0 : amax = maxval(work_g)
2856 0 : write(nu_diag,*) subname,' min, max, nrec = ', amin, amax, nrec
2857 : endif
2858 :
2859 : #else
2860 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2861 : file=__FILE__, line=__LINE__)
2862 : work_g = c0 ! to satisfy intent(out) attribute
2863 : #endif
2864 :
2865 0 : end subroutine ice_read_vec_nc
2866 :
2867 : !=======================================================================
2868 : ! Get number of variables of a given variable
2869 0 : subroutine ice_get_ncvarsize(fid,varname,recsize)
2870 :
2871 : integer (kind=int_kind), intent(in) :: &
2872 : fid ! file id
2873 : character (char_len), intent(in) :: &
2874 : varname ! field name in netcdf file
2875 : integer (kind=int_kind), intent(out) :: &
2876 : recsize ! Number of records in file
2877 :
2878 : ! local variables
2879 :
2880 : #ifdef USE_NETCDF
2881 : integer (kind=int_kind) :: &
2882 : ndims, i, status
2883 : character (char_len) :: &
2884 : cvar
2885 : #endif
2886 : character(len=*), parameter :: subname = '(ice_get_ncvarsize)'
2887 :
2888 : #ifdef USE_NETCDF
2889 0 : if (my_task == master_task) then
2890 0 : status=nf90_inquire(fid, nDimensions = nDims)
2891 0 : if (status /= nf90_noerr) then
2892 : call abort_ice(subname//' ERROR: inquire nDimensions', &
2893 0 : file=__FILE__, line=__LINE__ )
2894 : endif
2895 0 : do i=1,nDims
2896 0 : status = nf90_inquire_dimension(fid,i,name=cvar,len=recsize)
2897 0 : if (status /= nf90_noerr) then
2898 : call abort_ice(subname//' ERROR: inquire len for variable '//trim(cvar), &
2899 0 : file=__FILE__, line=__LINE__)
2900 : endif
2901 0 : if (trim(cvar) == trim(varname)) exit
2902 : enddo
2903 0 : if (trim(cvar) .ne. trim(varname)) then
2904 : call abort_ice(subname//' ERROR: Did not find variable '//trim(varname), &
2905 0 : file=__FILE__, line=__LINE__)
2906 : endif
2907 : endif
2908 : #else
2909 : call abort_ice(subname//' ERROR: USE_NETCDF cpp not defined', &
2910 : file=__FILE__, line=__LINE__)
2911 : recsize = 0 ! to satisfy intent(out) attribute
2912 : #endif
2913 :
2914 0 : end subroutine ice_get_ncvarsize
2915 :
2916 : !=======================================================================
2917 :
2918 : end module ice_read_write
2919 :
2920 : !=======================================================================
|