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