Blockstructured Adaptive Mesh Refinement in object-oriented C++
00001 00006 #include "PeanoHilbert.h" 00007 00008 /* 00009 ************************************************************************* 00010 * * 00011 * int PeanoHilbert::phGray(const int level) * 00012 * int PeanoHilbert::phGinv(const int level) * 00013 * * 00014 * Member functions phGray and phGinv perform a gray/inverse * 00015 * mapping of the sfcbasew digit corresponding to level "level" * 00016 * * 00017 ************************************************************************* 00018 */ 00019 00020 int PeanoHilbert::phGray(const int level) 00021 { 00022 register int tmp = sfcGetDigit(level); 00023 tmp^=(tmp>>1); 00024 sfcSetDigit(level,tmp); 00025 00026 return tmp; 00027 } 00028 00029 int PeanoHilbert::phGinv(const int level) 00030 { 00031 register int tmp = sfcGetDigit(level); 00032 register int tmp1 = tmp; 00033 while ( tmp1 > 0 ) { 00034 tmp1 >>= 1 ; 00035 tmp ^= tmp1 ; 00036 } 00037 sfcSetDigit(level,tmp); 00038 00039 return tmp; 00040 } 00041 00042 /* 00043 ************************************************************************* 00044 * * 00045 * void PeanoHilbert::Invert(int *coords, const int index) * 00046 * * 00047 * Member function Invert generates the sfcdim coordinate values * 00048 * corresponding to "index". * 00049 * * 00050 ************************************************************************* 00051 */ 00052 00053 void PeanoHilbert::Invert(int *coords, const int index) 00054 { 00055 sfcSetIndex(index); 00056 Invert(coords); 00057 } 00058 00059 /* 00060 ************************************************************************* 00061 * * 00062 * void PeanoHilbert::Invert(int *coords, const int index, * 00063 * const int idxlev) * 00064 * * 00065 * Member function Invert generates the sfcdim coordinate values * 00066 * corresponding to index "index" at level "idxlevel". * 00067 * * 00068 ************************************************************************* 00069 */ 00070 00071 void PeanoHilbert::Invert(int *coords, const int index, 00072 const int idxlev) 00073 { 00074 sfcSetIndex(index,idxlev); 00075 Invert(coords); 00076 } 00077 00078 /* 00079 ************************************************************************* 00080 * * 00081 * void PeanoHilbert::Invert(int *coords, const int index, * 00082 * const int idxlev, const int nlev) * 00083 * * 00084 * Member function Invert generates the sfcdim coordinate values * 00085 * corresponding to index "index" at level "idxlevel"and for "nlev * 00086 * levels. * 00087 * * 00088 ************************************************************************* 00089 */ 00090 00091 void PeanoHilbert::Invert(int *coords, const int index, 00092 const int idxlev, const int nlev) 00093 { 00094 sfcSetIndex(index,idxlev,nlev); 00095 Invert(coords); 00096 } 00097 00098 /* 00099 *************************************************************************** 00100 * * 00101 * void PeanoHilbert::ResetBase(const int lev, const int extent) * 00102 * * 00103 * Member function ResetBase set the index to the baseindex at the level * 00104 * * 00105 *************************************************************************** 00106 */ 00107 00108 void PeanoHilbert::ResetBase(const int lev, const int extent) 00109 { 00110 #ifdef DEBUG_PRINT 00111 assert(extent >= 0 && lev >= extent && lev <= sfclevs); 00112 #endif 00113 00114 for (register int i=lev-extent+1;i<=sfclevs;i++) 00115 sfcSetDigit(i,(int)0); 00116 00117 } 00118 00119 /* 00120 ************************************************************************* 00121 * * 00122 * void PeanoHilbert::phOrient(const int level, const int pos) * 00123 * * 00124 * Member function phOrient modifys the digit corresponding to * 00125 * sfcIndexUnit at level "level" as per the orientation defined by "pos".* 00126 * This routine currently is defined for 2 and 3 dimensions. It will * 00127 * have to modified to reorient for higher dimensions. * 00128 * * 00129 ************************************************************************* 00130 */ 00131 00132 void PeanoHilbert::phOrient(const int level, const int pos) 00133 { 00134 00135 #ifdef DEBUG_PRINT 00136 assert(sfcdim <= 3); 00137 #endif 00138 00139 switch(sfcdim) 00140 { 00141 case 1: 00142 break; 00143 case 2: 00144 switch(pos) 00145 { 00146 case 0: 00147 phRotate(level,1,2); 00148 break; 00149 case 1: case 3: 00150 break; 00151 case 2: 00152 phRotate(level,1,2); 00153 phTranslate(level,1); 00154 phSwapDir(level,2); 00155 break; 00156 default: 00157 break; 00158 } 00159 break; 00160 case 3: 00161 switch(pos) 00162 { 00163 case 0: 00164 phRotate(level,1,3); 00165 break; 00166 case 1: case 3: 00167 phRotate(level,1,2); 00168 break; 00169 case 2: case 6: 00170 phTranslate(level,2); 00171 phTranslate(level,3); 00172 break; 00173 case 4: 00174 phRotate(level,1,3); 00175 phTranslate(level,1); 00176 phSwapDir(level,3); 00177 break; 00178 case 5: case 7: 00179 phRotate(level,1,2); 00180 phTranslate(level,1); 00181 phSwapDir(level,2); 00182 break; 00183 default: 00184 break; 00185 } 00186 break; 00187 } 00188 } 00189 00190 /* 00191 ************************************************************************* 00192 * * 00193 * void PeanoHilbert::Map(const int *coords) * 00194 * * 00195 * Member function Map generates the sfcIndex corresponding to "c" * 00196 * * 00197 ************************************************************************* 00198 */ 00199 00200 void PeanoHilbert::Map(const int *coords) 00201 { 00202 00203 register int i,j; 00204 #ifdef DEBUG_PRINT 00205 register int cmax = GetDimMax(sfclevs); 00206 for(i=0;i<sfcdim;i++) 00207 assert(coords[i] <= cmax); 00208 //assert(coords[i] >= 0 && coords[i] <= cmax); 00209 #endif 00210 00211 /* Initial orientation */ 00212 /* ph_pos = 0; | */ 00213 int ph_pos = -1; /* -> */ 00214 00215 sfcCreateLocNum(coords); 00216 00217 for (i=1;i<=sfclevs;i++) { 00218 for (j=i;j<=sfclevs;j++) 00219 phOrient(j,ph_pos); 00220 00221 ph_pos = sfcGetDigit(i); 00222 phGinv(i); 00223 } 00224 } 00225 00226 /* 00227 ************************************************************************* 00228 * * 00229 * void PeanoHilbert::Invert(int *coords) const * 00230 * * 00231 * Member function Invert generates the sfcdim coordinate values * 00232 * corresponding to the index currently stored in the sfcIndex. * 00233 * * 00234 ************************************************************************* 00235 */ 00236 00237 void PeanoHilbert::Invert(int *coords) const 00238 { 00239 00240 #ifdef DEBUG_PRINT 00241 assert(coords != 0); 00242 //if (!coords) coords = new int[sfcdim]; 00243 #endif 00244 00245 PeanoHilbert phtmp(*this); 00246 00247 register int i,j; 00248 for (i=sfclevs;i>0;i--) 00249 phtmp.phGray(i); 00250 00251 for (i=sfclevs;i>0;i--) 00252 for (j=i-1;j>0;j--) 00253 phtmp.phOrient(i,phtmp.sfcGetDigit(j)); 00254 00255 phtmp.sfcGetCoords(coords); 00256 00257 } 00258 00259 /* 00260 *************************************************************************** 00261 * * 00262 * PeanoHilbert *PeanoHilbert::GetBox(const int lev, const int nlev) const * 00263 * * 00264 * Member function GetBox returns the index corresponding to the * 00265 * upper bound of the of the dim sfcdim cube with extent nlev * 00266 * rooted at the PH index stored in "this". * 00267 * This routine is used to get the bounding box of the GridUnit whose * 00268 * baseindex is maintained by this. * 00269 * * 00270 * This routine has be defined of 2 and 3 dimensions only. * 00271 * * 00272 *************************************************************************** 00273 */ 00274 00275 PeanoHilbert *PeanoHilbert::GetBox(const int lev, const int nlev) const 00276 { 00277 00278 #ifdef DEBUG_PRINT 00279 assert(nlev >= 0 && lev >= nlev && lev <= sfclevs); 00280 assert(sfcdim <= 3); 00281 #endif 00282 00283 PeanoHilbert *phtmp = new PeanoHilbert(*this); 00284 00285 if(nlev == 0) return phtmp; 00286 00287 register int i; 00288 switch(sfcdim) 00289 { 00290 case 3: 00291 /* 00292 // digits at lev + i should be 0 since the sfcindex 00293 // corresponds to a GridUnit at level lev; and so we 00294 // can set it instead of xor-ing it with the original 00295 // stored value. 00296 // phtmp->sfcSetDigit(lev+1,(sfcGetDigit(i)^5)); 00297 // for (i=lev+2;i<=lev+nlev;i++) { 00298 // phtmp->sfcSetDigit(i,(sfcGetDigit(i)^1)); 00299 // } 00300 */ 00301 phtmp->sfcSetDigit(lev-nlev+1,5); 00302 for (i=lev-nlev+2;i<=lev;i++) 00303 phtmp->sfcSetDigit(i,1); 00304 00305 break; 00306 00307 case 2: 00308 /* 00309 //for (i=lev+1;i<lev+nlev;i++) 00310 // phtmp->sfcSetDigit(i,(sfcGetDigit(i)^2)); 00311 */ 00312 for (i=lev-nlev+1;i<=lev;i++) 00313 phtmp->sfcSetDigit(i,2); 00314 00315 break; 00316 00317 case 1: 00318 for (i=lev-nlev+1;i<=lev;i++) 00319 phtmp->sfcMaxDigit(i); 00320 00321 break; 00322 } 00323 00324 return phtmp; 00325 } 00326 00327 void PeanoHilbert::SetBox(const int lev, const int nlev) 00328 { 00329 00330 #ifdef DEBUG_PRINT 00331 assert(nlev >= 0 && lev >= nlev && lev <= sfclevs); 00332 assert(sfcdim <= 3); 00333 #endif 00334 00335 if(nlev == 0) return; 00336 00337 register int i; 00338 switch(sfcdim) 00339 { 00340 case 3: 00341 sfcIndex::sfcSetDigit(lev-nlev+1,5); 00342 for (i=lev-nlev+2;i<=lev;i++) sfcIndex::sfcSetDigit(i,1); 00343 for (i=lev+1;i<=sfclevs;i++) sfcIndex::sfcUnsetDigit(i); 00344 break; 00345 00346 case 2: 00347 for (i=lev-nlev+1;i<=lev;i++) sfcIndex::sfcSetDigit(i,2); 00348 for (i=lev+1;i<=sfclevs;i++) sfcIndex::sfcUnsetDigit(i); 00349 break; 00350 00351 case 1: 00352 for (i=lev-nlev+1;i<=lev;i++) sfcIndex::sfcMaxDigit(i); 00353 for (i=lev+1;i<=sfclevs;i++) sfcIndex::sfcUnsetDigit(i); 00354 break; 00355 } 00356 } 00357 00358 /* 00359 *************************************************************************** 00360 * * 00361 * PeanoHilbert *PeanoHilbert::GetMax(const int lev, const int nlev) const * 00362 * * 00363 * Member function GetMax returns the index corresponding to the * 00364 * maximum index in the dim sfcdim cube with extent nlev rooted at the PH * 00365 * index stored in "this". * 00366 * * 00367 *************************************************************************** 00368 */ 00369 00370 PeanoHilbert *PeanoHilbert::GetMax(const int lev, const int nlev) const 00371 { 00372 00373 #ifdef DEBUG_PRINT 00374 assert(nlev >= 0 && lev >= nlev && lev <= sfclevs); 00375 #endif 00376 00377 PeanoHilbert *phtmp = new PeanoHilbert(*this); 00378 00379 if(nlev == 0) return phtmp; 00380 00381 for (register int i=lev-nlev+1;i<=lev;i++) 00382 phtmp->sfcMaxDigit(i); 00383 00384 return phtmp; 00385 } 00386 00387 void PeanoHilbert::SetMax(const int lev, const int nlev) 00388 { 00389 #ifdef DEBUG_PRINT 00390 assert(nlev >= 0 && lev >= nlev && lev <= sfclevs); 00391 #endif 00392 if(nlev == 0) return; 00393 register int i; 00394 for (i=lev-nlev+1;i<=lev;i++) sfcMaxDigit(i); 00395 for (i=lev+1;i<=sfclevs;i++) sfcUnsetDigit(i); 00396 } 00397 00398 /* 00399 ************************************************************************* 00400 * * 00401 * void PeanoHilbert::GetCoords(int *coords, const int lev) const * 00402 * * 00403 * Member function GetCoords returns a copy of the coordinates in "c" at * 00404 * level "lev" of refinement. * 00405 * * 00406 ************************************************************************* 00407 */ 00408 00409 void PeanoHilbert::GetCoords(int *coords, const int lev) const 00410 { 00411 #ifdef DEBUG_PRINT 00412 assert(lev > 0 && lev <= sfclevs); 00413 #endif 00414 00415 register int h = GetDimCardinality(lev); 00416 00417 Invert(coords); 00418 00419 for (register int i=0;i<sfcdim;i++) { 00420 coords[i] = (coords[i]/h)*h; 00421 } 00422 00423 } 00424 00425 int *PeanoHilbert::GetCoords(const int lev) const 00426 { 00427 #ifdef DEBUG_PRINT 00428 assert(lev > 0 && lev <= sfclevs); 00429 #endif 00430 00431 register int h = GetDimCardinality(lev); 00432 int *coords = new int[sfcdim]; 00433 00434 Invert(coords); 00435 00436 for (register int i=0;i<sfcdim;i++) coords[i] = (coords[i]/h)*h; 00437 00438 return (coords); 00439 } 00440 00441 /*********************** 00442 ostream& operator << (ostream& os, PeanoHilbert& ph) 00443 { 00444 if (&ph == (PeanoHilbert *)NULL) return os; 00445 00446 for (int i=0;i<=ph.sfclevs;i++) os << ph.sfcGetIndex(i,1); 00447 00448 os << "\n"; 00449 00450 return os; 00451 } 00452 ***********************/
Quickstart Users Guide Programmers Reference Installation Examples Download
AMROC Main Home Contactlast update: 06/01/04