Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

peano.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <math.h>
00005 #include <mpi.h>
00006 
00007 #include "allvars.h"
00008 #include "proto.h"
00009 
00019 static struct peano_hilbert_data
00020 {
00021   peanokey key;
00022   int index;
00023 }
00024  *mp;
00025 
00026 static int *Id;
00027 
00028 
00034 void peano_hilbert_order(void)
00035 {
00036   int i;
00037 
00038   if(ThisTask == 0)
00039     printf("begin Peano-Hilbert order...\n");
00040 
00041   if(N_gas)
00042     {
00043       mp = malloc(sizeof(struct peano_hilbert_data) * N_gas);
00044       Id = malloc(sizeof(int) * N_gas);
00045 
00046       for(i = 0; i < N_gas; i++)
00047         {
00048           mp[i].index = i;
00049           mp[i].key = Key[i];
00050         }
00051 
00052       qsort(mp, N_gas, sizeof(struct peano_hilbert_data), compare_key);
00053 
00054       for(i = 0; i < N_gas; i++)
00055         Id[mp[i].index] = i;
00056 
00057       reorder_gas();
00058 
00059       free(Id);
00060       free(mp);
00061     }
00062 
00063 
00064   if(NumPart - N_gas > 0)
00065     {
00066       mp = malloc(sizeof(struct peano_hilbert_data) * (NumPart - N_gas));
00067       mp -= (N_gas);
00068 
00069       Id = malloc(sizeof(int) * (NumPart - N_gas));
00070       Id -= (N_gas);
00071 
00072       for(i = N_gas; i < NumPart; i++)
00073         {
00074           mp[i].index = i;
00075           mp[i].key = Key[i];
00076         }
00077 
00078       qsort(mp + N_gas, NumPart - N_gas, sizeof(struct peano_hilbert_data), compare_key);
00079 
00080       for(i = N_gas; i < NumPart; i++)
00081         Id[mp[i].index] = i;
00082 
00083       reorder_particles();
00084 
00085       Id += N_gas;
00086       free(Id);
00087       mp += N_gas;
00088       free(mp);
00089     }
00090 
00091   if(ThisTask == 0)
00092     printf("Peano-Hilbert done.\n");
00093 }
00094 
00095 
00098 int compare_key(const void *a, const void *b)
00099 {
00100   if(((struct peano_hilbert_data *) a)->key < (((struct peano_hilbert_data *) b)->key))
00101     return -1;
00102 
00103   if(((struct peano_hilbert_data *) a)->key > (((struct peano_hilbert_data *) b)->key))
00104     return +1;
00105 
00106   return 0;
00107 }
00108 
00109 
00117 void reorder_gas(void)
00118 {
00119   int i;
00120   struct particle_data Psave, Psource;
00121   struct sph_particle_data SphPsave, SphPsource;
00122   int idsource, idsave, dest;
00123 
00124   for(i = 0; i < N_gas; i++)
00125     {
00126       if(Id[i] != i)
00127         {
00128           Psource = P[i];
00129           SphPsource = SphP[i];
00130 
00131           idsource = Id[i];
00132           dest = Id[i];
00133 
00134           do
00135             {
00136               Psave = P[dest];
00137               SphPsave = SphP[dest];
00138               idsave = Id[dest];
00139 
00140               P[dest] = Psource;
00141               SphP[dest] = SphPsource;
00142               Id[dest] = idsource;
00143 
00144               if(dest == i)
00145                 break;
00146 
00147               Psource = Psave;
00148               SphPsource = SphPsave;
00149               idsource = idsave;
00150 
00151               dest = idsource;
00152             }
00153           while(1);
00154         }
00155     }
00156 }
00157 
00158 
00166 void reorder_particles(void)
00167 {
00168   int i;
00169   struct particle_data Psave, Psource;
00170   int idsource, idsave, dest;
00171 
00172   for(i = N_gas; i < NumPart; i++)
00173     {
00174       if(Id[i] != i)
00175         {
00176           Psource = P[i];
00177           idsource = Id[i];
00178 
00179           dest = Id[i];
00180 
00181           do
00182             {
00183               Psave = P[dest];
00184               idsave = Id[dest];
00185 
00186               P[dest] = Psource;
00187               Id[dest] = idsource;
00188 
00189               if(dest == i)
00190                 break;
00191 
00192               Psource = Psave;
00193               idsource = idsave;
00194 
00195               dest = idsource;
00196             }
00197           while(1);
00198         }
00199     }
00200 }
00201 
00202 
00203 
00204 
00205 
00206 
00207 static int quadrants[24][2][2][2] = {
00208   /* rotx=0, roty=0-3 */
00209   {{{0, 7}, {1, 6}}, {{3, 4}, {2, 5}}},
00210   {{{7, 4}, {6, 5}}, {{0, 3}, {1, 2}}},
00211   {{{4, 3}, {5, 2}}, {{7, 0}, {6, 1}}},
00212   {{{3, 0}, {2, 1}}, {{4, 7}, {5, 6}}},
00213   /* rotx=1, roty=0-3 */
00214   {{{1, 0}, {6, 7}}, {{2, 3}, {5, 4}}},
00215   {{{0, 3}, {7, 4}}, {{1, 2}, {6, 5}}},
00216   {{{3, 2}, {4, 5}}, {{0, 1}, {7, 6}}},
00217   {{{2, 1}, {5, 6}}, {{3, 0}, {4, 7}}},
00218   /* rotx=2, roty=0-3 */
00219   {{{6, 1}, {7, 0}}, {{5, 2}, {4, 3}}},
00220   {{{1, 2}, {0, 3}}, {{6, 5}, {7, 4}}},
00221   {{{2, 5}, {3, 4}}, {{1, 6}, {0, 7}}},
00222   {{{5, 6}, {4, 7}}, {{2, 1}, {3, 0}}},
00223   /* rotx=3, roty=0-3 */
00224   {{{7, 6}, {0, 1}}, {{4, 5}, {3, 2}}},
00225   {{{6, 5}, {1, 2}}, {{7, 4}, {0, 3}}},
00226   {{{5, 4}, {2, 3}}, {{6, 7}, {1, 0}}},
00227   {{{4, 7}, {3, 0}}, {{5, 6}, {2, 1}}},
00228   /* rotx=4, roty=0-3 */
00229   {{{6, 7}, {5, 4}}, {{1, 0}, {2, 3}}},
00230   {{{7, 0}, {4, 3}}, {{6, 1}, {5, 2}}},
00231   {{{0, 1}, {3, 2}}, {{7, 6}, {4, 5}}},
00232   {{{1, 6}, {2, 5}}, {{0, 7}, {3, 4}}},
00233   /* rotx=5, roty=0-3 */
00234   {{{2, 3}, {1, 0}}, {{5, 4}, {6, 7}}},
00235   {{{3, 4}, {0, 7}}, {{2, 5}, {1, 6}}},
00236   {{{4, 5}, {7, 6}}, {{3, 2}, {0, 1}}},
00237   {{{5, 2}, {6, 1}}, {{4, 3}, {7, 0}}}
00238 };
00239 
00240 
00241 static int rotxmap_table[24] = { 4, 5, 6, 7, 8, 9, 10, 11,
00242   12, 13, 14, 15, 0, 1, 2, 3, 17, 18, 19, 16, 23, 20, 21, 22
00243 };
00244 
00245 static int rotymap_table[24] = { 1, 2, 3, 0, 16, 17, 18, 19,
00246   11, 8, 9, 10, 22, 23, 20, 21, 14, 15, 12, 13, 4, 5, 6, 7
00247 };
00248 
00249 static int rotx_table[8] = { 3, 0, 0, 2, 2, 0, 0, 1 };
00250 static int roty_table[8] = { 0, 1, 1, 2, 2, 3, 3, 0 };
00251 
00252 static int sense_table[8] = { -1, -1, -1, +1, +1, -1, -1, -1 };
00253 
00254 static int flag_quadrants_inverse = 1;
00255 static char quadrants_inverse_x[24][8];
00256 static char quadrants_inverse_y[24][8];
00257 static char quadrants_inverse_z[24][8];
00258 
00259 
00263 peanokey peano_hilbert_key(int x, int y, int z, int bits)
00264 {
00265   int i, quad, bitx, bity, bitz;
00266   int mask, rotation, rotx, roty, sense;
00267   peanokey key;
00268 
00269 
00270   mask = 1 << (bits - 1);
00271   key = 0;
00272   rotation = 0;
00273   sense = 1;
00274 
00275 
00276   for(i = 0; i < bits; i++, mask >>= 1)
00277     {
00278       bitx = (x & mask) ? 1 : 0;
00279       bity = (y & mask) ? 1 : 0;
00280       bitz = (z & mask) ? 1 : 0;
00281 
00282       quad = quadrants[rotation][bitx][bity][bitz];
00283 
00284       key <<= 3;
00285       key += (sense == 1) ? (quad) : (7 - quad);
00286 
00287       rotx = rotx_table[quad];
00288       roty = roty_table[quad];
00289       sense *= sense_table[quad];
00290 
00291       while(rotx > 0)
00292         {
00293           rotation = rotxmap_table[rotation];
00294           rotx--;
00295         }
00296 
00297       while(roty > 0)
00298         {
00299           rotation = rotymap_table[rotation];
00300           roty--;
00301         }
00302     }
00303 
00304   return key;
00305 }
00306 
00307 
00313 void peano_hilbert_key_inverse(peanokey key, int bits, int *x, int *y, int *z)
00314 {
00315   int i, keypart, bitx, bity, bitz, mask, quad, rotation, shift;
00316   char sense, rotx, roty;
00317 
00318   if(flag_quadrants_inverse)
00319     {
00320       flag_quadrants_inverse = 0;
00321       for(rotation = 0; rotation < 24; rotation++)
00322         for(bitx = 0; bitx < 2; bitx++)
00323           for(bity = 0; bity < 2; bity++)
00324             for(bitz = 0; bitz < 2; bitz++)
00325               {
00326                 quad = quadrants[rotation][bitx][bity][bitz];
00327                 quadrants_inverse_x[rotation][quad] = bitx;
00328                 quadrants_inverse_y[rotation][quad] = bity;
00329                 quadrants_inverse_z[rotation][quad] = bitz;
00330               }
00331     }
00332 
00333   shift = 3 * (bits - 1);
00334   mask = 7 << shift;
00335 
00336   rotation = 0;
00337   sense = 1;
00338 
00339   *x = *y = *z = 0;
00340 
00341   for(i = 0; i < bits; i++, mask >>= 3, shift -= 3)
00342     {
00343       keypart = (key & mask) >> shift;
00344 
00345       quad = (sense == 1) ? (keypart) : (7 - keypart);
00346 
00347       *x = (*x << 1) + quadrants_inverse_x[rotation][quad];
00348       *y = (*y << 1) + quadrants_inverse_y[rotation][quad];
00349       *z = (*z << 1) + quadrants_inverse_z[rotation][quad];
00350 
00351       rotx = rotx_table[quad];
00352       roty = roty_table[quad];
00353       sense *= sense_table[quad];
00354 
00355       while(rotx > 0)
00356         {
00357           rotation = rotxmap_table[rotation];
00358           rotx--;
00359         }
00360 
00361       while(roty > 0)
00362         {
00363           rotation = rotymap_table[rotation];
00364           roty--;
00365         }
00366     }
00367 }

Generated on Sun May 22 17:33:29 2005 for GADGET-2 by  doxygen 1.3.9.1