OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
stat2thcond
1#!@Python3_EXECUTABLE@
2"""Heat Flux Correlation function
3
4Computes the correlation function of the heat flux vector
5that has been stored in a stat file. These can be used to compute
6the thermal conductivity.
7
8Usage: stat2thcond
9
10Options:
11 -h, --help show this help
12 -f, --stat-file=... use specified stat file
13 -o, --output-file=... use specified output (.pcorr) file
14 -e, --einstein use Einstein relation (based on Hess 2002 paper)
15
16The Einstein relation option will compute: V*<(\int_0^t (S(t')-<S>)dt')^2>/2kT^2,
17which will grow approximately linearly in time. The long-time slope of this
18function will be the viscosity.
19
20Example:
21 stat2thcond -f ring5.stat -o ring5.pcorr
22
23"""
24
25__author__ = "Dan Gezelter (gezelter@nd.edu)"
26__copyright__ = "Copyright (c) 2004-present The University of Notre Dame. All Rights Reserved."
27__license__ = "OpenMD"
28
29import sys
30import getopt
31import string
32import math
33
34def usage():
35 print(__doc__)
36
37def readStatFile(statFileName):
38
39 global time
40 global temperature
41 global pressure
42 global volume
43 global Sx
44 global Sy
45 global Sz
46 time = []
47 temperature = []
48 pressure = []
49 volume = []
50 Sx = []
51 Sy = []
52 Sz = []
53
54 statFile = open(statFileName, 'r')
55
56 print("reading File")
57 pressSum = 0.0
58 volSum = 0.0
59 tempSum = 0.0
60
61 line = statFile.readline()
62 while ("#" in line):
63 line = statFile.readline()
64
65 while True:
66 L = line.split()
67 time.append(float(L[0]))
68 temperature.append(float(L[4]))
69 #
70 # OpenMD prints out pressure in units of atm.
71 #
72 pressure.append(float(L[5]))
73 volume.append(float(L[6]))
74 #
75 # OpenMD prints out heatflux in units of kcal / (mol s Ang^2).
76 #
77 Sx.append(float(L[8]))
78 Sy.append(float(L[9]))
79 Sz.append(float(L[10]))
80
81 line = statFile.readline()
82 if not line: break
83
84 statFile.close()
85
86def computeAverages():
87
88 global tempAve
89 global pressAve
90 global volAve
91 global pvAve
92
93 print("computing Averages")
94
95 tempSum = 0.0
96 pressSum = 0.0
97 volSum = 0.0
98 pvSum = 0.0
99
100 temp2Sum = 0.0
101 press2Sum = 0.0
102 vol2Sum = 0.0
103 pv2Sum = 0.0
104
105 # converts amu*fs^-2*Ang^-1 -> atm
106 pressureConvert = 1.63882576e8
107
108 for i in range(len(time)):
109 tempSum = tempSum + temperature[i]
110 pressSum = pressSum + pressure[i]
111 volSum = volSum + volume[i]
112 # in units of amu Ang^2 fs^-1
113 pvTerm = pressure[i]*volume[i] / pressureConvert
114 pvSum = pvSum + pvTerm
115 temp2Sum = temp2Sum + math.pow(temperature[i], 2)
116 press2Sum = press2Sum + math.pow(pressure[i], 2)
117 vol2Sum = vol2Sum + math.pow(volume[i], 2)
118 pv2Sum = pv2Sum + math.pow(pvTerm, 2)
119
120 tempAve = tempSum / float(len(time))
121 pressAve = pressSum / float(len(time))
122 volAve = volSum / float(len(time))
123 pvAve = pvSum / float(len(time))
124
125 tempSdev = math.sqrt(temp2Sum / float(len(time)) - math.pow(tempAve, 2))
126 pressSdev = math.sqrt(press2Sum / float(len(time)) - math.pow(pressAve, 2))
127 if (vol2Sum / float(len(time)) < math.pow(volAve, 2)):
128 volSdev = 0.0
129 else:
130 volSdev = math.sqrt(vol2Sum / float(len(time)) - math.pow(volAve, 2))
131 pvSdev = math.sqrt(pv2Sum / float(len(time)) - math.pow(pvAve, 2))
132
133 print(" Average pressure = %f +/- %f (atm)" % (pressAve, pressSdev))
134 print(" Average volume = %f +/- %f (Angst^3)" % (volAve, volSdev))
135 print("Average temperature = %f +/- %f (K)" % (tempAve, tempSdev))
136 print(" Average PV product = %f +/- %f (amu Angst^2 fs^-1)" % (pvAve, pvSdev))
137
138def computeCorrelations(outputFileName):
139
140 # converts amu*fs^-2*Ang^-1 -> atm
141 pressureConvert = 1.63882576e8
142
143 # converts Ang^-3 * kcal/mol * Ang / fs to m^-3 * J/mol * m /s (= W / mol m^2)
144 heatfluxConvert = 4.187e38
145
146 # converts fs to s
147 dtConvert = 1e-15
148
149 # Boltzmann's constant amu*Ang^2*fs^-2/K
150 kB = 8.31451e-7
151
152 # converts Ang^3 / (amu*Ang^2*fs^-2/K * K^2) -> m s^2 / (kg K^2)
153 thcondConvert = 6.0224e-14
154
155 preV = thcondConvert * volAve / (kB * tempAve * tempAve)
156
157
158 if doEinstein:
159 print("computing Einstein-style Correlation Function")
160
161 # Precompute sum variables to aid integration.
162 # The integral from t0 -> t0 + t can be easily obtained
163 # from the precomputed sum variables: sum[t0+t] - sum[t0-1]
164
165 xSum = []
166 xSum.append(Sx[0])
167 ySum = []
168 ySum.append(Sy[0])
169 zSum = []
170 zSum.append(Sz[0])
171 for i in range(1, len(time)):
172 xSum.append(xSum[i-1] + Sx[i])
173 ySum.append(ySum[i-1] + Sy[i])
174 zSum.append(zSum[i-1] + Sz[i])
175
176 dt = time[1] - time[0]
177
178 eXcorr = []
179 eYcorr = []
180 eZcorr = []
181
182 # i corresponds to the total duration of the integral
183 for i in range(len(time)):
184
185 xIntSum = 0.0
186 yIntSum = 0.0
187 zIntSum = 0.0
188 # j corresponds to the starting point of the integral
189 for j in range(len(time) - i):
190 if (j == 0):
191
192 xInt = dt*xSum[j+i]
193 yInt = dt*ySum[j+i]
194 zInt = dt*zSum[j+i]
195 else:
196 xInt = dt*(xSum[j+i] - xSum[j-1])
197 yInt = dt*(ySum[j+i] - ySum[j-1])
198 zInt = dt*(zSum[j+i] - zSum[j-1])
199
200 xIntSum = xIntSum + xInt*xInt
201 yIntSum = yIntSum + yInt*yInt
202 zIntSum = zIntSum + zInt*zInt
203
204 eXcorr.append(xIntSum / float(len(time)-i))
205 eYcorr.append(yIntSum / float(len(time)-i))
206 eZcorr.append(zIntSum / float(len(time)-i))
207
208 outputFile = open(outputFileName, 'w')
209 for i in range(len(time)):
210 if doEinstein:
211 outputFile.write("%f\t%13e\n" % (time[i], 0.5 * preV * heatfluxConvert * heatfluxConvert * dtConvert * dtConvert * (eXcorr[i] + eYcorr[i] + eZcorr[i])))
212 outputFile.close()
213
214def main(argv):
215 global doEinstein
216 global haveStatFileName
217 global haveOutputFileName
218
219 haveStatFileName = False
220 haveOutputFileName = False
221 doEinstein = False
222
223 try:
224 opts, args = getopt.getopt(argv, "hgesf:o:", ["help", "einstein", "stat-file=", "output-file="])
225 except getopt.GetoptError:
226 usage()
227 sys.exit(2)
228 for opt, arg in opts:
229 if opt in ("-h", "--help"):
230 usage()
231 sys.exit()
232 elif opt in ("-e", "--einstein"):
233 doEinstein = True
234 elif opt in ("-f", "--stat-file"):
235 statFileName = arg
236 haveStatFileName = True
237 elif opt in ("-o", "--output-file"):
238 outputFileName = arg
239 haveOutputFileName = True
240 if (not haveStatFileName):
241 usage()
242 print("No stat file was specified")
243 sys.exit()
244 if (not haveOutputFileName):
245 usage()
246 print("No output file was specified")
247 sys.exit()
248
249 readStatFile(statFileName);
250 computeAverages();
251 computeCorrelations(outputFileName);
252
253if __name__ == "__main__":
254 if len(sys.argv) == 1:
255 usage()
256 sys.exit()
257 main(sys.argv[1:])