@@ -38,42 +38,52 @@ def read_dftb_plus(
3838 symbols = None
3939 forces = None
4040 energy = None
41+ natoms = None
4142 with open_file (fn_1 ) as f :
42- flag = 0
43- for line in f :
44- if flag == 1 :
45- flag += 1
46- elif flag == 2 :
47- components = line .split ()
48- flag += 1
49- elif line .startswith ("Geometry" ):
50- flag = 1
51- coord = []
52- symbols = []
53- elif flag in (3 , 4 , 5 , 6 ):
54- s = line .split ()
55- components_num = int (s [1 ])
56- symbols .append (components [components_num - 1 ])
43+ lines = iter (f )
44+ for line in lines :
45+ if not line .startswith ("Geometry" ):
46+ continue
47+ # GenFormat declares the atom count on the first line after the
48+ # opening brace and the element table on the next line. The old
49+ # state machine hard-coded four geometry rows, so ammonia-sized
50+ # fixtures passed while larger molecules were truncated.
51+ count_line = next (lines ).split ()
52+ natoms = int (count_line [0 ])
53+ coordinate_mode = count_line [1 ].upper ()
54+ components = next (lines ).split ()
55+ coord = []
56+ symbols = []
57+ for _ in range (natoms ):
58+ s = next (lines ).split ()
59+ symbols .append (components [int (s [1 ]) - 1 ])
5760 coord .append ([float (s [2 ]), float (s [3 ]), float (s [4 ])])
58- flag += 1
59- if flag == 7 :
60- flag = 0
61+ if coordinate_mode == "F" :
62+ # Fractional GenFormat coordinates are expressed in the
63+ # lattice-vector basis that follows the atom records.
64+ origin = np .array ([float (value ) for value in next (lines ).split ()])
65+ lattice = np .array (
66+ [[float (value ) for value in next (lines ).split ()] for _ in range (3 )]
67+ )
68+ coord = (np .asarray (coord ) @ lattice + origin ).tolist ()
69+ elif coordinate_mode not in {"C" , "S" }:
70+ raise ValueError (
71+ f"unsupported GenFormat coordinate mode: { coordinate_mode } "
72+ )
73+ break
74+ if natoms is None :
75+ raise ValueError ("GenFormat Geometry block not found in DFTB+ input" )
6176 with open_file (fn_2 ) as f :
62- flag = 0
63- for line in f :
77+ lines = iter ( f )
78+ for line in lines :
6479 if line .startswith ("Total Forces" ):
65- flag = 8
6680 forces = []
67- elif flag in (8 , 9 , 10 , 11 ):
68- s = line .split ()
69- forces .append ([float (s [1 ]), float (s [2 ]), float (s [3 ])])
70- flag += 1
71- if flag == 12 :
72- flag = 0
81+ for _ in range (natoms ):
82+ s = next (lines ).split ()
83+ forces .append ([float (s [1 ]), float (s [2 ]), float (s [3 ])])
7384 elif line .startswith ("Total energy:" ):
7485 s = line .split ()
7586 energy = float (s [2 ])
76- flag = 0
7787
7888 symbols = np .array (symbols )
7989 forces = np .array (forces )
0 commit comments