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 #include "Hdf5DataWriter.hpp"
00034
00035 #include "Exception.hpp"
00036 #include "OutputFileHandler.hpp"
00037 #include "PetscTools.hpp"
00038 #include "Version.hpp"
00039
00040 Hdf5DataWriter::Hdf5DataWriter(DistributedVectorFactory& rVectorFactory,
00041 const std::string& rDirectory,
00042 const std::string& rBaseName,
00043 bool cleanDirectory,
00044 bool extendData)
00045 : mrVectorFactory(rVectorFactory),
00046 mDirectory(rDirectory),
00047 mBaseName(rBaseName),
00048 mCleanDirectory(cleanDirectory),
00049 mIsInDefineMode(true),
00050 mIsFixedDimensionSet(false),
00051 mIsUnlimitedDimensionSet(false),
00052 mFileFixedDimensionSize(0u),
00053 mDataFixedDimensionSize(0u),
00054 mLo(mrVectorFactory.GetLow()),
00055 mHi(mrVectorFactory.GetHigh()),
00056 mNumberOwned(0u),
00057 mOffset(0u),
00058 mIsDataComplete(true),
00059 mNeedExtend(false),
00060 mCurrentTimeStep(0)
00061 {
00062 if (extendData && cleanDirectory)
00063 {
00064 EXCEPTION("You are asking to delete a file and then extend it, change arguments to constructor.");
00065 }
00066
00067 if (extendData)
00068 {
00069
00070 OutputFileHandler output_file_handler(mDirectory, false);
00071 std::string results_dir = output_file_handler.GetOutputDirectoryFullPath();
00072 std::string file_name = results_dir + mBaseName + ".h5";
00073
00074
00075 hid_t property_list_id = H5Pcreate(H5P_FILE_ACCESS);
00076 H5Pset_fapl_mpio(property_list_id, PETSC_COMM_WORLD, MPI_INFO_NULL);
00077
00078
00079 mFileId = H5Fopen(file_name.c_str(), H5F_ACC_RDWR, property_list_id);
00080 H5Pclose(property_list_id);
00081
00082 if (mFileId < 0)
00083 {
00084 mDatasetId = 0;
00085 EXCEPTION("Hdf5DataWriter could not open " + file_name);
00086 }
00087
00088
00089 mDatasetId = H5Dopen(mFileId, "Data");
00090 hid_t variables_dataspace = H5Dget_space(mDatasetId);
00091
00092 hsize_t dataset_max_sizes[DATASET_DIMS];
00093 H5Sget_simple_extent_dims(variables_dataspace, mDatasetDims, dataset_max_sizes);
00094 H5Sclose(variables_dataspace);
00095
00096 if (dataset_max_sizes[0] != H5S_UNLIMITED)
00097 {
00098 H5Dclose(mDatasetId);
00099 H5Fclose(mFileId);
00100 EXCEPTION("Tried to open a datafile for extending which doesn't have an unlimited dimension.");
00101 }
00102 mIsUnlimitedDimensionSet = true;
00103
00104 for (unsigned i=1; i<DATASET_DIMS; i++)
00105 {
00106 assert(mDatasetDims[i] == dataset_max_sizes[i]);
00107 }
00108 mFileFixedDimensionSize = mDatasetDims[1];
00109 mIsFixedDimensionSet = true;
00110 mVariables.reserve(mDatasetDims[2]);
00111
00112
00113 hid_t attribute_id = H5Aopen_name(mDatasetId, "Variable Details");
00114 hid_t attribute_type = H5Aget_type(attribute_id);
00115 hid_t attribute_space = H5Aget_space(attribute_id);
00116 hsize_t attr_dataspace_dim;
00117 H5Sget_simple_extent_dims(attribute_space, &attr_dataspace_dim, NULL);
00118 unsigned num_columns = H5Sget_simple_extent_npoints(attribute_space);
00119 assert(num_columns == mDatasetDims[2]);
00120
00121 char* string_array = (char *)malloc(sizeof(char)*MAX_STRING_SIZE*(int)num_columns);
00122 H5Aread(attribute_id, attribute_type, string_array);
00123
00124 for (unsigned index=0; index<num_columns; index++)
00125 {
00126
00127 std::string column_name_unit(&string_array[MAX_STRING_SIZE*index]);
00128
00129 size_t name_length = column_name_unit.find('(');
00130 size_t unit_length = column_name_unit.find(')') - name_length - 1;
00131
00132 DataWriterVariable var;
00133 var.mVariableName = column_name_unit.substr(0, name_length);
00134 var.mVariableUnits = column_name_unit.substr(name_length+1, unit_length);
00135 mVariables.push_back(var);
00136 }
00137
00138 free(string_array);
00139 H5Tclose(attribute_type);
00140 H5Sclose(attribute_space);
00141 H5Aclose(attribute_id);
00142
00143
00144 mUnlimitedDimensionName = "Time";
00145 mTimeDatasetId = H5Dopen(mFileId, mUnlimitedDimensionName.c_str());
00146 mUnlimitedDimensionUnit = "ms";
00147
00148 hid_t timestep_dataspace = H5Dget_space(mTimeDatasetId);
00149 hsize_t num_timesteps;
00150 H5Sget_simple_extent_dims(timestep_dataspace, &num_timesteps, NULL);
00151 H5Sclose(timestep_dataspace);
00152 mCurrentTimeStep = (long)num_timesteps - 1;
00153
00154
00155 attribute_id = H5Aopen_name(mDatasetId, "IsDataComplete");
00156 if (attribute_id < 0)
00157 {
00158 #define COVERAGE_IGNORE
00159
00160 EXCEPTION("Extending old-format files isn't supported.");
00161 #undef COVERAGE_IGNORE
00162 }
00163 else
00164 {
00165 attribute_type = H5Aget_type(attribute_id);
00166 attribute_space = H5Aget_space(attribute_id);
00167 unsigned is_data_complete;
00168 H5Aread(attribute_id, H5T_NATIVE_UINT, &is_data_complete);
00169 mIsDataComplete = (is_data_complete == 1) ? true : false;
00170 H5Tclose(attribute_type);
00171 H5Sclose(attribute_space);
00172 H5Aclose(attribute_id);
00173 }
00174 if (mIsDataComplete)
00175 {
00176 mNumberOwned = mrVectorFactory.GetLocalOwnership();
00177 mOffset = mLo;
00178 mDataFixedDimensionSize = mFileFixedDimensionSize;
00179 }
00180 else
00181 {
00182
00183 attribute_id = H5Aopen_name(mDatasetId, "NodeMap");
00184 attribute_type = H5Aget_type(attribute_id);
00185 attribute_space = H5Aget_space(attribute_id);
00186
00187 unsigned num_node_indices = H5Sget_simple_extent_npoints(attribute_space);
00188
00189 mIncompleteNodeIndices.clear();
00190 mIncompleteNodeIndices.resize(num_node_indices);
00191 H5Aread(attribute_id, H5T_NATIVE_UINT, &mIncompleteNodeIndices[0]);
00192
00193 H5Tclose(attribute_type);
00194 H5Sclose(attribute_space);
00195 H5Aclose(attribute_id);
00196
00197 mNumberOwned = mrVectorFactory.GetLocalOwnership();
00198 ComputeIncompleteOffset();
00202 mDataFixedDimensionSize = UINT_MAX;
00203 H5Dclose(mDatasetId);
00204 H5Dclose(mTimeDatasetId);
00205 H5Fclose(mFileId);
00206 EXCEPTION("Unable to extend an incomplete data file at present.");
00207 }
00208
00209
00210 mIsInDefineMode = false;
00211 AdvanceAlongUnlimitedDimension();
00212 }
00213 }
00214
00215 Hdf5DataWriter::~Hdf5DataWriter()
00216 {
00217 Close();
00218 }
00219
00220 void Hdf5DataWriter::DefineFixedDimension(long dimensionSize)
00221 {
00222 if (!mIsInDefineMode)
00223 {
00224 EXCEPTION("Cannot define variables when not in Define mode");
00225 }
00226 if (dimensionSize < 1)
00227 {
00228 EXCEPTION("Fixed dimension must be at least 1 long");
00229 }
00230 if (mIsFixedDimensionSet)
00231 {
00232 EXCEPTION("Fixed dimension already set");
00233 }
00234
00235
00236 mLo = mrVectorFactory.GetLow();
00237 mHi = mrVectorFactory.GetHigh();
00238 mNumberOwned = mrVectorFactory.GetLocalOwnership();
00239 mOffset = mLo;
00240 mFileFixedDimensionSize = dimensionSize;
00241 mDataFixedDimensionSize = dimensionSize;
00242 mIsFixedDimensionSet = true;
00243 }
00244
00245 void Hdf5DataWriter::DefineFixedDimension(const std::vector<unsigned>& rNodesToOuput, long vecSize)
00246 {
00247 unsigned vector_size = rNodesToOuput.size();
00248
00249 for (unsigned index=0; index < vector_size-1; index++)
00250 {
00251 if (rNodesToOuput[index] >= rNodesToOuput[index+1])
00252 {
00253 EXCEPTION("Input should be monotonic increasing");
00254 }
00255 }
00256
00257 if ((int) rNodesToOuput.back() >= vecSize)
00258 {
00259 EXCEPTION("Vector size doesn't match nodes to output");
00260 }
00261
00262 DefineFixedDimension(vecSize);
00263
00264 mFileFixedDimensionSize = vector_size;
00265 mIsDataComplete = false;
00266 mIncompleteNodeIndices = rNodesToOuput;
00267 ComputeIncompleteOffset();
00268 }
00269
00270 void Hdf5DataWriter::ComputeIncompleteOffset()
00271 {
00272 mOffset = 0;
00273 mNumberOwned = 0;
00274 for (unsigned i=0; i<mIncompleteNodeIndices.size(); i++)
00275 {
00276 if (mIncompleteNodeIndices[i] < mLo)
00277 {
00278 mOffset++;
00279 }
00280 else if (mIncompleteNodeIndices[i] < mHi)
00281 {
00282 mNumberOwned++;
00283 }
00284 }
00285 }
00286
00287 int Hdf5DataWriter::DefineVariable(const std::string& rVariableName,
00288 const std::string& rVariableUnits)
00289 {
00290 if (!mIsInDefineMode)
00291 {
00292 EXCEPTION("Cannot define variables when not in Define mode");
00293 }
00294
00295 CheckVariableName(rVariableName);
00296 CheckUnitsName(rVariableUnits);
00297
00298
00299 for (unsigned index=0; index<mVariables.size(); index++)
00300 {
00301 if (mVariables[index].mVariableName == rVariableName)
00302 {
00303 EXCEPTION("Variable name already exists");
00304 }
00305 }
00306
00307 DataWriterVariable new_variable;
00308 new_variable.mVariableName = rVariableName;
00309 new_variable.mVariableUnits = rVariableUnits;
00310 int variable_id;
00311
00312
00313 mVariables.push_back(new_variable);
00314
00315
00316
00317 variable_id = mVariables.size() - 1;
00318
00319 return variable_id;
00320 }
00321
00322 void Hdf5DataWriter::CheckVariableName(const std::string& rName)
00323 {
00324 if (rName.length() == 0)
00325 {
00326 EXCEPTION("Variable name not allowed: may not be blank.");
00327 }
00328 CheckUnitsName(rName);
00329 }
00330
00331 void Hdf5DataWriter::CheckUnitsName(const std::string& rName)
00332 {
00333 for (unsigned i=0; i<rName.length(); i++)
00334 {
00335 if (!isalnum(rName[i]) && !(rName[i]=='_'))
00336 {
00337 std::string error = "Variable name/units '" + rName + "' not allowed: may only contain alphanumeric characters or '_'.";
00338 EXCEPTION(error);
00339 }
00340 }
00341 }
00342
00343 void Hdf5DataWriter::EndDefineMode()
00344 {
00345
00346 if (mVariables.size() < 1)
00347 {
00348 EXCEPTION("Cannot end define mode. No variables have been defined.");
00349 }
00350
00351
00352 if (mIsFixedDimensionSet == false)
00353 {
00354 EXCEPTION("Cannot end define mode. One fixed dimension should be defined.");
00355 }
00356
00357 OutputFileHandler output_file_handler(mDirectory, mCleanDirectory);
00358 std::string results_dir = output_file_handler.GetOutputDirectoryFullPath();
00359 std::string file_name = results_dir + mBaseName + ".h5";
00360
00361
00362 hid_t property_list_id = H5Pcreate(H5P_FILE_ACCESS);
00363 H5Pset_fapl_mpio(property_list_id, PETSC_COMM_WORLD, MPI_INFO_NULL);
00364
00365
00366 mFileId = H5Fcreate(file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, property_list_id);
00367 H5Pclose(property_list_id);
00368 if (mFileId < 0)
00369 {
00370 EXCEPTION("Hdf5DataWriter could not create " + file_name);
00371 }
00372 mIsInDefineMode = false;
00373
00374
00375
00376
00377
00378 mDatasetDims[0] = 1;
00379 mDatasetDims[1] = mFileFixedDimensionSize;
00380 mDatasetDims[2] = mVariables.size();
00381
00382 hsize_t* max_dims = NULL;
00383 hsize_t dataset_max_dims[DATASET_DIMS];
00384
00385 hid_t cparms = H5P_DEFAULT;
00386
00387 if (mIsUnlimitedDimensionSet)
00388 {
00389 dataset_max_dims[0] = H5S_UNLIMITED;
00390 dataset_max_dims[1] = mDatasetDims[1];
00391 dataset_max_dims[2] = mDatasetDims[2];
00392 max_dims = dataset_max_dims;
00393
00394
00395 hsize_t chunk_dims[DATASET_DIMS] ={1, mDatasetDims[1], mDatasetDims[2]};
00396 cparms = H5Pcreate (H5P_DATASET_CREATE);
00397 H5Pset_chunk( cparms, DATASET_DIMS, chunk_dims);
00398 }
00399
00400 hid_t filespace = H5Screate_simple(DATASET_DIMS, mDatasetDims, max_dims);
00401
00402
00403 mDatasetId = H5Dcreate(mFileId, "Data", H5T_NATIVE_DOUBLE, filespace, cparms);
00404 H5Sclose(filespace);
00405
00406
00407 const unsigned MAX_STRING_SIZE = 100;
00408 hsize_t columns[1] = {mVariables.size()};
00409 hid_t colspace = H5Screate_simple(1, columns, NULL);
00410
00411
00412 char* col_data = (char*) malloc(mVariables.size() * sizeof(char) * MAX_STRING_SIZE);
00413
00414 char* col_data_offset = col_data;
00415 for (unsigned var=0; var<mVariables.size(); var++)
00416 {
00417 std::string full_name = mVariables[var].mVariableName + "(" + mVariables[var].mVariableUnits + ")";
00418 strcpy (col_data_offset, full_name.c_str());
00419 col_data_offset += sizeof(char) * MAX_STRING_SIZE;
00420 }
00421
00422
00423 hid_t string_type = H5Tcopy(H5T_C_S1);
00424 H5Tset_size(string_type, MAX_STRING_SIZE );
00425 hid_t attr = H5Acreate(mDatasetId, "Variable Details", string_type, colspace, H5P_DEFAULT);
00426
00427
00428 H5Awrite(attr, string_type, col_data);
00429
00430
00431 free(col_data);
00432 H5Sclose(colspace);
00433 H5Aclose(attr);
00434
00435
00436 columns[0] = 1;
00437 colspace = H5Screate_simple(1, columns, NULL);
00438 attr = H5Acreate(mDatasetId, "IsDataComplete", H5T_NATIVE_UINT, colspace, H5P_DEFAULT);
00439
00440
00441 unsigned is_data_complete = mIsDataComplete ? 1 : 0;
00442 H5Awrite(attr, H5T_NATIVE_UINT, &is_data_complete);
00443
00444 H5Sclose(colspace);
00445 H5Aclose(attr);
00446
00447 if (!mIsDataComplete)
00448 {
00449
00450
00451 columns[0] = mFileFixedDimensionSize;
00452 colspace = H5Screate_simple(1, columns, NULL);
00453 attr = H5Acreate(mDatasetId, "NodeMap", H5T_NATIVE_UINT, colspace, H5P_DEFAULT);
00454
00455
00456 H5Awrite(attr, H5T_NATIVE_UINT, &mIncompleteNodeIndices[0]);
00457
00458 H5Sclose(colspace);
00459 H5Aclose(attr);
00460 }
00461
00462
00463
00464
00465 if (mIsUnlimitedDimensionSet)
00466 {
00467 hsize_t time_dataset_dims[1] = {1};
00468 hsize_t time_dataset_max_dims[1] = {H5S_UNLIMITED};
00469
00470
00471 hsize_t time_chunk_dims[1] ={1};
00472 hid_t time_cparms = H5Pcreate (H5P_DATASET_CREATE);
00473 H5Pset_chunk( time_cparms, 1, time_chunk_dims);
00474
00475 hid_t time_filespace = H5Screate_simple(1, time_dataset_dims, time_dataset_max_dims);
00476
00477
00478 mTimeDatasetId = H5Dcreate(mFileId, mUnlimitedDimensionName.c_str(), H5T_NATIVE_DOUBLE, time_filespace, time_cparms);
00479
00480
00481 hsize_t one = 1;
00482 hid_t one_column_space = H5Screate_simple(1, &one, NULL);
00483
00484
00485 hid_t unit_attr = H5Acreate(mTimeDatasetId, "Unit", string_type, one_column_space, H5P_DEFAULT);
00486
00487
00488 char unit_string[MAX_STRING_SIZE];
00489 strcpy(unit_string, mUnlimitedDimensionUnit.c_str());
00490 H5Awrite(unit_attr, string_type, unit_string);
00491
00492
00493 H5Sclose(one_column_space);
00494 H5Aclose(unit_attr);
00495 H5Sclose(time_filespace);
00496 }
00497
00498
00499
00500
00501
00502 const unsigned MAX_PROVENANCE_STRING_SIZE = 365;
00503 hid_t long_string_type = H5Tcopy(H5T_C_S1);
00504 H5Tset_size(long_string_type, MAX_PROVENANCE_STRING_SIZE );
00505 hsize_t prov_columns[1] = {1};
00506 hid_t provenance_space = H5Screate_simple(1, prov_columns, NULL);
00507 char* provenance_data = (char*) malloc(sizeof(char) * MAX_PROVENANCE_STRING_SIZE);
00508 assert( ChasteBuildInfo::GetProvenanceString().length() < MAX_PROVENANCE_STRING_SIZE);
00509
00510 strcpy(provenance_data, ChasteBuildInfo::GetProvenanceString().c_str());
00511 hid_t prov_attr = H5Acreate(mDatasetId, "Chaste Provenance", long_string_type, provenance_space, H5P_DEFAULT);
00512
00513
00514 H5Awrite(prov_attr, long_string_type, provenance_data);
00515
00516
00517 free(provenance_data);
00518 H5Sclose(provenance_space);
00519 H5Aclose(prov_attr);
00520
00521 }
00522
00523 void Hdf5DataWriter::PutVector(int variableID, Vec petscVector)
00524 {
00525 if (mIsInDefineMode)
00526 {
00527 EXCEPTION("Cannot write data while in define mode.");
00528 }
00529
00530 int vector_size;
00531 VecGetSize(petscVector, &vector_size);
00532
00533 if ((unsigned) vector_size != mDataFixedDimensionSize)
00534 {
00535 EXCEPTION("Vector size doesn't match fixed dimension");
00536 }
00537
00538
00539 PossiblyExtend();
00540
00541
00542 hid_t memspace=0;
00543 if (mNumberOwned !=0)
00544 {
00545 hsize_t v_size[1] = {mNumberOwned};
00546 memspace = H5Screate_simple(1, v_size, NULL);
00547 }
00548
00549 hsize_t count[DATASET_DIMS] = {1, mNumberOwned, 1};
00550 hsize_t offset_dims[DATASET_DIMS] = {mCurrentTimeStep, mOffset, variableID};
00551 hid_t file_dataspace = H5Dget_space(mDatasetId);
00552
00553
00554 hid_t property_list_id = H5Pcreate(H5P_DATASET_XFER);
00555 H5Pset_dxpl_mpio(property_list_id, H5FD_MPIO_COLLECTIVE);
00556
00557 H5Sselect_hyperslab(file_dataspace, H5S_SELECT_SET, offset_dims, NULL, count, NULL);
00558
00559 double* p_petsc_vector;
00560 VecGetArray(petscVector, &p_petsc_vector);
00561
00562 if (mIsDataComplete)
00563 {
00564 H5Dwrite(mDatasetId, H5T_NATIVE_DOUBLE, memspace, file_dataspace, property_list_id, p_petsc_vector);
00565 }
00566 else
00567 {
00568
00569 double local_data[mNumberOwned];
00570 for (unsigned i=0; i<mNumberOwned; i++)
00571 {
00572 local_data[i] = p_petsc_vector[ mIncompleteNodeIndices[mOffset+i]-mLo ];
00573
00574 }
00575 H5Dwrite(mDatasetId, H5T_NATIVE_DOUBLE, memspace, file_dataspace, property_list_id, local_data);
00576 }
00577
00578 VecRestoreArray(petscVector, &p_petsc_vector);
00579
00580 H5Pclose(property_list_id);
00581 H5Sclose(file_dataspace);
00582 if (mNumberOwned !=0)
00583 {
00584 H5Sclose(memspace);
00585 }
00586 }
00587
00588 void Hdf5DataWriter::PutStripedVector(int firstVariableID, int secondVariableID, Vec petscVector)
00589 {
00590 if (mIsInDefineMode)
00591 {
00592 EXCEPTION("Cannot write data while in define mode.");
00593 }
00594
00595 int NUM_STRIPES=2;
00596
00597
00598 if (secondVariableID-firstVariableID != 1)
00599 {
00600 EXCEPTION("Columns should be consecutive. Try reordering them.");
00601 }
00602
00603 int vector_size;
00604 VecGetSize(petscVector, &vector_size);
00605
00606 if ((unsigned) vector_size != NUM_STRIPES*mDataFixedDimensionSize)
00607 {
00608 EXCEPTION("Vector size doesn't match fixed dimension");
00609 }
00610
00611
00612 PossiblyExtend();
00613
00614
00615 hid_t memspace=0;
00616 if (mNumberOwned !=0)
00617 {
00618 hsize_t v_size[1] = {mNumberOwned*NUM_STRIPES};
00619 memspace = H5Screate_simple(1, v_size, NULL);
00620 }
00621
00622
00623 hsize_t start[DATASET_DIMS] = {mCurrentTimeStep, mOffset, firstVariableID};
00624 hsize_t stride[DATASET_DIMS] = {1, 1, secondVariableID-firstVariableID};
00625 hsize_t block_size[DATASET_DIMS] = {1, mNumberOwned, 1};
00626 hsize_t number_blocks[DATASET_DIMS] = {1, 1, NUM_STRIPES};
00627
00628 hid_t hyperslab_space = H5Dget_space(mDatasetId);
00629 H5Sselect_hyperslab(hyperslab_space, H5S_SELECT_SET, start, stride, number_blocks, block_size);
00630
00631
00632 hid_t property_list_id = H5Pcreate(H5P_DATASET_XFER);
00633 H5Pset_dxpl_mpio(property_list_id, H5FD_MPIO_COLLECTIVE);
00634
00635 double* p_petsc_vector;
00636 VecGetArray(petscVector, &p_petsc_vector);
00637
00638 if (mIsDataComplete)
00639 {
00640 H5Dwrite(mDatasetId, H5T_NATIVE_DOUBLE, memspace, hyperslab_space, property_list_id, p_petsc_vector);
00641 }
00642 else
00643 {
00644
00645 double local_data[mNumberOwned*NUM_STRIPES];
00646 for (unsigned i=0; i<mNumberOwned; i++)
00647 {
00649 unsigned local_node_number=mIncompleteNodeIndices[mOffset+i] - mLo;
00650 local_data[NUM_STRIPES*i] = p_petsc_vector[ local_node_number*NUM_STRIPES ];
00651 local_data[NUM_STRIPES*i+1] = p_petsc_vector[ local_node_number*NUM_STRIPES + 1];
00652 }
00653 H5Dwrite(mDatasetId, H5T_NATIVE_DOUBLE, memspace, hyperslab_space, property_list_id, local_data);
00654 }
00655
00656 VecRestoreArray(petscVector, &p_petsc_vector);
00657
00658 H5Sclose(hyperslab_space);
00659 if (mNumberOwned != 0)
00660 {
00661 H5Sclose(memspace);
00662 }
00663 H5Pclose(property_list_id);
00664 }
00665
00666 void Hdf5DataWriter::PutUnlimitedVariable(double value)
00667 {
00668 if (mIsInDefineMode)
00669 {
00670 EXCEPTION("Cannot write data while in define mode.");
00671 }
00672
00673 if (!mIsUnlimitedDimensionSet)
00674 {
00675 EXCEPTION("PutUnlimitedVariable() called but no unlimited dimension has been set");
00676 }
00677
00678
00679 if (!PetscTools::AmMaster())
00680 {
00681 return;
00682 }
00683
00684
00685 PossiblyExtend();
00686
00687 hsize_t size[1] = {1};
00688 hid_t memspace = H5Screate_simple(1, size, NULL);
00689
00690
00691 hsize_t count[1] = {1};
00692 hsize_t offset[1] = {mCurrentTimeStep};
00693 hid_t hyperslab_space = H5Dget_space(mTimeDatasetId);
00694 H5Sselect_hyperslab(hyperslab_space, H5S_SELECT_SET, offset, NULL, count, NULL);
00695
00696 H5Dwrite(mTimeDatasetId, H5T_NATIVE_DOUBLE, memspace, hyperslab_space, H5P_DEFAULT, &value);
00697
00698 H5Sclose(hyperslab_space);
00699 H5Sclose(memspace);
00700 }
00701
00702 void Hdf5DataWriter::Close()
00703 {
00704 if (mIsInDefineMode)
00705 {
00706 return;
00707 }
00708
00709 H5Dclose(mDatasetId);
00710 if (mIsUnlimitedDimensionSet)
00711 {
00712 H5Dclose(mTimeDatasetId);
00713 }
00714 H5Fclose(mFileId);
00715
00716
00717 mIsInDefineMode = true;
00718 }
00719
00720 void Hdf5DataWriter::DefineUnlimitedDimension(const std::string& rVariableName,
00721 const std::string& rVariableUnits)
00722 {
00723 if (mIsUnlimitedDimensionSet)
00724 {
00725 EXCEPTION("Unlimited dimension already set. Cannot be defined twice");
00726 }
00727
00728 if (!mIsInDefineMode)
00729 {
00730 EXCEPTION("Cannot define variables when not in Define mode");
00731 }
00732
00733 mIsUnlimitedDimensionSet = true;
00734 mUnlimitedDimensionName = rVariableName;
00735 mUnlimitedDimensionUnit = rVariableUnits;
00736 }
00737
00738 void Hdf5DataWriter::AdvanceAlongUnlimitedDimension()
00739 {
00740 if (!mIsUnlimitedDimensionSet)
00741 {
00742 EXCEPTION("Trying to advance along an unlimited dimension without having defined any");
00743 }
00744
00745
00746 mDatasetDims[0]++;
00747 mNeedExtend = true;
00748
00749 mCurrentTimeStep++;
00750 }
00751
00752 void Hdf5DataWriter::PossiblyExtend()
00753 {
00754 if (mNeedExtend)
00755 {
00756 H5Dextend (mDatasetId, mDatasetDims);
00757 H5Dextend (mTimeDatasetId, mDatasetDims);
00758 }
00759 mNeedExtend = false;
00760 }
00761
00762 int Hdf5DataWriter::GetVariableByName(const std::string& rVariableName)
00763 {
00764 int id = -1;
00765
00766 for (unsigned index=0; index<mVariables.size(); index++)
00767 {
00768 if (mVariables[index].mVariableName == rVariableName)
00769 {
00770 id = index;
00771 break;
00772 }
00773 }
00774 if (id == -1)
00775 {
00776 EXCEPTION("Variable does not exist in hdf5 definitions.");
00777 }
00778 return id;
00779 }