alex-robinson / ncio

Simple Fortran interface to NetCDF reading and writing.
23 stars 9 forks source link

Append values along one or more 'unlimited' dimension for NETCDF4 file. #9

Open liuchao95 opened 4 years ago

liuchao95 commented 4 years ago

The netCDF4 library allows one or more 'unlimited' dimensions so that arrays can be appended along them. Could the authors further implement the 'append' mode and allows the usages of multiple 'unlimited' dimensions?

liuchao95 commented 4 years ago

I realized that the 'append' mode can be achieved with the 'nc_write' subroutine.

However, the usage of multiple 'unlimited' dimensions seems not allowed with the ncio. The following error message occurred when I try to write two "unlimited" dimensions with 'nc_write_dim' subroutine. "ncio:: error: NetCDF: NC_UNLIMITED size already in use STOP stopped by ncio."

alex-robinson commented 4 years ago

ncio is not under active development at the moment. However, I will keep this in mind. Looking over the ncio source code, I don't immediately see a reason why ncio would prevent defining multiple unlimited dimensions. This part of the error you get "NetCDF: NC_UNLIMITED size already in use" looks like it comes directly from NetCDF, so perhaps it is related to the version of NetCDF you have installed?

If you see a way to improve this, I would be happy to pull it into the code.

liuchao95 commented 4 years ago

Hi Alex,

I think it may be related to the the "nc_create" subroutine in the ncio. The cmode can only be "nf90_clobber" or "nf90_noclobber", which might prevent defining multiple unlimited dimensions.

I write a simple test scipt with my netcdf lib (version 4.6.0) by changing the cmode to "nf90_netcdf4" and it works well for the mlutiple unlimited dimensions. If I switch the cmode back to "nf90_clobber" then it issueS an error "NetCDF: NC_UNLIMITED size already in use".

The testing code is as follows and I hope it can helpful for your improvment.

`module NCIO use netcdf implicit none

contains
    subroutine check(status)
        integer, intent(in) :: status
        if(status/=nf90_noerr) then 
            print *, trim(nf90_strerror(status))
            stop "Stopped due to NETCDF I/O"
        end if
end subroutine

end module NCIO

program main use netcdf use NCIO implicit none

integer, parameter :: ndim = 3
    integer, parameter :: nt = 10, nx = 144, ny = 73
    integer :: ncid, sstid, timeid, lonid, latid, dimid(ndim)
real(kind=8)    :: sst(nx,ny,nt), time(nt)
real(kind=4)    :: lat(ny), lon(nx)
integer :: i

lat = (/(-90 + i*2.5, i=0,ny-1)/)
lon = (/(0 + i*2.5, i=0,nx-1)/)
sst = 0.0 
time= (/(i, i= 1,10)/)

!call check( nf90_create("sst.nc", NF90_NETCDF4, ncid) )
call check( nf90_create("sst.nc", NF90_CLOBBER, ncid) )

! define the dimension and return dimension ID 
  call check( nf90_def_dim(ncid, "time",NF90_UNLIMITED, dimid(3)) )
call check( nf90_def_dim(ncid, "lat", NF90_UNLIMITED, dimid(2)) )
call check( nf90_def_dim(ncid, "lon", NF90_UNLIMITED, dimid(1)) )

! define the variable name 
call check( nf90_def_var(ncid, "sst",  NF90_DOUBLE, dimid, sstid) )
call check( nf90_def_var(ncid, "time", NF90_DOUBLE, dimid(3), timeid) )
call check( nf90_def_var(ncid, "lat",  NF90_FLOAT,  dimid(2), latid) )
call check( nf90_def_var(ncid, "lon",  NF90_FLOAT,  dimid(1), lonid) )

! define the attribute 
call check(NF90_PUT_ATT(ncid, NF90_GLOBAL, "detail", "liuc test"))

! finish the define mode 
call check(nf90_enddef(ncid) )

! start writing the data 
call check(nf90_put_var(ncid, sstid, sst))
call check(nf90_put_var(ncid, timeid,time))
call check(nf90_put_var(ncid, latid, lat))
call check(nf90_put_var(ncid, lonid, lon))

! close file 
call check( nf90_close(ncid) )

end program main`