mpp_io_mod, is a set of simple calls for parallel I/O on distributed systems. It is geared toward the writing of data in netCDF format. It requires the modules mpp_domains_mod and mpp_mod, upon which it is built.
type, public :: axistype
sequence
character(len=128) :: name
character(len=128) :: units
character(len=256) :: longname
character(len=8) :: cartesian
integer :: len
integer :: sense !+/-1, depth or height?
type(domain1D), pointer :: domain
real, dimension(:), pointer :: data
integer :: id, did
integer :: type ! external NetCDF type format for axis data
integer :: natt
type(atttype), pointer :: Att(:) ! axis attributes
end type axistype A field is described using the type fieldtype:
type, public :: fieldtype
sequence
character(len=128) :: name
character(len=128) :: units
character(len=256) :: longname
real :: min, max, missing, fill, scale, add
integer :: pack
type(axistype), dimension(:), pointer :: axes
integer, dimension(:), pointer :: size
integer :: time_axis_index
integer :: id
integer :: type ! external NetCDF format for field data
integer :: natt, ndim
type(atttype), pointer :: Att(:) ! field metadata
end type fieldtype An attribute (global, field or axis) is described using the atttype:
type, public :: atttype
sequence
integer :: type, len
character(len=128) :: name
character(len=256) :: catt
real(FLOAT_KIND), pointer :: fatt(:)
end type atttype
This default set of field attributes corresponds
closely to various conventions established for netCDF files. The pack attribute of a field defines whether or not a
field is to be packed on output. Allowed values of pack are 1,2,4 and 8. The value of pack is the number of variables written into 8
bytes. In typical use, we write 4-byte reals to netCDF output; thus
the default value of pack is 2. For pack = 4 or 8, packing uses a simple-minded linear
scaling scheme using the scale and add attributes. There is thus likely to be a significant loss of dynamic
range with packing. When a field is declared to be packed, the missing and fill attributes, if
supplied, are packed also.
...
type(domain2D), dimension(:), allocatable, target :: domain
type(fieldtype) :: field
type(axistype) :: x, y, z, t
...
call mpp_define_domains( (/1,nx,1,ny/), domain )
allocate( a(domain(pe)%x%data%start_index:domain(pe)%x%data%end_index, &
domain(pe)%y%data%start_index:domain(pe)%y%data%end_index,nz) )
...
call mpp_write_meta( unit, x, 'X', 'km', 'X distance', &
domain=domain(pe)%x, data=(/(float(i),i=1,nx)/) )
call mpp_write_meta( unit, y, 'Y', 'km', 'Y distance', &
domain=domain(pe)%y, data=(/(float(i),i=1,ny)/) )
call mpp_write_meta( unit, z, 'Z', 'km', 'Z distance', &
data=(/(float(i),i=1,nz)/) )
call mpp_write_meta( unit, t, 'Time', 'second', 'Time' )
call mpp_write_meta( unit, field, (/x,y,z,t/), 'a', '(m/s)', AAA', &
missing=-1e36 )
...
call mpp_write( unit, x )
call mpp_write( unit, y )
call mpp_write( unit, z )
... In this example, x and y have been
declared as distributed axes, since a domain decomposition has been
associated. z and t are undistributed
axes. t is known to be a record axis (netCDF
terminology) since we do not allocate the data element
of the axistype. Only one record axis may be
associated with a file. The call to mpp_write_meta initializes
the axes, and associates a unique variable ID with each axis. The call
to mpp_write_meta with argument field declared field to be a 4D variable that is a function
of (x,y,z,t), and a unique variable ID is associated
with it. A 3D field will be written at each call to mpp_write(field).
...
integer :: unit, natt, nvar, ntime
type(domain2D), dimension(:), allocatable, target :: domain
type(fieldtype), allocatable, dimension(:) :: fields
type(atttype), allocatable, dimension(:) :: global_atts
real, allocatable, dimension(:) :: times
...
call mpp_define_domains( (/1,nx,1,ny/), domain )
call mpp_read_meta(unit)
call mpp_get_info(unit,natt,nvar,ntime)
allocate(global_atts(natt))
call mpp_get_atts(unit,global_atts)
allocate(fields(nvar))
call mpp_get_vars(unit, fields)
allocate(times(ntime))
call mpp_get_times(unit, times)
allocate( a(domain(pe)%x%data%start_index:domain(pe)%x%data%end_index, &
domain(pe)%y%data%start_index:domain(pe)%y%data%end_index,nz) )
...
do i=1, nvar
if (fields(i)%name == 'a') call mpp_read(unit,fields(i),domain(pe), a,
tindex)
enddo
... In this example, the data are distributed as in the previous
example. The call to mpp_read_meta initializes
all of the metadata associated with the file, including global
attributes, variable attributes and non-record dimension data. The
call to mpp_get_info returns the number of global
attributes (natt), variables (nvar) and
time levels (ntime) associated with the file
identified by a unique ID (unit). mpp_get_atts returns all global attributes for
the file in the derived type atttype(natt). mpp_get_vars returns variable types
(fieldtype(nvar)). Since the record dimension data are not allocated for calls to mpp_write, a separate call to mpp_get_times is required to access record dimension data. Subsequent calls to mpp_read return the field data arrays corresponding to
the fieldtype. The domain type is an optional
argument. If domain is omitted, the incoming field
array should be dimensioned for the global domain, otherwise, the
field data is assigned to the computational domain of a local array.
mpp_data_mod
mpp_datatype_mod
mpp_parameter_mod
mpp_io_util_mod
mpp_io_misc_mod
mpp_io_write_mod
mpp_io_read_mod
mpp_io_connect_mod