@@ -18,6 +18,12 @@ def get_log_file(fname, inlines):
18
18
def get_coords_from_log (loglines ,natoms ):
19
19
'''
20
20
NOTICE: unit of coords and cells is Angstrom
21
+ order:
22
+ coordinate
23
+ cell (no output if cell is not changed)
24
+ energy (no output, if SCF is not converged)
25
+ force (no output, if cal_force is not setted or abnormal ending)
26
+ stress (no output, if set cal_stress is not setted or abnormal ending)
21
27
'''
22
28
natoms_log = 0
23
29
for line in loglines :
@@ -31,47 +37,43 @@ def get_coords_from_log(loglines,natoms):
31
37
coords = []
32
38
force = []
33
39
stress = []
40
+ coord_direct = [] #if the coordinate is direct type or not
34
41
35
42
for i in range (len (loglines )):
36
43
line = loglines [i ]
37
44
if line [18 :41 ] == "lattice constant (Bohr)" :
38
45
a0 = float (line .split ()[- 1 ])
39
46
elif len (loglines [i ].split ()) >= 2 and loglines [i ].split ()[1 ] == 'COORDINATES' :
47
+ #read coordinate information
40
48
coords .append ([])
41
49
direct_coord = False
42
50
if loglines [i ].split ()[0 ] == 'DIRECT' :
43
- direct_coord = True
51
+ coord_direct . append ( True )
44
52
for k in range (2 ,2 + natoms ):
45
53
coords [- 1 ].append (list (map (lambda x : float (x ),loglines [i + k ].split ()[1 :4 ])))
46
54
elif loglines [i ].split ()[0 ] == 'CARTESIAN' :
55
+ coord_direct .append (False )
47
56
for k in range (2 ,2 + natoms ):
48
57
coords [- 1 ].append (list (map (lambda x : float (x )* a0 ,loglines [i + k ].split ()[1 :4 ])))
49
58
else :
50
59
assert (False ),"Unrecongnized coordinate type, %s, line:%d" % (loglines [i ].split ()[0 ],i )
60
+
61
+ elif loglines [i ][1 :56 ] == "Lattice vectors: (Cartesian coordinate: in unit of a_0)" :
62
+ #add the cell information for previous structures
63
+ while len (cells ) < len (coords ) - 1 :
64
+ cells .append (cells [- 1 ])
65
+ #get current cell information
66
+ cells .append ([])
67
+ for k in range (1 ,4 ):
68
+ cells [- 1 ].append (list (map (lambda x :float (x )* a0 ,loglines [i + k ].split ()[0 :3 ])))
51
69
52
- converg = True
53
- for j in range (i ):
54
- if loglines [i - j - 1 ][1 :36 ] == 'Ion relaxation is not converged yet' :
55
- converg = False
56
- break
57
- elif loglines [i - j - 1 ][1 :29 ] == 'Ion relaxation is converged!' :
58
- converg = True
59
- break
60
-
61
- if converg :
62
- for j in range (i + 1 ,len (loglines )):
63
- if loglines [j ][1 :56 ] == "Lattice vectors: (Cartesian coordinate: in unit of a_0)" :
64
- cells .append ([])
65
- for k in range (1 ,4 ):
66
- cells [- 1 ].append (list (map (lambda x :float (x )* a0 ,loglines [j + k ].split ()[0 :3 ])))
67
- break
68
- else :
69
- cells .append (cells [- 1 ])
70
-
71
- coords [- 1 ] = np .array (coords [- 1 ])
72
- if direct_coord :
73
- coords [- 1 ] = coords [- 1 ].dot (cells [- 1 ])
74
-
70
+ elif line [1 :14 ] == "final etot is" :
71
+ #add the energy for previous structures whose SCF is not converged
72
+ while len (energy ) < len (coords ) - 1 :
73
+ energy .append (np .nan )
74
+ #get the energy of current structure
75
+ energy .append (float (line .split ()[- 2 ]))
76
+
75
77
elif line [4 :15 ] == "TOTAL-FORCE" :
76
78
force .append ([])
77
79
for j in range (5 ,5 + natoms ):
@@ -80,18 +82,58 @@ def get_coords_from_log(loglines,natoms):
80
82
stress .append ([])
81
83
for j in range (4 ,7 ):
82
84
stress [- 1 ].append (list (map (lambda x :float (x ),loglines [i + j ].split ()[0 :3 ])))
83
- elif line [1 :14 ] == "final etot is" :
84
- energy .append (float (line .split ()[- 2 ]))
85
-
86
- assert (len (cells ) == len (coords ) or len (cells )+ 1 == len (coords )),"ERROR: detected %d coordinates and %d cells" % (len (coords ),len (cells ))
87
- if len (cells )+ 1 == len (coords ): del (coords [- 1 ])
88
85
86
+ #delete last structures which has no energy
87
+ while len (energy ) < len (coords ):
88
+ del coords [- 1 ]
89
+ del coord_direct [- 1 ]
90
+
91
+ #add cells for last structures whose cell is not changed
92
+ while len (cells ) < len (coords ):
93
+ cells .append (cells [- 1 ])
94
+
95
+ #only keep structures that have all of coord, force and stress
96
+ if len (stress ) == 0 and len (force ) == 0 :
97
+ minl = len (coords )
98
+ elif len (stress ) == 0 :
99
+ minl = min (len (coords ),len (force ))
100
+ force = force [:minl ]
101
+ elif len (force ) == 0 :
102
+ minl = min (len (coords ),len (stress ))
103
+ stress = stress [:minl ]
104
+ else :
105
+ minl = min (len (coords ),len (force ),len (stress ))
106
+ force = force [:minl ]
107
+ stress = stress [:minl ]
108
+
109
+ coords = coords [:minl ]
110
+ energy = energy [:minl ]
111
+ cells = cells [:minl ]
112
+
113
+ #delete structures whose energy is np.nan
114
+ for i in range (minl ):
115
+ if np .isnan (energy [i - minl ]):
116
+ del energy [i - minl ]
117
+ del coords [i - minl ]
118
+ del cells [i - minl ]
119
+ del coord_direct [i - minl ]
120
+ if len (force ) > 0 :
121
+ del force [i - minl ]
122
+ if len (stress ) > 0 :
123
+ del stress [i - minl ]
124
+
89
125
energy = np .array (energy )
90
126
cells = np .array (cells )
91
127
coords = np .array (coords )
92
128
stress = np .array (stress )
93
129
force = np .array (force )
94
130
131
+ #transfer direct coordinate to cartessian type
132
+ for i in range (len (coords )):
133
+ if coord_direct [i ]:
134
+ coords [i ] = coords [i ].dot (cells [i ])
135
+
136
+ #transfer bohrium to angstrom
95
137
cells *= bohr2ang
96
138
coords *= bohr2ang
97
139
0 commit comments