Due to the current gap in continued funding from the U.S. National Science Foundation (NSF), the NSF Unidata Program Center has temporarily paused most operations. See NSF Unidata Pause in Most Operations for details.
Hi John, I think that using f90 generic functions as wrappers to the type specific netCDF routines addresses the problem you have presented. Here is an example of using a generic function for writing a 1D array of real data: module mod1 implicit none save private public :: writenc_var_real interface writenc_var_real module procedure writenc_var_sp, writenc_var_dp end interface contains integer function writenc_var_sp( ncid, varid, vals ) ! Write single precision data to a netCDF file. implicit none include 'netcdf.inc' integer, intent(in) :: ncid, varid real, intent(in), dimension(:) :: vals writenc_var_sp = NF_PUT_VAR_REAL( ncid, varid, vals ) end function writenc_var_sp integer function writenc_var_dp( ncid, varid, vals ) ! Write double precision data to a netCDF file. implicit none include 'netcdf.inc' integer, intent(in) :: ncid, varid double precision, intent(in), dimension(:) :: vals writenc_var_dp = NF_PUT_VAR_DOUBLE( ncid, varid, vals ) end function writenc_var_dp end module mod1 program main ! Write single or double precision data to a netCDF file. use mod1 implicit none include 'netcdf.inc' integer, parameter :: len = 4 real :: arr(len) = (/ 1., 2., 3., 4. /) integer :: ret, ncid, ndims = 1, dimid, varid ! Create file. ret = NF_CREATE( 'zzz.nc', NF_CLOBBER, ncid ) ! Define dimensions. ret = NF_DEF_DIM( ncid, 'len', len, dimid ) ! Define variables. ret = NF_DEF_VAR( ncid, 'arr', NF_FLOAT, ndims, dimid, varid ) ! End definition mode. ret = NF_ENDDEF( ncid ) ! Write the data. ret = writenc_var_real( ncid, varid, arr ) ! Close file. ret = NF_CLOSE( ncid ) end program main Notes: 1. The module should be compiled separately, and it can't be compiled with a -r8 flag because then the specific funtions have identical interfaces and the generic function is ambiguous. 2. The main program can be compiled with or without a -r8 flag and the generic function writenc_var_real calls the correct netCDF function. Alternatively the main program can declare different real types using real*4, real*8, or parameterized real types as in f90. I did manage to break the code on a Cray J90 using a real(selected_real_kind(p=6)) declaration of arr. This is because the J90 returned a kind value of 4 even though there are no 4-byte floating point representations on that machine. 3. Since generic functions identify the correct specific functions based on both type and rank of array arguments, additional specific functions need to be added to writenc_var_real to generalize this example to arrays of dimension other than one. 4. This should work on Crays in general (with the specific exception described in note 2.). On the older PVP type machines using Cray floating point the specific function for writing double precision data (16-byte) is of course broken, but under normal circumstances that function would not be called. The newer Crays use IEEE floating point and things should work the same there as on non-Cray platforms. Regards, Brian Brian Eaton | email: eaton@xxxxxxxx Climate Modeling Section | National Center for Atmospheric Research | P.O. Box 3000, Boulder, CO 80307 |
netcdfgroup
archives: