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 axistypeA 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 fieldtypeAn 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 atttypeThis 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