Skip to content

Commit a3d2133

Browse files
authored
Fix(abacus/relax): refactor the read of results from log file (#409)
1 parent cfc9fd4 commit a3d2133

File tree

4 files changed

+1283
-34
lines changed

4 files changed

+1283
-34
lines changed

dpdata/abacus/relax.py

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ def get_log_file(fname, inlines):
1818
def get_coords_from_log(loglines,natoms):
1919
'''
2020
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)
2127
'''
2228
natoms_log = 0
2329
for line in loglines:
@@ -31,47 +37,43 @@ def get_coords_from_log(loglines,natoms):
3137
coords = []
3238
force = []
3339
stress = []
40+
coord_direct = [] #if the coordinate is direct type or not
3441

3542
for i in range(len(loglines)):
3643
line = loglines[i]
3744
if line[18:41] == "lattice constant (Bohr)":
3845
a0 = float(line.split()[-1])
3946
elif len(loglines[i].split()) >=2 and loglines[i].split()[1] == 'COORDINATES':
47+
#read coordinate information
4048
coords.append([])
4149
direct_coord = False
4250
if loglines[i].split()[0] == 'DIRECT':
43-
direct_coord = True
51+
coord_direct.append(True)
4452
for k in range(2,2+natoms):
4553
coords[-1].append(list(map(lambda x: float(x),loglines[i+k].split()[1:4])))
4654
elif loglines[i].split()[0] == 'CARTESIAN':
55+
coord_direct.append(False)
4756
for k in range(2,2+natoms):
4857
coords[-1].append(list(map(lambda x: float(x)*a0,loglines[i+k].split()[1:4])))
4958
else:
5059
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])))
5169

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+
7577
elif line[4:15] == "TOTAL-FORCE":
7678
force.append([])
7779
for j in range(5,5+natoms):
@@ -80,18 +82,58 @@ def get_coords_from_log(loglines,natoms):
8082
stress.append([])
8183
for j in range(4,7):
8284
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])
8885

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+
89125
energy = np.array(energy)
90126
cells = np.array(cells)
91127
coords = np.array(coords)
92128
stress = np.array(stress)
93129
force = np.array(force)
94130

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
95137
cells *= bohr2ang
96138
coords *= bohr2ang
97139

0 commit comments

Comments
 (0)