This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
>To: address@hidden >From: Ben Foster <address@hidden> >Subject: Re: 20020611: writing doubles to netcdf >Organization: HAO Ben, > Russ: Thanks for the hints. It works now when I compile > with -r4 (lib r4i4), define the var as NF_DOUBLE, and call > nf_put_var_real. Presumably, netcdf is promoting my 4-byte > real. However, I guess I could be loosing precision reading > 8-byte floats from the cray file into 4-byte reals, so > maybe I should compile with -r8 and call nf_put_var_double. OK, but if you compile with -r8 that says Fortran reals are 8-bytes, so in that case you should be calling nf_put_var_real(), linking with a netCDF library that was also built with -r8. The TYPE in the function name nf_put_var_TYPE refers to the native (internal) type of the array you are writing, not to the external netCDF type of the variable you are writing into. > Anyway, I did put together a small test program, see attached. > I am running this on dataproc with the r4i4 lib, so presumably > netcdf was compiled with -r4. In the test, I don't understand > why compiling with -r4 and writing nf_put_var_double does not > work (whether the var was defined NF_FLOAT or NF_DOUBLE). I guess > its not kosher to pass a 4-byte real in the put double call. The problem is with the call istat = nf_put_var_double(ncid,id_sigtn,sigtn) ! wrong (why?) which says you are providing an array of doubles, but sigtn is an array of reals. The (internal) type of the data you are writing must match the name of the function you array using to write it. No matter whether you compile with -r4 and use a library compiled with -r4, or compile with -r8 and use a library compiled with -r8, when you declare real :: sigtn(nsigt) then sigtn is real and you must use nf_put_var_real() to write it. The netCDF library will convert the internal type to whatever the external type of the variable is before writing it on disk, but the nf_put_var_TYPE function can't figure out the type of the array it was passed, it can only assume that you have provided the right type. The fact that istat = nf_put_var_double(ncid,id_sigtn,sigtn) ! works works when compiled with -r8 even though sigtn is declared real is because both reals and doubles are 8-bytes under "-r8" (you would have to include "-d16" to specify 16-byte doubles). So in this case it doesn't matter that sigtn is the wrong type, since booth reals and doubles are the same size. So this works but isn't right. --Russ ! program nctest ! ! From Makefile for SGI: ! FC = f90 ! #FFLAGS= -I/usr/local/include -r4 -64 -mips4 # 4-byte reals ! FFLAGS= -I/usr/local/include -r8 -64 -mips4 # 8-byte reals ! LIBS= -L /usr/local/lib64/r4i4 -lnetcdf ! LDFLAGS = -64 ! ! Create netcdf dataset for testing on SGI O2K dataproc. ! implicit none #include "netcdf.inc" integer,parameter :: nsigt=6 real :: sigtn(nsigt) real(kind=8) :: sigtn8(nsigt) integer :: ncid,istat,id_nsigt,id_sigtn,ids1(1) character(len=16) :: filename = 'nctest.nc' ! sigtn = (/180.,200.,220.,230.,240.,250./) sigtn8 = sigtn ! put 4-byte values in 8-byte real ! ! Create dataset: istat = nf_create(filename,NF_CLOBBER,ncid) ! ! Define nsigt dimension: istat = nf_def_dim(ncid,"nsigt",nsigt,id_nsigt) ! ! Define sigtn variable (1 dimensional vector): ! Use NF_DOUBLE to write 8-byte reals, or NF_FLOAT to write 4-byte reals ! ids1(1) = id_nsigt istat = nf_def_var(ncid,"sigtn",NF_DOUBLE,1,ids1,id_sigtn) ! istat = nf_def_var(ncid,"sigtn",NF_FLOAT,1,ids1,id_sigtn) ! ! Exit define mode: istat = nf_enddef(ncid) ! ! Write vector to the file: ! ! When compiled with -r4 and lib r4i4: istat = nf_put_var_double(ncid,id_sigtn,sigtn) ! wrong (why?) ! istat = nf_put_var_double(ncid,id_sigtn,sigtn8) ! works (8-byte reals) ! istat = nf_put_var_real(ncid,id_sigtn,sigtn) ! works (4-byte reals promoted) ! ! When compiled with -r8 and lib r4i4: ! istat = nf_put_var_double(ncid,id_sigtn,sigtn) ! works ! istat = nf_put_var_double(ncid,id_sigtn,sigtn8) ! works, but unecessary ! istat = nf_put_var_real(ncid,id_sigtn,sigtn) ! wrong (does not demote?) ! ! Close the new netcdf file: istat = nf_close(ncid) write(6,"('Wrote file ',a)") filename end program nctest --Steam_of_Minnows_287_000 Content-Type: TEXT/x-sun-Makefile; name=Makefile; charset=us-ascii; x-unix-mode=0664 Content-Description: Makefile Content-MD5: S2XaaV0IZO9ZTsKteRhodw== # EXEC=nctest FC = f90 FFLAGS= -I/usr/local/include -r4 -64 -mips4 #FFLAGS= -I/usr/local/include -r8 -64 -mips4 LIBS= -L /usr/local/lib64/r4i4 -lnetcdf LDFLAGS = -64 # OBJS = nctest.o .SUFFIXES: .F # $(EXEC): $(OBJS) $(FC) -o $@ $(OBJS) $(LDFLAGS) $(LIBS) .f.o: $(FC) -c $(FFLAGS) $< .F.o: $(FC) -c $(FFLAGS) $< --Steam_of_Minnows_287_000--