ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/heatflux/src/applications/utilities/stat2thcond
Revision: 1675
Committed: Thu Feb 16 17:17:24 2012 UTC (13 years, 6 months ago) by chuckv
File size: 7889 byte(s)
Log Message:
Updated version of Gianluca's stat2thcond.

File Contents

# User Rev Content
1 chuckv 1675 #!/usr/bin/env python
2     """Heat Flux Correlation function
3    
4     Computes the correlation function of the heat flux vector
5     that has been stored in a stat file. These can be used to compute
6     the thermal conductivity.
7    
8     Usage: stat2thcond
9    
10     Options:
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    
16     The Einstein relation option will compute: V*<(\int_0^t (S(t')-<S>)dt')^2>/2kT^2,
17     which will grow approximately linearly in time. The long-time slope of this
18     function will be the viscosity.
19    
20     Example:
21     stat2thcond -f ring5.stat -o ring5.pcorr
22    
23     """
24    
25     __author__ = "Dan Gezelter (gezelter@nd.edu)"
26     __version__ = "$Revision: 1665 $"
27     __date__ = "$Date: 2011-12-08 15:25:26 -0400 (Thu, 9 December 2011) $"
28    
29     __copyright__ = "Copyright (c) 2007 by the University of Notre Dame"
30     __license__ = "OpenMD"
31    
32     import sys
33     import getopt
34     import string
35     import math
36    
37     def usage():
38     print __doc__
39    
40     def readStatFile(statFileName):
41    
42     global time
43     global temperature
44     global pressure
45     global volume
46     global Sx
47     global Sy
48     global Sz
49     time = []
50     temperature = []
51     pressure = []
52     volume = []
53     Sx = []
54     Sy = []
55     Sz = []
56    
57     statFile = open(statFileName, 'r')
58     line = statFile.readline()
59    
60     print "reading File"
61     pressSum = 0.0
62     volSum = 0.0
63     tempSum = 0.0
64     line = statFile.readline()
65     while 1:
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    
86     def 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    
138     def 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     # Boltzmann's constant kcal/K
153     kB = 3.29762e-27
154    
155     # converts (amu/fs^3)^2*fs^2 --> kcal^2/angstrom^4
156     intSSdtdtConvert = 1.57288e-41
157    
158    
159     # preV = thcondConvert * volAve / (kB * tempAve * tempAve)
160    
161     # Without unit conversions as follows it should be in Ang^3 / (kcal K)
162     preV = volAve / (kB * tempAve * tempAve)
163    
164     if doEinstein:
165     print "computing Einstein-style Correlation Function"
166    
167     # Precompute sum variables to aid integration.
168     # The integral from t0 -> t0 + t can be easily obtained
169     # from the precomputed sum variables: sum[t0+t] - sum[t0-1]
170     #for i in range(1, len(time)):
171     xSum = []
172     xSum.append(Sx[0])
173     ySum = []
174     ySum.append(Sy[0])
175     zSum = []
176     zSum.append(Sz[0])
177     for i in range(1, len(time)):
178     xSum.append(xSum[i-1] + Sx[i])
179     ySum.append(ySum[i-1] + Sy[i])
180     zSum.append(zSum[i-1] + Sz[i])
181    
182     dt = time[1] - time[0]
183    
184     eXcorr = []
185     eYcorr = []
186     eZcorr = []
187    
188     # i corresponds to the total duration of the integral
189     for i in range(len(time)):
190    
191     xIntSum = 0.0
192     yIntSum = 0.0
193     zIntSum = 0.0
194     # j corresponds to the starting point of the integral
195     for j in range(len(time) - i):
196     if (j == 0):
197    
198     xInt = dt*xSum[j+i]
199     yInt = dt*ySum[j+i]
200     zInt = dt*zSum[j+i]
201     else:
202     xInt = dt*(xSum[j+i] - xSum[j-1])
203     yInt = dt*(ySum[j+i] - ySum[j-1])
204     zInt = dt*(zSum[j+i] - zSum[j-1])
205    
206     xIntSum = xIntSum + xInt*xInt
207     yIntSum = yIntSum + yInt*yInt
208     zIntSum = zIntSum + zInt*zInt
209    
210     eXcorr.append(xIntSum / float(len(time)-i))
211     eYcorr.append(yIntSum / float(len(time)-i))
212     eZcorr.append(zIntSum / float(len(time)-i))
213    
214    
215     outputFile = open(outputFileName, 'w')
216     for i in range(len(time)):
217    
218     if doEinstein:
219     # outputFile.write("%f\t%13e\n" % (time[i], 0.5 * preV * heatfluxConvert * heatfluxConvert * dtConvert * dtConvert * (eXcorr[i] + eYcorr[i] + eZcorr[i])))
220     outputFile.write("%f\t%13e\n" % (time[i], 0.5 * preV * intSSdtdtConvert * (eXcorr[i] + eYcorr[i] + eZcorr[i])))
221     # Ang^3 / (kcal K) * kcal^2/angstrom^4
222     outputFile.close()
223    
224     def main(argv):
225     global doEinstein
226     global haveStatFileName
227     global haveOutputFileName
228    
229     haveStatFileName = False
230     haveOutputFileName = False
231     doEinstein = False
232    
233     try:
234     opts, args = getopt.getopt(argv, "hgesf:o:", ["help", "einstein", "stat-file=", "output-file="])
235     except getopt.GetoptError:
236     usage()
237     sys.exit(2)
238     for opt, arg in opts:
239     if opt in ("-h", "--help"):
240     usage()
241     sys.exit()
242     elif opt in ("-e", "--einstein"):
243     doEinstein = True
244     elif opt in ("-f", "--stat-file"):
245     statFileName = arg
246     haveStatFileName = True
247     elif opt in ("-o", "--output-file"):
248     outputFileName = arg
249     haveOutputFileName = True
250     if (not haveStatFileName):
251     usage()
252     print "No stat file was specified"
253     sys.exit()
254     if (not haveOutputFileName):
255     usage()
256     print "No output file was specified"
257     sys.exit()
258    
259     readStatFile(statFileName);
260     computeAverages();
261     computeCorrelations(outputFileName);
262    
263     if __name__ == "__main__":
264     if len(sys.argv) == 1:
265     usage()
266     sys.exit()
267     main(sys.argv[1:])

Properties

Name Value
svn:executable *