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