I do a numerical simulation. I have 50,000 particles that crystallize in a box, in which there are several crystals (with periodic boundary condition). I try to find the biggest crystal in the box. The code works well, but it takes about 100 [s]
on my computer. The rate determining step is the function find_neighbors()
below.
Is there a way to use parallel computing to shorten the computational time?
My computer has 12 cores. Maybe we can divide the array (center) into 12 parts?
The output of my function is a 2-D list.
Here is the find_neighbors()
function, written without parallel computing :
# Calculate if two particles are neighbors (Periodic Boundary Condition)
# center is the coordinates of the particles
# d is the distance threshold for two clusters to be neighbors
# Maxima_Range and
# Lattice_Range are for periodic boundary conditions
# Pos_3d is a list.
# Suppose particle i has neighbors j,k,l.
# Pos_3d[i] = [j,k,l]
def find_neighbors(center,d,Maxima_Range,Lattice_Range):
a,b = np.shape(center) # get the dimension of the array
flag_3d = np.zeros(a) # count the number of neighbors for particle i
Pos_3d = [[] for i in range(a)] # Pos_3d is a two dimensional list.
# # Pos_3d[i] includes the indices of all the neighbors of particle i
diff_sqrt = d ** 0.5
for i in range(a):
if i % 6 == 5: # for some reason, when i % 6 == 5,
# # it is the center coordinates,
# # this cannot be changed.
for j in range(i+1,a):
if j % 6 == 5:
diff_x = center[i][0]-center[j][0]
diff_y = center[i][1]-center[j][1]
diff_z = center[i][2]-center[j][2]
if ( diff_x < diff_sqrt
and diff_y < diff_sqrt
and diff_z < diff_sqrt
and diff_x > -diff_sqrt
and diff_y > -diff_sqrt
and diff_z > -diff_sqrt ):
# # if one of the x,y,z component is already
# # bigger than d, we don't need
# # to calculate their distance in 3-D.
# # They are not neighbors.
diff = ( diff_x * diff_x
+ diff_y * diff_y
+ diff_z * diff_z
)
if diff <= d: # without period boundary condition
flag_3d[i] +=1
flag_3d[j] +=1
Pos_3d[i].append(j)
Pos_3d[j].append(i)
continue
# With periodic boundary condition
# in x
do something..
return Pos_3d