OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
stat2tension
1#!@Python3_EXECUTABLE@
2
3__author__ = "Dan Gezelter (gezelter@nd.edu)"
4__copyright__ = "Copyright (c) 2004-present The University of Notre Dame. All Rights Reserved."
5__license__ = "OpenMD"
6
7import sys
8import string
9import math
10import argparse
11from argparse import RawDescriptionHelpFormatter
12
13def readStatFile(statFileName):
14
15 global TimeStamp
16 global Pxx
17 global Pyy
18 global Pzz
19
20 TimeStamp = []
21 Pxx = []
22 Pyy = []
23 Pzz = []
24
25 statFile = open(statFileName, 'r')
26
27 print("reading File")
28 line = statFile.readline()
29 while ("#" in line):
30 line = statFile.readline()
31 while True:
32 L = line.split()
33 if (len(L) > 16):
34 #
35 # OpenMD prints out the pressure tensor in units of amu*fs^-2*Ang^-1
36 #
37 TimeStamp.append(float(L[0]))
38 Pxx.append(float(L[8]))
39 Pyy.append(float(L[12]))
40 Pzz.append(float(L[16]))
41 else:
42 print("Not enough columns are present in the .stat file")
43 print("to calculate the shear viscosity...")
44 print()
45 print("stat2tension expects to find all 9 elements of the")
46 print("pressure tensor in columns 9-17 of the .stat file")
47 print()
48 print("You may need to set the statFileFormat string")
49 print("explicitly in your .omd file when running OpenMD.")
50 print("Consult the OpenMD documentation for more details.")
51 sys.exit()
52
53 line = statFile.readline()
54 if not line: break
55
56 statFile.close()
57
58def computeAverages(Lz, outFileName):
59
60 print("computing Averages")
61
62 outFile = open(outFileName, 'w')
63 outFile.write("# Time \t Surface Tension \n")
64
65
66 # converts amu fs^-2 to milli N / m (a common surface tension unit)
67 gammaConvert = 1.660539040e6
68 gammaSum = 0.0
69 gamma2Sum = 0.0
70
71 for i in range(len(Pzz)):
72 instaGamma = gammaConvert * Lz * 0.5 * (Pzz[i] - 0.5 * (Pxx[i] + Pyy[i]))
73 gammaSum = gammaSum + instaGamma
74 gamma2Sum = gamma2Sum + instaGamma * instaGamma
75
76 gammaAve = gammaSum / float(i+1)
77 outFile.write(str(TimeStamp[i]) + "\t" + str(gammaAve) + "\n")
78
79
80 gammaAve = gammaSum / float(len(Pzz))
81 gammaSdev = math.sqrt(gamma2Sum / float(len(Pzz)) - math.pow(gammaAve, 2))
82 gammaErr = gammaSdev * 1.96 / math.sqrt(len(Pzz))
83
84 print("Average surface tension = %f +/- %f (mN/m)" % (gammaAve, gammaErr))
85
86
87def main(argv):
88
89
90 parser = argparse.ArgumentParser(prog="stat2tension",
91 formatter_class=argparse.RawDescriptionHelpFormatter,
92 description='''\
93This script accumulates the surface tension from an OpenMD stat file
94that has been run with PRESSURE_TENSOR added to the statFileFormat.
95
96This script assumes that the interface is normal to the z-axis, so
97
98 Pn = Pzz
99
100and that the tangential contributions are averaged over the remaining axes:
101
102 Pt(z) = (Pxx + Pyy) / 2
103
104The surface tension is defined using the normal and tangential components:
105
106 \gamma = \int_{-\infty}^{\infty} (Pn - Pt(z)) dz
107
108The tangential pressure is different from the normal pressure only in
109the vicinity of the interfaces, so the net surface tension for the
110system can be simplified:
111
112 \gamma = Lz (Pn - <Pt>)
113
114where <Pt> is the statistical average of the tangential pressure.
115
116In practice, many surface tension simulations comprise two regions,
117with one material in each region. Periodic boundary conditions then
118require two interfaces, so
119
120 \gamma = Lz (Pn - <Pt>)
121
122For more details: Vazquez, U.O.M., Shinoda, W., Moore, P.B. et al.
123J Math Chem (2009) 45: 161. doi:10.1007/s10910-008-9374-7
124''',
125 epilog="Example: stat2tension -s iceWater.stat -z 120.45 -o iceWater.tens")
126
127 parser.add_argument("-s", "--stat-file=",
128 action="store", required=True, dest="statFileName",
129 help="use specified stat (.stat) file")
130
131 parser.add_argument("-z", "--box-length=",
132 action="store", required=True, dest="Lz", type=float,
133 help="dimension of the box in the normal (z) direction")
134 parser.add_argument("-o", "--output-file=",
135 action="store", required=True, dest="outFileName",
136 help="specified output (.tens) file")
137
138
139 if len(sys.argv) == 1:
140 parser.print_help()
141 sys.exit(2)
142 args = parser.parse_args()
143
144 if (not args.statFileName):
145 parser.print_help()
146 parser.error("No stat file name was specified")
147
148 if (not args.Lz):
149 parser.print_help()
150 parser.error("No box z-length was specified")
151
152 if (not args.outFileName):
153 parser.print_help()
154 parser.error("No outpuf file name was specified")
155
156 readStatFile(args.statFileName)
157 computeAverages(args.Lz, args.outFileName)
158
159if __name__ == "__main__":
160 main(sys.argv[1:])