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
00028 #define MAXLEV 11
00029
00036 template <class DataType>
00037 class HierarchyStorage {
00038 public:
00039 typedef GridData<DataType,3> data_block_type;
00040 typedef std::pair<data_block_type*,int> storage_type;
00041 typedef std::vector<storage_type> block_list_type;
00042
00043 public:
00044 HierarchyStorage(int nl) : _NLevels(nl), _RealTime(0.0) {
00045 _BlockList = new block_list_type*[_NLevels];
00046 for (int i=0; i<_NLevels; i++)
00047 _BlockList[i] = new block_list_type;
00048 }
00049
00050 ~HierarchyStorage() {
00051 for (int i=0; i<_NLevels; i++) {
00052 for (typename block_list_type::iterator bit=BlockList(i).begin();
00053 bit!=BlockList(i).end(); bit++)
00054 delete (*bit).first;
00055 BlockList(i).clear();
00056 delete _BlockList[i];
00057 }
00058 delete _BlockList;
00059 }
00060
00061 int ReadIn(char* fname, int RefineFactor[], Coords DimUsed, int Symmetry[], int Periodic[],
00062 int Eliminate, DataType EliminateValue, const int& MaxProcs,
00063 BBox *_where, BBox *_to, BBox *_from, const int& RestrictData) {
00064
00065 char dataname[256];
00066 char filename[256];
00067 int32 level,gridID,step,rank,proc;
00068 int result;
00069 int32 ori[3],dims[3],res[4];
00070 int i,j,k,ii,jj,kk,s,ss,sss,maxlevel=0;
00071 int maxsize[3] = { 0, 0, 0};
00072 short olap[3] = { 0, 0, 0};
00073 bool parData=false, NoData=true;
00074
00075 std::sprintf(filename,"%s.hdf",fname);
00076 if (access(filename, F_OK)) parData = true;
00077
00078 for (int me=0; me<MaxProcs; me++) {
00079 if (parData) {
00080 std::sprintf(filename,"%s.%d.hdf",fname,me);
00081 if (access(filename, F_OK)) continue;
00082 }
00083 if (access(filename, R_OK)) {
00084 std::cerr << "No read permission on " << filename << " !" << std::endl;
00085 return -1;
00086 }
00087 if (access(filename, W_OK)) {
00088 std::cerr << "No write permission on " << filename << " !"
00089 << std::endl;
00090 return -1;
00091 }
00092
00093 do{
00094
00095 result=AMRreadAttribs(filename,dataname,&proc,&level,&gridID,&step,
00096 &_RealTime,&rank,dims,ori,res);
00097
00098 if(result>=0){
00099 if (SDSgetNT(filename)!=DFNT_FLOAT32 && sizeof(DataType)==4) {
00100 std::cerr << "Numbertype must be float!" << std::endl;
00101 return -1;
00102 }
00103 if (SDSgetNT(filename)!=DFNT_FLOAT64 && sizeof(DataType)==8) {
00104 std::cerr << "Numbertype must be double!" << std::endl;
00105 return -1;
00106 }
00107
00108 i=ori[0];
00109 j=ori[1];
00110 k=ori[2];
00111 s=res[0];
00112 ss=res[1];
00113 sss=res[2];
00114 ii=i+s*(dims[0]-1);
00115 jj=j+ss*(dims[1]-1);
00116 kk=k+sss*(dims[2]-1);
00117
00118 if(level>maxlevel) maxlevel=level;
00119 if(ii+s>maxsize[0]) maxsize[0]=ii+s;
00120 if(jj+s>maxsize[1]) maxsize[1]=jj+s;
00121 if(kk+s>maxsize[2]) maxsize[2]=kk+s;
00122
00123 if (Eliminate) {
00124 BBox tmpbb(3,i,j,k,ii,jj,kk,s,ss,sss);
00125 Coords step(3,s,ss,sss);
00126 data_block_type tmpblock(tmpbb);
00127 AMRreadData(filename,rank,dims,tmpblock.data());
00128
00129 BBoxList cbbl, obbl;
00130 BeginFastIndex3(tmp, tmpblock.bbox(), tmpblock.data(), DataType);
00131 for_3 (n,m,l,tmpblock.bbox(),step)
00132 if (FastIndex3(tmp,n,m,l)==EliminateValue)
00133 cbbl.add(BBox(3,n,m,l,n,m,l,s,ss,sss));
00134 end_for
00135 EndFastIndex3(tmp);
00136
00137 obbl.add(tmpblock.bbox());
00138 obbl -= cbbl;
00139 obbl.mergeboxes(olap);
00140 for (BBox *bb=obbl.first();bb;bb=obbl.next()) {
00141 BlockList(level).push_back(storage_type(new data_block_type(*bb),proc));
00142 BlockList(level).back().first->equals(tmpblock,*bb);
00143 }
00144 }
00145 else {
00146 BBox tmpbb(3,i,j,k,ii,jj,kk,s,ss,sss);
00147 Coords step(3,s,ss,sss);
00148 BlockList(level).push_back(storage_type(new data_block_type(tmpbb),proc));
00149 AMRreadData(filename,rank,dims,BlockList(level).back().first->data());
00150 BeginFastIndex3(tmp, tmpbb, BlockList(level).back().first->data(), DataType);
00151 for_3 (n,m,l,tmpbb,step)
00152 if (FastIndex3(tmp,n,m,l)==EliminateValue)
00153 FastIndex3(tmp,n,m,l) = FLT_MAX;
00154 end_for
00155 EndFastIndex3(tmp);
00156 }
00157 NoData = false;
00158
00159 if (BlockList(level).size()>0) {
00160 if (!_where[level].empty()) {
00161 BBox where(_where[level]);
00162 Coords ss(BlockList(level).back().first->stepsize());
00163 for (int i=0;i<3;i++) {
00164 if (where.stepsize(i)>ss(i))
00165 where.refine(i,where.stepsize(i)/ss(i),0);
00166 else where.coarsen(i,ss(i)/where.stepsize(i));
00167 }
00168 BBox tmpbb = BlockList(level).back().first->bbox()*where;
00169 std::cerr << ".";
00170 data_block_type* tmpblock = new data_block_type(tmpbb);
00171 tmpblock->equals(*(BlockList(level).back().first));
00172 delete BlockList(level).back().first;
00173 BlockList(level).back().first = tmpblock;
00174 }
00175 else {
00176 unsigned int cp=BlockList(level).size()-1;
00177 Coords ss(BlockList(level).at(cp).first->stepsize());
00178 for (register int lev=0; lev<MAXLEV; lev++) {
00179 if (!_to[lev].empty() && !_from[lev].empty() && ss==_from[lev].stepsize()) {
00180 BBox to(_to[lev]), from(_from[lev]);
00181 BBox bb(BlockList(level).at(cp).first->bbox());
00182 Coords cs;
00183 for (int i=0;i<3;i++)
00184 if (from.extents(i)/to.extents(i)>1)
00185 cs(i) = from.extents(i)/to.extents(i);
00186 else cs(i) = 1;
00187
00188 data_block_type* tmpblock = new data_block_type(coarsen(bb,cs));
00189 BeginFastIndex3(src, bb, BlockList(level).at(cp).first->data(), DataType);
00190 BeginFastIndex3(tmp, tmpblock->bbox(), tmpblock->data(), DataType);
00191 for_3 (n,m,l,tmpblock->bbox(),tmpblock->stepsize())
00192 FastIndex3(tmp,n,m,l)=0.;
00193 BBox bbadd(3,n,m,l,n,m,l,tmpblock->stepsize(0),tmpblock->stepsize(1),tmpblock->stepsize(2));
00194 bbadd.refine(cs); bbadd*=bb;
00195 for_3 (nn,mm,ll,bbadd,bbadd.stepsize())
00196 FastIndex3(tmp,n,m,l)+=FastIndex3(src,nn,mm,ll);
00197 end_for
00198 FastIndex3(tmp,n,m,l)/=bbadd.size();
00199 end_for
00200 EndFastIndex3(tmp);
00201 EndFastIndex3(src);
00202
00203 BBox newbb(tmpblock->bbox());
00204 Coords ex = newbb.extents();
00205 newbb.stepsize() = to.stepsize();
00206 newbb.lower() += to.lower()-from.lower();
00207 newbb.lower() /= (from.extents()*from.stepsize())/(to.extents()*to.stepsize());
00208 newbb.upper() = newbb.lower()-newbb.stepsize()+ex*newbb.stepsize();
00209 std::cerr << ".";
00210 DataType *data;
00211 tmpblock->deallocate(data);
00212 delete tmpblock;
00213 delete BlockList(level).at(cp).first;
00214 BlockList(level).erase(BlockList(level).begin()+cp);
00215 data_block_type* newblock = new data_block_type(newbb,data);
00216 BlockList(lev).push_back(storage_type(newblock,proc));
00217 if (lev>maxlevel) maxlevel=lev;
00218 }
00219 }
00220 }
00221 }
00222 }
00223
00224 } while(result>=0);
00225 SDSclose(filename);
00226 if (!parData) break;
00227 }
00228 if (NoData) {
00229 std::cerr << "Nothing read for " << filename << " !" << std::endl;
00230 return -1;
00231 }
00232
00233 if (RestrictData != 0) {
00234 for (level=maxlevel;level>0; level--){
00235 std::cerr << "Restrict level " << level;
00236 typename block_list_type::iterator bit;
00237 if (BlockList(level-1).empty()) {
00238 BBoxList bblc;
00239 for (bit=BlockList(level).begin();bit!=BlockList(level).end();bit++)
00240 bblc.add((*bit).first->bbox());
00241 short olap[DAGHMaxRank];
00242 for (int i=0;i<DAGHMaxRank;i++) olap[i]=0;
00243 bblc.mergeboxes(olap);
00244 for (BBox *_b = bblc.first();_b;_b=bblc.next()) {
00245 for (int i=0;i<3;i++)
00246 if (DimUsed(i)) _b->coarsen(i,RefineFactor[level-1]);
00247 BlockList(level-1).push_back(storage_type(new data_block_type(*_b),0));
00248 }
00249 }
00250 for (bit=BlockList(level).begin();bit!=BlockList(level).end();bit++) {
00251 BBox bb = (*bit).first->bbox();
00252 typename block_list_type::iterator bitc;
00253 for (bitc=BlockList(level-1).begin();bitc!=BlockList(level-1).end();bitc++) {
00254 BBox bbc = (*bitc).first->bbox();
00255 Coords cs = bbc.stepsize()/bb.stepsize();
00256 BBox bbwork(bbc * coarsen(bb,cs));
00257 if (!bbwork.empty()) {
00258 std::cerr << ".";
00259 BeginFastIndex3(src, bb, (*bit).first->data(), DataType);
00260 BeginFastIndex3(dst, bbc, (*bitc).first->data(), DataType);
00261 for_3 (n,m,l,bbwork,bbwork.stepsize())
00262 FastIndex3(dst,n,m,l)=0.;
00263 BBox bbadd(3,n,m,l,n,m,l,bbwork.stepsize(0),bbwork.stepsize(1),bbwork.stepsize(2));
00264 bbadd.refine(cs); bbadd*=bb;
00265 for_3 (nn,mm,ll,bbadd,bbadd.stepsize())
00266 FastIndex3(dst,n,m,l)+=FastIndex3(src,nn,mm,ll);
00267 end_for
00268 FastIndex3(dst,n,m,l)/=bbadd.size();
00269 end_for
00270 EndFastIndex3(dst);
00271 EndFastIndex3(src);
00272 }
00273 }
00274 }
00275 std::cerr << std::endl;
00276 }
00277 }
00278
00279 for (int d=0; d<3; d++)
00280 if (Symmetry[d] != 0)
00281
00282 for (level=0;level<=maxlevel; level++){
00283 block_list_type TempStorage;
00284 typename block_list_type::iterator bit;
00285 for (bit=BlockList(level).begin();bit!=BlockList(level).end();bit++)
00286 {
00287 if (Symmetry[d] > 0) {
00288 BBox bbwork = (*bit).first->bbox();
00289 bbwork.lower(d)=2*maxsize[d]-(*bit).first->bbox().upper(d)-
00290 (*bit).first->bbox().stepsize(d);
00291 bbwork.upper(d)=2*maxsize[d]-(*bit).first->bbox().lower(d)-
00292 (*bit).first->bbox().stepsize(d);
00293 TempStorage.push_back(storage_type(new data_block_type(bbwork),(*bit).second));
00294
00295 BeginFastIndex3(source,(*bit).first->bbox(),
00296 (*bit).first->data(), DataType);
00297 BeginFastIndex3(target, TempStorage.back().first->bbox(),
00298 TempStorage.back().first->data(), DataType);
00299 switch(d) {
00300 case 0:
00301 for_3 (n, m, l,(*bit).first->bbox(), (*bit).first->bbox().stepsize())
00302 FastIndex3(target, 2*maxsize[0]-n-(*bit).first->bbox().stepsize(0),
00303 m,l) = FastIndex3(source,n,m,l);
00304 end_for
00305 break;
00306 case 1:
00307 for_3 (n, m, l,(*bit).first->bbox(), (*bit).first->bbox().stepsize())
00308 FastIndex3(target,n, 2*maxsize[1]-m-(*bit).first->bbox().stepsize(1),
00309 l) = FastIndex3(source,n,m,l);
00310 end_for
00311 break;
00312 default:
00313 for_3 (n, m, l,(*bit).first->bbox(), (*bit).first->bbox().stepsize())
00314 FastIndex3(target,n,m,2*maxsize[2]-l-(*bit).first->bbox().stepsize(2)
00315 ) = FastIndex3(source,n,m,l);
00316 end_for
00317 break;
00318 }
00319 EndFastIndex3(source);
00320 EndFastIndex3(target);
00321 }
00322
00323 else {
00324 BBox bbwork = (*bit).first->bbox();
00325 bbwork.lower(d)=maxsize[d]+(*bit).first->bbox().lower(d);
00326 bbwork.upper(d)=maxsize[d]+(*bit).first->bbox().upper(d);
00327 TempStorage.push_back(storage_type(new data_block_type(bbwork),(*bit).second));
00328 TempStorage.back().first->copy(
00329 *((*bit).first),TempStorage.back().first->bbox(),
00330 (*bit).first->bbox());
00331
00332 bbwork = (*bit).first->bbox();
00333 bbwork.lower(d)=maxsize[d]-(*bit).first->bbox().upper(d)-
00334 (*bit).first->bbox().stepsize(d);
00335 bbwork.upper(d)=maxsize[d]-(*bit).first->bbox().lower(d)-
00336 (*bit).first->bbox().stepsize(d);
00337 TempStorage.push_back(storage_type(new data_block_type(bbwork),(*bit).second));
00338
00339 BeginFastIndex3(source,(*bit).first->bbox(),
00340 (*bit).first->data(), DataType);
00341 BeginFastIndex3(target, TempStorage.back().first->bbox(),
00342 TempStorage.back().first->data(), DataType);
00343 switch(d) {
00344 case 0:
00345 for_3 (n, m, l, (*bit).first->bbox(),(*bit).first->bbox().stepsize())
00346 FastIndex3(target, maxsize[0]-n-(*bit).first->bbox().stepsize(0),
00347 m,l) = FastIndex3(source,n,m,l);
00348 end_for
00349 break;
00350 case 1:
00351 for_3 (n, m, l, (*bit).first->bbox(),(*bit).first->bbox().stepsize())
00352 FastIndex3(target,n, maxsize[1]-m-(*bit).first->bbox().stepsize(1),
00353 l) = FastIndex3(source,n,m,l);
00354 end_for
00355 break;
00356 default:
00357 for_3 (n, m, l, (*bit).first->bbox(),(*bit).first->bbox().stepsize())
00358 FastIndex3(target,n,m,maxsize[2]-l-(*bit).first->bbox().stepsize(2)
00359 ) = FastIndex3(source,n,m,l);
00360 end_for
00361 break;
00362 }
00363 EndFastIndex3(source);
00364 EndFastIndex3(target);
00365 }
00366 }
00367
00368 if (Symmetry[d] < 0) {
00369 for (bit=BlockList(level).begin();bit!=BlockList(level).end(); bit++)
00370 delete (*bit).first;
00371 BlockList(level).clear();
00372 }
00373
00374 for(bit=TempStorage.begin();bit!=TempStorage.end();bit++)
00375 BlockList(level).push_back(storage_type((*bit).first,(*bit).second));
00376 TempStorage.clear();
00377 }
00378
00379 else if (Periodic[d] > 0)
00380
00381 for (level=0;level<=maxlevel; level++){
00382 block_list_type TempStorage;
00383 typename block_list_type::iterator bit;
00384 for (bit=BlockList(level).begin();bit!=BlockList(level).end();bit++)
00385 for (int pc=1; pc<=Periodic[d]; pc++) {
00386 BBox bbwork = (*bit).first->bbox();
00387 bbwork.lower(d)=pc*maxsize[d]+(*bit).first->bbox().lower(d);
00388 bbwork.upper(d)=pc*maxsize[d]+(*bit).first->bbox().upper(d);
00389 TempStorage.push_back(
00390 storage_type(new data_block_type(bbwork),(*bit).second));
00391 TempStorage.back().first->copy(
00392 *(*bit).first, bbwork, (*bit).first->bbox());
00393 }
00394
00395 for (bit=TempStorage.begin();bit!=TempStorage.end();bit++)
00396 BlockList(level).push_back(
00397 storage_type((*bit).first,(*bit).second));
00398 TempStorage.clear();
00399 }
00400 return (parData ? 1 : 0);
00401 }
00402
00403
00404 block_list_type& BlockList(int Level) {
00405 assert(Level >=0 && Level < _NLevels);
00406 return (*_BlockList[Level]);
00407 }
00408
00409 inline const int& NLevels() const { return _NLevels; }
00410 inline int NLevels() { return _NLevels; }
00411 inline float64 RealTime() const { return _RealTime; }
00412
00413 private:
00414 int _NLevels;
00415 float64 _RealTime;
00416 block_list_type** _BlockList;
00417 };
00418
00419
00420 #endif