Пример #1
0
void discretise_structure( struct Structure This_Structure , float grid_span , int grid_size , float *grid ) {

/************/

  /* Counters */

  int	residue , atom ;

  /* Co-ordinates */

  int	x , y , z ;
  int	steps , x_step , y_step , z_step ;

  float		x_centre , y_centre , z_centre ;

  /* Variables */

  float         distance , one_span ;

/************/

  one_span = grid_span / (float)grid_size ;

  distance = 1.8 ;

/************/

  for( x = 0 ; x < grid_size ; x ++ ) {
    for( y = 0 ; y < grid_size ; y ++ ) {
      for( z = 0 ; z < grid_size ; z ++ ) {

        grid[gaddress(x,y,z,grid_size)] = (float)0 ;

      }
    }
  }

/************/

  steps = (int)( ( distance / one_span ) + 1.5 ) ;

  for( residue = 1 ; residue <= This_Structure.length ; residue ++ ) {
    for( atom = 1 ; atom <= This_Structure.Residue[residue].size ; atom ++ ) {

      x = gord( This_Structure.Residue[residue].Atom[atom].coord[1] , grid_span , grid_size ) ;
      y = gord( This_Structure.Residue[residue].Atom[atom].coord[2] , grid_span , grid_size ) ;
      z = gord( This_Structure.Residue[residue].Atom[atom].coord[3] , grid_span , grid_size ) ;

      for( x_step = max( ( x - steps ) , 0 ) ; x_step <= min( ( x + steps ) , ( grid_size - 1 ) ) ; x_step ++ ) {

        x_centre  = gcentre( x_step , grid_span , grid_size ) ;

        for( y_step = max( ( y - steps ) , 0 ) ; y_step <= min( ( y + steps ) , ( grid_size - 1 ) ) ; y_step ++ ) {

          y_centre  = gcentre( y_step , grid_span , grid_size ) ;

          for( z_step = max( ( z - steps ) , 0 ) ; z_step <= min( ( z + steps ) , ( grid_size - 1 ) ) ; z_step ++ ) {

            z_centre  = gcentre( z_step , grid_span , grid_size ) ;

            if( pythagoras( This_Structure.Residue[residue].Atom[atom].coord[1] , This_Structure.Residue[residue].Atom[atom].coord[2] , This_Structure.Residue[residue].Atom[atom].coord[3] , x_centre , y_centre , z_centre ) < distance ) grid[gaddress(x_step,y_step,z_step,grid_size)] = (float)1 ;

          }
        }
      }

    }
  }

/************/

  return ;

}
Пример #2
0
void electric_field(struct Structure This_Structure, float grid_span, int grid_size, float *grid) {
    /************/

    /* Counters */

    int residue, atom;

    /* Co-ordinates */

    int   x, y, z;
    float x_centre, y_centre, z_centre;

    /* Variables */

    float distance;
    float phi, epsilon;

    /************/

    for (x = 0; x < grid_size; x++) {
        for (y = 0; y < grid_size; y++) {
            for (z = 0; z < grid_size; z++) {
                grid[gaddress(x, y, z, grid_size)] = (float)0;
            }
        }
    }

    /************/

    setvbuf(stdout, (char *)NULL, _IONBF, 0);

    printf("  electric field calculations ( one dot / grid sheet ) ");

    for (residue = 1; residue <= This_Structure.length; residue++) {
        printf(".");
        for (atom = 1; atom <= This_Structure.Residue[residue].size; atom++) {
            if (This_Structure.Residue[residue].Atom[atom].charge == 0) continue;
            for (x = 0; x < grid_size; x++) {
                x_centre = gcentre(x, grid_span, grid_size);
                for (y = 0; y < grid_size; y++) {
                    y_centre = gcentre(y, grid_span, grid_size);
                    for (z = 0; z < grid_size; z++) {
                        z_centre = gcentre(z, grid_span, grid_size);

                        // Inlined pythagoras function with a macro to avoid call overhead
                        distance = PYTHAGORAS(This_Structure.Residue[residue].Atom[atom].coord[1],
                                              This_Structure.Residue[residue].Atom[atom].coord[2],
                                              This_Structure.Residue[residue].Atom[atom].coord[3],
                                              x_centre,
                                              y_centre,
                                              z_centre);

                        if (distance < 2.0) distance = 2.0;

                        if (distance >= 2.0) {
                            if (distance >= 8.0) {
                                epsilon = 80;
                            } else {
                                if (distance <= 6.0) {
                                    epsilon = 4;
                                } else {
                                    epsilon = (38 * distance) - 224;
                                }
                            }

                            grid[gaddress(x, y, z, grid_size)] += (This_Structure.Residue[residue].Atom[atom].charge / (epsilon * distance));
                        }
                    }
                }
            }
        }
    }

    printf("\n");

    /************/
}
Пример #3
0
void electric_field(struct Structure This_Structure, float grid_span, int grid_size, fftw_real * grid, int *shared_x, struct atom_values *atoms, int natoms_in)
{

/************/

	/* Counters */

	int residue, atom, i;

	/* Co-ordinates */

	int x, y, z;
	float x_centre, y_centre, z_centre;

	/* Variables */

	float distance;
	float phi, epsilon;

	while (1) {
		
		pthread_mutex_lock(&shared_x_mutex);
		x = *shared_x;
		*shared_x = *shared_x + 1;
		pthread_mutex_unlock(&shared_x_mutex);
		
		if (x >= grid_size)
			break;
		
		printf(".");

		x_centre = gcentre(x, grid_span, grid_size);
		__mtype mx_centre = _set1_ps(x_centre);

		for (y = 0; y < grid_size; y++) {

			y_centre = gcentre(y, grid_span, grid_size);
			__mtype my_centre = _set1_ps(y_centre);

			for (z = 0; z < grid_size; z++) {

				z_centre = gcentre(z, grid_span, grid_size);
				__mtype mz_centre = _set1_ps(z_centre);

				phi = 0;
				__mtype phis = _set1_ps(0.0);
				
				for (i = 0; i < natoms_in; i++) {
				
					__mtype xs = _load_ps(atoms[i].xs);
					__mtype ys = _load_ps(atoms[i].ys);
					__mtype zs = _load_ps(atoms[i].zs);
					__mtype charges = _load_ps(atoms[i].charges);
					__mtype distances;
					
					// Calculo distancias (el original pythagoras)
					__mtype diffxs = _sub_ps(xs, mx_centre);
					__mtype diffys = _sub_ps(ys, my_centre);
					__mtype diffzs = _sub_ps(zs, mz_centre);
					
					diffxs = _mul_ps(diffxs, diffxs);
					diffys = _mul_ps(diffys, diffys);
					diffzs = _mul_ps(diffzs, diffzs);
					
					distances = _add_ps(diffxs, diffys);
					distances = _add_ps(distances, diffzs);
					
					distances = _sqrt_ps(distances);
					
					// A partir de aquí implemento los if's originales usando solo máscaras de bits
					
					// Trunco a 2 como mínimo
					distances = _max_ps(distances, _set1_ps(2.0));
					
					__mtype epsilons = _set1_ps(0.0);
					__mtype tmp;
					__mtype tmp2;
					
					// if >= 8
					tmp = _cmpge_ps(distances, _set1_ps(8.0));
					epsilons = _and_ps(tmp, _set1_ps(80.0));
					
					// else if <= 6
					tmp = _cmple_ps(distances, _set1_ps(6.0));
					tmp = _and_ps(tmp, _set1_ps(4.0));
					epsilons = _or_ps(epsilons, tmp);
					
					// else
					tmp = _cmpgt_ps(distances, _set1_ps(6.0));
					tmp2 = _cmpeq_ps(epsilons, _set1_ps(0.0));
					tmp = _and_ps(tmp, tmp2);
					tmp2 = _mul_ps(distances, _set1_ps(38.0));
					tmp2 = _sub_ps(tmp2, _set1_ps(224.0));
					tmp = _and_ps(tmp, tmp2);
			
					// Valor final
					epsilons = _or_ps(epsilons, tmp);
					
					// Calculo las phis
					tmp = _mul_ps(epsilons, distances);
					tmp = _div_ps(charges, tmp);
					
					// Acumulo las phis
					phis = _add_ps(phis, tmp);
				}
				#ifdef USE_AVX
				
				phis = _mm256_hadd_ps(phis, phis);
				phis = _mm256_hadd_ps(phis, phis);
				
				phi = phis[0] + phis[4];
				
				#else
				
				float tmp, tmp2;
				
				tmp = phis[0] + phis[1];
				tmp2 = phis[2] + phis[3];
				
				phi = tmp + tmp2;
				
				#endif
				grid[gaddress(x, y, z, grid_size)] = (fftw_real) phi;

			}
		}
	}

/************/

	return;

}
Пример #4
0
void electric_point_charge(struct Structure This_Structure, float grid_span, int grid_size, float *grid) {
    /************/

    /* Counters */

    int residue, atom;

    /* Co-ordinates */

    int x, y, z;
    int x_low, x_high, y_low, y_high, z_low, z_high;

    float a, b, c;
    float x_corner, y_corner, z_corner;
    float w;

    /* Variables */

    float one_span;

    /************/

    for (x = 0; x < grid_size; x++) {
        for (y = 0; y < grid_size; y++) {
            for (z = 0; z < grid_size; z++) {
                grid[gaddress(x, y, z, grid_size)] = (float)0;
            }
        }
    }

    /************/

    one_span = grid_span / (float)grid_size;

    for (residue = 1; residue <= This_Structure.length; residue++) {
        for (atom = 1; atom <= This_Structure.Residue[residue].size; atom++) {
            if (This_Structure.Residue[residue].Atom[atom].charge != 0) {
                x_low = gord(This_Structure.Residue[residue].Atom[atom].coord[1] - (one_span / 2),
                             grid_span,
                             grid_size);
                y_low = gord(This_Structure.Residue[residue].Atom[atom].coord[2] - (one_span / 2),
                             grid_span,
                             grid_size);
                z_low = gord(This_Structure.Residue[residue].Atom[atom].coord[3] - (one_span / 2),
                             grid_span,
                             grid_size);

                x_high = x_low + 1;
                y_high = y_low + 1;
                z_high = z_low + 1;

                a = This_Structure.Residue[residue].Atom[atom].coord[1] -
                    gcentre(x_low, grid_span, grid_size) - (one_span / 2);
                b = This_Structure.Residue[residue].Atom[atom].coord[2] -
                    gcentre(y_low, grid_span, grid_size) - (one_span / 2);
                c = This_Structure.Residue[residue].Atom[atom].coord[3] -
                    gcentre(z_low, grid_span, grid_size) - (one_span / 2);

                for (x = x_low; x <= x_high; x++) {
                    x_corner = one_span * ((float)(x - x_high) + .5);

                    for (y = y_low; y <= y_high; y++) {
                        y_corner = one_span * ((float)(y - y_high) + .5);

                        for (z = z_low; z <= z_high; z++) {
                            z_corner = one_span * ((float)(z - z_high) + .5);

                            w = ((x_corner + a) * (y_corner + b) * (z_corner + c)) /
                                (8.0 * x_corner * y_corner * z_corner);

                            grid[gaddress(x, y, z,
                                          grid_size)] +=
                                (float)(w * This_Structure.Residue[residue].Atom[atom].charge);
                        }
                    }
                }
            }
        }
    }

    /************/
}
Пример #5
0
void *th_electric_field(void *argthinfo) {
	Thinfo *thinfo = (Thinfo *) argthinfo;
	float * charge = thinfo->charge;
	float * coord1 = thinfo->coord1;
	float * coord2 = thinfo->coord2;
	float * coord3 = thinfo->coord3;
	float grid_span = thinfo->grid_span;
	int grid_size = thinfo->grid_size;
	int totalElements = thinfo->totalElements;
	int block_size = thinfo->block_size;
	int x_start = thinfo->x_start;
	int x_end = thinfo->x_end;
	int num_threads = thinfo->num_threads;
	fftw_real *grid = thinfo->grid;

	float phi;
	int block_ini, block_fin;
	float x_centre, y_centre, z_centre;
	int x, y, z, i, k;
	
	__m128 _phi_tmp;
	__m128 _phiSet;
	float *phiSet = (float *) &_phiSet;

	float * distance;
	float * epsilon;

  if ((posix_memalign((void**)&distance, 16, 4*sizeof(float))!=0)) {
    printf("No memory.\n");
    exit(-1);
  }
  if ((posix_memalign((void**)&epsilon, 16, 4*sizeof(float))!=0)) {
    printf("No memory.\n");
    exit(-1);
  }

	for (block_ini = 0; block_ini < totalElements-(block_size-1); block_ini += block_size) { 
		block_fin = block_ini + block_size;
	  for (x = x_start; x < x_end; x++) {
	    x_centre  = gcentre(x ,grid_span, grid_size ) ;
	    for (y = 0; y < grid_size; y++) {
	      y_centre = gcentre(y ,grid_span ,grid_size ) ;
	      for (z = 0; z < grid_size; z++) {
	        z_centre  = gcentre( z , grid_span , grid_size ) ;
	        phi = 0 ;
					computeBlock(block_ini, block_fin);
	    	  grid[gaddress(x,y,z,grid_size)] += (fftw_real)phi;
	      }
	    }
	  }
		//Changing block. Must wait for others threads to finish.
		pthread_mutex_lock(&mut);
		ready_threads++;
		if (ready_threads==num_threads) {
			ready_threads=0;
			pthread_cond_broadcast(&cond);
		} else {
			pthread_cond_wait(&cond, &mut);
		}
		pthread_mutex_unlock(&mut);
	}

	//Last block is not a multiple of block_size
	if (block_ini != totalElements) {
	  for (x = x_start; x < x_end; x++ ) {
	    x_centre = gcentre(x, grid_span, grid_size) ;
	    for (y = 0; y < grid_size; y++) {
	      y_centre = gcentre(y, grid_span, grid_size) ;
	      for (z = 0; z < grid_size; z++) {
	        z_centre = gcentre(z, grid_span, grid_size) ;
	        phi = 0 ;
					computeEndBlock(block_ini, totalElements);
	    	  grid[gaddress(x,y,z,grid_size)] += (fftw_real)phi ;
	      }
	    }
	  }
	}
	pthread_exit(NULL);
	return ;
}