AMROC Main     Blockstructured Adaptive Mesh Refinement in object-oriented C++


Main Page   Class Hierarchy   Compound List   File List  

PeanoHilbert.C

Go to the documentation of this file.
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      Contact
last update: 06/01/04