mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-24 05:47:35 -04:00
157 lines
4.3 KiB
C
157 lines
4.3 KiB
C
/***************************************************************************
|
|
*cr
|
|
*cr (C) Copyright 2008-2010 The Board of Trustees of the
|
|
*cr University of Illinois
|
|
*cr All Rights Reserved
|
|
*cr
|
|
***************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <parboil.h>
|
|
|
|
#include "atom.h"
|
|
#include "cutoff.h"
|
|
|
|
#define CELLEN 4.f
|
|
#define INV_CELLEN (1.f/CELLEN)
|
|
|
|
extern int remove_exclusions(
|
|
Lattice *lattice, /* the lattice */
|
|
float cutoff, /* exclusion cutoff distance */
|
|
Atoms *atoms /* array of atoms */
|
|
)
|
|
{
|
|
int nx = lattice->dim.nx;
|
|
int ny = lattice->dim.ny;
|
|
int nz = lattice->dim.nz;
|
|
float xlo = lattice->dim.lo.x;
|
|
float ylo = lattice->dim.lo.y;
|
|
float zlo = lattice->dim.lo.z;
|
|
float gridspacing = lattice->dim.h;
|
|
Atom *atom = atoms->atoms;
|
|
|
|
const float a2 = cutoff * cutoff;
|
|
const float inv_gridspacing = 1.f / gridspacing;
|
|
const int radius = (int) ceilf(cutoff * inv_gridspacing) - 1;
|
|
/* lattice point radius about each atom */
|
|
|
|
int n;
|
|
int i, j, k;
|
|
int ia, ib, ic;
|
|
int ja, jb, jc;
|
|
int ka, kb, kc;
|
|
int index;
|
|
int koff, jkoff;
|
|
|
|
float x, y, z, q;
|
|
float dx, dy, dz;
|
|
float dz2, dydz2, r2;
|
|
float e;
|
|
float xstart, ystart;
|
|
|
|
float *pg;
|
|
|
|
int gindex;
|
|
int ncell, nxcell, nycell, nzcell;
|
|
int *first, *next;
|
|
float inv_cellen = INV_CELLEN;
|
|
Vec3 minext, maxext;
|
|
|
|
/* find min and max extent */
|
|
get_atom_extent(&minext, &maxext, atoms);
|
|
|
|
/* number of cells in each dimension */
|
|
nxcell = (int) floorf((maxext.x-minext.x) * inv_cellen) + 1;
|
|
nycell = (int) floorf((maxext.y-minext.y) * inv_cellen) + 1;
|
|
nzcell = (int) floorf((maxext.z-minext.z) * inv_cellen) + 1;
|
|
ncell = nxcell * nycell * nzcell;
|
|
|
|
/* allocate for cursor link list implementation */
|
|
first = (int *) malloc(ncell * sizeof(int));
|
|
for (gindex = 0; gindex < ncell; gindex++) {
|
|
first[gindex] = -1;
|
|
}
|
|
next = (int *) malloc(atoms->size * sizeof(int));
|
|
for (n = 0; n < atoms->size; n++) {
|
|
next[n] = -1;
|
|
}
|
|
|
|
/* geometric hashing */
|
|
for (n = 0; n < atoms->size; n++) {
|
|
if (0==atom[n].q) continue; /* skip any non-contributing atoms */
|
|
i = (int) floorf((atom[n].x - minext.x) * inv_cellen);
|
|
j = (int) floorf((atom[n].y - minext.y) * inv_cellen);
|
|
k = (int) floorf((atom[n].z - minext.z) * inv_cellen);
|
|
gindex = (k*nycell + j)*nxcell + i;
|
|
next[n] = first[gindex];
|
|
first[gindex] = n;
|
|
}
|
|
|
|
/* traverse the grid cells */
|
|
for (gindex = 0; gindex < ncell; gindex++) {
|
|
for (n = first[gindex]; n != -1; n = next[n]) {
|
|
x = atom[n].x - xlo;
|
|
y = atom[n].y - ylo;
|
|
z = atom[n].z - zlo;
|
|
q = atom[n].q;
|
|
|
|
/* find closest grid point with position less than or equal to atom */
|
|
ic = (int) (x * inv_gridspacing);
|
|
jc = (int) (y * inv_gridspacing);
|
|
kc = (int) (z * inv_gridspacing);
|
|
|
|
/* find extent of surrounding box of grid points */
|
|
ia = ic - radius;
|
|
ib = ic + radius + 1;
|
|
ja = jc - radius;
|
|
jb = jc + radius + 1;
|
|
ka = kc - radius;
|
|
kb = kc + radius + 1;
|
|
|
|
/* trim box edges so that they are within grid point lattice */
|
|
if (ia < 0) ia = 0;
|
|
if (ib >= nx) ib = nx-1;
|
|
if (ja < 0) ja = 0;
|
|
if (jb >= ny) jb = ny-1;
|
|
if (ka < 0) ka = 0;
|
|
if (kb >= nz) kb = nz-1;
|
|
|
|
/* loop over surrounding grid points */
|
|
xstart = ia*gridspacing - x;
|
|
ystart = ja*gridspacing - y;
|
|
dz = ka*gridspacing - z;
|
|
for (k = ka; k <= kb; k++, dz += gridspacing) {
|
|
koff = k*ny;
|
|
dz2 = dz*dz;
|
|
|
|
dy = ystart;
|
|
for (j = ja; j <= jb; j++, dy += gridspacing) {
|
|
jkoff = (koff + j)*nx;
|
|
dydz2 = dy*dy + dz2;
|
|
|
|
dx = xstart;
|
|
index = jkoff + ia;
|
|
pg = lattice->lattice + index;
|
|
|
|
for (i = ia; i <= ib; i++, pg++, dx += gridspacing) {
|
|
r2 = dx*dx + dydz2;
|
|
|
|
/* If atom and lattice point are too close, set the lattice value
|
|
* to zero */
|
|
if (r2 < a2) *pg = 0;
|
|
}
|
|
}
|
|
} /* end loop over surrounding grid points */
|
|
|
|
} /* end loop over atoms in a gridcell */
|
|
} /* end loop over gridcells */
|
|
|
|
/* free memory */
|
|
free(next);
|
|
free(first);
|
|
|
|
return 0;
|
|
}
|