void calculate_force(double forces[][3], double ****neighbor, double particles[][3], double region, int amount){
// Updates the force for each particle based on the neighbor list
  int i,j,k;
  double r = region/2.;

  
  for (i=0; i<amount; i++){
    for (j=0; j<3; j++){
      forces[i][j] = 0;
    }
  }
  
  omp_set_num_threads(NUM_THREADS);
  #pragma omp parallel for private(j,k)
    for (i=0; i<amount; i++){
      int neighbors = *neighbor[i][0][0];
      for (j=1; j<=neighbors; j++){
        double d = distance_periodic(particles[i],*neighbor[i][j],region);
        double di = 1./d;
        double d3 = di * di *di;
        for (k=0; k<3; k++){
          double dl = particles[i][k] - *neighbor[i][j][k];
          if (dl > r){
            dl -= region;
          }
          else if (dl < -r){
            dl += region;
          }
          forces[i][k] += 48.*d3*(d3-0.5)*di*dl;
        }
      }
    }
  #pragma omp barrier
}
void update_neighborlist(double ****neighbor, double *amount_neighbor, double particles[][3], double radius, int amount, double region){
// Updates the neighbor list for each particle within a given radius
// The first element of each row contains a pointer to the amount of neighbors
  int i,j,k;

  omp_set_num_threads(NUM_THREADS);
  #pragma omp parallel for private(j,k)
    for (i=0; i<amount; i++){
      int l = 0;
      for (j=0; j<amount; j++){
        if (i!=j){
          double distance_ij = distance_periodic(particles[i],particles[j],region);
          if (distance_ij<radius*radius){
            for (k=0; k<3; k++){
              neighbor[i][l+1][k] = &particles[j][k];
            }
            l++;
          }
        }
      }
      amount_neighbor[i] = (double)l;
      neighbor[i][0][0] = &amount_neighbor[i];
    }
  #pragma omp barrier
}
Пример #3
0
void test_distance_periodic(void)
{
    //real distance_periodic(Vector p1, Vector p2)
    real L = 32;
    Vector a, b;

    a.x = 1;  a.y = 1;
    b.x = 31; b.y = 1;
    assert_almost_equal(distance_periodic(a, b, L), real(2));

    a.x = 1; a.y = 1;
    b.x = 1; b.y = 31;
    assert_almost_equal(distance_periodic(a, b, L), real(2));

    a.x = 1; a.y = 1;
    b.x = 31; b.y = 31;
    assert_almost_equal(distance_periodic(a, b, L), real(2)*std::sqrt(real(2)));

    a.x = 1; a.y = 1;
    b.x = 3; b.y = 1;
    assert_almost_equal(distance_periodic(a, b, L), real(2));

    a.x = 1; a.y = 1;
    b.x = 1; b.y = 3;
    assert_almost_equal(distance_periodic(a, b, L), real(2));

    a.x = 1; a.y = 1;
    b.x = 3; b.y = 3;
    assert_almost_equal(distance_periodic(a, b, L), real(2)*std::sqrt(real(2)));
}