162 subroutine mpp_open( unit, file, action, form, access, threading, &
163 fileset, iospec, nohdrs, recl, &
164 iostat, is_root_pe, domain, &
169 integer,
intent(out) :: unit
170 character(len=*),
intent(in) :: file
171 integer,
intent(in),
optional :: action, form, access
172 integer,
intent(in),
optional :: threading, fileset, recl
173 character(len=*),
intent(in),
optional :: iospec
174 logical,
intent(in),
optional :: nohdrs
175 integer,
intent(out),
optional :: iostat
176 logical,
intent(in),
optional :: is_root_pe
177 type(domain2d),
intent(in),
optional :: domain
180 type(domainUG),
target,
intent(in),
optional :: domain_ug
182 character(len=16) :: act, acc, for, pos
183 character(len=128) :: mesg
184 character(len=256) :: text2
185 integer :: action_flag, form_flag, access_flag, threading_flag, fileset_flag, length
186 integer :: nfiles, tile_id(1), io_layout(2)
187 logical :: exists, on_root_pe, dist_file
188 logical :: write_on_this_pe, read_on_this_pe, io_domain_exist
189 integer :: ios, nc_pos
190 type(axistype) :: unlim
194 type(domain2d),
pointer :: io_domain
195 type(domainUG),
pointer :: io_domain_ug
196 integer(i4_kind) :: io_layout_ug
197 integer(i4_kind) :: tile_id_ug
201 integer :: info, ierror
202 integer,
dimension(:),
allocatable :: glist(:)
204 character(len=12) ::ncblk
205 character(len=128) ::nc_name
206 integer ::f_size, f_stat
207 integer ::fsize, inital = 0
208 character(len=128) :: f_test
213 if (
present(domain) .and.
present(domain_ug))
then
214 call mpp_error(fatal, &
215 "mpp_open: domain and domain_ug cannot both be" &
216 //
" present in the same mpp_open call.")
221 io_domain_ug => null()
224 call mpp_clock_begin(mpp_open_clock)
225 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_OPEN: must first call mpp_io_init.' )
226 on_root_pe =
mpp_pe() == mpp_root_pe()
227 if(
present(is_root_pe)) on_root_pe = is_root_pe
231 action_flag = mpp_wronly
232 if(
PRESENT(action) )action_flag = action
233 form_flag = mpp_ascii
234 if(
PRESENT(form) )form_flag = form
236 if( form_flag.EQ.mpp_netcdf ) &
237 call mpp_error( fatal, &
238 &
'MPP_OPEN: To open a file with form=MPP_NETCDF, you must compile mpp_io with -Duse_netCDF.')
240 access_flag = mpp_sequential
241 if(
PRESENT(access) )access_flag = access
242 threading_flag = mpp_single
243 if( npes.GT.1 .AND.
PRESENT(threading) )threading_flag = threading
244 fileset_flag = mpp_multi
245 if(
PRESENT(fileset) )fileset_flag = fileset
246 if( threading_flag.EQ.mpp_single )fileset_flag = mpp_single
249 if(
PRESENT(iospec) ) &
250 &
call mpp_error( note,
'MPP_OPEN: iospec option has been deprecated and will be removed at some future date')
253 io_domain_exist = .false.
254 if(
PRESENT(domain) )
then
256 if(
associated(io_domain)) io_domain_exist = .true.
260 elseif (
present(domain_ug))
then
261 io_domain_ug => mpp_get_ug_io_domain(domain_ug)
262 io_domain_exist = .true.
267 write_on_this_pe = .true.
268 read_on_this_pe = .true.
269 if( threading_flag.EQ.mpp_single .AND. .NOT.on_root_pe )
then
270 write_on_this_pe = .false.
271 read_on_this_pe = .false.
273 if(form_flag == mpp_netcdf .AND. action_flag .NE. mpp_rdonly)
then
274 if(fileset_flag .EQ.mpp_single .AND. threading_flag.EQ.mpp_multi)
then
275 call mpp_error(fatal,
"mpp_io_connect.inc(mpp_open): multiple thread and single "// &
276 "file writing/appending is not supported for netCDF file")
278 if( fileset_flag.EQ.mpp_single .AND. .NOT.on_root_pe )
then
279 write_on_this_pe = .false.
280 read_on_this_pe = .false.
284 if( io_domain_exist)
then
288 if (
associated(io_domain))
then
291 elseif (
associated(io_domain_ug))
then
292 write_on_this_pe = mpp_domain_ug_is_tile_root_pe(io_domain_ug)
297 if( action_flag == mpp_rdonly) write_on_this_pe = .false.
299 if( .NOT. write_on_this_pe .AND. action_flag.NE.mpp_rdonly .AND. .NOT. io_domain_exist)
then
301 call mpp_clock_end(mpp_open_clock)
304 if( form_flag.EQ.mpp_netcdf )
then
305 do unit = maxunits+1,2*maxunits
306 if( .NOT.mpp_file(unit)%valid )
exit
308 if( unit.GT.2*maxunits )
then
309 write(mesg,*)
'all the units between ',maxunits+1,
' and ',2*maxunits,
' are used'
310 call mpp_error( fatal,
'MPP_OPEN: too many open netCDF files.'//trim(mesg) )
313 do unit = unit_begin, unit_end
314 inquire( unit,opened=mpp_file(unit)%opened )
315 if( .NOT.mpp_file(unit)%opened )
exit
317 if( unit.GT.unit_end )
then
318 write(mesg,*)
'all the units between ',unit_begin,
' and ',unit_end,
' are used'
319 call mpp_error( fatal,
'MPP_OPEN: no available units.'//trim(mesg) )
322 mpp_file(unit)%valid = .true.
323 mpp_file(unit)%write_on_this_pe = write_on_this_pe
324 mpp_file(unit)%read_on_this_pe = read_on_this_pe
325 mpp_file(unit)%io_domain_exist = io_domain_exist
326 if(
PRESENT(domain) )
then
327 allocate(mpp_file(unit)%domain)
328 mpp_file(unit)%domain = domain
332 elseif (
present(domain_ug))
then
333 mpp_file(unit)%domain_ug => domain_ug
339 nc_pos = index(file,
'.nc.')
342 length = len_trim(file)
343 if(form_flag.EQ.mpp_netcdf.AND. file(length-2:length) /=
'.nc' .AND. .NOT.dist_file) &
344 text = trim(file)//
'.nc'
350 if (
present(domain))
then
352 elseif (
present(domain_ug))
then
353 io_layout_ug = mpp_get_io_domain_ug_layout(domain_ug)
357 if( io_domain_exist)
then
361 if (
present(domain) .and. io_layout(1)*io_layout(2) .gt. 1)
then
362 fileset_flag = mpp_multi
363 threading_flag = mpp_multi
366 if (tile_id(1) .ge. 10000)
then
367 call mpp_error(fatal, &
368 "mpp_open: tile_id should be less than" &
369 //
" 10000 when io_domain exist")
371 write(text,
'(a,i4.4)') trim(text)//
'.',tile_id(1)
372 if (action_flag .eq. mpp_rdonly)
then
373 inquire(file=trim(text),exist=exists)
374 if (.not. exists)
then
375 write(text2,
'(a,i6.6)') trim(text2)//
'.',tile_id(1)
376 inquire(file=trim(text2),exist=exists)
377 if (.not.exists)
then
378 call mpp_error(fatal, &
379 "mpp_open: neither "// &
380 trim(text)//
" nor "// &
381 trim(text2)//
" exist and io" &
387 elseif (
present(domain_ug) .and. io_layout_ug .gt. 1)
then
388 fileset_flag = mpp_multi
389 threading_flag = mpp_multi
390 tile_id_ug = mpp_get_ug_domain_tile_id(io_domain_ug)
392 if (tile_id_ug .ge. 10000)
then
393 call mpp_error(fatal, &
394 "mpp_open: tile_id should be less than" &
395 //
" 10000 when io_domain exist")
397 write(text,
'(a,i4.4)') trim(text)//
'.',tile_id_ug
398 if (action_flag .eq. mpp_rdonly)
then
399 inquire(file=trim(text),exist=exists)
400 if (.not. exists)
then
401 write(text2,
'(a,i6.6)') trim(text2)//
'.',tile_id_ug
402 inquire(file=trim(text2),exist=exists)
403 if (.not.exists)
then
404 call mpp_error(fatal, &
405 "mpp_open: neither "// &
406 trim(text)//
" nor "// &
407 trim(text2)//
" exist and io" &
414 fileset_flag = mpp_single
415 threading_flag = mpp_single
419 else if( fileset_flag.EQ.mpp_multi )
then
421 write( text,
'(a,i6.6)' )trim(text)//
'.', pe-mpp_root_pe()
423 write( text,
'(a,i4.4)' )trim(text)//
'.', pe-mpp_root_pe()
426 mpp_file(unit)%name = text
427 if(verbose) print
'(a,2i6,x,a,5i5)',
'MPP_OPEN: PE, unit, filename, action, format, access, threading, fileset=',&
428 & pe, unit, trim(mpp_file(unit)%name), action_flag, form_flag, access_flag, threading_flag, fileset_flag
431 if( action_flag.EQ.mpp_rdonly )
then
434 else if( action_flag.EQ.mpp_wronly .OR. action_flag.EQ.mpp_overwr )
then
437 else if( action_flag.EQ.mpp_append )
then
441 call mpp_error( fatal,
'MPP_OPEN: action must be one of MPP_WRONLY, MPP_APPEND or MPP_RDONLY.' )
444 mpp_file(unit)%threading = threading_flag
445 mpp_file(unit)%fileset = fileset_flag
447 if( .NOT. write_on_this_pe .AND. action_flag.NE.mpp_rdonly )
then
448 call mpp_clock_end(mpp_open_clock)
453 if( form_flag.NE.mpp_netcdf )
then
454 if( access_flag.EQ.mpp_sequential )
then
456 else if( access_flag.EQ.mpp_direct )
then
458 if( form_flag.EQ.mpp_ascii )
call mpp_error( fatal, &
459 &
'MPP_OPEN: formatted direct access I/O is prohibited.' )
460 if( .NOT.
PRESENT(recl) ) &
461 call mpp_error( fatal, &
462 &
'MPP_OPEN: recl (record length in bytes) must be specified with access=MPP_DIRECT.')
463 mpp_file(unit)%record = 1
466 call mpp_error( fatal,
'MPP_OPEN: access must be one of MPP_SEQUENTIAL or MPP_DIRECT.' )
471 if( threading_flag.EQ.mpp_multi )
then
473 if( fileset_flag.EQ.mpp_single )
then
474 if( form_flag.EQ.mpp_netcdf .AND. act.EQ.
'WRITE' ) &
475 call mpp_error( fatal, &
476 &
'MPP_OPEN: netCDF currently does not support single-file multi-threaded output.' )
478 else if( fileset_flag.NE.mpp_multi )
then
479 call mpp_error( fatal,
'MPP_OPEN: fileset must be one of MPP_MULTI or MPP_SINGLE.' )
481 else if( threading_flag.NE.mpp_single )
then
482 call mpp_error( fatal,
'MPP_OPEN: threading must be one of MPP_SINGLE or MPP_MULTI.' )
486 if( form_flag.EQ.mpp_netcdf )
then
489 if( .NOT.
PRESENT(pelist))
then
490 allocate (glist(0:npes-1))
491 call mpp_get_current_pelist(glist, name, comm)
495 call mpi_info_create(info, ierror)
499 call getenv(
'NC_BLKSZ', ncblk)
503 if (ncblk /=
"")
then
505 call mpi_info_set(info,
"cb_buffer_size", ncblk, ierror)
506 call mpi_info_set(info,
"ind_rd_buffer_size", ncblk, ierror)
507 call mpi_info_set(info,
"ind_wr_buffer_size", ncblk, ierror)
510 call mpi_info_set(info,
"ind_rd_buffer_size",
"16777216", ierror)
511 call mpi_info_set(info,
"ind_wr_buffer_size",
"16777216", ierror)
521 nc_name =
'NC_BLKSZ_'//trim(mpp_file(unit)%name)
529 call getenv( trim(nc_name),ncblk )
533 if (ncblk .EQ.
'')
then
535 call getenv(
'NC_BLKSZ', ncblk)
541 if (ncblk .EQ.
'')
then
547 call file_size(ncblk, mpp_file(unit)%name, fsize)
551 if(debug)
write(*,*)
'Blocksize for ', trim(mpp_file(unit)%name),
' is ', fsize
557 if( action_flag.EQ.mpp_wronly )
then
558 if(debug)
write(*,*)
'Blocksize for create of ', trim(mpp_file(unit)%name),
' is ', fsize
559 error = nf__create( trim(mpp_file(unit)%name), nf_noclobber, inital, fsize, mpp_file(unit)%ncid )
560 call netcdf_err( error, mpp_file(unit) )
561 if( verbose )print
'(a,i6,i16)',
'MPP_OPEN: new netCDF file: pe, ncid=', pe, mpp_file(unit)%ncid
562 else if( action_flag.EQ.mpp_overwr )
then
563 if(debug)
write(*,*)
'Blocksize for create of ', trim(mpp_file(unit)%name),
' is ', fsize
564 error = nf__create( trim(mpp_file(unit)%name),nf_clobber, inital, fsize, mpp_file(unit)%ncid )
565 call netcdf_err( error, mpp_file(unit) )
566 action_flag = mpp_wronly
568 if( verbose )print
'(a,i6,i16)',
'MPP_OPEN: overwrite netCDF file: pe, ncid=', pe, mpp_file(unit)%ncid
569 else if( action_flag.EQ.mpp_append )
then
570 inquire(file=trim(mpp_file(unit)%name),exist=exists)
571 if (.NOT.exists)
call mpp_error(fatal,
'MPP_OPEN:'&
572 &//trim(mpp_file(unit)%name)//
' does not exist.')
573 error=nf__open(trim(mpp_file(unit)%name),nf_write,fsize,mpp_file(unit)%ncid)
574 call netcdf_err(error, mpp_file(unit))
576 error = nf_inq_unlimdim( mpp_file(unit)%ncid, unlim%did )
577 if( error.EQ.nf_noerr )
then
578 error = nf_inq_dim( mpp_file(unit)%ncid, unlim%did, unlim%name, mpp_file(unit)%time_level )
579 call netcdf_err( error, mpp_file(unit) )
580 error = nf_inq_varid( mpp_file(unit)%ncid, unlim%name, mpp_file(unit)%id )
581 call netcdf_err( error, mpp_file(unit), unlim )
583 if( verbose )print
'(a,i6,i16,i4)',
'MPP_OPEN: append to existing netCDF file: pe, ncid, time_axis_id=',&
584 pe, mpp_file(unit)%ncid, mpp_file(unit)%id
585 mpp_file(unit)%format=form_flag
586 call mpp_read_meta(unit, read_time=.false.)
587 else if( action_flag.EQ.mpp_rdonly )
then
588 inquire(file=trim(mpp_file(unit)%name),exist=exists)
589 if (.NOT.exists)
call mpp_error(fatal,
'MPP_OPEN:'&
590 &//trim(mpp_file(unit)%name)//
' does not exist.')
591 error=nf__open(trim(mpp_file(unit)%name),nf_nowrite,fsize,mpp_file(unit)%ncid)
592 call netcdf_err(error, mpp_file(unit))
593 if( verbose )print
'(a,i6,i16,i4)',
'MPP_OPEN: opening existing netCDF file: pe, ncid, time_axis_id=',&
594 pe, mpp_file(unit)%ncid, mpp_file(unit)%id
595 mpp_file(unit)%format=form_flag
596 call mpp_read_meta(unit, read_time=.true.)
598 mpp_file(unit)%opened = .true.
600 if( action_flag.EQ.mpp_wronly )
then
601 if(debug)
write(*,*)
'Blocksize for create of ', trim(mpp_file(unit)%name),
' is ', fsize
602 error = nf__create( trim(mpp_file(unit)%name),ior(nf_64bit_offset,nf_noclobber),inital,fsize, &
603 & mpp_file(unit)%ncid )
604 call netcdf_err( error, mpp_file(unit) )
605 if( verbose )print
'(a,i6,i16)',
'MPP_OPEN: new netCDF file: pe, ncid=', pe, mpp_file(unit)%ncid
606 else if( action_flag.EQ.mpp_overwr )
then
607 if(debug)
write(*,*)
'Blocksize for create of ', trim(mpp_file(unit)%name),
' is ', fsize
608 error = nf__create( trim(mpp_file(unit)%name),ior(nf_64bit_offset,nf_clobber), inital, fsize, &
609 & mpp_file(unit)%ncid )
610 call netcdf_err( error, mpp_file(unit) )
611 action_flag = mpp_wronly
613 if( verbose )print
'(a,i6,i16)',
'MPP_OPEN: overwrite netCDF file: pe, ncid=', pe, mpp_file(unit)%ncid
614 else if( action_flag.EQ.mpp_append )
then
615 inquire(file=trim(mpp_file(unit)%name),exist=exists)
616 if (.NOT.exists)
call mpp_error(fatal,
'MPP_OPEN:'&
617 &//trim(mpp_file(unit)%name)//
' does not exist.')
618 error=nf__open(trim(mpp_file(unit)%name),nf_write,fsize,mpp_file(unit)%ncid)
619 call netcdf_err(error, mpp_file(unit))
621 error = nf_inq_unlimdim( mpp_file(unit)%ncid, unlim%did )
622 if( error.EQ.nf_noerr )
then
623 error = nf_inq_dim( mpp_file(unit)%ncid, unlim%did, unlim%name, mpp_file(unit)%time_level )
624 call netcdf_err( error, mpp_file(unit) )
625 error = nf_inq_varid( mpp_file(unit)%ncid, unlim%name, mpp_file(unit)%id )
626 call netcdf_err( error, mpp_file(unit), unlim )
628 if( verbose )print
'(a,i6,i16,i4)',
'MPP_OPEN: append to existing netCDF file: pe, ncid, time_axis_id=',&
629 pe, mpp_file(unit)%ncid, mpp_file(unit)%id
630 mpp_file(unit)%format=form_flag
631 call mpp_read_meta(unit, read_time=.false.)
632 else if( action_flag.EQ.mpp_rdonly )
then
633 inquire(file=trim(mpp_file(unit)%name),exist=exists)
634 if (.NOT.exists)
call mpp_error(fatal,
'MPP_OPEN:'&
635 &//trim(mpp_file(unit)%name)//
' does not exist.')
636 error=nf__open(trim(mpp_file(unit)%name),nf_nowrite,fsize,mpp_file(unit)%ncid)
637 call netcdf_err(error, mpp_file(unit))
638 if( verbose )print
'(a,i6,i16,i4)',
'MPP_OPEN: opening existing netCDF file: pe, ncid, time_axis_id=',&
639 pe, mpp_file(unit)%ncid, mpp_file(unit)%id
640 mpp_file(unit)%format=form_flag
641 call mpp_read_meta(unit, read_time=.true.)
643 mpp_file(unit)%opened = .true.
645 if( action_flag.EQ.mpp_wronly )
then
646 if(debug)
write(*,*)
'Blocksize for create of ', trim(mpp_file(unit)%name),
' is ', fsize
647 error=nf__create( trim(mpp_file(unit)%name), ior(nf_netcdf4,nf_classic_model), inital, fsize, &
648 & mpp_file(unit)%ncid )
649 call netcdf_err( error, mpp_file(unit) )
650 if( verbose )print
'(a,i6,i16)',
'MPP_OPEN: new netCDF file: pe, ncid=', pe, mpp_file(unit)%ncid
651 else if( action_flag.EQ.mpp_overwr )
then
652 if(debug)
write(*,*)
'Blocksize for create of ', trim(mpp_file(unit)%name),
' is ', fsize
653 error=nf__create( trim(mpp_file(unit)%name), ior(nf_netcdf4,nf_classic_model), inital, fsize, &
654 & mpp_file(unit)%ncid )
655 call netcdf_err( error, mpp_file(unit) )
656 action_flag = mpp_wronly
658 if( verbose )print
'(a,i6,i16)',
'MPP_OPEN: overwrite netCDF file: pe, ncid=', pe, mpp_file(unit)%ncid
659 else if( action_flag.EQ.mpp_append )
then
660 inquire(file=trim(mpp_file(unit)%name),exist=exists)
661 if (.NOT.exists)
call mpp_error(fatal,
'MPP_OPEN:'&
662 &//trim(mpp_file(unit)%name)//
' does not exist.')
663 error=nf__open(trim(mpp_file(unit)%name),nf_write,fsize,mpp_file(unit)%ncid)
664 call netcdf_err(error,mpp_file(unit))
666 error = nf_inq_unlimdim( mpp_file(unit)%ncid, unlim%did )
667 if( error.EQ.nf_noerr )
then
668 error = nf_inq_dim( mpp_file(unit)%ncid, unlim%did, unlim%name, mpp_file(unit)%time_level )
669 call netcdf_err( error, mpp_file(unit) )
670 error = nf_inq_varid( mpp_file(unit)%ncid, unlim%name, mpp_file(unit)%id )
671 call netcdf_err( error, mpp_file(unit), unlim )
673 if( verbose )print
'(a,i6,i16,i4)',
'MPP_OPEN: append to existing netCDF file: pe, ncid, time_axis_id=',&
674 pe, mpp_file(unit)%ncid, mpp_file(unit)%id
675 mpp_file(unit)%format=form_flag
676 call mpp_read_meta(unit, read_time=.false.)
677 else if( action_flag.EQ.mpp_rdonly )
then
678 inquire(file=trim(mpp_file(unit)%name),exist=exists)
679 if (.NOT.exists)
call mpp_error(fatal,
'MPP_OPEN:'&
680 &//trim(mpp_file(unit)%name)//
' does not exist.')
681 error=nf__open(trim(mpp_file(unit)%name),nf_nowrite,fsize,mpp_file(unit)%ncid)
682 call netcdf_err(error,mpp_file(unit))
683 if( verbose )print
'(a,i6,i16,i4)',
'MPP_OPEN: opening existing netCDF file: pe, ncid, time_axis_id=',&
684 pe, mpp_file(unit)%ncid, mpp_file(unit)%id
685 mpp_file(unit)%format=form_flag
686 call mpp_read_meta(unit, read_time=.true.)
688 mpp_file(unit)%opened = .true.
694 if( form_flag.EQ.mpp_ascii )
then
696 else if( form_flag.EQ.mpp_ieee32 )
then
698 else if( form_flag.EQ.mpp_native )
then
701 call mpp_error( fatal,
'MPP_OPEN: form must be one of MPP_ASCII, MPP_NATIVE, MPP_IEEE32 or MPP_NETCDF.' )
703 inquire( file=trim(mpp_file(unit)%name), exist=exists )
704 if( exists .AND. action_flag.EQ.mpp_wronly ) &
705 call mpp_error( warning,
'MPP_OPEN: File '//trim(mpp_file(unit)%name)//
' opened WRONLY already exists!')
706 if( action_flag.EQ.mpp_overwr )action_flag = mpp_wronly
709 if(
PRESENT(recl) )
then
710 if( verbose )print
'(2(x,a,i6),5(x,a),a,i8)',
'MPP_OPEN: PE=', pe, &
711 'unit=', unit, trim(mpp_file(unit)%name),
'attributes=', trim(acc), trim(for), trim(act), &
713 open( unit, file=trim(mpp_file(unit)%name), access=acc, form=for, action=act, recl=recl,iostat=ios )
715 if( verbose )print
'(2(x,a,i6),6(x,a))',
'MPP_OPEN: PE=', pe, &
716 'unit=', unit, trim(mpp_file(unit)%name),
'attributes=', trim(acc), trim(for), trim(pos), trim(act)
717 open( unit, file=trim(mpp_file(unit)%name), access=acc, form=for, action=act, position=pos, iostat=ios)
720 inquire( unit,opened=mpp_file(unit)%opened )
722 if (
PRESENT(iostat))
then
724 call mpp_error( warning,
'MPP_OPEN: error in OPEN for '//trim(mpp_file(unit)%name)//
'.' )
725 call mpp_clock_end(mpp_open_clock)
728 call mpp_error( fatal,
'MPP_OPEN: error in OPEN for '//trim(mpp_file(unit)%name)//
'.' )
731 if( .NOT.mpp_file(unit)%opened )
call mpp_error( fatal,
'MPP_OPEN: error in OPEN() statement.' )
733 mpp_file(unit)%action = action_flag
734 mpp_file(unit)%format = form_flag
735 mpp_file(unit)%access = access_flag
736 if(
PRESENT(nohdrs) )mpp_file(unit)%nohdrs = nohdrs
738 if( action_flag.EQ.mpp_wronly )
then
739 if( form_flag.NE.mpp_netcdf .AND. access_flag.EQ.mpp_direct )
call mpp_write_meta( unit, &
740 &
'record_length', ival=recl )
742 call mpp_write_meta( unit,
'filename', cval=mpp_file(unit)%name)
746 if( threading_flag.EQ.mpp_multi .AND. fileset_flag.EQ.mpp_multi )
then
747 if(
present(domain))
then
748 nfiles = io_layout(1)*io_layout(2)
750 if(nfiles > npes) nfiles = npes
754 elseif (
present(domain_ug))
then
755 nfiles = io_layout_ug
756 npes = mpp_get_ug_domain_npes(domain_ug)
757 if (nfiles .gt. npes)
then
765 call mpp_write_meta( unit,
'NumFilesInSet', ival=nfiles)
772 if (
associated(io_domain))
then
775 if (
associated(io_domain_ug))
then
776 io_domain_ug => null()
780 call mpp_clock_end(mpp_open_clock)
782 end subroutine mpp_open
801 subroutine mpp_close( unit, action )
802 integer,
intent(in) :: unit
803 integer,
intent(in),
optional :: action
804 character(len=8) :: status
808 call mpp_clock_begin(mpp_close_clock)
809 if( .NOT.module_is_initialized )
call mpp_error( fatal,
'MPP_CLOSE: must first call mpp_io_init.' )
810 if( unit.EQ.nullunit .OR. unit .EQ.
stderr() )
then
811 call mpp_clock_end(mpp_close_clock)
818 if(
PRESENT(action) )
then
819 if( action.EQ.mpp_delete )
then
820 if( pe.EQ.mpp_root_pe() .OR. mpp_file(unit)%fileset.EQ.mpp_multi )status =
'DELETE'
821 else if( action.EQ.mpp_collect )
then
823 call mpp_error( warning,
'MPP_CLOSE: the COLLECT operation is not yet implemented.' )
825 call mpp_error( fatal,
'MPP_CLOSE: action must be one of MPP_DELETE or MPP_COLLECT.' )
828 if( mpp_file(unit)%fileset.NE.mpp_multi )collect = .false.
829 if( mpp_file(unit)%opened)
then
830 if( mpp_file(unit)%format.EQ.mpp_netcdf )
then
832 error = nf_close(mpp_file(unit)%ncid);
call netcdf_err( error, mpp_file(unit) )
835 close(unit,status=status)
838 if (
associated(mpp_file(unit)%Axis) )
then
839 do i=1, mpp_file(unit)%ndim
840 if (
associated(mpp_file(unit)%Axis(i)%data) )
then
841 deallocate(mpp_file(unit)%Axis(i)%data)
842 nullify(mpp_file(unit)%Axis(i)%data)
845 if (
associated(mpp_file(unit)%Axis(i)%Att) )
then
846 do j=1, mpp_file(unit)%Axis(i)%natt
847 if (
associated(mpp_file(unit)%Axis(i)%Att(j)%fatt) )
then
848 deallocate(mpp_file(unit)%Axis(i)%Att(j)%fatt)
849 nullify(mpp_file(unit)%Axis(i)%Att(j)%fatt)
852 deallocate(mpp_file(unit)%Axis(i)%Att)
853 nullify(mpp_file(unit)%Axis(i)%Att)
856 deallocate(mpp_file(unit)%Axis)
857 nullify(mpp_file(unit)%Axis)
860 if (
associated(mpp_file(unit)%var) )
then
861 do i=1, mpp_file(unit)%nvar
862 if (
associated(mpp_file(unit)%var(i)%Axes) )
then
864 deallocate(mpp_file(unit)%var(i)%Axes)
865 nullify(mpp_file(unit)%var(i)%Axes)
867 if (
associated(mpp_file(unit)%var(i)%size) )
then
868 deallocate(mpp_file(unit)%var(i)%size)
869 nullify(mpp_file(unit)%var(i)%size)
871 if (
associated(mpp_file(unit)%var(i)%Att) )
then
872 do j=1, mpp_file(unit)%var(i)%natt
873 if (
associated(mpp_file(unit)%var(i)%Att(j)%fatt) )
then
874 deallocate(mpp_file(unit)%var(i)%Att(j)%fatt)
875 nullify(mpp_file(unit)%var(i)%Att(j)%fatt)
878 deallocate(mpp_file(unit)%var(i)%Att)
879 nullify(mpp_file(unit)%var(i)%Att)
882 deallocate(mpp_file(unit)%var)
883 nullify(mpp_file(unit)%var)
886 if (
associated(mpp_file(unit)%att) )
then
887 do i=1, mpp_file(unit)%natt
888 if (
associated(mpp_file(unit)%att(i)%fatt) )
then
889 deallocate(mpp_file(unit)%att(i)%fatt)
890 nullify(mpp_file(unit)%att(i)%fatt)
893 deallocate(mpp_file(unit)%att)
894 nullify(mpp_file(unit)%att)
897 if (
associated(mpp_file(unit)%time_values) )
then
898 deallocate(mpp_file(unit)%time_values)
899 nullify(mpp_file(unit)%time_values)
902 mpp_file(unit)%name =
' '
903 mpp_file(unit)%action = -1
904 mpp_file(unit)%format = -1
905 mpp_file(unit)%access = -1
906 mpp_file(unit)%threading = -1
907 mpp_file(unit)%fileset = -1
908 mpp_file(unit)%record = -1
909 mpp_file(unit)%ncid = -1
910 mpp_file(unit)%opened = .false.
911 mpp_file(unit)%initialized = .false.
912 mpp_file(unit)%id = -1
913 mpp_file(unit)%ndim = -1
914 mpp_file(unit)%nvar = -1
915 mpp_file(unit)%time_level = 0
916 mpp_file(unit)%time = nulltime
917 mpp_file(unit)%valid = .false.
918 mpp_file(unit)%io_domain_exist = .false.
919 mpp_file(unit)%write_on_this_pe = .false.
926 if (
associated(mpp_file(unit)%domain))
then
927 deallocate(mpp_file(unit)%domain)
928 mpp_file(unit)%domain => null()
929 elseif (
associated(mpp_file(unit)%domain_ug))
then
930 mpp_file(unit)%domain_ug => null()
934 call mpp_clock_end(mpp_close_clock)
936 end subroutine mpp_close
939 subroutine file_size(fsize, fname, size)
941 character(len=12),
intent(in) ::fsize
942 character(len=128) ::filesize
943 character(len=128),
intent(in),
optional :: fname
944 character(len=128) :: filename
945 integer*4 :: fstat(13)
947 character(len=16) ::number
948 integer,
intent(OUT) :: size
949 integer*4 ::ierr, stat
957 length = len(trim(fsize))
962 if (filesize .EQ.
'file')
then
963 filename = trim(fname)
964 INQUIRE( file=filename, exist=there )
966 ierr = stat(filename, fstat)
967 if (ierr .EQ. 0)
then
973 elseif((filesize(length:length)>=
'a'.AND.fsize(length:length)<=
'z').OR.(filesize(length:length)>=
'A' &
974 .AND.fsize(length:length)<=
'Z'))
then
975 number = filesize(1:tend)
976 READ(number, fmt=
'(I9)')
size
977 if (filesize(length:length) >=
'a' .AND. fsize(length:length) <=
'z')
then
978 filesize(length:length) = achar( ichar(filesize(length:length)) - 32)
980 if ( filesize(length:length) .EQ.
'K')
then
982 elseif ( filesize(length:length) .EQ.
'M')
then
983 size = (size*1024)*1024
984 elseif ( filesize(length:length) .EQ.
'G')
then
985 size = (((size*1024)*1024)*1024)
990 READ(filesize, fmt=
'(I9)')
size
993 if (
size .eq. 0)
then
999 end subroutine file_size
integer function mpp_get_domain_npes(domain)
Set user stack size.
integer function, dimension(size(domain%tile_id(:))) mpp_get_tile_id(domain)
Returns the tile_id on current pe.
integer function, dimension(2) mpp_get_io_domain_layout(domain)
Set user stack size.
type(domain2d) function, pointer mpp_get_io_domain(domain)
Set user stack size.
logical function mpp_domain_is_tile_root_pe(domain)
Returns if current pe is the root pe of the tile, if number of tiles on current pe is greater than 1,...
integer function stderr()
This function returns the current standard fortran unit numbers for error messages.
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.