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
420 if(mpp_npes() > 10000)
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,...