subroutine SANN !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Fortran implementation of the SANN algorithm ! ! ! ! van Meel, Filion, Valeriani and Frenkel November (2011) ! ! ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! declare all variable used in the subroutine implicit none ! npart = total number of particles in the system integer npart ! m = tentative number of neighbours integer i,j,k,m ! countneighbors = number of neighbours of particle i integer countneighbors(1000) ! neighbor = list of neighbours of particles i integer neighbor(1000,100) ! sortneighbor = sorted neighbours integer sortneighbor(1000,100) ! selectedneighbors = list of selected neighbours integer selectedneighbors(1000,100) ! Nb = final number of neighbours of particle i integer Nb(1000) ! edge of the simulation box double precision box ! distance = list of distances between each ! neighbour of particle i and particle i double precision distance(1000,100) ! distancesorted = sorted distances double precision distancesorted(1000,100) ! R(m) as in Eq.3 in the manuscript double precision rm,rm1 ! x,y,z component of every particle i double precision x(1000),y(1000),z(1000) ! distance between particle i and particle j double precision dr ! cutoff distance to identify all potential neighbours double precision rcutoff ! Step 1: ! first we identify the particles within a cutoff radius rcutoff do i=1,npart ! loop over all particles different from i do j =1,npart if (j.ne.i)then ! compute x,y,z component of the distance between particle i and j dx = x(j) - x(i) dy = y(j) - y(i) dz = z(j) - z(i) ! applying periodic boundary conditions dx=dx-nint(dx/box)*box dy=dy-nint(dy/box)*box dz=dz-nint(dz/box)*box ! compute distance dr between particle i and j dr = sqrt(dx*dx+dy*dy+dz*dz) ! identify neighbours that are within a cutoff (rcutoff) if(dr.lt.rcutoff)then ! j is a neighbour of i countneighbors(i) = countneighbors(i) + 1 ! build a list of neighbours neighbor(i,countneighbors(i))= j ! create a list with the distance between i and j distance(i,countneighbors(i))=dr endif endif enddo enddo ! Step 2: ! for every particle i sort all (countneighbors) ! neighbours (neighbor) according to their ! distances (distance) and create a new list of ! particle i's (sortneighbor) ! and a new sorted list of distances (distancesorted) do i=1,npart call sort(i,countneighbors,distance,neighbor, & sortneighbor,distancesorted) enddo do i=1,npart ! Step 3: ! start with 3 neighbours m = 3 ! Step 4: ! compute R(m) as in Eq.3 rm = 0 do k=1,m rm = rm + distancesorted(i,k) enddo rm = rm/(m-2) ! compute r(m+1) do j = 1,countneighbors(i) rm1 = 0 do k=1,m rm1 = rm1 + distancesorted(i,k) enddo rm1 = rm1/(m-2) ! Step 5: ! if rm > rm1 if(rm.ge.rm1)then rm = rm1 ! increase m m = m+1 else ! Step 6: ! if rm < rm1, m is the final number of neighbours exit endif enddo ! the final number of neighbours is m = Nb(i) ! and the neighbours are selectedneighbors Nb(i) = m do j=1,Nb(i) selectedneighbors(i,j) = sortneighbor(i,j) enddo enddo return end !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!