Exemple #1
0
void peano_hilbert_order(void)
{
  int i;

  if(ThisTask == 0)
    printf("begin Peano-Hilbert order...\n");

  if(N_gas)
    {
      mp = malloc(sizeof(struct peano_hilbert_data) * N_gas);
      Id = malloc(sizeof(int) * N_gas);

      for(i = 0; i < N_gas; i++)
	{
	  mp[i].index = i;
	  mp[i].key = Key[i];
	}

      qsort(mp, N_gas, sizeof(struct peano_hilbert_data), compare_key);

      for(i = 0; i < N_gas; i++)
	Id[mp[i].index] = i;

      reorder_gas();

      free(Id);
      free(mp);
    }


  if(NumPart - N_gas > 0)
    {
      mp = malloc(sizeof(struct peano_hilbert_data) * (NumPart - N_gas));
      mp -= (N_gas);

      Id = malloc(sizeof(int) * (NumPart - N_gas));
      Id -= (N_gas);

      for(i = N_gas; i < NumPart; i++)
	{
	  mp[i].index = i;
	  mp[i].key = Key[i];
	}

      qsort(mp + N_gas, NumPart - N_gas, sizeof(struct peano_hilbert_data), compare_key);

      for(i = N_gas; i < NumPart; i++)
	Id[mp[i].index] = i;

      reorder_particles();

      Id += N_gas;
      free(Id);
      mp += N_gas;
      free(mp);
    }

  if(ThisTask == 0)
    printf("Peano-Hilbert done.\n");
}
/*! This function puts the particles into Peano-Hilbert order by sorting them
 *  according to their keys. The latter half already been computed in the
 *  domain decomposition. Since gas particles need to stay at the beginning of
 *  the particle list, they are sorted as a separate block.
 */
void peano_hilbert_order(void)
{
  int i;
#if N_GRAVS > 1
  int offset, k;
#endif


  if(ThisTask == 0)
    printf("begin Peano-Hilbert order...\n");

  if(N_gas)
    {
      mp = malloc(sizeof(struct peano_hilbert_data) * N_gas);
      Id = malloc(sizeof(int) * N_gas);

      for(i = 0; i < N_gas; i++)
	{
	  mp[i].index = i;
	  mp[i].key = Key[i];
	}

      qsort(mp, N_gas, sizeof(struct peano_hilbert_data), compare_key);

      for(i = 0; i < N_gas; i++)
	Id[mp[i].index] = i;

      reorder_gas();

      free(Id);
      free(mp);
    }
 
#if N_GRAVS > 1 // && defined PMGRID
  // KC 10/8/14
  // To keep from traversing the entire particle list N_GRAVS^2 times
  // while in PMGRID mode
  // we Peano-Hilbert sort each type of particle, but keep the types strictly
  // ordered on the local processors.  Thus, we do what is done for gas particles (they sit
  // at the head of the P list) for all the types.
  // 
  // Hopefully this will still reap some of the spatial localization/memory localization
  // benefits of Peano-Hilbert ordering!

  // First, type order 
  if(NumPart - N_gas > 0) {

    mp = malloc(sizeof(struct peano_hilbert_data) * (NumPart - N_gas));
    mp -= N_gas;
    
    Id = malloc(sizeof(int) * (NumPart - N_gas));
    memset(Id, -1, NumPart-N_gas);
    Id -= N_gas;
    
    for(i = N_gas; i < NumPart; ++i) {
    
      mp[i].index = i;
      mp[i].key = TypeToGrav[P[i].Type];
    }
  
    // KC 10/20/14
    // Sort based on gravitational interaction, not on particle type

    // KC 10/12/14
    // mp[position in P list] = {position in P list, type of particle in this position}
    qsort(mp + N_gas, NumPart - N_gas, sizeof(struct peano_hilbert_data), compare_key);
  
    // KC 10/12/14
    // mp[destination position] = {(source) position in P list, type of particle in this position}
    // Now sort within type by peano-hilbert key
    // The indexes of Key correspond to the original indexes of P before any kind of sort.    
    // So we care about mp[i].index
    
    // Temporarily ignore the gas particles
    NgravLocal[0] -= N_gas;

    offset = N_gas;
    for(k = 0; k < N_GRAVS; ++k) {
      
      mp2 = malloc(sizeof(struct peano_hilbert_data) * NgravLocal[k]);
      mp2 -= offset;
   
      for(i = offset; i < offset + NgravLocal[k]; ++i) {
	
	mp2[i].index = mp[i].index;
	mp2[i].key = Key[mp[i].index];
      }

      qsort(mp2 + offset, NgravLocal[k], sizeof(struct peano_hilbert_data), compare_key);

      for(i = offset; i < offset + NgravLocal[k]; ++i)
	Id[mp2[i].index] = i;

      mp2 += offset;
      free(mp2);

      offset += NgravLocal[k];
    }
    
    // Put the gas particles back on
    NgravLocal[0] += N_gas;

    mp += N_gas;
    free(mp);

    reorder_particles();

    // Dump particles
    //    for(i = 0; i < NumPart; ++i) 
    //  printf("PEANO: %d has {type,gravtype}={%d, %d}\n", i, P[i].Type, TypeToGrav[P[i].Type]);

    Id += N_gas;
    free(Id);

    if(ThisTask == 0)
      printf("ngravs: Type ordering complete, Peano-Hilbert subordered.\n");

  }
#else
  if(NumPart - N_gas > 0)
    {
      mp = malloc(sizeof(struct peano_hilbert_data) * (NumPart - N_gas));
      mp -= (N_gas);

      Id = malloc(sizeof(int) * (NumPart - N_gas));
      Id -= (N_gas);

      for(i = N_gas; i < NumPart; i++)
	{
	  mp[i].index = i;
	  mp[i].key = Key[i];
	}

      qsort(mp + N_gas, NumPart - N_gas, sizeof(struct peano_hilbert_data), compare_key);

      for(i = N_gas; i < NumPart; i++)
	Id[mp[i].index] = i;

      reorder_particles();

      Id += N_gas;
      free(Id);
      mp += N_gas;
      free(mp);
    }
#endif

  if(ThisTask == 0)
    printf("Peano-Hilbert done.\n");
}