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 int index = 0;
00669 for(DataIterator dit(a_data.dataIterator()); dit.ok(); ++dit, ++index)
00670 {
00671
00672 buff.index.push_back(index);
00673 Box region = layout[dit()];
00674 region.grow(outputGhost);
00675 dataSize(a_data[dit()], thisSize, region, comps);
00676 buff.offsets.push_back(thisSize);
00677 }
00678 Vector<OffsetBuffer> gathering(numProc());
00679 gather(gathering, buff, uniqueProc(SerialTask::compute));
00680 broadcast(gathering, uniqueProc(SerialTask::compute));
00681
00682 for(int i=0; i<numProc(); ++i)
00683 {
00684 OffsetBuffer& offbuf = gathering[i];
00685 for(int num=0; num<offbuf.index.size(); num++)
00686 {
00687 int index = offbuf.index[num];
00688 for(unsigned int j=0; j<types; ++j)
00689 {
00690
00691 offsets[j][index+1] = offbuf.offsets[num][j];
00692 }
00693 }
00694 }
00695 for(int i=0; i<layout.size(); i++)
00696 {
00697 for(unsigned int j=0; j<types; ++j)
00698 {
00699
00700 offsets[j][i+1] += offsets[j][i];
00701 }
00702 }
00703 }
00704
00705
00706 }
00707
00708
00709
00710
00711
00712
00713
00714 template <class T>
00715 int write(HDF5Handle& a_handle, const BoxLayoutData<T>& a_data,
00716 const std::string& a_name, const IntVect& outputGhost)
00717 {
00718 int ret = 0;
00719
00720 Interval comps = a_data.interval();
00721 T dummy;
00722 Vector<hid_t> types;
00723 dataTypes(types, dummy);
00724
00725 Vector<Vector<long long> > offsets;
00726 Vector<long long> bufferCapacity(types.size(), 1);
00727 Vector<void*> buffers(types.size(), NULL);
00728
00729 getOffsets(offsets, a_data, types.size(), comps, outputGhost);
00730
00731
00732 hsize_t flatdims[1];
00733 char dataname[100];
00734 Vector<hid_t> dataspace(types.size());
00735 Vector<hid_t> dataset(types.size());
00736
00737
00738
00739 herr_t err;
00740 hsize_t count[1];
00741 hssize_t offset[1];
00742
00743 for(unsigned int i=0; i<types.size(); ++i)
00744 {
00745 flatdims[0] = offsets[i][offsets[i].size()-1];
00746 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00747 dataspace[i] = H5Screate_simple(1, flatdims, NULL);
00748 assert(dataspace[i] >=0);
00749 dataset[i] = H5Dcreate(a_handle.groupID(), dataname,
00750 types[i],
00751 dataspace[i], H5P_DEFAULT);
00752 assert(dataset[i] >= 0);
00753 }
00754
00755 hid_t offsetspace, offsetData;
00756 for(unsigned int i=0; i<types.size(); ++i)
00757 {
00758 flatdims[0] = offsets[i].size();
00759 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00760 offsetspace = H5Screate_simple(1, flatdims, NULL);
00761 assert(offsetspace >= 0);
00762 offsetData = H5Dcreate(a_handle.groupID(), dataname,
00763 H5T_NATIVE_LLONG, offsetspace, H5P_DEFAULT);
00764 assert(offsetData >= 0);
00765 if(procID() == 0)
00766 {
00767 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00768 assert(memdataspace >= 0);
00769 err = H5Dwrite(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00770 H5P_DEFAULT, &(offsets[i][0]));
00771 assert(err >= 0);
00772 H5Sclose(memdataspace);
00773 }
00774 H5Sclose(offsetspace);
00775 H5Dclose(offsetData);
00776 }
00777
00778
00779 HDF5HeaderData info;
00780 info.m_int["comps"] = comps.size();
00781 info.m_string["objectType"] = name(dummy);
00782 std::string group = a_handle.getGroup();
00783 a_handle.setGroup(group+"/"+a_name+"_attributes");
00784 info.writeToFile(a_handle);
00785 a_handle.setGroup(group);
00786
00787
00788
00789
00790 Vector<size_t> type_size(types.size());
00791 for(unsigned int i=0; i<types.size(); ++i)
00792 {
00793 type_size[i] = H5Tget_size(types[i]);
00794 }
00795
00796 Vector<int> thisSize(types.size());
00797
00798
00799
00800 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00801 {
00802 unsigned int index = a_data.boxLayout().index(it());
00803 for(unsigned int i=0; i<types.size(); ++i)
00804 {
00805 long long size = (offsets[i][index+1] - offsets[i][index])
00806 * type_size[i];
00807 assert(size >= 0);
00808 if(size > bufferCapacity[i])
00809 {
00810 bufferCapacity[i] = size;
00811 }
00812 }
00813 }
00814 for(unsigned int i=0; i<types.size(); ++i)
00815 {
00816 buffers[i] = malloc(bufferCapacity[i]);
00817 if(buffers[i] == NULL) {
00818 pout() << " i=" << i
00819 << " types.size() = " << types.size()
00820 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
00821 << endl;
00822 MayDay::Error("memory error in buffer allocation write");
00823 }
00824 }
00825
00826
00827
00828
00829 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
00830 {
00831 const T& data = a_data[it()];
00832 unsigned int index = a_data.boxLayout().index(it());
00833 Box box = a_data.box(it());
00834 box.grow(outputGhost);
00835 write(data, buffers, box, comps);
00836 for(unsigned int i=0; i<types.size(); ++i)
00837 {
00838 offset[0] = offsets[i][index];
00839 count[0] = offsets[i][index+1] - offset[0];
00840 if(count[0] > 0){
00841 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
00842 offset, NULL,
00843 count, NULL);
00844 assert(err >= 0);
00845 hid_t memdataspace = H5Screate_simple(1, count, NULL);
00846 assert(memdataspace >= 0);
00847 err = H5Dwrite(dataset[i], types[i], memdataspace, dataspace[i],
00848 H5P_DEFAULT, buffers[i]);
00849 assert(err >= 0);
00850 H5Sclose(memdataspace);
00851 if(err < 0) { ret = err; goto cleanup;}
00852 }
00853 }
00854 }
00855
00856
00857
00858 cleanup:
00859 for(unsigned int i=0; i<types.size(); ++i)
00860 {
00861 free(buffers[i]);
00862 H5Sclose(dataspace[i]);
00863 H5Dclose(dataset[i]);
00864 }
00865 return ret;
00866
00867 }
00868
00869 template <class T>
00870 int write(HDF5Handle& a_handle, const LevelData<T>& a_data,
00871 const std::string& a_name, const IntVect& outputGhost)
00872 {
00873 HDF5HeaderData info;
00874 info.m_intvect["ghost"] = a_data.ghostVect();
00875 IntVect og(outputGhost);
00876 og.min(a_data.ghostVect());
00877 info.m_intvect["outputGhost"] = og;
00878 std::string group = a_handle.getGroup();
00879 a_handle.setGroup(group+"/"+a_name+"_attributes");
00880 info.writeToFile(a_handle);
00881 a_handle.setGroup(group);
00882 return write(a_handle, (const BoxLayoutData<T>&)a_data, a_name, og);
00883 }
00884
00885 template <class T>
00886 int read(HDF5Handle& a_handle, LevelData<T>& a_data, const std::string& a_name,
00887 const DisjointBoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00888 {
00889 if(a_redefineData)
00890 {
00891 HDF5HeaderData info;
00892 std::string group = a_handle.getGroup();
00893 if(a_handle.setGroup(group+"/"+a_name+"_attributes"))
00894 {
00895 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00896 MayDay::Warning(message.c_str());
00897 return 1;
00898 }
00899 info.readFromFile(a_handle);
00900 a_handle.setGroup(group);
00901 int ncomp = info.m_int["comps"];
00902 IntVect ghost = info.m_intvect["ghost"];
00903 if(a_comps.end() > 0 && ncomp < a_comps.end())
00904 {
00905 MayDay::Error("attempt to read component interval that is not available");
00906 }
00907 if(a_comps.size() == 0)
00908 a_data.define(a_layout, ncomp, ghost);
00909 else
00910 a_data.define(a_layout, a_comps.size(), ghost);
00911 }
00912 return read(a_handle, (BoxLayoutData<T>&)a_data, a_name, a_layout, a_comps, false);
00913
00914 }
00915 template <class T>
00916 int read(HDF5Handle& a_handle, BoxLayoutData<T>& a_data, const std::string& a_name,
00917 const BoxLayout& a_layout, const Interval& a_comps, bool a_redefineData)
00918 {
00919 int ret = 0;
00920
00921 herr_t err;
00922
00923 char dataname[100];
00924 hsize_t count[1];
00925 hssize_t offset[1];
00926 Vector<Vector<long long> > offsets;
00927
00928 T dummy;
00929 Vector<hid_t> types;
00930 dataTypes(types, dummy);
00931 Vector<hid_t> dataspace(types.size());
00932 Vector<hid_t> dataset(types.size());
00933 offsets.resize(types.size(), Vector<long long>(a_layout.size() +1));
00934
00935 Vector<int> bufferCapacity(types.size(), 500);
00936 Vector<void*> buffers(types.size(), NULL);
00937
00938 for(unsigned int i=0; i<types.size(); ++i)
00939 {
00940 sprintf(dataname, "%s:datatype=%i",a_name.c_str(), i);
00941 dataset[i] = H5Dopen(a_handle.groupID(), dataname);
00942 if(dataset[i] < 0) {MayDay::Warning("dataset open failure"); return dataset[i];}
00943 dataspace[i] = H5Dget_space(dataset[i]);
00944 if(dataspace[i] < 0) {MayDay::Warning("dataspace open failure"); return dataspace[i];}
00945 }
00946
00947 hid_t offsetspace, offsetData;
00948 hsize_t flatdims[1];
00949 for(unsigned int i=0; i<types.size(); ++i)
00950 {
00951 flatdims[0] = offsets[i].size();
00952 sprintf(dataname, "%s:offsets=%i",a_name.c_str(), i);
00953 offsetspace = H5Screate_simple(1, flatdims, NULL);
00954 assert(offsetspace >= 0);
00955 offsetData = H5Dopen(a_handle.groupID(), dataname);
00956 assert(offsetData >= 0);
00957 hid_t memdataspace = H5Screate_simple(1, flatdims, NULL);
00958 assert(memdataspace >= 0);
00959 err = H5Dread(offsetData, H5T_NATIVE_LLONG, memdataspace, offsetspace,
00960 H5P_DEFAULT, &(offsets[i][0]));
00961 assert(err >=0);
00962 H5Sclose(memdataspace);
00963 H5Sclose(offsetspace);
00964 H5Dclose(offsetData);
00965 }
00966
00967 HDF5HeaderData info;
00968 std::string group = a_handle.getGroup();
00969 if(a_handle.setGroup(a_handle.getGroup()+"/"+a_name+"_attributes"))
00970 {
00971 std::string message = "error opening "+a_handle.getGroup()+"/"+a_name ;
00972 MayDay::Warning(message.c_str());
00973 return 1;
00974 }
00975
00976 info.readFromFile(a_handle);
00977 a_handle.setGroup(group);
00978 int ncomps = info.m_int["comps"];
00979 IntVect outputGhost(IntVect::Zero);
00980 if(info.m_intvect.find("outputGhost") != info.m_intvect.end())
00981 {
00982 outputGhost = info.m_intvect["outputGhost"];
00983 }
00984 if(ncomps <= 0){
00985 MayDay::Warning("ncomps <= 0 in read");
00986 return ncomps;
00987 }
00988
00989 if(a_redefineData){
00990 if(a_comps.size() != 0){
00991 a_data.define(a_layout, a_comps.size());
00992 } else {
00993 a_data.define(a_layout, ncomps);
00994 }
00995 }
00996
00997 Interval comps(0, ncomps-1);
00998
00999
01000
01001
01002
01003 Vector<size_t> type_size(types.size());
01004 for(unsigned int i=0; i<types.size(); ++i)
01005 {
01006 type_size[i] = H5Tget_size(types[i]);
01007 buffers[i] = malloc(bufferCapacity[i]);
01008 if(buffers[i] == NULL) {
01009 pout() << " i= " << i
01010 << " types.size()=" << types.size()
01011 << " bufferCapacity[i] = " << (int)bufferCapacity[i]
01012 << endl;
01013 MayDay::Error("memory error in buffer allocation read");
01014 }
01015 }
01016
01017 Vector<int> thisSize(types.size());
01018 for(DataIterator it = a_data.dataIterator(); it.ok(); ++it)
01019 {
01020 T& data = a_data[it()];
01021 unsigned int index = a_data.boxLayout().index(it());
01022 Box box = a_data.box(it());
01023
01024 for(unsigned int i=0; i<types.size(); ++i)
01025 {
01026 if(a_comps.size() == 0){
01027 offset[0] = offsets[i][index];
01028 count[0] = offsets[i][index+1] - offset[0];
01029 } else {
01030 offset[0] = offsets[i][index] + box.numPts()*a_comps.begin();
01031 count[0] = a_comps.size() * box.numPts();
01032 }
01033 if(count[0] > 0)
01034 {
01035 int size = count[0] * type_size[i];
01036 if(size > bufferCapacity[i])
01037 {
01038 free(buffers[i]);
01039 bufferCapacity[i] = Max(2*bufferCapacity[i], size);
01040 buffers[i] = malloc(bufferCapacity[i]);
01041 if(buffers[i] == NULL) {
01042 MayDay::Error("memory error in buffer allocation read");
01043 }
01044 }
01045
01046 err = H5Sselect_hyperslab(dataspace[i], H5S_SELECT_SET,
01047 offset, NULL,
01048 count, NULL);
01049 assert(err >= 0);
01050 hid_t memdataspace = H5Screate_simple(1, count, NULL);
01051 assert(memdataspace >= 0);
01052 err = H5Dread(dataset[i], types[i], memdataspace, dataspace[i],
01053 H5P_DEFAULT, buffers[i]);
01054 assert(err >= 0);
01055 H5Sclose(memdataspace);
01056 if(err < 0) { ret = err; goto cleanup;}
01057 }
01058 }
01059 box.grow(outputGhost);
01060 read(data, buffers, box, comps);
01061 }
01062
01063 cleanup:
01064 for(unsigned int i=0; i<types.size(); ++i)
01065 {
01066 free(buffers[i]);
01067 H5Sclose(dataspace[i]);
01068 H5Dclose(dataset[i]);
01069 }
01070 return ret;
01071 }
01072
01073
01074 template <class T>
01075 int writeLevel(HDF5Handle& a_handle,
01076 const int& a_level,
01077 const LevelData<T>& a_data,
01078 const Real& a_dx,
01079 const Real& a_dt,
01080 const Real& a_time,
01081 const Box& a_domain,
01082 const int& a_refRatio,
01083 const IntVect& outputGhost)
01084 {
01085 int error;
01086 char levelName[10];
01087 std::string currentGroup = a_handle.getGroup();
01088 sprintf(levelName, "/level_%i",a_level);
01089 error = a_handle.setGroup(currentGroup + levelName);
01090 if(error != 0) return 1;
01091
01092 HDF5HeaderData meta;
01093 meta.m_real["dx"] = a_dx;
01094 meta.m_real["dt"] = a_dt;
01095 meta.m_real["time"] = a_time;
01096 meta.m_box["prob_domain"] = a_domain;
01097 meta.m_int["ref_ratio"] = a_refRatio;
01098
01099 error = meta.writeToFile(a_handle);
01100 if(error != 0) return 2;
01101
01102 error = write(a_handle, a_data.boxLayout());
01103 if(error != 0) return 3;
01104
01105 error = write(a_handle, a_data, "data", outputGhost);
01106 if(error != 0) return 4;
01107
01108 a_handle.setGroup(currentGroup);
01109
01110 return 0;
01111 }
01112
01113
01114 template <class T>
01115 int readLevel(HDF5Handle& a_handle,
01116 const int& a_level,
01117 LevelData<T>& a_data,
01118 Real& a_dx,
01119 Real& a_dt,
01120 Real& a_time,
01121 Box& a_domain,
01122 int& a_refRatio,
01123 const Interval& a_comps,
01124 const IntVect& ghost,
01125 bool setGhost)
01126 {
01127 HDF5HeaderData header;
01128 header.readFromFile(a_handle);
01129 int nComp = header.m_int["num_components"];
01130
01131 int error;
01132 char levelName[10];
01133 std::string currentGroup = a_handle.getGroup();
01134 sprintf(levelName, "/level_%i",a_level);
01135 error = a_handle.setGroup(currentGroup + levelName);
01136 if(error != 0) return 1;
01137
01138 HDF5HeaderData meta;
01139 error = meta.readFromFile(a_handle);
01140 if(error != 0) return 2;
01141 a_dx = meta.m_real["dx"];
01142 a_dt = meta.m_real["dt"];
01143 a_time = meta.m_real["time"];
01144 a_domain = meta.m_box["prob_domain"];
01145 a_refRatio = meta.m_int["ref_ratio"];
01146
01147 Vector<Box> boxes;
01148 error = read(a_handle, boxes);
01149 Vector<int> procIDs;
01150 LoadBalance(procIDs, boxes);
01151
01152 DisjointBoxLayout layout(boxes, procIDs);
01153
01154 layout.close();
01155 if(error != 0) return 3;
01156
01157 if(!setGhost)
01158 error = read(a_handle, a_data, "data", layout, a_comps);
01159 else
01160 {
01161 if(a_comps.size() != 0)
01162 a_data.define(layout, a_comps.size(), ghost);
01163 else
01164 a_data.define(layout, nComp, ghost);
01165
01166 error = read(a_handle, a_data, "data", layout, a_comps, false);
01167
01168 }
01169 if(error != 0) return 4;
01170
01171 a_handle.setGroup(currentGroup);
01172
01173 return 0;
01174 }
01175
01176
01177
01178 #endif // HDF5_H
01179
01180 #endif // HDF5