00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "AbstractHdf5Converter.hpp"
00037 #include "Version.hpp"
00038
00039
00040
00041
00042
00043 herr_t op_func (hid_t loc_id,
00044 const char *name,
00045 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >=8
00046 const H5L_info_t *info,
00047 #endif
00048 void *operator_data);
00049
00050
00051 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00052 AbstractHdf5Converter<ELEMENT_DIM, SPACE_DIM>::AbstractHdf5Converter(const FileFinder& rInputDirectory,
00053 const std::string& rFileBaseName,
00054 AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>* pMesh,
00055 const std::string& rSubdirectoryName,
00056 unsigned precision)
00057 : mrH5Folder(rInputDirectory),
00058 mFileBaseName(rFileBaseName),
00059 mOpenDatasetIndex(UNSIGNED_UNSET),
00060 mpMesh(pMesh),
00061 mRelativeSubdirectory(rSubdirectoryName),
00062 mPrecision(precision)
00063 {
00064 GenerateListOfDatasets(mrH5Folder, mFileBaseName);
00065
00066
00067 FileFinder sub_directory(mRelativeSubdirectory, mrH5Folder);
00068 mpOutputFileHandler = new OutputFileHandler(sub_directory, false);
00069
00070 MoveOntoNextDataset();
00071 }
00072
00073 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00074 void AbstractHdf5Converter<ELEMENT_DIM, SPACE_DIM>::WriteInfoFile()
00075 {
00076
00077 if (PetscTools::AmMaster())
00078 {
00079 std::string time_info_filename;
00080
00081
00082
00083 if (mDatasetNames[mOpenDatasetIndex]=="Data")
00084 {
00085 time_info_filename = mFileBaseName + "_times.info";
00086 }
00087 else
00088 {
00089 time_info_filename = mDatasetNames[mOpenDatasetIndex] + "_times.info";
00090 }
00091 out_stream p_file = mpOutputFileHandler->OpenOutputFile(time_info_filename);
00092
00093 std::vector<double> time_values = mpReader->GetUnlimitedDimensionValues();
00094 unsigned num_timesteps = time_values.size();
00095 double first_timestep = time_values.front();
00096 double last_timestep = time_values.back();
00097
00098 double timestep = num_timesteps > 1 ? time_values[1] - time_values[0] : DOUBLE_UNSET;
00099
00100 *p_file << "Number of timesteps " << num_timesteps << std::endl;
00101 *p_file << "timestep " << timestep << std::endl;
00102 *p_file << "First timestep " << first_timestep << std::endl;
00103 *p_file << "Last timestep " << last_timestep << std::endl;
00104 *p_file << ChasteBuildInfo::GetProvenanceString();
00105
00106 p_file->close();
00107 }
00108 }
00109
00110 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00111 AbstractHdf5Converter<ELEMENT_DIM,SPACE_DIM>::~AbstractHdf5Converter()
00112 {
00113 delete mpOutputFileHandler;
00114 }
00115
00116 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00117 std::string AbstractHdf5Converter<ELEMENT_DIM,SPACE_DIM>::GetSubdirectory()
00118 {
00119 return mRelativeSubdirectory;
00120 }
00121
00122 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00123 bool AbstractHdf5Converter<ELEMENT_DIM,SPACE_DIM>::MoveOntoNextDataset()
00124 {
00125
00126 if (mDatasetNames.size() == mOpenDatasetIndex+1u)
00127 {
00128 return false;
00129 }
00130
00131
00132 if (mOpenDatasetIndex==UNSIGNED_UNSET)
00133 {
00134 mOpenDatasetIndex = 0u;
00135 }
00136 else
00137 {
00138 mOpenDatasetIndex++;
00139 }
00140
00141
00142 mpReader.reset(new Hdf5DataReader(mrH5Folder, mFileBaseName, mDatasetNames[mOpenDatasetIndex]));
00143
00144
00145 std::vector<std::string> variable_names = mpReader->GetVariableNames();
00146 mNumVariables = variable_names.size();
00147
00148 if (mpReader->GetNumberOfRows() != mpMesh->GetNumNodes())
00149 {
00150 delete mpOutputFileHandler;
00151 EXCEPTION("Mesh and HDF5 file have a different number of nodes");
00152 }
00153 WriteInfoFile();
00154
00155 return true;
00156 }
00157
00158 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00159 void AbstractHdf5Converter<ELEMENT_DIM,SPACE_DIM>::GenerateListOfDatasets(const FileFinder& rH5Folder,
00160 const std::string& rFileName)
00161 {
00162
00163
00164
00165 std::string file_name = rH5Folder.GetAbsolutePath() + rFileName + ".h5";
00166 hid_t file = H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
00167
00168
00169
00170
00171 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >=8
00172
00173 H5Literate(file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, op_func, &mDatasetNames);
00174 #else
00175
00176 H5Giterate(file, "/", NULL, op_func, &mDatasetNames);
00177 #endif
00178
00179 H5Fclose(file);
00180
00181
00182 std::string ending = "_Unlimited";
00183
00184
00185 std::vector<std::string>::iterator iter;
00186 for (iter = mDatasetNames.begin(); iter != mDatasetNames.end(); )
00187 {
00188
00189
00190
00191
00192 if ( (*(iter) == "Time") ||
00193 ( ( iter->length() > ending.length() ) &&
00194 ( 0 == iter->compare(iter->length() - ending.length(), ending.length(), ending) ) ) )
00195 {
00196 iter = mDatasetNames.erase(iter);
00197 }
00198 else
00199 {
00200 ++iter;
00201 }
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 herr_t op_func (hid_t loc_id, const char *name,
00215 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >=8
00216 const H5L_info_t *info,
00217 #endif
00218 void *operator_data)
00219 {
00220 std::vector<std::string>* p_dataset_names = static_cast<std::vector< std::string > * >(operator_data);
00221
00222
00223
00224
00225
00226
00227 #if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >=8
00228 H5O_info_t infobuf;
00229 H5Oget_info_by_name (loc_id, name, &infobuf, H5P_DEFAULT);
00230 switch (infobuf.type)
00231 {
00232
00233
00234
00235 case H5O_TYPE_DATASET:
00236 p_dataset_names->push_back(name);
00237 break;
00238
00239
00240
00241 #else // HDF5 1.6.x
00242 H5G_stat_t statbuf;
00243 H5Gget_objinfo (loc_id, name, 0, &statbuf);
00244 switch (statbuf.type)
00245 {
00246
00247
00248
00249 case H5G_DATASET:
00250
00251 p_dataset_names->push_back(name);
00252 break;
00253
00254
00255
00256 #endif
00257 default:
00258 NEVER_REACHED;
00259
00260
00261
00262 }
00263 return 0;
00264 }
00265
00266
00268
00270
00271 template class AbstractHdf5Converter<1,1>;
00272 template class AbstractHdf5Converter<1,2>;
00273 template class AbstractHdf5Converter<2,2>;
00274 template class AbstractHdf5Converter<1,3>;
00275 template class AbstractHdf5Converter<2,3>;
00276 template class AbstractHdf5Converter<3,3>;