-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclass_rdf.py
148 lines (126 loc) · 5.22 KB
/
class_rdf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# rdf class
import os
from scipy import *
import scipy.linalg
from scipy.linalg import norm
from pbc_dist import pbc_dist
from loadlammpstrj import loadlammpstrj
from class_bead import bead
from class_bond import bond
class rdf:
def __init__(self, upboundary = 10.0, increasingstep = 1.0, atom_1 = '2', atom_2 = '5'):
if upboundary>0 and increasingstep >0 and upboundary/increasingstep>=1:
self.upbd = upboundary
self.step = increasingstep
self.bins = []
self.boxlo = []
self.boxhi = []
for i in range(0, int(self.upbd / self.step) ):
self.bins.append([ ( (i+0.5) * self.step ) ])
self.bins[i].append(0) #RDF value
#print(self.bins)
self.at_1 = atom_1
self.at_2 = atom_2
else:
print('rdf N/A')
def loadfile(self, trjfile):
self.f = open(trjfile, 'r+')
[ self.timestep, self.Natom, self.boxhi, self.boxlo, self.data_start_pt] = loadlammpstrj(self.f)
# The 'trjfile' in fact is a pointer.
# So it passes the pointer into the function.
# Every step in the function loadlammpstrj operates on the pointer 'self.f'.
# That is why no need to run self.f.seek(self.data_start_pt) in the following functions.
#
def genlist(self,atomname):
list_1 = []
spos = self.f.tell()
for i in range(0, self.Natom):
cline = self.f.readline().split()
if cline[2] == atomname:
coor_1 = array( [ float(cline[3]), float(cline[4]), float(cline[5]) ] )
b1 = bead( coor_1, cline[2], int(cline[0]), float(cline[1]) )
list_1.append(b1)
self.f.seek(spos)
return list_1
def gen2list(self):
self.list_1 = self.genlist(self.at_1)
if self.at_1 != self.at_2:
self.list_2 = self.genlist(self.at_2)
else:
self.list_2 = None
#
# print section
print('Number of atoms in list1: '+ str(len(self.list_1) ) )
if self.list_2:
print('Number of atoms in list2: '+ str(len(self.list_2) ) )
else:
print('No list2')
# close file
self.f.close()
del self.f
def sortpairs(self):
self.gen2list()
if self.list_2:
for b1 in self.list_1:
for b2 in self.list_2:
pair = bond(b2, b1)
pair.blength = pbc_dist(b2.coor, b1.coor , self.boxlo, self.boxhi)
for kbin in self.bins:
# The criteron might need to be reconsidered.
# In this code, it is a [r_in , r_out ) domain.
# The first bin includes the distance=0 case.
# This might be a problem.
# Fortunately, it should be impossible for 2 atoms
# having exactly the same coordinates.
if pair.blength >= ( kbin[0] - self.step/2 ) and pair.blength < ( kbin[0] + self.step/2) :
kbin[1] = kbin[1] + 1
else:
for i in range(0, len(self.list_1)):
# Notice that j is from i+1!!
# I made the mistake that j went from i,
# which made an error for the first bin!
for j in range(i+1, len(self.list_1)):
pair = bond(self.list_1[i], self.list_1[j])
pair.blength = pbc_dist(self.list_1[i].coor, self.list_1[j].coor , self.boxlo, self.boxhi)
for kbin in self.bins:
if pair.blength >= ( kbin[0] - self.step/2 ) and pair.blength < ( kbin[0] + self.step/2) :
kbin[1] = kbin[1] +1
def calrdf(self):
self.result = []
#
#calculate normal factor
if self.at_1 != self.at_2 :
normfactor = (self.boxhi[0] - self.boxlo[0])\
* (self.boxhi[1] - self.boxlo[1]) \
* (self.boxhi[2] - self.boxlo[2]) \
/ len(self.list_1) / len(self.list_2)
else:
normfactor = (self.boxhi[0] - self.boxlo[0])\
* (self.boxhi[1] - self.boxlo[1]) \
* (self.boxhi[2] - self.boxlo[2]) \
/ len(self.list_1) / (len(self.list_1)-1) *2
print 'normal factor is :'
print normfactor
print '\n'
for kbin in self.bins:
Npairbin = kbin[1]
#
# Print the number of atoms in each bin.
# This is to help us understand the data.
print Npairbin
#
bindensity = Npairbin / \
( 4.0/3.0 * 3.14159 \
* ( (kbin[0] + self.step /2 )**3 - (kbin[0] - self.step /2 )**3 ) \
)
gofrdata = bindensity * normfactor
self.result.append([kbin[0], gofrdata])
del self.bins
del self.list_1
del self.list_2
return self.result
def savetofile(self, outfilename):
out = open(outfilename, 'w+')
for i in range(0, len(self.result)):
out.write(str(self.result[i][0])+' '+str(self.result[i][1])+'\n' )
out.close()