00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef AMROC_HIERARCHYSTORAGE_H
00010 #define AMROC_HIERARCHYSTORAGE_H
00011
00019 #include <cassert>
00020 #include <unistd.h>
00021 #include <vector>
00022 #include <utility>
00023
00024 #include "GridData3.h"
00025 #include "DAGHIO_hdf_ncsa.h"
00026 #include "BBoxList.h"
00027
00034 template <class DataType>
00035 class HierarchyStorage {
00036 public:
00037 typedef GridData<DataType,3> data_block_type;
00038 typedef std::pair<data_block_type*,int> storage_type;
00039 typedef std::vector<storage_type> block_list_type;
00040
00041 public:
00042 HierarchyStorage(int nl) : _NLevels(nl), _RealTime(0.0) {
00043 _BlockList = new block_list_type*[_NLevels];
00044 for (int i=0; i<_NLevels; i++)
00045 _BlockList[i] = new block_list_type;
00046 }
00047
00048 ~HierarchyStorage() {
00049 for (int i=0; i<_NLevels; i++) {
00050 for (typename block_list_type::iterator bit=BlockList(i).begin();
00051 bit!=BlockList(i).end(); bit++)
00052 delete (*bit).first;
00053 BlockList(i).clear();
00054 delete _BlockList[i];
00055 }
00056 delete _BlockList;
00057 }
00058
00059 int ReadIn(char* fname, int Symmetry[], int Periodic[],
00060 int Eliminate, DataType EliminateValue, const int& MaxProcs) {
00061
00062 char dataname[256];
00063 char filename[256];
00064 int32 level,gridID,step,rank,proc;
00065 int result;
00066 int32 ori[3],dims[3],res[4];
00067 int i,j,k,ii,jj,kk,s,ss,sss,maxlevel=0;
00068 int maxsize[3] = { 0, 0, 0};
00069 short olap[3] = { 0, 0, 0};
00070 bool parData=false, NoData=true;
00071
00072 std::sprintf(filename,"%s.hdf",fname);
00073 if (access(filename, F_OK)) parData = true;
00074
00075 for (int me=0; me<MaxProcs; me++) {
00076 if (parData) {
00077 std::sprintf(filename,"%s.%d.hdf",fname,me);
00078 if (access(filename, F_OK)) continue;
00079 }
00080 if (access(filename, R_OK)) {
00081 std::cerr << "No read permission on " << filename << " !" << std::endl;
00082 return -1;
00083 }
00084 if (access(filename, W_OK)) {
00085 std::cerr << "No write permission on " << filename << " !"
00086 << std::endl;
00087 return -1;
00088 }
00089
00090 do{
00091
00092 result=AMRreadAttribs(filename,dataname,&proc,&level,&gridID,&step,
00093 &_RealTime,&rank,dims,ori,res);
00094
00095 if(result>=0){
00096 if (SDSgetNT(filename)!=DFNT_FLOAT32 && sizeof(DataType)==4) {
00097 std::cerr << "Numbertype must be float!" << std::endl;
00098 return -1;
00099 }
00100 if (SDSgetNT(filename)!=DFNT_FLOAT64 && sizeof(DataType)==8) {
00101 std::cerr << "Numbertype must be double!" << std::endl;
00102 return -1;
00103 }
00104
00105 i=ori[0];
00106 j=ori[1];
00107 k=ori[2];
00108 s=res[0];
00109 ss=res[1];
00110 sss=res[2];
00111 ii=i+s*(dims[0]-1);
00112 jj=j+ss*(dims[1]-1);
00113 kk=k+sss*(dims[2]-1);
00114
00115 if(level>maxlevel) maxlevel=level;
00116 if(ii+s>maxsize[0]) maxsize[0]=ii+s;
00117 if(jj+s>maxsize[1]) maxsize[1]=jj+s;
00118 if(kk+s>maxsize[2]) maxsize[2]=kk+s;
00119
00120 if (Eliminate) {
00121 BBox tmpbb(3,i,j,k,ii,jj,kk,s,ss,sss);
00122 Coords step(3,s,ss,sss);
00123 data_block_type tmpblock(tmpbb);
00124 AMRreadData(filename,rank,dims,tmpblock.data());
00125
00126 BBoxList cbbl, obbl;
00127 BeginFastIndex3(tmp, tmpblock.bbox(), tmpblock.data(), DataType);
00128 for_3 (n,m,l,tmpblock.bbox(),step)
00129 if (FastIndex3(tmp,n,m,l)==EliminateValue)
00130 cbbl.add(BBox(3,n,m,l,n,m,l,s,ss,sss));
00131 end_for
00132 EndFastIndex3(tmp);
00133
00134 obbl.add(tmpblock.bbox());
00135 obbl -= cbbl;
00136 obbl.mergeboxes(olap);
00137 for (BBox *bb=obbl.first();bb;bb=obbl.next()) {
00138 BlockList(level).push_back(storage_type(new data_block_type(*bb),proc));
00139 BlockList(level).back().first->equals(tmpblock,*bb);
00140 }
00141 }
00142 else {
00143 BlockList(level).push_back(storage_type(new data_block_type(i,j,k,ii,jj,kk,s,ss,sss),proc));
00144 AMRreadData(filename,rank,dims,BlockList(level).back().first->data());
00145 }
00146 NoData = false;
00147 }
00148
00149 } while(result>=0);
00150 SDSclose(filename);
00151 if (!parData) break;
00152 }
00153 if (NoData) {
00154 std::cerr << "Nothing read for " << filename << " !" << std::endl;
00155 return -1;
00156 }
00157
00158 for (int d=0; d<3; d++)
00159 if (Symmetry[d] != 0)
00160
00161 for (level=0;level<=maxlevel; level++){
00162 block_list_type TempStorage;
00163 typename block_list_type::iterator bit;
00164 for (bit=BlockList(level).begin();bit!=BlockList(level).end();bit++)
00165 {
00166 if (Symmetry[d] > 0) {
00167 BBox bbwork = (*bit).first->bbox();
00168 bbwork.lower(d)=2*maxsize[d]-(*bit).first->bbox().upper(d)-
00169 (*bit).first->bbox().stepsize(d);
00170 bbwork.upper(d)=2*maxsize[d]-(*bit).first->bbox().lower(d)-
00171 (*bit).first->bbox().stepsize(d);
00172 TempStorage.push_back(storage_type(new data_block_type(bbwork),(*bit).second));
00173
00174 BeginFastIndex3(source,(*bit).first->bbox(),
00175 (*bit).first->data(), DataType);
00176 BeginFastIndex3(target, TempStorage.back().first->bbox(),
00177 TempStorage.back().first->data(), DataType);
00178 switch(d) {
00179 case 0:
00180 for_3 (n, m, l,(*bit).first->bbox(), (*bit).first->bbox().stepsize())
00181 FastIndex3(target, 2*maxsize[0]-n-(*bit).first->bbox().stepsize(0),
00182 m,l) = FastIndex3(source,n,m,l);
00183 end_for
00184 break;
00185 case 1:
00186 for_3 (n, m, l,(*bit).first->bbox(), (*bit).first->bbox().stepsize())
00187 FastIndex3(target,n, 2*maxsize[1]-m-(*bit).first->bbox().stepsize(1),
00188 l) = FastIndex3(source,n,m,l);
00189 end_for
00190 break;
00191 default:
00192 for_3 (n, m, l,(*bit).first->bbox(), (*bit).first->bbox().stepsize())
00193 FastIndex3(target,n,m,2*maxsize[2]-l-(*bit).first->bbox().stepsize(2)
00194 ) = FastIndex3(source,n,m,l);
00195 end_for
00196 break;
00197 }
00198 EndFastIndex3(source);
00199 EndFastIndex3(target);
00200 }
00201
00202 else {
00203 BBox bbwork = (*bit).first->bbox();
00204 bbwork.lower(d)=maxsize[d]+(*bit).first->bbox().lower(d);
00205 bbwork.upper(d)=maxsize[d]+(*bit).first->bbox().upper(d);
00206 TempStorage.push_back(storage_type(new data_block_type(bbwork),(*bit).second));
00207 TempStorage.back().first->copy(
00208 *((*bit).first),TempStorage.back().first->bbox(),
00209 (*bit).first->bbox());
00210
00211 bbwork = (*bit).first->bbox();
00212 bbwork.lower(d)=maxsize[d]-(*bit).first->bbox().upper(d)-
00213 (*bit).first->bbox().stepsize(d);
00214 bbwork.upper(d)=maxsize[d]-(*bit).first->bbox().lower(d)-
00215 (*bit).first->bbox().stepsize(d);
00216 TempStorage.push_back(storage_type(new data_block_type(bbwork),(*bit).second));
00217
00218 BeginFastIndex3(source,(*bit).first->bbox(),
00219 (*bit).first->data(), DataType);
00220 BeginFastIndex3(target, TempStorage.back().first->bbox(),
00221 TempStorage.back().first->data(), DataType);
00222 switch(d) {
00223 case 0:
00224 for_3 (n, m, l, (*bit).first->bbox(),(*bit).first->bbox().stepsize())
00225 FastIndex3(target, maxsize[0]-n-(*bit).first->bbox().stepsize(0),
00226 m,l) = FastIndex3(source,n,m,l);
00227 end_for
00228 break;
00229 case 1:
00230 for_3 (n, m, l, (*bit).first->bbox(),(*bit).first->bbox().stepsize())
00231 FastIndex3(target,n, maxsize[1]-m-(*bit).first->bbox().stepsize(1),
00232 l) = FastIndex3(source,n,m,l);
00233 end_for
00234 break;
00235 default:
00236 for_3 (n, m, l, (*bit).first->bbox(),(*bit).first->bbox().stepsize())
00237 FastIndex3(target,n,m,maxsize[2]-l-(*bit).first->bbox().stepsize(2)
00238 ) = FastIndex3(source,n,m,l);
00239 end_for
00240 break;
00241 }
00242 EndFastIndex3(source);
00243 EndFastIndex3(target);
00244 }
00245 }
00246
00247 if (Symmetry[d] < 0) {
00248 for (bit=BlockList(level).begin();bit!=BlockList(level).end(); bit++)
00249 delete (*bit).first;
00250 BlockList(level).clear();
00251 }
00252
00253 for(bit=TempStorage.begin();bit!=TempStorage.end();bit++)
00254 BlockList(level).push_back(storage_type((*bit).first,(*bit).second));
00255 TempStorage.clear();
00256 }
00257
00258 else if (Periodic[d] > 0)
00259
00260 for (level=0;level<=maxlevel; level++){
00261 block_list_type TempStorage;
00262 typename block_list_type::iterator bit;
00263 for (bit=BlockList(level).begin();bit!=BlockList(level).end();bit++)
00264 for (int pc=1; pc<=Periodic[d]; pc++) {
00265 BBox bbwork = (*bit).first->bbox();
00266 bbwork.lower(d)=pc*maxsize[d]+(*bit).first->bbox().lower(d);
00267 bbwork.upper(d)=pc*maxsize[d]+(*bit).first->bbox().upper(d);
00268 TempStorage.push_back(
00269 storage_type(new data_block_type(bbwork),(*bit).second));
00270 TempStorage.back().first->copy(
00271 *(*bit).first, bbwork, (*bit).first->bbox());
00272 }
00273
00274 for (bit=TempStorage.begin();bit!=TempStorage.end();bit++)
00275 BlockList(level).push_back(
00276 storage_type((*bit).first,(*bit).second));
00277 TempStorage.clear();
00278 }
00279 return (parData ? 1 : 0);
00280 }
00281
00282
00283 block_list_type& BlockList(int Level) {
00284 assert(Level >=0 && Level < _NLevels);
00285 return (*_BlockList[Level]);
00286 }
00287
00288 inline const int& NLevels() const { return _NLevels; }
00289 inline int NLevels() { return _NLevels; }
00290 inline float64 RealTime() const { return _RealTime; }
00291
00292 private:
00293 int _NLevels;
00294 float64 _RealTime;
00295 block_list_type** _BlockList;
00296 };
00297
00298
00299 #endif