Coverage for /builds/ase/ase/ase/io/crystal.py: 78.79%
66 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
1# fmt: off
3from ase.atoms import Atoms
4from ase.utils import reader, writer
7@writer
8def write_crystal(fd, atoms):
9 """Method to write atom structure in crystal format
10 (fort.34 format)
11 """
13 ispbc = atoms.get_pbc()
14 box = atoms.get_cell()
16 # here it is assumed that the non-periodic direction are z
17 # in 2D case, z and y in the 1D case.
19 if ispbc[2]:
20 fd.write('%2s %2s %2s %23s \n' %
21 ('3', '1', '1', 'E -0.0E+0 DE 0.0E+0( 1)'))
22 elif ispbc[1]:
23 fd.write('%2s %2s %2s %23s \n' %
24 ('2', '1', '1', 'E -0.0E+0 DE 0.0E+0( 1)'))
25 box[2, 2] = 500.
26 elif ispbc[0]:
27 fd.write('%2s %2s %2s %23s \n' %
28 ('1', '1', '1', 'E -0.0E+0 DE 0.0E+0( 1)'))
29 box[2, 2] = 500.
30 box[1, 1] = 500.
31 else:
32 fd.write('%2s %2s %2s %23s \n' %
33 ('0', '1', '1', 'E -0.0E+0 DE 0.0E+0( 1)'))
34 box[2, 2] = 500.
35 box[1, 1] = 500.
36 box[0, 0] = 500.
38 # write box
39 # crystal dummy
40 fd.write(' %.17E %.17E %.17E \n'
41 % (box[0][0], box[0][1], box[0][2]))
42 fd.write(' %.17E %.17E %.17E \n'
43 % (box[1][0], box[1][1], box[1][2]))
44 fd.write(' %.17E %.17E %.17E \n'
45 % (box[2][0], box[2][1], box[2][2]))
47 # write symmetry operations (not implemented yet for
48 # higher symmetries than C1)
49 fd.write(' %2s \n' % (1))
50 fd.write(f' {1:.17E} {0:.17E} {0:.17E} \n')
51 fd.write(f' {0:.17E} {1:.17E} {0:.17E} \n')
52 fd.write(f' {0:.17E} {0:.17E} {1:.17E} \n')
53 fd.write(f' {0:.17E} {0:.17E} {0:.17E} \n')
55 # write coordinates
56 fd.write(' %8s \n' % (len(atoms)))
57 coords = atoms.get_positions()
58 tags = atoms.get_tags()
59 atomnum = atoms.get_atomic_numbers()
60 for iatom, coord in enumerate(coords):
61 fd.write('%5i %19.16f %19.16f %19.16f \n'
62 % (atomnum[iatom] + tags[iatom],
63 coords[iatom][0], coords[iatom][1], coords[iatom][2]))
66@reader
67def read_crystal(fd):
68 """Method to read coordinates form 'fort.34' files
69 additionally read information about
70 periodic boundary condition
71 """
72 lines = fd.readlines()
74 atoms_pos = []
75 anumber_list = []
76 my_pbc = [False, False, False]
77 mycell = []
79 if float(lines[4]) != 1:
80 raise ValueError('High symmetry geometry is not allowed.')
82 if float(lines[1].split()[0]) < 500.0:
83 cell = [float(c) for c in lines[1].split()]
84 mycell.append(cell)
85 my_pbc[0] = True
86 else:
87 mycell.append([1, 0, 0])
89 if float(lines[2].split()[1]) < 500.0:
90 cell = [float(c) for c in lines[2].split()]
91 mycell.append(cell)
92 my_pbc[1] = True
93 else:
94 mycell.append([0, 1, 0])
96 if float(lines[3].split()[2]) < 500.0:
97 cell = [float(c) for c in lines[3].split()]
98 mycell.append(cell)
99 my_pbc[2] = True
100 else:
101 mycell.append([0, 0, 1])
103 natoms = int(lines[9].split()[0])
104 for i in range(natoms):
105 index = 10 + i
106 anum = int(lines[index].split()[0]) % 100
107 anumber_list.append(anum)
109 position = [float(p) for p in lines[index].split()[1:]]
110 atoms_pos.append(position)
112 atoms = Atoms(positions=atoms_pos, numbers=anumber_list,
113 cell=mycell, pbc=my_pbc)
115 return atoms