Skip to content

Commit c226a07

Browse files
author
root
committed
fix bug in reading abacus stru
1 parent b671420 commit c226a07

File tree

4 files changed

+24
-182
lines changed

4 files changed

+24
-182
lines changed

dpgen/auto_test/lib/abacus.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import dpdata
66
import numpy as np
7-
from dpdata.abacus.scf import make_unlabeled_stru
7+
from dpdata.abacus.stru import make_unlabeled_stru
88
from dpdata.utils import uniq_atom_names
99
from dpdata.vasp import poscar as dpdata_poscar
1010
from pymatgen.core.structure import Structure

dpgen/generator/lib/abacus_scf.py

Lines changed: 18 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import re
44

55
import numpy as np
6-
from dpdata.abacus.scf import get_cell, get_coords, get_nele_from_stru
6+
7+
from dpdata.abacus.stru import get_frame_from_stru, make_unlabeled_stru
78

89
from dpgen.auto_test.lib import vasp
910

@@ -209,90 +210,19 @@ def make_abacus_scf_stru(
209210
fp_pp_files,
210211
fp_orb_files=None,
211212
fp_dpks_descriptor=None,
212-
fp_params=None,
213213
type_map=None,
214214
pporb="", # pull all pp orb dpks files to pporb folder
215215
):
216-
atom_names = sys_data["atom_names"]
217-
atom_numbs = sys_data["atom_numbs"]
218-
if type_map is None:
219-
type_map = atom_names
220-
221-
assert len(atom_names) == len(atom_numbs), "Please check the name of atoms. "
222-
cell = sys_data["cells"].reshape([3, 3])
223-
coord = sys_data["coords"].reshape([sum(atom_numbs), 3])
224-
# volume = np.linalg.det(cell)
225-
# lattice_const = np.power(volume, 1/3)
226-
227-
ret = "ATOMIC_SPECIES\n"
228-
for iatom in range(len(atom_names)):
229-
assert atom_names[iatom] in type_map, (
230-
"element %s is not defined in type_map" % atom_names[iatom]
231-
)
232-
idx = type_map.index(atom_names[iatom])
233-
if "atom_masses" not in sys_data:
234-
ret += (
235-
atom_names[iatom]
236-
+ " 1.00 "
237-
+ os.path.join(pporb, fp_pp_files[idx])
238-
+ "\n"
239-
)
240-
else:
241-
ret += (
242-
atom_names[iatom]
243-
+ " %.3f " % sys_data["atom_masses"][iatom]
244-
+ os.path.join(pporb, fp_pp_files[idx])
245-
+ "\n"
246-
)
247-
248-
if fp_params is not None and "lattice_constant" in fp_params:
249-
ret += "\nLATTICE_CONSTANT\n"
250-
ret += (
251-
str(fp_params["lattice_constant"]) + "\n\n"
252-
) # in Bohr, in this way coord and cell are in Angstrom
253-
else:
254-
ret += "\nLATTICE_CONSTANT\n"
255-
ret += str(1 / bohr2ang) + "\n\n"
256-
257-
ret += "LATTICE_VECTORS\n"
258-
for ix in range(3):
259-
for iy in range(3):
260-
ret += str(cell[ix][iy]) + " "
261-
ret += "\n"
262-
ret += "\n"
263-
264-
ret += "ATOMIC_POSITIONS\n"
265-
ret += "Cartesian # Cartesian(Unit is LATTICE_CONSTANT)\n"
266-
# ret += "\n"
267-
natom_tot = 0
268-
for iele in range(len(atom_names)):
269-
ret += atom_names[iele] + "\n"
270-
ret += "0.0\n"
271-
ret += str(atom_numbs[iele]) + "\n"
272-
for iatom in range(atom_numbs[iele]):
273-
ret += "%.12f %.12f %.12f %d %d %d\n" % (
274-
coord[natom_tot, 0],
275-
coord[natom_tot, 1],
276-
coord[natom_tot, 2],
277-
1,
278-
1,
279-
1,
280-
)
281-
natom_tot += 1
282-
assert natom_tot == sum(atom_numbs)
283-
216+
# re-construct the path of files by pporb + file name
217+
fp_pp_files = [os.path.join(pporb, i) for i in fp_pp_files]
284218
if fp_orb_files is not None:
285-
ret += "\nNUMERICAL_ORBITAL\n"
286-
assert len(fp_orb_files) == len(type_map)
287-
for iatom in range(len(atom_names)):
288-
idx = type_map.index(atom_names[iatom])
289-
ret += os.path.join(pporb, fp_orb_files[idx]) + "\n"
290-
219+
fp_orb_files = [os.path.join(pporb, i) for i in fp_orb_files]
291220
if fp_dpks_descriptor is not None:
292-
ret += "\nNUMERICAL_DESCRIPTOR\n"
293-
ret += os.path.join(pporb, fp_dpks_descriptor) + "\n"
294-
295-
return ret
221+
fp_dpks_descriptor = os.path.join(pporb, fp_dpks_descriptor)
222+
223+
c = make_unlabeled_stru(sys_data, 0, pp_files=fp_pp_files, numerical_orbital=fp_orb_files, numerical_descriptor=fp_dpks_descriptor)
224+
225+
return c
296226

297227

298228
def get_abacus_input_parameters(INPUT):
@@ -307,106 +237,17 @@ def get_abacus_input_parameters(INPUT):
307237
return input_parameters
308238

309239

310-
def get_mass_from_STRU(geometry_inlines, atom_names):
311-
nele = get_nele_from_stru(geometry_inlines)
312-
assert nele > 0
313-
mass_list = [0 for i in atom_names]
314-
pp_file_list = [i for i in atom_names]
315-
for iline, line in enumerate(geometry_inlines):
316-
if line.split() == []:
317-
continue
318-
if "ATOMIC_SPECIES" == line.split()[0]:
319-
for iele1 in range(1, 1 + nele):
320-
for iele2 in range(nele):
321-
if geometry_inlines[iline + iele1].split()[0] == atom_names[iele2]:
322-
mass_list[iele2] = float(
323-
geometry_inlines[iline + iele1].split()[1]
324-
)
325-
pp_file_list[iele2] = geometry_inlines[iline + iele1].split()[2]
326-
for iele in range(len(mass_list)):
327-
assert mass_list[iele] > 0
328-
return mass_list, pp_file_list
329-
330-
331-
def get_natoms_from_stru(geometry_inlines):
332-
key_words_list = [
333-
"ATOMIC_SPECIES",
334-
"NUMERICAL_ORBITAL",
335-
"LATTICE_CONSTANT",
336-
"LATTICE_VECTORS",
337-
"ATOMIC_POSITIONS",
338-
"NUMERICAL_DESCRIPTOR",
339-
]
340-
keyword_sequence = []
341-
keyword_line_index = []
342-
atom_names = []
343-
atom_numbs = []
344-
tmp_line = []
345-
for i in geometry_inlines:
346-
if i.strip() != "":
347-
tmp_line.append(i)
348-
for iline, line in enumerate(tmp_line):
349-
if line.split() == []:
350-
continue
351-
have_key_word = False
352-
for keyword in key_words_list:
353-
if keyword in line and keyword == line.split()[0]:
354-
keyword_sequence.append(keyword)
355-
keyword_line_index.append(iline)
356-
assert len(keyword_line_index) == len(keyword_sequence)
357-
assert len(keyword_sequence) > 0
358-
keyword_line_index.append(len(tmp_line))
359-
for idx, keyword in enumerate(keyword_sequence):
360-
if keyword == "ATOMIC_POSITIONS":
361-
iline = keyword_line_index[idx] + 2
362-
while iline < keyword_line_index[idx + 1] - 1:
363-
atom_names.append(tmp_line[iline].split()[0])
364-
atom_numbs.append(int(tmp_line[iline + 2].split()[0]))
365-
iline += 3 + atom_numbs[-1]
366-
return atom_names, atom_numbs
367-
368-
369-
def get_additional_from_STRU(geometry_inlines, nele):
370-
dpks_descriptor_kw = "NUMERICAL_DESCRIPTOR"
371-
orb_file_kw = "NUMERICAL_ORBITAL"
372-
dpks_descriptor = None
373-
orb_file = None
374-
for iline in range(len(geometry_inlines)):
375-
if len(geometry_inlines[iline]) > 0:
376-
if orb_file_kw == geometry_inlines[iline].split()[0]:
377-
orb_file = []
378-
for iele in range(nele):
379-
orb_file.append(geometry_inlines[iline + iele + 1].strip())
380-
if dpks_descriptor_kw == geometry_inlines[iline].split()[0]:
381-
dpks_descriptor = geometry_inlines[iline + 1].strip()
382-
return orb_file, dpks_descriptor
383-
384-
385240
def get_abacus_STRU(STRU, INPUT=None, n_ele=None):
386241
# read in geometry from STRU file. n_ele is the number of elements.
387242
# Either n_ele or INPUT should be provided.
388-
with open(STRU) as fp:
389-
geometry_inlines = fp.read().split("\n")
390-
for iline, line in enumerate(geometry_inlines):
391-
if line.split() == [] or len(line) == 0:
392-
del geometry_inlines[iline]
393-
geometry_inlines.append("")
394-
celldm, cell = get_cell(geometry_inlines)
395-
atom_names, natoms, types, coords = get_coords(celldm, cell, geometry_inlines)
396-
masses, pp_files = get_mass_from_STRU(geometry_inlines, atom_names)
397-
orb_files, dpks_descriptor = get_additional_from_STRU(geometry_inlines, len(masses))
398-
data = {}
399-
data["atom_names"] = atom_names
400-
data["atom_numbs"] = natoms
401-
data["atom_types"] = types
402-
data["cells"] = cell
403-
data["coords"] = coords
404-
data["atom_masses"] = (
405-
masses # Notice that this key is not defined in dpdata system.
406-
)
407-
data["pp_files"] = pp_files
408-
data["orb_files"] = orb_files
409-
data["dpks_descriptor"] = dpks_descriptor
243+
data = get_frame_from_stru(STRU)
244+
data["atom_masses"] = data.pop("masses")
245+
data["cells"] = data.pop("cells")[0]
246+
data["coords"] = data.pop("coords")[0]
247+
if "orb_files" not in data:
248+
data["orb_files"] = None
249+
if "dpks_descriptor" not in data:
250+
data["dpks_descriptor"] = None
410251
return data
411252

412253

dpgen/generator/run.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3482,7 +3482,6 @@ def make_fp_abacus_scf(iter_index, jdata):
34823482
fp_pp_files,
34833483
fp_orb_files,
34843484
fp_dpks_descriptor,
3485-
fp_params,
34863485
type_map=jdata["type_map"],
34873486
pporb=pporb_path,
34883487
)

tests/auto_test/test_abacus.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def test_make_input_file_kspacing_three_value(self):
216216
kpt = f1.read().strip().split("\n")[-1].split()
217217
self.assertEqual(kpt, ["9", "5", "3", "0", "0", "0"])
218218

219-
def test_compuate(self):
219+
def test_compute(self):
220220
ret = self.ABACUS.compute(os.path.join(self.equi_path))
221221
self.assertIsNone(ret)
222222
shutil.copy(
@@ -246,8 +246,10 @@ def compare_dict(dict1, dict2):
246246
)
247247
else:
248248
self.assertTrue(dict1[key] == dict2[key])
249-
250-
compare_dict(ret, ret_ref.as_dict())
249+
compare_keys = ["atom_numbs", "atom_names", "atom_types", "cells", "coords",
250+
'energies', 'forces', 'virials', 'stress']
251+
compare_dict({k:ret["data"][k] for k in compare_keys},
252+
{k: ret_ref.data[k] for k in compare_keys})
251253

252254

253255
class TestABACUSDeepKS(unittest.TestCase):

0 commit comments

Comments
 (0)