[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Always Zeros, was:Re: 980504: Non ANSI C++ and netCDF



>From: Markus Werle <address@hidden>
>Subject: Non ANSI C++
>Organization: Lehr- und Forschungsgebiet fuer Mechanik, RWTH-Aachen
>Keywords: 199805041934.NAA23467 netCDF g++

Markus,

> Your answers were very helpful, thanks alot.
> 
> Nethertheless there seems to be a deeper, sophisticated problem
> for which I cannot figure out the reason.
> All values are zero (!) in the dumped netcdf-file of
> my little test project:

The problem is close() is never getting called on the open netCDF file,
so its buffers never get flushed to disk and the result is a
half-written file.

The C++ interface automatically calls close on a netCDF file when its
destructor is called, which would happen if you had the NcFile object in
scope in the main program, but since pDataFile is encapsulated in the
Mesh class, you need to provide an explicit method to close it when you
are done writing.

Just add the following public method to the Mesh class (and include a
declaration for it among the declarations for Mesh's public methods):

 void Mesh::CloseFile()
 {
   pDataFile->close();
 }

and call it at the end of your main program before you return:

  OriginalMesh.CloseFile();

I tried this, and it seemed to work fine.

--Russ


> -------------------------------------------------------------------------------
> netcdf test {
> dimensions:
>         dimension_in_i-direction = 4 ;
>         dimension_in_j-direction = 4 ;
>         no_of_space_dimensions = 2 ;
> variables:
>         double Grid_Points(no_of_space_dimensions, dimension_in_i-direction, 
> dim
> ension_in_j-direction) ;
>                 Grid_Points:long_name = "A structured curvilinear Grid" ;
>         double Garbage(dimension_in_i-direction) ;
> 
> // global attributes:
>                 :history = "created by Markus Werle" ;
>                 :title = "Mesh" ;
> data:
> 
>  Grid_Points =
>   0, 0, 0, 0,
>   0, 0, 0, 0,
>   0, 0, 0, 0,
>   0, 0, 0, 0,
>   0, 0, 0, 0,
>   0, 0, 0, 0,
>   0, 0, 0, 0,
>   0, 0, 0, 0 ;
> 
>  Garbage = 0, 0, 0, 0 ;
> }
> 
> -----------------------------------------------------------------------------
> 
> 
> Please take a short glance at my spaghetti code (2 pages)
> I send You the Makefile with it, so after changing 3 lines in it
> You should be able to let it run on Your environment and see,
> if it has the same behaviour.
> 
> I declared all variables of my class as public by now, just to see
> that it had no effect, so don't get confused by the commented
> parts of the code.
> 
> 
> 
> --markus
> 
> --------------21F0CE3D193E0D49DEE74DF0
> Content-Type: text/plain; charset=us-ascii; name="main.C"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline; filename="main.C"
> 
> #include <iostream.h>
> #include "netcdf.hh"
> #include "ncvalues.hh"
> 
> //==============================================================================
> class Mesh {
> //==============================================================================
> public:
>   Mesh(const long c_spacedim, const long c_jdim, const long c_idim);
>   int OpenFile(const char* path);
>   int WriteMeshPointDataToFile(const double * pMeshData,
>                              const long spacedim,
>                              const long jdim,
>                              const long idim);
>   
>   //private:
>   long _idim;
>   long _jdim;
>   long _spacedim;
> 
>   // The declaration of data file ...
>   NcFile* pDataFile;
>         
>   // ... and dimensions ...
>   NcDim* Nc_idim;
>   NcDim* Nc_jdim;
>   NcDim* Nc_spacedim;
> 
>   // ... and variables
>   NcVar* NcMeshPointsInFile;
>   NcVar* NcGarbage;
>   
> };
>   
> //==============================================================================
> // Constructor of Mesh
> Mesh::Mesh(const long c_spacedim, const long c_jdim, const long c_idim)
> {
>   _idim = c_idim;
>   _jdim = c_jdim;
>   _spacedim = c_spacedim;
> }
> 
> //==============================================================================
> int Mesh::OpenFile(const char* path)
> {
>   // The definition of the data file
>   pDataFile = new NcFile(path, NcFile::Replace);
>   
> 
>   // Check if the file was opened
>   if (! (*pDataFile).is_valid()){
>     cerr << "can't create netCDF file " << path << "\n";
>     return 0;
>   }
> 
>   // Create dimensions 
>   Nc_idim = 
>     (*pDataFile).add_dim("dimension_in_i-direction", _idim);
>   Nc_jdim = 
>     (*pDataFile).add_dim("dimension_in_j-direction", _jdim);
>   Nc_spacedim = 
>     (*pDataFile).add_dim("no_of_space_dimensions", _spacedim);
>     
>   // Create variables and their attributes
>   NcMeshPointsInFile = 
>     (*pDataFile).add_var("Grid_Points", ncDouble, 
>                    Nc_spacedim, Nc_idim, Nc_jdim);
>  
>   NcMeshPointsInFile->add_att("long_name", "A structured curvilinear Grid");
> 
>   
>   NcGarbage = (*pDataFile).add_var("Garbage", ncDouble, Nc_idim);
>                                
>     
> 
>   // Global attributes
>   (*pDataFile).add_att("history", "created by Markus Werle");
>   (*pDataFile).add_att("title", "Mesh");
>                      
> 
>   double a[] = {1, 2, 3, 4, 5};
>   cout << "a[2]=" << a[2] << endl;
>   
>   NcGarbage->put(a, _idim);
>   
>   if (! (*NcGarbage).is_valid()){
>     cerr << "error while writing data NcGarbage" << "\n";
>     return 0;
>   }
>   
>   return 0;
> }
> 
> 
> int Mesh::WriteMeshPointDataToFile(const double * pMeshData,
>                                  const long spacedim,
>                                  const long jdim,
>                                  const long idim)
> {
>   for (int i=0; i<(idim*jdim*spacedim); i++)
>     cout << pMeshData[i] << endl;
>   
> 
>   NcMeshPointsInFile->put(pMeshData, spacedim, jdim, idim);
>   
>   return 0;
> }
> 
> 
> int main (int nargs, const char** args)
> {
>   const char* path = "test.nc";
>   //cout << i << endl;
>   
>   cout << "The file is " << path << endl;
> 
>   long spacedim=2;
>   long jdim=4;
>   long idim=4;
>   
>   Mesh OriginalMesh(spacedim,jdim,idim);
>   OriginalMesh.OpenFile(path);
> 
>   double MeshPointData[spacedim][jdim][idim];
>   double* pMeshPointData = &MeshPointData[0][0][0];
>   
>   for (int s=0; s<spacedim; s++){
>     for (int i=0; i<idim; i++){
>       for (int j=0; j<jdim; j++){
>       cout << i << " " << j << " " << s << ": " 
>            << j + (i*idim) + (idim*jdim*s) << endl;
>       int index = j + (i*idim) + (idim*jdim*s);
>       
>       pMeshPointData[index] = double(index);
>       //cout << MeshPointData[index] << endl;
>       }
>     }
>   }
> 
> 
>   
>   OriginalMesh.WriteMeshPointDataToFile(&MeshPointData[0][0][0],
>                                       spacedim, 
>                                       jdim, idim);
> 
>   //OriginalMesh.NcMeshPointsInFile->put(&MeshPointData[0][0][0], 
>   //                                 spacedim, jdim, idim);  
> 
>   //OriginalMesh.NcMeshPointsInFile->put(&MeshPointData[0][0][0], 
>   //                                 
> OriginalMesh.NcMeshPointsInFile->edges());
>   return 0;
>   
> }
>   
> 
> 
> 
> 
> 
> 
> 
> 
>  
> 
>   
>   
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> --------------21F0CE3D193E0D49DEE74DF0
> Content-Type: text/plain; charset=us-ascii; name="Makefile"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline; filename="Makefile"
> 
> # ====================================================================
> # Makefile for a test of netCDF Data access
> # ====================================================================
> 
> 
> 
> # the compiler
> CXX = g++
> #CXX = CC
> 
> # compiler flags
> ifeq ($(CXX),g++)
>   CXXFLAGS = -Wall
> else
>   CXXFLAGS = -g -Aa +DA1.1
> endif
> 
> 
> # Where to find libraries
> ifeq ($(CXX),g++)
>   LIBDIR = -L/rayleigh/markus/SOFTWARE/netCDF/netcdf-3.3.1/lib 
> -L/usr/local/lib
> else
>   LIBDIR = -L/rayleigh/markus/SOFTWARE/netCDF/netcdf-3.3.1/lib -L/usr/lib
> endif
> 
> #
> 
> # Which libraries to use
> LIBS = -lnetcdf_c++ -lnetcdf 
> 
> # Where to find include files
> INCLUDE = -I/rayleigh/markus/SOFTWARE/netCDF/netcdf-3.3.1/include
> ifeq ($(CXX),g++)
>   INCLUDE := $(INCLUDE) -I/usr/local/lib/g++-include
> endif
> 
> 
> OBJS = main.o
> #OBJS = example.o
> #OBJS = nctst.o
> 
> all: $(OBJS) binary
> 
> 
> %.o : %.C 
>       $(CXX) $(CXXFLAGS) $(INCLUDE) -c $<
> 
> binary: 
>       $(CXX) $(CXXFLAGS) -o test.exe $(OBJS) $(LIBDIR) $(LIBS) 
> 
> #/opt/langtools/lib/end.o
> 
> 
> 
> clean:
>       rm *.o test.exe
> 
> 
> 
> 
> 
> 
> 
> --------------21F0CE3D193E0D49DEE74DF0--
> 
>