/** * Create a netCdf-file * Any existing file will be replaced. * * @param i_baseName base name of the netCDF-file to which the data will be written to. * @param i_nX number of cells in the horizontal direction. * @param i_nY number of cells in the vertical direction. * @param i_dX cell size in x-direction. * @param i_dY cell size in y-direction. * @param i_originX * @param i_originY */ io::NetCdfWriter::NetCdfWriter( const std::string &i_baseName, const Float2D &i_b, int i_nX, int i_nY, float i_dX, float i_dY, float i_originX, float i_originY) : io::Writer(i_baseName + ".nc", i_b,{{1, 1, 1, 1}}, i_nX, i_nY), flush(0) { int status; status = nc_create(fileName.c_str(), NC_NETCDF4, &dataFile); //check if the netCDF-file open command succeeded. if (status != NC_NOERR) { assert(false); return; } //dimensions int l_timeDim, l_xDim, l_yDim; nc_def_dim(dataFile, "time", NC_UNLIMITED, &l_timeDim); nc_def_dim(dataFile, "x", nX, &l_xDim); nc_def_dim(dataFile, "y", nY, &l_yDim); //variables (TODO: add rest of CF-1.5) int l_xVar, l_yVar; nc_def_var(dataFile, "time", NC_FLOAT, 1, &l_timeDim, &timeVar); ncPutAttText(timeVar, "long_name", "Time"); ncPutAttText(timeVar, "units", "seconds since simulation start"); // the word "since" is important for the paraview reader 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 int dims[] = {l_timeDim, l_yDim, l_xDim}; nc_def_var(dataFile, "b", NC_FLOAT, 3, dims, &bVar); //set attributes to match CF-1.5 convention ncPutAttText(NC_GLOBAL, "Conventions", "CF-1.5"); ncPutAttText(NC_GLOBAL, "title", "Computed tsunami solution"); ncPutAttText(NC_GLOBAL, "history", "SWE"); ncPutAttText(NC_GLOBAL, "institution", "Technische Universitaet Muenchen, Department of Informatics, Chair of Scientific Computing"); 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; for(size_t i = 0; i < nX; i++) { nc_put_var1_float(dataFile, l_xVar, &i, &gridPosition); gridPosition += i_dX; } gridPosition = i_originY + (float).5 * i_dY; for(size_t j = 0; j < nY; j++) { nc_put_var1_float(dataFile, l_yVar, &j, &gridPosition); gridPosition += i_dY; } nc_sync(dataFile); }
/** * Encodes a BoundaryType and writes it to an attribute in the NetCDF-File * * @param varid The NetCDF variable ID * @param name The attribute name * @param boundaryType The type of the boundary */ void io::NetCdfWriter::ncPutBoundaryTypeAtt(int varid, const char *name, BoundaryType boundaryType) { std::string boundaryTypeName; switch(boundaryType) { case WALL: boundaryTypeName = std::string("wall"); break; case OUTFLOW: boundaryTypeName = std::string("outflow"); break; case INFLOW: boundaryTypeName = std::string("inflow"); break; case PASSIVE: boundaryTypeName = std::string("passive"); break; case CONNECT: boundaryTypeName = std::string("connect"); break; default: std::cerr << "WARNING: Unsupported BoundaryType in Checkpointing!" << std::endl; assert(false); return; break; } ncPutAttText(varid, name, boundaryTypeName.c_str()); }
/** * Create a netCdf-file * Any existing file will be replaced. * * @param i_baseName base name of the netCDF-file to which the data will be written to. * @param i_nX number of cells in the horizontal direction. * @param i_nY number of cells in the vertical direction. * @param i_dX cell size in x-direction. * @param i_dY cell size in y-direction. * @param i_originX * @param i_originY * @param i_flush If > 0, flush data to disk every i_flush write operation * @param i_dynamicBathymetry */ io::NetCdfWriter::NetCdfWriter( const std::string &i_baseName, const Float2D &i_b, const BoundarySize &i_boundarySize, int i_nX, int i_nY, float i_dX, float i_dY, float i_originX, float i_originY, unsigned int i_flush, size_t contTimestep, unsigned int compression) : //const bool &i_dynamicBathymetry) : //!TODO io::Writer(i_baseName + ".nc", i_b, i_boundarySize, i_nX, i_nY, contTimestep), flush(i_flush), compress(compression) { int status; if(contTimestep) { status = nc_open(fileName.c_str(), NC_WRITE, &dataFile); //check if the netCDF-file open command succeeded. if (status != NC_NOERR) { assert(false); return; } size_t l_length; if(status = nc_inq_varid(dataFile, "time", &timeVar)) ERR(status); if(status = nc_inq_varid(dataFile, "h", &hVar)) ERR(status); if(status = nc_inq_varid(dataFile, "hu", &huVar)) ERR(status); if(status = nc_inq_varid(dataFile, "hv", &hvVar)) ERR(status); if(status = nc_inq_varid(dataFile, "b", &bVar)) ERR(status); //if(status = nc_inq_dimlen(dataFile, timeVar, &timeStep)) ERR(status); } else { //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. if (status != NC_NOERR) { assert(false); return; } // std::cout << "i_nX, i_nY, i_dX, i_dY: " << nX << ", " << nY << ", " << i_dX << ", " << i_dY << std::endl; adjust(nX, nY, i_dX, i_dY, compress); // std::cout << "i_nX, i_nY, i_dX, i_dY: " << nX << ", " << nY << ", " << i_dX << ", " << i_dY << std::endl; #ifdef PRINT_NETCDFWRITER_INFORMATION std::cout << " *** io::NetCdfWriter::createNetCdfFile" << std::endl; std::cout << " created/replaced: " << fileName << 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 << " origin(x,y): " << i_originX << ", " << i_originY << std::endl; #endif //dimensions int l_timeDim, l_xDim, l_yDim; nc_def_dim(dataFile, "time", NC_UNLIMITED, &l_timeDim); nc_def_dim(dataFile, "x", nX, &l_xDim); nc_def_dim(dataFile, "y", nY, &l_yDim); //variables (TODO: add rest of CF-1.5) int l_xVar, l_yVar; nc_def_var(dataFile, "time", NC_FLOAT, 1, &l_timeDim, &timeVar); ncPutAttText(timeVar, "long_name", "Time"); ncPutAttText(timeVar, "units", "seconds since simulation start"); // the word "since" is important for the paraview reader 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 int dims[] = {l_timeDim, l_yDim, l_xDim}; nc_def_var(dataFile, "h", NC_FLOAT, 3, dims, &hVar); nc_def_var(dataFile, "hu", NC_FLOAT, 3, dims, &huVar); nc_def_var(dataFile, "hv", NC_FLOAT, 3, dims, &hvVar); nc_def_var(dataFile, "b", NC_FLOAT, 3, dims, &bVar); //set attributes to match CF-1.5 convention ncPutAttText(NC_GLOBAL, "Conventions", "CF-1.5"); ncPutAttText(NC_GLOBAL, "title", "Computed tsunami solution"); ncPutAttText(NC_GLOBAL, "history", "SWE"); ncPutAttText(NC_GLOBAL, "institution", "Technische Universitaet Muenchen, Department of Informatics, Chair of Scientific Computing"); 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; for(size_t i = 0; i < nX; i++) { nc_put_var1_float(dataFile, l_xVar, &i, &gridPosition); gridPosition += i_dX; } gridPosition = i_originY + (float).5 * i_dY; for(size_t j = 0; j < nY; j++) { nc_put_var1_float(dataFile, l_yVar, &j, &gridPosition); gridPosition += i_dY; } nc_sync(dataFile); } }
/** * Create or open an existing netCdf-file * * If i_baseName appended with the ".nc" extension represents an existing * NetCDF file, the file is opened and it is tried to append to the * file (e.g. open a checkpoint-file of a previously crashed run) * * @param i_baseName base name of the netCDF-file to which the data will be written to. * @param i_nX number of cells in the horizontal direction. * @param i_nY number of cells in the vertical direction. * @param i_dX cell size in x-direction. * @param i_dY cell size in y-direction. * @param i_originX * @param i_originY * @param i_coarseness The coarseness factor * @param i_flush If > 0, flush data to disk every i_flush write operation * @param i_dynamicBathymetry */ io::NetCdfWriter::NetCdfWriter( const std::string &i_baseName, const Float2D &i_b, const BoundarySize &i_boundarySize, int i_nX, int i_nY, float i_dX, float i_dY, float i_originX, float i_originY, float i_coarseness, unsigned int i_flush) : //const bool &i_dynamicBathymetry) : //!TODO io::Writer(i_baseName + ".nc", i_b, i_boundarySize, i_nX, i_nY, i_coarseness), flush(i_flush) { int status; // variables (TODO: add rest of CF-1.5) int l_xVar, l_yVar; // dimensions int l_timeDim, l_xDim, l_yDim; // Try to open the file (to see if it is an existing checkpoint file) status = nc_open(fileName.c_str(), NC_WRITE, &dataFile); if(status == NC_NOERR) { // File exists and is a NetCDF file we can write to // Read ID for time, x, y, h, hu, hv and b dimensions and variables status = nc_inq_unlimdim(dataFile, &l_timeDim); status = nc_inq_dimid(dataFile, "x", &l_xDim); status = nc_inq_dimid(dataFile, "y", &l_yDim); status = nc_inq_varid(dataFile, "time", &timeVar); status = nc_inq_varid(dataFile, "x", &l_xVar); status = nc_inq_varid(dataFile, "y", &l_yVar); status = nc_inq_varid(dataFile, "h", &hVar); status = nc_inq_varid(dataFile, "hu", &huVar); status = nc_inq_varid(dataFile, "hv", &hvVar); status = nc_inq_varid(dataFile, "b", &bVar); // Read Dimensions for x and y variable size_t l_xLen, l_yLen; status = nc_inq_dimlen(dataFile, l_xDim, &l_xLen); status = nc_inq_dimlen(dataFile, l_yDim, &l_yLen); // Set next timeStep status = nc_inq_dimlen(dataFile, l_timeDim, &timeStep); // Check actual dimensions in file against supplied dimensions assert(l_xLen == coarseX); assert(l_yLen == coarseY); } else { // File does not exist or is not a valid NetCDF file //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. if (status != NC_NOERR) { assert(false); return; } #ifdef PRINT_NETCDFWRITER_INFORMATION std::cout << " *** io::NetCdfWriter::createNetCdfFile" << std::endl; std::cout << " created/replaced: " << fileName << std::endl; std::cout << " internal dimensions(nx, ny): " << nX << ", " << nY << std::endl; std::cout << " dimensions(nx, ny): " << coarseX << ", " << coarseY << std::endl; std::cout << " coarseness: " << coarseness << 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; #endif nc_def_dim(dataFile, "time", NC_UNLIMITED, &l_timeDim); nc_def_dim(dataFile, "x", coarseX, &l_xDim); nc_def_dim(dataFile, "y", coarseY, &l_yDim); nc_def_var(dataFile, "time", NC_FLOAT, 1, &l_timeDim, &timeVar); ncPutAttText(timeVar, "long_name", "Time"); ncPutAttText(timeVar, "units", "seconds since simulation start"); // the word "since" is important for the paraview reader 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 int dims[] = {l_timeDim, l_yDim, l_xDim}; nc_def_var(dataFile, "h", NC_FLOAT, 3, dims, &hVar); nc_def_var(dataFile, "hu", NC_FLOAT, 3, dims, &huVar); nc_def_var(dataFile, "hv", NC_FLOAT, 3, dims, &hvVar); nc_def_var(dataFile, "b", NC_FLOAT, 2, &dims[1], &bVar); //set attributes to match CF-1.5 convention ncPutAttText(NC_GLOBAL, "Conventions", "CF-1.5"); ncPutAttText(NC_GLOBAL, "title", "Computed tsunami solution"); ncPutAttText(NC_GLOBAL, "history", "SWE"); ncPutAttText(NC_GLOBAL, "institution", "Technische Universitaet Muenchen, Department of Informatics, Chair of Scientific Computing"); 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; for(size_t i = 0; i < coarseX; i++) { nc_put_var1_float(dataFile, l_xVar, &i, &gridPosition); gridPosition += i_dX; } gridPosition = i_originY + (float).5 * i_dY; for(size_t j = 0; j < coarseY; j++) { nc_put_var1_float(dataFile, l_yVar, &j, &gridPosition); gridPosition += i_dY; } } }