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 #ifdef HDF5 // if you don't have HDF5, then this file is useless
00030
00031 #ifndef HDF5_H
00032 #define HDF5_H
00033
00034 #include <iostream>
00035 using std::cout;
00036 using std::endl;
00037
00038 #ifdef MPI
00039 #include <mpi.h>
00040 #endif
00041
00042 #include "LevelData.H"
00043 #include "HDF5Portable.H"
00044
00045 #undef inline
00046 #include <string>
00047 #include <map>
00048 #include "RealVect.H"
00049
00050 using std::map;
00051
00052 class HDF5Handle;
00053
00054
00055
00056
00057
00059
00070 template <class T>
00071 int writeLevel(HDF5Handle& a_handle,
00072 const int& a_level,
00073 const LevelData<T>& a_data,
00074 const Real& a_dx,
00075 const Real& a_dt,
00076 const Real& a_time,
00077 const Box& a_domain,
00078 const int& a_refRatio,
00079 const IntVect& outputGhost = IntVect::Zero);
00080
00081 template <class T>
00082 int readLevel(HDF5Handle& a_handle,
00083 const int& a_level,
00084 LevelData<T>& a_data,
00085 Real& a_dx,
00086 Real& a_dt,
00087 Real& a_time,
00088 Box& a_domain,
00089 int& a_refRatio,
00090 const Interval& a_comps = Interval(),
00091 const IntVect& ghost = IntVect::Zero,
00092 bool setGhost = false);
00093
00094
00095
00096
00097
00098
00100
00107 int write(HDF5Handle& a_handle,
00108 const BoxLayout& a_layout);
00109
00111
00116 template <class T>
00117 int write(HDF5Handle& a_handle,
00118 const BoxLayoutData<T>& a_data,
00119 const std::string& a_name,
00120 const IntVect& outputGhost = IntVect::Zero);
00121
00123
00130 template <class T>
00131 int write(HDF5Handle& a_handle,
00132 const LevelData<T>& a_data,
00133 const std::string& a_name,
00134 const IntVect& outputGhost = IntVect::Zero);
00135
00137
00144 int read(HDF5Handle& a_handle,
00145 Vector<Box>& boxes);
00146
00148
00155 int readBoxes(HDF5Handle& a_handle,
00156 Vector<Vector<Box> >& boxes);
00157
00158
00160
00168 int readFArrayBox(HDF5Handle& a_handle,
00169 FArrayBox& a_fab,
00170 int a_level,
00171 int a_boxNumber,
00172 const Interval& a_components,
00173 const std::string& a_dataName = "data" );
00174
00176
00182 template <class T>
00183 int read(HDF5Handle& a_handle,
00184 BoxLayoutData<T>& a_data,
00185 const std::string& a_name,
00186 const BoxLayout& a_layout,
00187 const Interval& a_comps = Interval(),
00188 bool redefineData = true);
00189
00191
00197 template <class T>
00198 int read(HDF5Handle& a_handle,
00199 LevelData<T>& a_data,
00200 const std::string& a_name,
00201 const DisjointBoxLayout& a_layout,
00202 const Interval& a_comps = Interval(),
00203 bool redefineData = true);
00204
00206
00216 class HDF5Handle
00217 {
00218 public:
00220
00234 enum mode {CREATE, OPEN_RDONLY, OPEN_RDWR};
00235
00237
00239
00244 HDF5Handle();
00245
00247
00255 HDF5Handle(const std::string& a_filename, mode a_mode);
00256
00258
00260
00280 int open(const std::string& a_filename, mode a_mode);
00281
00283
00286 bool isOpen() const;
00287
00289
00294 void close();
00295
00297
00299
00302 void setGroupToLevel(int a_level);
00303
00305
00312 int setGroup(const std::string& groupAbsPath);
00313
00315
00321 const std::string& getGroup() const;
00322
00323 const hid_t& fileID() const;
00324 const hid_t& groupID() const;
00325 static hid_t box_id;
00326 static hid_t intvect_id;
00327 static hid_t realvect_id;
00328
00329 private:
00330
00331 HDF5Handle(const HDF5Handle&);
00332 HDF5Handle& operator=(const HDF5Handle&);
00333
00334 hid_t m_fileID;
00335 hid_t m_currentGroupID;
00336 bool m_isOpen;
00337 std::string m_filename;
00338 std::string m_group;
00339 int m_level;
00340
00341 static hid_t file_access;
00342 static bool initialized;
00343 static void initialize();
00344
00345 };
00346
00348
00390 class HDF5HeaderData
00391 {
00392 public:
00393
00395
00401 int writeToFile(HDF5Handle& file) const;
00402
00404
00412 int readFromFile(HDF5Handle& file);
00413
00415 void clear();
00416
00418 map<std::string, Real> m_real;
00419
00421 map<std::string, int> m_int;
00422
00424 map<std::string, std::string> m_string;
00425
00427 map<std::string, IntVect> m_intvect;
00428
00430 map<std::string, Box> m_box;
00431
00433 map<std::string, RealVect> m_realvect;
00434
00435
00436
00437 int writeToLocation(hid_t loc_id) const;
00438 int readFromLocation(hid_t loc_id);
00439
00440 private:
00441 static herr_t attributeScan(hid_t loc_id, const char *name, void *opdata);
00442 };
00443
00444 extern "C"{
00445 herr_t HDF5HeaderDataattributeScan(hid_t loc_id, const char *name, void *opdata);
00446 }
00447
00448 std::ostream& operator<<(std::ostream& os, const HDF5HeaderData& data);
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 #include "LoadBalance.H"
00487 #include "LayoutIterator.H"
00488 #include "Vector.H"
00489 #include "memtrack.H"
00490
00491
00492
00493
00494 struct OffsetBuffer
00495 {
00496 Vector<int> index;
00497 Vector<Vector<int> > offsets;
00498 void operator=(const OffsetBuffer& rhs);
00499 };
00500
00501 ostream& operator<<(ostream& os, const OffsetBuffer& ob);
00502
00503
00504 template < >
00505 int linearSize(const OffsetBuffer& a_input);
00506
00507
00508 template < >
00509 void linearIn(OffsetBuffer& a_outputT, const void* const a_inBuf);
00510
00511
00512 template < >
00513 void linearOut(void* const a_outBuf, const OffsetBuffer& a_inputT);
00514
00515 template < > int linearSize(const Vector<OffsetBuffer>& a_input);
00516 template < > void linearIn(Vector<OffsetBuffer>& a_outputT, const void* const inBuf);
00517 template < > void linearOut(void* const a_outBuf, const Vector<OffsetBuffer>& a_inputT);
00518
00519
00520
00521 template <>
00522 inline void dataTypes(Vector<hid_t>& a_types, const BaseFab<int>& dummy)
00523 {
00524 a_types.resize(1);
00525 a_types[0] = H5T_NATIVE_INT;
00526 }
00527
00528
00529
00530
00531 template <>
00532 inline void dataTypes(Vector<hid_t>& a_types, const FArrayBox& dummy)
00533 { a_types.resize(1); a_types[0] = H5T_NATIVE_REAL;}
00534
00535
00536 template <>
00537 inline void dataSize(const BaseFab<int>& item, Vector<int>& a_sizes,
00538 const Box& box, const Interval& comps)
00539 {
00540 a_sizes[0] = box.numPts() * comps.size();
00541 }
00542
00543 template <>
00544 inline void dataSize(const FArrayBox& item, Vector<int>& a_sizes,
00545 const Box& box, const Interval& comps)
00546 {
00547 a_sizes[0] = box.numPts() * comps.size();
00548 }
00549
00550 template <>
00551 inline const char* name(const FArrayBox& a_dummySpecializationArg)
00552 {
00553
00554
00555 const char* name = "FArrayBox";
00556 return name;
00557 }
00558
00559 template <>
00560 inline const char* name(const BaseFab<int>& a_dummySpecializationArg)
00561 {
00562
00563
00564 const char* name = "BaseFab<int>";
00565 return name;
00566 }
00567
00568
00569
00570
00571
00572 template <class T>
00573 inline void dataTypes(Vector<hid_t>& a_types, const T& dummy)
00574 { a_types.resize(1); a_types[0] = H5T_NATIVE_CHAR;}
00575
00576 template <class T>
00577 inline void dataSize(const T& item, Vector<int>& a_sizes,
00578 const Box& box, const Interval& comps)
00579 {
00580 a_sizes[0] = item.size(box, comps);
00581 }
00582
00583
00584 template <class T>
00585 inline void write(const T& item, Vector<void*>& a_allocatedBuffers,
00586 const Box& box, const Interval& comps)
00587 {
00588 item.linearOut(a_allocatedBuffers[0], box, comps);
00589 }
00590
00591 template <class T>
00592 inline void read(T& item, Vector<void*>& a_allocatedBuffers,
00593 const Box& box, const Interval& comps)
00594 {
00595 item.linearIn(a_allocatedBuffers[0], box, comps);
00596 }
00597
00598 template <class T>
00599 inline const char* name(const T& a_dummySpecializationArg)
00600 {
00601 static const char* name = "unknown";
00602 return name;
00603 }
00604
00605 template <class T>
00606 void getOffsets(Vector<Vector<long long> >& offsets, const BoxLayoutData<T>& a_data,
00607 int types, const Interval& comps, const IntVect& outputGhost)
00608 {
00609
00610
00611 const BoxLayout& layout = a_data.boxLayout();
00612 offsets.resize(types, Vector<long long>(layout.size()+1));
00613
00614 for(int t=0; t<types; t++) offsets[t][0] = 0;
00615 Vector<int> thisSize(types);
00616 if(T::preAllocatable()==0)
00617 {
00618 T dummy;
00619 unsigned int index = 1;
00620 for(LayoutIterator it(layout.layoutIterator()); it.ok(); ++it)
00621 {
00622 Box region = layout[it()];
00623 region.grow(outputGhost);
00624 dataSize(dummy, thisSize, region, comps);
00625 for(unsigned int i=0; i<thisSize.size(); ++i)
00626 {
00627
00628 offsets[i][index] = offsets[i][index-1] + thisSize[i];
00629 }
00630 ++index;
00631 }
00632 }
00633 else
00634 {
00635 OffsetBuffer buff;
00636 int index = 0;
00637 for(DataIterator dit(a_data.dataIterator()); dit.ok(); ++dit, ++index)
00638 {
00639
00640 buff.index.push_back(index);
00641 Box region = layout[dit()];
00642 region.grow(outputGhost);
00643 dataSize(a_data[dit()], thisSize, region, comps);
00644 buff.offsets.push_back(thisSize);
00645 }
00646 Vector<OffsetBuffer> gathering(numProc());
00647 gather(gathering, buff, uniqueProc(SerialTask::compute));
00648 broadcast(gathering, uniqueProc(SerialTask::compute));
00649
00650 for(int i=0; i<numProc(); ++i)
00651 {
00652 OffsetBuffer& offbuf = gathering[i];
00653 for(int num=0; num<offbuf.index.size(); num++)
00654 {
00655 int index = offbuf.index[num];
00656 for(unsigned int j=0; j<types; ++j)
00657 {
00658
00659 offsets[j][index+1] = offbuf.offsets[num][j];
00660 }
00661 }
00662 }
00663 for(int i=0; i<layout.size(); i++)
00664 {
00665 for(unsigned int j=0; j<types; ++j)
00666 {
00667
00668 offsets[j][i+1] += offsets[j][i];
00669 }
00670 }
00671 }
00672
00673
00674 }
00675
00676
00677
00678
00679
00680
00681
00682 template <class T>
00683 int write(HDF5Handle& a_handle, const BoxLayoutData<T>& a_data,
00684 const std::string& a_name, const IntVect& outputGhost)
00685 {
00686 int ret = 0;
00687
00688 Interval comps = a_data.interval();
00689 T dummy;
00690 Vector<hid_t> types;
00691 dataTypes(types, dummy);
00692
00693 Vector<Vector<long long> > offsets;
00694 Vector<long long> bufferCapacity(types.size(), 1);
00695 Vector<void*> buffers(types.size(), NULL);
00696
00697 getOffsets(offsets, a_data, types.size(), comps, outputGhost);
00698
00699
00700 hsize_t flatdims[1];
00701 char dataname[100];
00702 Vector<hid_t> dataspace(types.size());
00703 Vector<hid_t> dataset(types.size());
00704
00705
00706
00707 herr_t err;
00708 hsize_t count[1];
00709 hssize_t offset[1];
00710
00711 for(unsigned int i=0; i<types.size(); ++i)
00712 {
00713 flatdims[0] = offsets[i][offsets[i].size()-1];
00714 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00715 dataspace[i] = H5Screate_simple(1, flatdims, NULL);
00716 assert(dataspace[i] >=0);
00717 dataset[i] = H5Dcreate(a_handle.groupID(), dataname,
00718 types[i],
00719 dataspace[i], H5P_DEFAULT);
00720 assert(dataset[i] >= 0);
00721 }
00722
00723 hid_t offsetspace, offsetData;
00724 for(unsigned int i=0; i<types.size(); ++i)
00725 {
00726 flatdims[0] = offsets[i].size();
00727 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00728 offsetspace = H5Screate_simple(1, flatdims, NULL);
00729 assert(offsetspace >= 0);
00730 offsetData = H5Dcreate(a_handle.groupID(), dataname,
00731 H5T_NATIVE_LLONG, offsetspace, H5P_DEFAULT);
00732 assert(offsetData >= 0);
00733 if(procID() == 0)
00734 {
00735 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00736 assert(memdataspace >= 0);
00737 err = H5Dwrite(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00738 H5P_DEFAULT, &(offsets[i][0]));
00739 assert(err >= 0);
00740 H5Sclose(memdataspace);
00741 }
00742 H5Sclose(offsetspace);
00743 H5Dclose(offsetData);
00744 }
00745
00746
00747 HDF5HeaderData info;
00748 info.m_int["comps"] = comps.size();
00749 info.m_string["objectType"] = name(dummy);
00750 std::string group = a_handle.getGroup();
00751 a_handle.setGroup(group+"/"+a_name+"_attributes");
00752 info.writeToFile(a_handle);
00753 a_handle.setGroup(group);
00754
00755
00756
00757
00758 Vector<size_t> type_size(types.size());
00759 for(unsigned int i=0; i<types.size(); ++i)
00760 {
00761 type_size[i] = H5Tget_size(types[i]);
00762 }
00763
00764 Vector<int> thisSize(types.size());
00765
00766
00767
00768 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00769 {
00770 unsigned int index = a_data.boxLayout().index(it());
00771 for(unsigned int i=0; i<types.size(); ++i)
00772 {
00773 long long size = (offsets[i][index+1] - offsets[i][index])
00774 * type_size[i];
00775 assert(size > 0);
00776 if(size > bufferCapacity[i])
00777 {
00778 bufferCapacity[i] = size;
00779 }
00780 }
00781 }
00782 for(unsigned int i=0; i<types.size(); ++i)
00783 {
00784 buffers[i] = malloc(bufferCapacity[i]);
00785 if(buffers[i] == NULL) {
00786 pout() << " i=" << i
00787 << " types.size() = " << types.size()
00788 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
00789 << endl;
00790 MayDay::Error("memory error in buffer allocation write");
00791 }
00792 }
00793
00794
00795
00796
00797 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00798 {
00799 const T& data = a_data[it()];
00800 unsigned int index = a_data.boxLayout().index(it());
00801 Box box = a_data.box(it());
00802 box.grow(outputGhost);
00803 write(data, buffers, box, comps);
00804 for(unsigned int i=0; i<types.size(); ++i)
00805 {
00806 offset[0] = offsets[i][index];
00807 count[0] = offsets[i][index+1] - offset[0];
00808 assert(count[0] > 0);
00809 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
00810 offset, NULL,
00811 count, NULL);
00812 assert(err >= 0);
00813 hid_t memdataspace = H5Screate_simple(1, count, NULL);
00814 assert(memdataspace >= 0);
00815 err = H5Dwrite(dataset[i], types[i], memdataspace, dataspace[i],
00816 H5P_DEFAULT, buffers[i]);
00817 assert(err >= 0);
00818 H5Sclose(memdataspace);
00819 if(err < 0) { ret = err; goto cleanup;}
00820 }
00821 }
00822
00823
00824
00825 cleanup:
00826 for(unsigned int i=0; i<types.size(); ++i)
00827 {
00828 free(buffers[i]);
00829 H5Sclose(dataspace[i]);
00830 H5Dclose(dataset[i]);
00831 }
00832 return ret;
00833
00834 }
00835
00836 template <class T>
00837 int write(HDF5Handle& a_handle, const LevelData<T>& a_data,
00838 const std::string& a_name, const IntVect& outputGhost)
00839 {
00840 HDF5HeaderData info;
00841 info.m_intvect["ghost"] = a_data.ghostVect();
00842 IntVect og(outputGhost);
00843 og.min(a_data.ghostVect());
00844 info.m_intvect["outputGhost"] = og;
00845 std::string group = a_handle.getGroup();
00846 a_handle.setGroup(group+"/"+a_name+"_attributes");
00847 info.writeToFile(a_handle);
00848 a_handle.setGroup(group);
00849 return write(a_handle, (const BoxLayoutData<T>&)a_data, a_name, og);
00850 }
00851
00852 template <class T>
00853 int read(HDF5Handle& a_handle, LevelData<T>& a_data, const std::string& a_name,
00854 const DisjointBoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00855 {
00856 if(a_redefineData)
00857 {
00858 HDF5HeaderData info;
00859 std::string group = a_handle.getGroup();
00860 if(a_handle.setGroup(group+"/"+a_name+"_attributes"))
00861 {
00862 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00863 MayDay::Warning(message.c_str());
00864 return 1;
00865 }
00866 info.readFromFile(a_handle);
00867 a_handle.setGroup(group);
00868 int ncomp = info.m_int["comps"];
00869 IntVect ghost = info.m_intvect["ghost"];
00870 if(a_comps.end() > 0 && ncomp < a_comps.end())
00871 {
00872 MayDay::Error("attempt to read component interval that is not available");
00873 }
00874 if(a_comps.size() == 0)
00875 a_data.define(a_layout, ncomp, ghost);
00876 else
00877 a_data.define(a_layout, a_comps.size(), ghost);
00878 }
00879 return read(a_handle, (BoxLayoutData<T>&)a_data, a_name, a_layout, a_comps, false);
00880
00881 }
00882 template <class T>
00883 int read(HDF5Handle& a_handle, BoxLayoutData<T>& a_data, const std::string& a_name,
00884 const BoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00885 {
00886 int ret = 0;
00887
00888 herr_t err;
00889
00890 char dataname[100];
00891 hsize_t count[1];
00892 hssize_t offset[1];
00893 Vector<Vector<long long> > offsets;
00894
00895 T dummy;
00896 Vector<hid_t> types;
00897 dataTypes(types, dummy);
00898 Vector<hid_t> dataspace(types.size());
00899 Vector<hid_t> dataset(types.size());
00900 offsets.resize(types.size(), Vector<long long>(a_layout.size() +1));
00901
00902 Vector<int> bufferCapacity(types.size(), 500);
00903 Vector<void*> buffers(types.size(), NULL);
00904
00905 for(unsigned int i=0; i<types.size(); ++i)
00906 {
00907 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00908 dataset[i] = H5Dopen(a_handle.groupID(), dataname);
00909 if(dataset[i] < 0) {MayDay::Warning("dataset open failure"); return dataset[i];}
00910 dataspace[i] = H5Dget_space(dataset[i]);
00911 if(dataspace[i] < 0) {MayDay::Warning("dataspace open failure"); return dataspace[i];}
00912 }
00913
00914 hid_t offsetspace, offsetData;
00915 hsize_t flatdims[1];
00916 for(unsigned int i=0; i<types.size(); ++i)
00917 {
00918 flatdims[0] = offsets[i].size();
00919 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00920 offsetspace = H5Screate_simple(1, flatdims, NULL);
00921 assert(offsetspace >= 0);
00922 offsetData = H5Dopen(a_handle.groupID(), dataname);
00923 assert(offsetData >= 0);
00924 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00925 assert(memdataspace >= 0);
00926 err = H5Dread(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00927 H5P_DEFAULT, &(offsets[i][0]));
00928 assert(err >=0);
00929 H5Sclose(memdataspace);
00930 H5Sclose(offsetspace);
00931 H5Dclose(offsetData);
00932 }
00933
00934 HDF5HeaderData info;
00935 std::string group = a_handle.getGroup();
00936 if(a_handle.setGroup(a_handle.getGroup()+"/"+a_name+"_attributes"))
00937 {
00938 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00939 MayDay::Warning(message.c_str());
00940 return 1;
00941 }
00942
00943 info.readFromFile(a_handle);
00944 a_handle.setGroup(group);
00945 int ncomps = info.m_int["comps"];
00946 IntVect outputGhost(IntVect::Zero);
00947 if(info.m_intvect.find("outputGhost") != info.m_intvect.end())
00948 {
00949 outputGhost = info.m_intvect["outputGhost"];
00950 }
00951 if(ncomps <= 0){
00952 MayDay::Warning("ncomps <= 0 in read");
00953 return ncomps;
00954 }
00955
00956 if(a_redefineData){
00957 if(a_comps.size() != 0){
00958 a_data.define(a_layout, a_comps.size());
00959 } else {
00960 a_data.define(a_layout, ncomps);
00961 }
00962 }
00963
00964 Interval comps(0, ncomps-1);
00965 if(a_comps.size() != 0) comps = Interval(0, a_comps.size());
00966
00967
00968
00969 Vector<size_t> type_size(types.size());
00970 for(unsigned int i=0; i<types.size(); ++i)
00971 {
00972 type_size[i] = H5Tget_size(types[i]);
00973 buffers[i] = malloc(bufferCapacity[i]);
00974 if(buffers[i] == NULL) {
00975 pout() << " i= " << i
00976 << " types.size()=" << types.size()
00977 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
00978 << endl;
00979 MayDay::Error("memory error in buffer allocation read");
00980 }
00981 }
00982
00983 Vector<int> thisSize(types.size());
00984 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00985 {
00986 T& data = a_data[it()];
00987 unsigned int index = a_data.boxLayout().index(it());
00988 Box box = a_data.box(it());
00989
00990 for(unsigned int i=0; i<types.size(); ++i)
00991 {
00992 if(a_comps.size() == 0){
00993 offset[0] = offsets[i][index];
00994 count[0] = offsets[i][index+1] - offset[0];
00995 } else {
00996 offset[0] = offsets[i][index] + box.numPts()*a_comps.begin();
00997 count[0] = a_comps.size() * box.numPts();
00998 }
00999 assert(count[0] > 0);
01000 int size = count[0] * type_size[i];
01001 if(size > bufferCapacity[i])
01002 {
01003 free(buffers[i]);
01004 bufferCapacity[i] = Max(2*bufferCapacity[i], size);
01005 buffers[i] = malloc(bufferCapacity[i]);
01006 if(buffers[i] == NULL) {
01007 MayDay::Error("memory error in buffer allocation read");
01008 }
01009 }
01010
01011 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
01012 offset, NULL,
01013 count, NULL);
01014 assert(err >= 0);
01015 hid_t memdataspace = H5Screate_simple(1, count, NULL);
01016 assert(memdataspace >= 0);
01017 err = H5Dread(dataset[i], types[i], memdataspace, dataspace[i],
01018 H5P_DEFAULT, buffers[i]);
01019 assert(err >= 0);
01020 H5Sclose(memdataspace);
01021 if(err < 0) { ret = err; goto cleanup;}
01022 }
01023 box.grow(outputGhost);
01024 read(data, buffers, box, comps);
01025 }
01026
01027 cleanup:
01028 for(unsigned int i=0; i<types.size(); ++i)
01029 {
01030 free(buffers[i]);
01031 H5Sclose(dataspace[i]);
01032 H5Dclose(dataset[i]);
01033 }
01034 return ret;
01035 }
01036
01037
01038 template <class T>
01039 int writeLevel(HDF5Handle& a_handle,
01040 const int& a_level,
01041 const LevelData<T>& a_data,
01042 const Real& a_dx,
01043 const Real& a_dt,
01044 const Real& a_time,
01045 const Box& a_domain,
01046 const int& a_refRatio,
01047 const IntVect& outputGhost)
01048 {
01049 int error;
01050 char levelName[10];
01051 std::string currentGroup = a_handle.getGroup();
01052 sprintf(levelName, "/level_%i",a_level);
01053 error = a_handle.setGroup(currentGroup + levelName);
01054 if(error != 0) return 1;
01055
01056 HDF5HeaderData meta;
01057 meta.m_real["dx"] = a_dx;
01058 meta.m_real["dt"] = a_dt;
01059 meta.m_real["time"] = a_time;
01060 meta.m_box["prob_domain"] = a_domain;
01061 meta.m_int["ref_ratio"] = a_refRatio;
01062
01063 error = meta.writeToFile(a_handle);
01064 if(error != 0) return 2;
01065
01066 error = write(a_handle, a_data.boxLayout());
01067 if(error != 0) return 3;
01068
01069 error = write(a_handle, a_data, "data", outputGhost);
01070 if(error != 0) return 4;
01071
01072 a_handle.setGroup(currentGroup);
01073
01074 return 0;
01075 }
01076
01077
01078 template <class T>
01079 int readLevel(HDF5Handle& a_handle,
01080 const int& a_level,
01081 LevelData<T>& a_data,
01082 Real& a_dx,
01083 Real& a_dt,
01084 Real& a_time,
01085 Box& a_domain,
01086 int& a_refRatio,
01087 const Interval& a_comps,
01088 const IntVect& ghost,
01089 bool setGhost)
01090 {
01091 HDF5HeaderData header;
01092 header.readFromFile(a_handle);
01093 int nComp = header.m_int["num_components"];
01094
01095 int error;
01096 char levelName[10];
01097 std::string currentGroup = a_handle.getGroup();
01098 sprintf(levelName, "/level_%i",a_level);
01099 error = a_handle.setGroup(currentGroup + levelName);
01100 if(error != 0) return 1;
01101
01102 HDF5HeaderData meta;
01103 error = meta.readFromFile(a_handle);
01104 if(error != 0) return 2;
01105 a_dx = meta.m_real["dx"];
01106 a_dt = meta.m_real["dt"];
01107 a_time = meta.m_real["time"];
01108 a_domain = meta.m_box["prob_domain"];
01109 a_refRatio = meta.m_int["ref_ratio"];
01110
01111 Vector<Box> boxes;
01112 error = read(a_handle, boxes);
01113 Vector<int> procIDs;
01114 LoadBalance(procIDs, boxes);
01115
01116 DisjointBoxLayout layout(boxes, procIDs);
01117
01118 layout.close();
01119 if(error != 0) return 3;
01120
01121 if(!setGhost)
01122 error = read(a_handle, a_data, "data", layout, a_comps);
01123 else
01124 {
01125 if(a_comps.size() != 0)
01126 a_data.define(layout, a_comps.size(), ghost);
01127 else
01128 a_data.define(layout, nComp, ghost);
01129
01130 error = read(a_handle, a_data, "data", layout, a_comps, false);
01131
01132 }
01133 if(error != 0) return 4;
01134
01135 a_handle.setGroup(currentGroup);
01136
01137 return 0;
01138 }
01139
01140
01141
01142 #endif // HDF5_H
01143
01144 #endif // HDF5