diff options
Diffstat (limited to 'src/utils.cc')
-rw-r--r-- | src/utils.cc | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/utils.cc b/src/utils.cc index 168acc2..7140718 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -2,12 +2,25 @@ #include <string.h> #include <math.h> #include <string> +#include <sys/stat.h> +#include <errno.h> #include <iostream> #include "cctk.h" #include "cctk_Arguments.h" #include "cctk_Parameters.h" +#ifdef HAVE_CAPABILITY_HDF5 +// We currently support the HDF5 1.6 API (and when using 1.8 the +// compatibility mode introduced by H5_USE_16_API). Several machines +// in SimFactory use HDF5 1.6, so we cannot drop support for it. It +// seems it is hard to support both the 1.6 and 1.8 API +// simultaneously; for example H5Fopen takes a different number of +// arguments in the two versions. +#define H5_USE_16_API +#include <hdf5.h> +#endif + #include "utils.hh" #include "integrate.hh" @@ -133,6 +146,113 @@ void Multipole_OutputComplexToFile(CCTK_ARGUMENTS, const string &name, CCTK_REAL } } +//////////////////////////////////////////////////////////////////////// +// HDF5 complex output +//////////////////////////////////////////////////////////////////////// + +#ifdef HAVE_CAPABILITY_HDF5 + +bool dataset_exists(hid_t file, const string &dataset_name) +{ + // To test whether a dataset exists, the recommended way in API 1.6 + // is to use H5Gget_objinfo, but this prints an error to stderr if + // the dataset does not exist. We explicitly avoid this by wrapping + // the call in H5E_BEGIN_TRY/H5E_END_TRY statements. In 1.8, + // H5Gget_objinfo is deprecated, and H5Lexists does the job. See + // http://www.mail-archive.com/hdf-forum@hdfgroup.org/msg00125.html + + #if 1 + bool exists; + H5E_BEGIN_TRY + { + exists = H5Gget_objinfo(file, dataset_name.c_str(), 1, NULL) >= 0; + } + H5E_END_TRY; + return exists; + #else + return H5Lexists(file, dataset_name.c_str(), H5P_DEFAULT); + #endif +} + +void Multipole_OutputComplexToH5File(CCTK_ARGUMENTS, const string &basename, const string &datasetname, + CCTK_REAL redata, CCTK_REAL imdata) +{ + DECLARE_CCTK_ARGUMENTS; + DECLARE_CCTK_PARAMETERS; + + string output_name = out_dir + string("/") + basename; + int status = 0; + static int first_time = true; + + hid_t file = + (first_time && IO_TruncateOutputFiles(cctkGH)) ? + H5Fcreate(output_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT) : + H5Fopen(output_name.c_str(), H5F_ACC_RDWR, H5P_DEFAULT); + + first_time = false; + + hid_t dataset = -1; + + if (dataset_exists(file, datasetname)) + { + dataset = H5Dopen(file, datasetname.c_str()); + } + else + { + hsize_t dims[2] = {0,3}; + hsize_t maxdims[2] = {H5S_UNLIMITED, 3}; + hid_t dataspace = H5Screate_simple(2, dims, maxdims); + + hid_t cparms = -1; + hsize_t chunk_dims[2] = {hdf5_chunk_size,3}; + cparms = H5Pcreate (H5P_DATASET_CREATE); + status = H5Pset_chunk(cparms, 2, chunk_dims); + + dataset = H5Dcreate(file, datasetname.c_str(), H5T_NATIVE_DOUBLE, dataspace, cparms); + H5Pclose(cparms); + } + + hid_t filespace = H5Dget_space (dataset); + hsize_t filedims[2]; + hsize_t maxdims[2]; + status = H5Sget_simple_extent_dims(filespace, filedims, maxdims); + + filedims[0] += 1; + hsize_t size[2] = {filedims[0], filedims[1]}; + status = H5Dextend (dataset, size); + H5Sclose(filespace); + + /* Select a hyperslab */ + hsize_t offset[2] = {filedims[0]-1, 0}; + hsize_t dims2[2] = {1,3}; + filespace = H5Dget_space (dataset); + status = H5Sselect_hyperslab (filespace, H5S_SELECT_SET, offset, NULL, + dims2, NULL); + + CCTK_REAL data[] = {cctk_time, redata, imdata}; + + hid_t memdataspace = H5Screate_simple(2, dims2, NULL); + + /* Write the data to the hyperslab */ + status = H5Dwrite (dataset, H5T_NATIVE_DOUBLE, memdataspace, filespace, + H5P_DEFAULT, data); + + H5Dclose(dataset); + H5Sclose(filespace); + H5Sclose(memdataspace); + + status = H5Fclose(file); +} + +#else + +void Multipole_OutputComplexToH5File(CCTK_ARGUMENTS, const string &basename, const string &datasetname, + CCTK_REAL redata, CCTK_REAL imdata) +{ + CCTK_WARN(0,"HDF5 output has been requested but Cactus has been compiled without HDF5 support"); +} + +#endif //////////////////////////////////////////////////////////////////////// // Coordinates |