예제 #1
0
static void omp_force (sotl_device_t *dev)
{
  sotl_atom_set_t *set = &dev->atom_set;
  tri(set);

  #pragma omp parallel num_threads(NB_THREAD )
  #pragma omp for schedule(static)
  for (int current = 0; current < (int)set->natoms; current++) {
    calc_t force[3] = { 0.0, 0.0, 0.0 };

    //atome Z supperieur
    for(int other = current-1;other>-1;other--){
	if(abs(set->pos.z[current]-set->pos.z[other]) > LENNARD_SQUARED_CUTOFF){
		break;
	}else{
		calc_t sq_dist = squared_distance (set, current, other);
		if (sq_dist < LENNARD_SQUARED_CUTOFF) {
	  		calc_t intensity = lennard_jones (sq_dist);

	  		force[0] += intensity * (set->pos.x[current] - set->pos.x[other]);
	  		force[1] += intensity * (set->pos.x[set->offset + current] -
						 set->pos.x[set->offset + other]);
	 		force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
				   		 set->pos.x[set->offset * 2 + other]);
		}
	}
    }
    //atome Z inferieur
    for(int other = current+1;other<(int)set->natoms;other++){
	if(abs(set->pos.z[current]-set->pos.z[other]) > LENNARD_SQUARED_CUTOFF){
		break;
	}else{
		calc_t sq_dist = squared_distance (set, current, other);
		if (sq_dist < LENNARD_SQUARED_CUTOFF) {
	  		calc_t intensity = lennard_jones (sq_dist);

	  		force[0] += intensity * (set->pos.x[current] - set->pos.x[other]);
		  	force[1] += intensity * (set->pos.x[set->offset + current] -
				   		 set->pos.x[set->offset + other]);
			force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
						 set->pos.x[set->offset * 2 + other]);
	}
	}
    }
    set->speed.dx[current] += force[0];
    set->speed.dx[set->offset + current] += force[1];
    set->speed.dx[set->offset * 2 + current] += force[2];
	
  }

}
예제 #2
0
파일: openmp.c 프로젝트: amilliet/GPU
static void omp_force (sotl_device_t *dev)
{
  sotl_atom_set_t *set = &dev->atom_set;

  for (unsigned current = 0; current < set->natoms; current++) {
    calc_t force[3] = { 0.0, 0.0, 0.0 };

    for (unsigned other = 0; other < set->natoms; other++)
      if (current != other) {
	calc_t sq_dist = squared_distance (set, current, other);

	if (sq_dist < LENNARD_SQUARED_CUTOFF) {
	  calc_t intensity = lennard_jones (sq_dist);

	  force[0] += intensity * (set->pos.x[current] - set->pos.x[other]);
	  force[1] += intensity * (set->pos.x[set->offset + current] -
				   set->pos.x[set->offset + other]);
	  force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
				   set->pos.x[set->offset * 2 + other]);
	}

      }

    set->speed.dx[current] += force[0];
    set->speed.dx[set->offset + current] += force[1];
    set->speed.dx[set->offset * 2 + current] += force[2];
  }
}
예제 #3
0
파일: openmp.c 프로젝트: Thundzz/GPU
static void omp_force (sotl_device_t *dev)
{
    struct timeval tv1,tv2;

    sotl_atom_set_t *set = &dev->atom_set;

    gettimeofday(&tv1,NULL);
    int start_ind, end_ind;

    #pragma omp parallel for
    for (unsigned current = 0; current < set->natoms; current++)
    {
        calc_t force[3] = { 0.0, 0.0, 0.0 };
//
//    }
//        /*Version naive*/

//        for (unsigned other = 0; other < set->natoms; other++)
//            if (current != other)
//            {
//                calc_t sq_dist = squared_distance (set, current, other);
//
//                if (sq_dist < LENNARD_SQUARED_CUTOFF)
//                {
//                    calc_t intensity = lennard_jones (sq_dist);
//
//                    force[0] += intensity * (set->pos.x[current] - set->pos.x[other]);
//                    force[1] += intensity * (set->pos.x[set->offset + current] -
//                                             set->pos.x[set->offset + other]);
//                    force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
//                                             set->pos.x[set->offset * 2 + other]);
//                }
//
//            }
        /* Fin version naive */



        /**
          * Version Tri par boites :
          */
        unsigned other;
        int box_id_current = atom_box_calc(dev, current);
        if (is_valid_box(dev, box_id_current))
        {
            for (int i = -1; i<2; i++)
            {
                for (int j = -1; j<2; j++)
                {
                    for (int k = -1; k<2; k++)
                    {
                        int box_id_other = get_neighbour(dev, box_id_current, i, j, k);
                        if (is_valid_box(dev, box_id_other))
                        {
                            start_ind = box_count_cummul[box_id_other];
                            end_ind = box_count_cummul[box_id_other-1];
                            int size = start_ind - end_ind;
                            for (int l = 0; l < size; l++)
                            {
                                other = box_count_cummul[box_id_other]-l-1;
                                if (other != current)
                                {
                                    calc_t sq_dist = squared_distance (set, current, other);
                                    if (sq_dist < LENNARD_SQUARED_CUTOFF)
                                    {
                                        calc_t intensity = lennard_jones (sq_dist);
                                        force[0] += intensity * (set->pos.x[current] - set->pos.x[other]);
                                        force[1] += intensity * (set->pos.x[set->offset + current] -
                                                                 set->pos.x[set->offset + other]);
                                        force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
                                                                 set->pos.x[set->offset * 2 + other]);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        /*Fin version Tri par Boites */


        /** Version Tri par Z :
          */
//        for (unsigned other = current+1; other < set->natoms && ((set->pos.z[other] - set->pos.z[current]) < LENNARD_CUTOFF); other++)
//        {
//            //Now takes the atoms near from current according to the sorted array
//            if (current != other)
//            {
//                calc_t sq_dist = squared_distance (set, current, other);
//
//                if (sq_dist < LENNARD_SQUARED_CUTOFF)
//                {
//                    calc_t intensity = lennard_jones (sq_dist);
//
//                    force[0] += intensity * (set->pos.x[current] - set->pos.x[other]);
//                    force[1] += intensity * (set->pos.x[set->offset + current] -
//                                             set->pos.x[set->offset + other]);
//                    force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
//                                             set->pos.x[set->offset * 2 + other]);
//                }
//            }
//        }
//        for (unsigned other = current; other > 0 && ((set->pos.z[current] - set->pos.z[other-1]) < LENNARD_CUTOFF); other--)
//        {
//            //Now takes the atoms near from current according to the sorted array
//            if (current != other-1)
//            {
//                calc_t sq_dist = squared_distance (set, current, other-1);
//
//                if (sq_dist < LENNARD_SQUARED_CUTOFF)
//                {
//                    calc_t intensity = lennard_jones (sq_dist);
//
//                    force[0] += intensity * (set->pos.x[current] - set->pos.x[other-1]);
//                    force[1] += intensity * (set->pos.x[set->offset + current] -
//                                             set->pos.x[set->offset + other-1]);
//                    force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
//                                             set->pos.x[set->offset * 2 + other-1]);
//                }
//            }
//        }
        /*Fin version Tri par Z */

        set->speed.dx[current] += force[0];
        set->speed.dx[set->offset + current] += force[1];
        set->speed.dx[set->offset * 2 + current] += force[2];
    }

    gettimeofday(&tv2,NULL);
    time_force += (float)TIME_DIFF(tv1,tv2);
}
예제 #4
0
void omp_force_cube(sotl_device_t *dev){
	
  sotl_atom_set_t *set = &dev->atom_set;
  sotl_domain_t *domain = &dev->domain;

  sotl_atom_set_t *in = malloc(sizeof(sotl_atom_set_t));
  atom_set_init(in,set->natoms,set->offset);

 
  for(int i=0; i<(int)set->natoms; i++){
    atom_set_add(in,set->pos.x[i],set->pos.y[i],set->pos.z[i],set->speed.dx[i],set->speed.dy[i],set->speed.dz[i]);
  }

  int NbCubes = (int) domain->total_boxes;

  int* boite= calloc(NbCubes,sizeof(int));
  int* boiten= calloc(NbCubes,sizeof(int));

  for(int i= 0; i < (int)in->natoms; i++){
    int numb =atom_get_num_box(domain,in->pos.x[i],in->pos.y[i],in->pos.z[i],LENNARD_SQUARED_CUTOFF);
    boite[numb]++;
    boiten[numb]++;
  }

  
  for (int i = 1; i < NbCubes; i++){
    boite[i] += boite[i-1];
  }
	
  for(int i = 0; i < (int)in->natoms; i++){
    int numb =atom_get_num_box(domain,in->pos.x[i],in->pos.y[i],in->pos.z[i],LENNARD_SQUARED_CUTOFF);
    int indice = boite[numb-1]+boiten[numb]-1;
    set->pos.x[indice]=in->pos.x[i];
    set->pos.y[indice]=in->pos.y[i];
    set->pos.z[indice]=in->pos.z[i];
    set->speed.dx[indice]=in->speed.dx[i];
    set->speed.dy[indice]=in->speed.dy[i];
    set->speed.dz[indice]=in->speed.dz[i];
    boiten[numb]--;	
  }
    #pragma omp parallel num_threads(NB_THREAD )
    #pragma omp for schedule(static)
    for (int current = 0; current < (int)set->natoms; current++) {
      calc_t force[3] = { 0.0, 0.0, 0.0 };

      int bx =(int)((set->pos.x[current] - domain->min_border[0]) *LENNARD_SQUARED_CUTOFF);
      int by =(int)((set->pos.y[current] - domain->min_border[1]) *LENNARD_SQUARED_CUTOFF);
      int bz =(int)((set->pos.z[current] - domain->min_border[2]) *LENNARD_SQUARED_CUTOFF);
      
      for(int z =(bz==0)?bz:bz-1; z<= bz+1 && z<(int)domain->boxes[2]; z++){
	for(int y=(by==0)?by:by-1; y<= by+1 && y<(int)domain->boxes[1]; y++){
	  for(int x=(bx==0)?bx:bx-1;x<=bx+1 && x<(int)domain->boxes[0];x++){
            int numb = z * domain->boxes[0]* domain->boxes[1] + y * domain->boxes[0] + x;
	    for(int other =(numb==0)?boite[0]:boite[numb-1]; other<boite[numb]; other++){
	      if(current != other){
                calc_t sq_dist = squared_distance (set, current, other);

		if (sq_dist < LENNARD_SQUARED_CUTOFF) {
		  calc_t intensity = lennard_jones (sq_dist);
		  force[0] += intensity * (set->pos.x[current] - set->pos.x[other]);
		  force[1] += intensity * (set->pos.x[set->offset + current] -
					   set->pos.x[set->offset + other]);
		  force[2] += intensity * (set->pos.x[set->offset * 2 + current] -
					   set->pos.x[set->offset * 2 + other]);
		}
	      }
	    }
	  }
	}
      } 
	
	set->speed.dx[current] += force[0];
        set->speed.dx[set->offset + current] += force[1];
        set->speed.dx[set->offset * 2 + current] += force[2];
    }
    
    free(boiten);
    atom_set_free(in);
    free(in);
    free(boite);
  }