from visual import * # from math import * #IMPORT LIBRARIES from random import * # from numpy import array import time start = time.time() def PairCorrelationFunction_2D(x,y,S,rMax,dr): """Compute the two-dimensional pair correlation function, also known as the radial distribution function, for a set of circular particles contained in a square region of a plane. This simple function finds reference particles such that a circle of radius rMax drawn around the particle will fit entirely within the square, eliminating the need to compensate for edge effects. If no such particles exist, an error is returned. Try a smaller rMax...or write some code to handle edge effects! ;) Arguments: x an array of x positions of centers of particles y an array of y positions of centers of particles S length of each side of the square region of the plane rMax outer diameter of largest annulus dr increment for increasing radius of annulus Returns a tuple: (g, radii, interior_x, interior_y) g(r) a numpy array containing the correlation function g(r) radii a numpy array containing the radii of the annuli used to compute g(r) interior_x x coordinates of reference particles interior_y y coordinates of reference particles """ from numpy import zeros, sqrt, where, pi, average, arange, histogram # Number of particles in ring/area of ring/number of reference particles/number density # area of ring = pi*(r_outer**2 - r_inner**2) # Find particles which are close enough to the box center that a circle of radius # rMax will not cross any edge of the box bools1 = x>1.1*rMax bools2 = x<(S-1.1*rMax) bools3 = y>rMax*1.1 bools4 = y<(S-rMax*1.1) interior_indices, = where(bools1*bools2*bools3*bools4) num_interior_particles = len(interior_indices) if num_interior_particles < 1: raise RuntimeError ("No particles found for which a circle of radius rMax\ will lie entirely within a square of side length S. Decrease rMax\ or increase the size of the square.") edges = arange(0., rMax+1.1*dr, dr) num_increments = len(edges)-1 g = zeros([num_interior_particles, num_increments]) radii = zeros(num_increments) numberDensity = len(x)/S**2 # Compute pairwise correlation for each interior particle for p in range(num_interior_particles): index = interior_indices[p] d = sqrt((x[index]-x)**2 + (y[index]-y)**2) d[index] = 2*rMax (result,bins) = histogram(d, bins=edges, normed=False, new=True) g[p,:] = result/numberDensity # Average g(r) for all interior particles and compute radii g_average = zeros(num_increments) for i in range(num_increments): radii[i] = (edges[i] + edges[i+1])/2. rOuter = edges[i+1] rInner = edges[i] g_average[i] = average(g[:,i])/(pi*(rOuter**2 - rInner**2)) return (g_average, radii, x[interior_indices], y[interior_indices]) #my code starts here nlat=20 #HOW MANY DISKS ON THE SIDES OF THE BOX r = 0.5 #DISK RADIUS d = 2.0*r #DIAMETER s = 1.22 #GAPS, ALTER TO CHANGE DENSITY S = s - 1 L = (nlat*d)+(nlat-1)*S #LENGTH OF SIDES OF BOX rMax = 5.0 dr=0.08 # Radius for increasing the size of the bins S = L area = L**2 pi = 3.141592654 diskarea= pi*(r**2) * nlat**2 density = diskarea/area cpd = 0.9069 cpdf = (density / cpd)*100 print 'density = %f' % (density) print 'which is %f percent of the closest packed density' % (cpdf) scene.autoscale=0 #KEEP CAMERA STILL scene = display(title='Monte Carlo Simulation of a Hard Disk Fluid',width=600, height=600,center=(L/2,L/2,0), background=(1,1,1)) #################################DRAW THE BOX######################################### thk=0.3 s2 = L - thk s3 = L + thk wallR = box (pos=vector(L, L/2, 0), length=thk, height=s2, width=d, color = color.yellow) wallL = box (pos=vector(0, L/2, 0), length=thk, height=s2, width=d, color = color.yellow) wallB = box (pos=vector(L/2, 0, 0), length=s3, height=thk, width=d, color = color.yellow) wallT = box (pos=vector(L/2, L, 0), length=s3, height=thk, width=d, color = color.yellow) ################################################################################### #######CREATE SQUARE ARRAY OF PARTICLES (NLAT BY NLAT)############ alldisks = [] for x in range(0,nlat): for y in range(0,nlat): disk=sphere(pos=(x*s,y*s), radius = r, color=color.red) alldisks.append(disk) disk.id = (x,y) #################################################### nstep=0.0 #SET FIRST STEP = 0 reject=0.0 #COUNT THE NUMBER OF TIMES A STEP IS REJECTED maxpos=L #DEFINE BOUNDARY CONDITIONS while (nstep<5000):####HOW MANY STEPS?#### nstep=nstep+1 p = choice(alldisks) #CHOOSE A PARTICLE,P, AT RANDOM FROM THE ARRAY pnewx=p.x + 0.9*(random() -0.5) #GENERATE A STEP IN X CHANGE COEFFICIENT OF RANDOM TO GET 30% ACCEPTANCE pnewy=p.y + 0.9*(random() -0.5) #GENERATE A STEP IN Y ######PERIODIC BOUNDARY CONDITIONS############ if pnewx > L: #IF X GOES BEYOND THE RIGHT WALL pnewx=pnewx - L #MOVE X POSITION TO OTHER SIDE if pnewx < 0: #IF X FALLS BELOW THE LEFT WALL pnewx=pnewx + L #MOVE X POSITION TO OTHER SIDE if pnewy > L: #IF Y IS ABOVE BOX pnewy=pnewy - L #MOVE TO THE BOTTOM if pnewy < 0: #IF Y BELOW pnewy=pnewy + L #TO TOP ################################################# rejected = False for disk in alldisks: distance=mag((vector(pnewx,pnewy))-disk.pos)#WORK OUT THE DISTANCE BETWEEN THE NEW POSITION FOR THE DISK AND ANY OTHER DISK if (distance <= 2.0 * r) and p.id != disk.id: #if p overlaps any other disk rejected = True reject=reject+1 # COUNT HOW MANY TIMES THE STEP IS REJECTED break if not rejected: p.x=pnewx # p.y=pnewy #ACCEPT THE STEPS AS THE NEW POSITION FOR THE PARTICLE, P if (nstep % 1800) == 0: #DUMP AFTER SO MANY STEPS x_list = [] y_list = [] for disk in alldisks: x_list.append(disk.x) y_list.append(disk.y) output = open('output''%s' % (nstep), 'w') #open file for outputting (g, radii, newx, newy) = PairCorrelationFunction_2D(array(x_list), array(y_list), S, rMax, dr) #CALCULATE PAIR CORRELATION FUNCTION FOR EACH DUMP for index in range(len(g)): output.write( "%s %s\n" % (radii[index], g[index])) output.close() #close file continue rejection = (reject/nstep) * 100 #percentage of steps rejected acceptance = 100 - rejection print 'acceptance rate was %f per cent' % (acceptance) end = time.time() elapsed= end - start print "The simulation took", elapsed, "seconds to run"
for disk in alldisks: distance=mag((vector(pnewx,pnewy))-disk.pos)
v=vector(pnewx,pnewy) for disk in alldisks: distance=mag(v-disk.pos)

while (nstep<5000):####HOW MANY STEPS?#### nstep+=1 p = choice(alldisks) #CHOOSE A PARTICLE,P, AT RANDOM FROM THE ARRAY pnewx=p.x + 0.9*(random()-0.5) #GENERATE A STEP IN X CHANGE COEFFICIENT OF RANDOM TO GET 30% ACCEPTANCE pnewy=p.y + 0.9*(random()-0.5) #GENERATE A STEP IN Y ######PERIODIC BOUNDARY CONDITIONS############ if pnewx > L: #IF X GOES BEYOND THE RIGHT WALL pnewx-= L #MOVE X POSITION TO OTHER SIDE if pnewx < 0: #IF X FALLS BELOW THE LEFT WALL pnewx += L #MOVE X POSITION TO OTHER SIDE if pnewy > L: #IF Y IS ABOVE BOX pnewy-= L #MOVE TO THE BOTTOM if pnewy < 0: #IF Y BELOW pnewy+=L #TO TOP ################################################# rejected = False v=vector(pnewx,pnewy) for disk in alldisks: distance=mag(v-disk.pos)#WORK OUT THE DISTANCE BETWEEN THE NEW POSITION FOR THE DISK AND ANY OTHER DISK if (distance <= 2.0 * r) and p is not disk: #if p overlaps any other disk rejected = True reject+=1 # COUNT HOW MANY TIMES THE STEP IS REJECTED break if not rejected: p.x=pnewx # p.y=pnewy #ACCEPT THE STEPS AS THE NEW POSITION FOR THE PARTICLE, P if (nstep % 1800) == 0: #DUMP AFTER SO MANY STEPS x_list = [disk.x for disk in alldisks] y_list = [disk.y for disk in alldisks] output = open('output''%s' % (nstep), 'w') #open file for outputting (g, radii, newx, newy) = PairCorrelationFunction_2D(array(x_list), array(y_list), S, rMax, dr) #CALCULATE PAIR CORRELATION FUNCTION FOR EACH DUMP lg=len(g) for index in xrange(lg): output.write( "%s %s\n" % (radii[index], g[index])) output.close() #close file
x_list = [disk.x for disk in alldisks] y_list = [disk.y for disk in alldisks]
from visual import * # from math import sqrt #IMPORT LIBRARIES from random import random, choice # from numpy import zeros, sqrt, where, pi, average, arange, histogram, array import time start = time.time() def PairCorrelationFunction_2D(x,y,S,rMax,dr): """Compute the two-dimensional pair correlation function, also known as the radial distribution function, for a set of circular particles contained in a square region of a plane. This simple function finds reference particles such that a circle of radius rMax drawn around the particle will fit entirely within the square, eliminating the need to compensate for edge effects. If no such particles exist, an error is returned. Try a smaller rMax...or write some code to handle edge effects! ;) Arguments: x an array of x positions of centers of particles y an array of y positions of centers of particles S length of each side of the square region of the plane rMax outer diameter of largest annulus dr increment for increasing radius of annulus Returns a tuple: (g, radii, interior_x, interior_y) g(r) a numpy array containing the correlation function g(r) radii a numpy array containing the radii of the annuli used to compute g(r) interior_x x coordinates of reference particles interior_y y coordinates of reference particles """ from numpy import zeros, sqrt, where, pi, average, arange, histogram # Number of particles in ring/area of ring/number of reference particles/number density # area of ring = pi*(r_outer**2 - r_inner**2) # Find particles which are close enough to the box center that a circle of radius # rMax will not cross any edge of the box bools1 = x>1.1*rMax bools2 = x<(S-1.1*rMax) bools3 = y>rMax*1.1 bools4 = y<(S-rMax*1.1) interior_indices, = where(bools1*bools2*bools3*bools4) num_interior_particles = len(interior_indices) if num_interior_particles < 1: raise RuntimeError ("No particles found for which a circle of radius rMax\ will lie entirely within a square of side length S. Decrease rMax\ or increase the size of the square.") edges = arange(0., rMax+1.1*dr, dr) num_increments = len(edges)-1 g = zeros([num_interior_particles, num_increments]) radii = zeros(num_increments) numberDensity = len(x)/S**2 # Compute pairwise correlation for each interior particle for p in range(num_interior_particles): index = interior_indices[p] d = sqrt((x[index]-x)**2 + (y[index]-y)**2) d[index] = 2*rMax (result,bins) = histogram(d, bins=edges, normed=False, new=True) g[p,:] = result/numberDensity # Average g(r) for all interior particles and compute radii g_average = zeros(num_increments) for i in range(num_increments): radii[i] = (edges[i] + edges[i+1])/2. rOuter = edges[i+1] rInner = edges[i] g_average[i] = average(g[:,i])/(pi*(rOuter**2 - rInner**2)) return (g_average, radii, x[interior_indices], y[interior_indices]) #my code starts here nlat=20 #HOW MANY DISKS ON THE SIDES OF THE BOX r = 0.5 #DISK RADIUS d = 2.0*r #DIAMETER s = 1.22 #GAPS, ALTER TO CHANGE DENSITY S = s - 1 L = (nlat*d)+(nlat-1)*S #LENGTH OF SIDES OF BOX rMax = 5 dr=0.1 # Radius for increasing the size of the bins S = L area = L**2 pi = 3.141592654 diskarea= pi*(r**2) * nlat**2 density = diskarea/area cpd = 0.9069 cpdf = (density / cpd)*100 print 'density = %f' % (density) print 'which is %f percent of the closest packed density' % (cpdf) scene.hide() #######CREATE SQUARE ARRAY OF PARTICLES (NLAT BY NLAT)############ alldisks = [] for x in range(0,nlat): for y in range(0,nlat): disk=sphere(pos=(x*s,y*s), radius = r, color=color.red) alldisks.append(disk) disk.id = (x,y) #################################################### nstep=0.0 #SET FIRST STEP = 0 reject=0.0 #COUNT THE NUMBER OF TIMES A STEP IS REJECTED maxpos=L #DEFINE BOUNDARY CONDITIONS print 'Running Simulation.....' while (nstep<5000):####HOW MANY STEPS?#### nstep+=1 p = choice(alldisks) #CHOOSE A PARTICLE,P, AT RANDOM FROM THE ARRAY pnewx=p.x + 0.9*(random() -0.5) #GENERATE A STEP IN X CHANGE COEFFICIENT OF RANDOM TO GET 30% ACCEPTANCE pnewy=p.y + 0.9*(random() -0.5) #GENERATE A STEP IN Y ######PERIODIC BOUNDARY CONDITIONS############ if pnewx > L: #IF X GOES BEYOND THE RIGHT WALL pnewx-= L #MOVE X POSITION TO OTHER SIDE if pnewx < 0: #IF X FALLS BELOW THE LEFT WALL pnewx += L #MOVE X POSITION TO OTHER SIDE if pnewy > L: #IF Y IS ABOVE BOX pnewy-= L #MOVE TO THE BOTTOM if pnewy < 0: #IF Y BELOW pnewy+=L #TO TOP ################################################# rejected = False v=vector(pnewx,pnewy) for disk in alldisks: distance=mag(v-disk.pos)#WORK OUT THE DISTANCE BETWEEN THE NEW POSITION FOR THE DISK AND ANY OTHER DISK if (distance <= 2.0 * r) and p.id != disk.id: #if p overlaps any other disk rejected = True reject+=1 # COUNT HOW MANY TIMES THE STEP IS REJECTED break if not rejected: p.x=pnewx # p.y=pnewy #ACCEPT THE STEPS AS THE NEW POSITION FOR THE PARTICLE, P if (nstep % 1800) == 0: #DUMP AFTER SO MANY STEPS x_list = [] y_list = [] for disk in alldisks: x_list.append(disk.x) y_list.append(disk.y) output = open('output''%s' % (nstep), 'w') #open file for outputting (g, radii, newx, newy) = PairCorrelationFunction_2D(array(x_list), array(y_list), S, rMax, dr) #CALCULATE PAIR CORRELATION FUNCTION FOR EACH DUMP lg=len(g) for index in range(lg): output.write( "%s %s\n" % (radii[index], g[index])) output.close() #close file continue rejection = (reject/nstep) * 100 #percentage of steps rejected acceptance = 100 - rejection print 'acceptance rate was %f per cent' % (acceptance) end = time.time() elapsed= end - start print "The simulation took", elapsed, "seconds to run"
| DaniWeb Message | |
| Cancel Changes | |