Use c interface in netcdf writer

Add missing authors
parent 6ecfd4c1
...@@ -283,7 +283,7 @@ if 'libSDLDir' in env: ...@@ -283,7 +283,7 @@ if 'libSDLDir' in env:
# set the precompiler flags and includes for netCDF # set the precompiler flags and includes for netCDF
if env['writeNetCDF'] == True: if env['writeNetCDF'] == True:
env.Append(CPPDEFINES=['WRITENETCDF']) env.Append(CPPDEFINES=['WRITENETCDF'])
env.Append(LIBS=['netcdf','netcdf_c++']) env.Append(LIBS=['netcdf'])
# set netCDF location # set netCDF location
if 'netCDFDir' in env: if 'netCDFDir' in env:
env.Append(CPPPATH=[env['netCDFDir']+'/include']) env.Append(CPPPATH=[env['netCDFDir']+'/include'])
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* This file is part of SWE. * This file is part of SWE.
* *
* @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer) * @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
* *
* @section LICENSE * @section LICENSE
* *
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* This file is part of SWE. * This file is part of SWE.
* *
* @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer) * @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
* *
* @section LICENSE * @section LICENSE
* *
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* *
* @author Michael Bader (bader AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Univ.-Prof._Dr._Michael_Bader) * @author Michael Bader (bader AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Univ.-Prof._Dr._Michael_Bader)
* Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer) * Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
* *
* @section LICENSE * @section LICENSE
* *
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* This file is part of SWE. * This file is part of SWE.
* *
* @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer) * @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
* *
* @section LICENSE * @section LICENSE
* *
...@@ -30,7 +31,6 @@ ...@@ -30,7 +31,6 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
#include <netcdfcpp.h>
/** /**
* Constructor of a netCDF-writer. * Constructor of a netCDF-writer.
...@@ -49,6 +49,7 @@ io::NetCdfWriter::NetCdfWriter( const std::string &i_filename, ...@@ -49,6 +49,7 @@ io::NetCdfWriter::NetCdfWriter( const std::string &i_filename,
* Destructor of a netCDF-writer. * Destructor of a netCDF-writer.
*/ */
io::NetCdfWriter::~NetCdfWriter() { io::NetCdfWriter::~NetCdfWriter() {
nc_close(dataFile);
} }
/** /**
...@@ -66,73 +67,71 @@ void io::NetCdfWriter::createNetCdfFile( const float &i_dX, ...@@ -66,73 +67,71 @@ void io::NetCdfWriter::createNetCdfFile( const float &i_dX,
const float &i_originX, const float &i_originX,
const float &i_originY ) {//, const float &i_originY ) {//,
//const bool &i_dynamicBathymetry) { //!TODO //const bool &i_dynamicBathymetry) { //!TODO
//create a netCDF-file, an existing file will be replaced int status;
NcFile l_dataFile = NcFile(fileName.c_str(), NcFile::Replace);
//create a netCDF-file, an existing file will be replaced
status = nc_create(fileName.c_str(), NC_NETCDF4, &dataFile);
//check if the netCDF-file creation constructor succeeded. //check if the netCDF-file creation constructor succeeded.
if (!l_dataFile.is_valid()) { if (status != NC_NOERR) {
return; assert(false);
} return;
}
#ifdef PRINT_NETCDFWRITER_INFORMATION #ifdef PRINT_NETCDFWRITER_INFORMATION
std::cout << " *** io::NetCdfWriter::createNetCdfFile" << std::endl; std::cout << " *** io::NetCdfWriter::createNetCdfFile" << std::endl;
std::cout << " created/replaced: " << fileName << std::endl; std::cout << " created/replaced: " << fileName << std::endl;
std::cout << " dimensions(nx, ny): " << nX << ", " << nY << std::endl; std::cout << " dimensions(nx, ny): " << nX << ", " << nY << std::endl;
std::cout << " cell width(dx,dy): " << i_dX << ", " << i_dY << std::endl; std::cout << " cell width(dx,dy): " << i_dX << ", " << i_dY << std::endl;
std::cout << " origin(x,y): " << i_originX << ", " << i_originY << std::endl; std::cout << " origin(x,y): " << i_originX << ", " << i_originY << std::endl;
#endif #endif
//dimensions //dimensions
NcDim* l_timeDim = l_dataFile.add_dim("time", NC_UNLIMITED); int l_timeDim, l_xDim, l_yDim;
NcDim* l_xDim = l_dataFile.add_dim("x", nX); nc_def_dim(dataFile, "time", NC_UNLIMITED, &l_timeDim);
NcDim* l_yDim = l_dataFile.add_dim("y", nY); nc_def_dim(dataFile, "x", nX, &l_xDim);
nc_def_dim(dataFile, "y", nY, &l_yDim);
//variables (TODO: add rest of CF-1.5)
NcVar* l_ncVariable; //variables (TODO: add rest of CF-1.5)
int l_xVar, l_yVar;
l_ncVariable = l_dataFile.add_var("time", ncFloat, l_timeDim);
l_ncVariable->add_att("long_name", "Time"); nc_def_var(dataFile, "time", NC_FLOAT, 1, &l_timeDim, &timeVar);
l_ncVariable->add_att("units", "seconds since simulation start"); // the word "since" is important for the paraview reader ncPutAttText(timeVar, "long_name", "Time");
ncPutAttText(timeVar, "units", "seconds since simulation start"); // the word "since" is important for the paraview reader
l_dataFile.add_var("x", ncFloat, l_xDim);
l_dataFile.add_var("y", ncFloat, l_yDim); nc_def_var(dataFile, "x", NC_FLOAT, 1, &l_xDim, &l_xVar);
nc_def_var(dataFile, "y", NC_FLOAT, 1, &l_yDim, &l_yVar);
//variables, fastest changing index is on the right (C syntax), will be mirrored by the library
l_dataFile.add_var("h", ncFloat, l_timeDim, l_xDim, l_yDim); //variables, fastest changing index is on the right (C syntax), will be mirrored by the library
l_dataFile.add_var("hu", ncFloat, l_timeDim, l_xDim, l_yDim); int dims[] = {l_timeDim, l_yDim, l_xDim};
l_dataFile.add_var("hv", ncFloat, l_timeDim, l_xDim, l_yDim); nc_def_var(dataFile, "h", NC_FLOAT, 3, dims, &hVar);
l_dataFile.add_var("b", ncFloat, l_xDim, l_yDim); nc_def_var(dataFile, "hu", NC_FLOAT, 3, dims, &huVar);
nc_def_var(dataFile, "hv", NC_FLOAT, 3, dims, &hvVar);
//set attributes to match CF-1.5 convention nc_def_var(dataFile, "b", NC_FLOAT, 2, &dims[1], &bVar);
l_dataFile.add_att("Conventions", "CF-1.5");
l_dataFile.add_att("title", "Computed tsunami solution"); //set attributes to match CF-1.5 convention
l_dataFile.add_att("history", "SWE"); ncPutAttText(NC_GLOBAL, "Conventions", "CF-1.5");
l_dataFile.add_att("institution", "Technische Universitaet Muenchen, Department of Informatics, Chair of Scientific Computing"); ncPutAttText(NC_GLOBAL, "title", "Computed tsunami solution");
l_dataFile.add_att("source", "Bathymetry and displacement data."); ncPutAttText(NC_GLOBAL, "history", "SWE");
l_dataFile.add_att("references", "http://www5.in.tum.de/SWE"); ncPutAttText(NC_GLOBAL, "institution", "Technische Universitaet Muenchen, Department of Informatics, Chair of Scientific Computing");
l_dataFile.add_att("comment", "SWE is free software and licensed under the GNU General Public License. Remark: In general this does not hold for the used input data."); ncPutAttText(NC_GLOBAL, "source", "Bathymetry and displacement data.");
ncPutAttText(NC_GLOBAL, "references", "http://www5.in.tum.de/SWE");
ncPutAttText(NC_GLOBAL, "comment", "SWE is free software and licensed under the GNU General Public License. Remark: In general this does not hold for the used input data.");
//setup grid size
float gridPosition = i_originX + (float).5 * i_dX; //setup grid size
for(int i = 0; i < nX; i++) { float gridPosition = i_originX + (float).5 * i_dX;
l_ncVariable = l_dataFile.get_var("x"); for(size_t i = 0; i < nX; i++) {
l_ncVariable->set_cur(i); nc_put_var1_float(dataFile, l_xVar, &i, &gridPosition);
l_ncVariable->put(&gridPosition, 1);
gridPosition += i_dX;
gridPosition += i_dX; }
}
gridPosition = i_originY + (float).5 * i_dY;
gridPosition = i_originY + (float).5 * i_dY; for(size_t j = 0; j < nY; j++) {
for(int j = 0; j < nY; j++) { nc_put_var1_float(dataFile, l_yVar, &j, &gridPosition);
l_ncVariable = l_dataFile.get_var("y");
l_ncVariable->set_cur(j); gridPosition += i_dY;
l_ncVariable->put(&gridPosition, 1); }
gridPosition += i_dY;
}
//l_dataFile closed automatically (out of scope)
} }
/** /**
...@@ -145,17 +144,20 @@ void io::NetCdfWriter::createNetCdfFile( const float &i_dX, ...@@ -145,17 +144,20 @@ void io::NetCdfWriter::createNetCdfFile( const float &i_dX,
* *
* @param i_matrix array which contains time dependent data. * @param i_matrix array which contains time dependent data.
* @param i_boundarySize size of the boundaries. * @param i_boundarySize size of the boundaries.
* @param o_ncVariable time dependent netCDF-variable to which the output is written to. * @param i_ncVariable time dependent netCDF-variable to which the output is written to.
*/ */
void io::NetCdfWriter::writeVarTimeDependent( const Float2D &i_matrix, void io::NetCdfWriter::writeVarTimeDependent( const Float2D &i_matrix,
const int i_boundarySize[4], const int i_boundarySize[4],
NcVar* o_ncVariable ) { int i_ncVariable ) {
//write col wise, necessary to get rid of the boundary //write col wise, necessary to get rid of the boundary
//storage in Float2D is col wise //storage in Float2D is col wise
//read carefully, the dimensions are confusing //read carefully, the dimensions are confusing
for(int col = 0; col < nX; col++) { size_t start[] = {timeStep, 0, 0};
o_ncVariable->set_cur(timeStep, col, 0); //select col (dim "x") size_t count[] = {1, nY, 1};
o_ncVariable->put(&i_matrix[col+i_boundarySize[0]][i_boundarySize[2]], 1, 1, nY); //write col for(int col = 0; col < nX; col++) {
start[2] = col; //select col (dim "x")
nc_put_vara_float(dataFile, i_ncVariable, start, count,
&i_matrix[col+i_boundarySize[0]][i_boundarySize[2]]); //write col
} }
} }
...@@ -169,17 +171,20 @@ void io::NetCdfWriter::writeVarTimeDependent( const Float2D &i_matrix, ...@@ -169,17 +171,20 @@ void io::NetCdfWriter::writeVarTimeDependent( const Float2D &i_matrix,
* *
* @param i_matrix array which contains time independent data. * @param i_matrix array which contains time independent data.
* @param i_boundarySize size of the boundaries. * @param i_boundarySize size of the boundaries.
* @param o_ncVariable time independent netCDF-variable to which the output is written to. * @param i_ncVariable time independent netCDF-variable to which the output is written to.
*/ */
void io::NetCdfWriter::writeVarTimeIndependent( const Float2D &i_matrix, void io::NetCdfWriter::writeVarTimeIndependent( const Float2D &i_matrix,
const int i_boundarySize[4], const int i_boundarySize[4],
NcVar* o_ncVariable ) { int i_ncVariable ) {
//write col wise, necessary to get rid of the boundary //write col wise, necessary to get rid of the boundary
//storage in Float2D is col wise //storage in Float2D is col wise
//read carefully, the dimensions are confusing //read carefully, the dimensions are confusing
for(int col = 0; col < nX; col++) { size_t start[] = {0, 0};
o_ncVariable->set_cur(col, 0); //select col (dim "x") size_t count[] = {nY, 1};
o_ncVariable->put(&i_matrix[col+i_boundarySize[0]][i_boundarySize[2]], 1, nY); //write col for(int col = 0; col < nX; col++) {
start[1] = col; //select col (dim "x")
nc_put_vara_float(dataFile, i_ncVariable, start, count,
&i_matrix[col+i_boundarySize[0]][i_boundarySize[2]]); //write col
} }
} }
...@@ -202,57 +207,20 @@ void io::NetCdfWriter::writeUnknowns( const Float2D &i_h, ...@@ -202,57 +207,20 @@ void io::NetCdfWriter::writeUnknowns( const Float2D &i_h,
const Float2D &i_hv, const Float2D &i_hv,
const int i_boundarySize[4], const int i_boundarySize[4],
const float &i_time) { const float &i_time) {
//open dataFile //write i_time
NcFile l_dataFile = NcFile(fileName.c_str(), NcFile::Write); nc_put_var1_float(dataFile, timeVar, &timeStep, &i_time);
//check if the netCDF file open constructor succeeded.
if (!l_dataFile.is_valid()) {
std::cerr << "could not open " << fileName << std::endl;
assert(false);
}
else {
//set time
timeStep = l_dataFile.get_dim("time")->size();
}
//write i_time
NcVar* l_ncVariable = l_dataFile.get_var("time");
l_ncVariable->set_cur(timeStep);
l_ncVariable->put(&i_time, 1);
//write water height //write water height
l_ncVariable = l_dataFile.get_var("h"); writeVarTimeDependent(i_h, i_boundarySize, hVar);
writeVarTimeDependent(i_h, i_boundarySize, l_ncVariable);
//write momentum in x-direction //write momentum in x-direction
l_ncVariable = l_dataFile.get_var("hu"); writeVarTimeDependent(i_hu, i_boundarySize, huVar);
writeVarTimeDependent(i_hu, i_boundarySize, l_ncVariable);
//write momentum in y-direction //write momentum in y-direction
l_ncVariable = l_dataFile.get_var("hv"); writeVarTimeDependent(i_hv, i_boundarySize, hvVar);
writeVarTimeDependent(i_hv, i_boundarySize, l_ncVariable);
}
// Increment timeStep for next call
/** timeStep++;
* Write (static) bathymetry data to a netCDF-file (-> constructor) with respect to the boundary sizes.
*
* @param i_b bathymetry data.
* @param i_boundarySize size of the boundaries.
*/
//dynamic possible -> writeUnknowns
void io::NetCdfWriter::writeBathymetry( const Float2D &i_b,
const int i_boundarySize[4] ) {
//open dataFile
NcFile l_dataFile = NcFile(fileName.c_str(), NcFile::Write);
//check if the netCDF file open constructor succeeded.
if (!l_dataFile.is_valid()) {
std::cerr << "could not open " << fileName << std::endl;
assert(false);
}
NcVar* l_ncVariable = l_dataFile.get_var("b");
writeVarTimeIndependent(i_b, i_boundarySize, l_ncVariable);
} }
/** /**
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* This file is part of SWE. * This file is part of SWE.
* *
* @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer) * @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
* *
* @section LICENSE * @section LICENSE
* *
...@@ -28,9 +29,10 @@ ...@@ -28,9 +29,10 @@
#ifndef NETCDFWRITER_HH_ #ifndef NETCDFWRITER_HH_
#define NETCDFWRITER_HH_ #define NETCDFWRITER_HH_
#include <cstring>
#include <string> #include <string>
#include <vector> #include <vector>
#include <netcdfcpp.h> #include <netcdf.h>
#include "help.hh" #include "help.hh"
namespace io { namespace io {
...@@ -38,25 +40,31 @@ namespace io { ...@@ -38,25 +40,31 @@ namespace io {
} }
class io::NetCdfWriter { class io::NetCdfWriter {
//private: private:
//! dimensions of the grid in x- and y-direction. //! dimensions of the grid in x- and y-direction.
const int nX, nY; const int nX, nY;
//! current time step of the netCDF-file //! current time step of the netCDF-file
int timeStep; size_t timeStep;
//! file name of the netCDF-file //! file name of the netCDF-file
const std::string fileName; const std::string fileName;
/** netCDF file id*/
int dataFile;
/** Variable ids */
int timeVar, hVar, huVar, hvVar, bVar;
// writer time dependent variables. // writer time dependent variables.
void writeVarTimeDependent( const Float2D &i_matrix, void writeVarTimeDependent( const Float2D &i_matrix,
const int i_boundarySize[4], const int i_boundarySize[4],
NcVar* o_ncVariable); int i_ncVariable);
// writes time independent variables. // writes time independent variables.
void writeVarTimeIndependent( const Float2D &i_matrix, void writeVarTimeIndependent( const Float2D &i_matrix,
const int i_boundarySize[4], const int i_boundarySize[4],
NcVar* o_ncVariable); int i_ncVariable);
public: public:
...@@ -78,9 +86,19 @@ class io::NetCdfWriter { ...@@ -78,9 +86,19 @@ class io::NetCdfWriter {
const int i_boundarySize[4], const int i_boundarySize[4],
const float &i_time); const float &i_time);
// writes the time independent bathymetry (static displacement) to the netCDF-file. /**
* Write (static) bathymetry data to a netCDF-file (-> constructor) with respect to the boundary sizes.
*
* @param i_b bathymetry data.
* @param i_boundarySize size of the boundaries.
*
* @see writeUnknowns
*/
void writeBathymetry( const Float2D &i_b, void writeBathymetry( const Float2D &i_b,
const int i_boundarySize[4] ); const int i_boundarySize[4] )
{
writeVarTimeIndependent(i_b, i_boundarySize, bVar);
}
// writes one dimensional unknowns to the netCDF-file (not used in SWE). // writes one dimensional unknowns to the netCDF-file (not used in SWE).
void writeUnknownsOneDimensional( const std::vector<double> &i_h, void writeUnknownsOneDimensional( const std::vector<double> &i_h,
...@@ -94,6 +112,15 @@ class io::NetCdfWriter { ...@@ -94,6 +112,15 @@ class io::NetCdfWriter {
const int &i_leftBoundarySize, const int &i_leftBoundarySize,
const int &i_rightBoundarySize ); const int &i_rightBoundarySize );
private:
/**
* This is a small wrapper for `nc_put_att_text` which automatically sets the length.
*/
void ncPutAttText(int varid, const char* name, const char *value)
{
nc_put_att_text(dataFile, varid, name, strlen(value), value);
}
}; };
#endif /* NETCDFWRITER_HH_ */ #endif /* NETCDFWRITER_HH_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment