root / ase / io / xsf.py @ 19
Historique | Voir | Annoter | Télécharger (4,27 ko)
1 | 1 | tkerber | import numpy as np |
---|---|---|---|
2 | 1 | tkerber | |
3 | 1 | tkerber | from ase.atoms import Atoms |
4 | 1 | tkerber | from ase.units import Hartree |
5 | 1 | tkerber | from ase.parallel import paropen |
6 | 1 | tkerber | from ase.calculators.singlepoint import SinglePointCalculator |
7 | 1 | tkerber | |
8 | 1 | tkerber | |
9 | 1 | tkerber | def write_xsf(fileobj, images, data=None): |
10 | 1 | tkerber | if isinstance(fileobj, str): |
11 | 1 | tkerber | fileobj = paropen(fileobj, 'w')
|
12 | 1 | tkerber | |
13 | 1 | tkerber | if not isinstance(images, (list, tuple)): |
14 | 1 | tkerber | images = [images] |
15 | 1 | tkerber | |
16 | 1 | tkerber | fileobj.write('ANIMSTEPS %d\n' % len(images)) |
17 | 1 | tkerber | |
18 | 1 | tkerber | numbers = images[0].get_atomic_numbers()
|
19 | 1 | tkerber | |
20 | 1 | tkerber | pbc = images[0].get_pbc()
|
21 | 1 | tkerber | if pbc[2]: |
22 | 1 | tkerber | fileobj.write('CRYSTAL\n')
|
23 | 1 | tkerber | elif pbc[1]: |
24 | 1 | tkerber | fileobj.write('SLAB\n')
|
25 | 1 | tkerber | elif pbc[0]: |
26 | 1 | tkerber | fileobj.write('POLYMER\n')
|
27 | 1 | tkerber | else:
|
28 | 1 | tkerber | fileobj.write('MOLECULE\n')
|
29 | 1 | tkerber | |
30 | 1 | tkerber | for n, atoms in enumerate(images): |
31 | 1 | tkerber | if pbc.any():
|
32 | 1 | tkerber | fileobj.write('PRIMVEC %d\n' % (n + 1)) |
33 | 1 | tkerber | cell = atoms.get_cell() |
34 | 1 | tkerber | for i in range(3): |
35 | 1 | tkerber | fileobj.write(' %.14f %.14f %.14f\n' % tuple(cell[i])) |
36 | 1 | tkerber | |
37 | 1 | tkerber | fileobj.write('PRIMCOORD %d\n' % (n + 1)) |
38 | 1 | tkerber | |
39 | 1 | tkerber | # Get the forces if it's not too expensive:
|
40 | 1 | tkerber | calc = atoms.get_calculator() |
41 | 1 | tkerber | if (calc is not None and |
42 | 1 | tkerber | (hasattr(calc, 'calculation_required') and |
43 | 1 | tkerber | not calc.calculation_required(atoms,
|
44 | 1 | tkerber | ['energy', 'forces', 'stress']))): |
45 | 1 | tkerber | forces = atoms.get_forces() |
46 | 1 | tkerber | else:
|
47 | 1 | tkerber | forces = None
|
48 | 1 | tkerber | |
49 | 1 | tkerber | pos = atoms.get_positions() |
50 | 1 | tkerber | |
51 | 1 | tkerber | fileobj.write(' %d 1\n' % len(pos)) |
52 | 1 | tkerber | for a in range(len(pos)): |
53 | 1 | tkerber | fileobj.write(' %2d' % numbers[a])
|
54 | 1 | tkerber | fileobj.write(' %20.14f %20.14f %20.14f' % tuple(pos[a])) |
55 | 1 | tkerber | if forces is None: |
56 | 1 | tkerber | fileobj.write('\n')
|
57 | 1 | tkerber | else:
|
58 | 1 | tkerber | fileobj.write(' %20.14f %20.14f %20.14f\n' % tuple(forces[a])) |
59 | 1 | tkerber | |
60 | 1 | tkerber | if data is None: |
61 | 1 | tkerber | return
|
62 | 1 | tkerber | |
63 | 1 | tkerber | fileobj.write('BEGIN_BLOCK_DATAGRID_3D\n')
|
64 | 1 | tkerber | fileobj.write(' data\n')
|
65 | 1 | tkerber | fileobj.write(' BEGIN_DATAGRID_3Dgrid#1\n')
|
66 | 1 | tkerber | |
67 | 1 | tkerber | data = np.asarray(data) |
68 | 1 | tkerber | if data.dtype == complex: |
69 | 1 | tkerber | data = np.abs(data) |
70 | 1 | tkerber | |
71 | 1 | tkerber | shape = data.shape |
72 | 1 | tkerber | fileobj.write(' %d %d %d\n' % shape)
|
73 | 1 | tkerber | |
74 | 1 | tkerber | cell = atoms.get_cell() |
75 | 1 | tkerber | origin = np.zeros(3)
|
76 | 1 | tkerber | for i in range(3): |
77 | 1 | tkerber | if not pbc[i]: |
78 | 1 | tkerber | origin += cell[i] / shape[i] |
79 | 1 | tkerber | fileobj.write(' %f %f %f\n' % tuple(origin)) |
80 | 1 | tkerber | |
81 | 1 | tkerber | for i in range(3): |
82 | 1 | tkerber | fileobj.write(' %f %f %f\n' %
|
83 | 1 | tkerber | tuple(cell[i] * (shape[i] + 1) / shape[i])) |
84 | 1 | tkerber | |
85 | 1 | tkerber | for x in range(shape[2]): |
86 | 1 | tkerber | for y in range(shape[1]): |
87 | 1 | tkerber | fileobj.write(' ')
|
88 | 1 | tkerber | fileobj.write(' '.join(['%f' % d for d in data[x, y]])) |
89 | 1 | tkerber | fileobj.write('\n')
|
90 | 1 | tkerber | fileobj.write('\n')
|
91 | 1 | tkerber | |
92 | 1 | tkerber | fileobj.write(' END_DATAGRID_3D\n')
|
93 | 1 | tkerber | fileobj.write('END_BLOCK_DATAGRID_3D\n')
|
94 | 1 | tkerber | |
95 | 1 | tkerber | |
96 | 1 | tkerber | def read_xsf(fileobj, index=-1): |
97 | 1 | tkerber | if isinstance(fileobj, str): |
98 | 1 | tkerber | fileobj = open(fileobj)
|
99 | 1 | tkerber | |
100 | 1 | tkerber | readline = fileobj.readline |
101 | 1 | tkerber | line = readline() |
102 | 1 | tkerber | |
103 | 1 | tkerber | if line.startswith('ANIMSTEPS'): |
104 | 1 | tkerber | nimages = int(line.split()[1]) |
105 | 1 | tkerber | line = readline() |
106 | 1 | tkerber | else:
|
107 | 1 | tkerber | nimages = 1
|
108 | 1 | tkerber | |
109 | 1 | tkerber | if line.startswith('CRYSTAL'): |
110 | 1 | tkerber | pbc = True
|
111 | 1 | tkerber | elif line.startswith('SLAB'): |
112 | 1 | tkerber | pbc = (True, True, Flase) |
113 | 1 | tkerber | elif line.startswith('POLYMER'): |
114 | 1 | tkerber | pbc = (True, False, Flase) |
115 | 1 | tkerber | else:
|
116 | 1 | tkerber | pbc = False
|
117 | 1 | tkerber | |
118 | 1 | tkerber | images = [] |
119 | 1 | tkerber | for n in range(nimages): |
120 | 1 | tkerber | cell = None
|
121 | 1 | tkerber | if pbc:
|
122 | 1 | tkerber | line = readline() |
123 | 1 | tkerber | assert line.startswith('PRIMVEC') |
124 | 1 | tkerber | cell = [] |
125 | 1 | tkerber | for i in range(3): |
126 | 1 | tkerber | cell.append([float(x) for x in readline().split()]) |
127 | 1 | tkerber | |
128 | 1 | tkerber | line = readline() |
129 | 1 | tkerber | assert line.startswith('PRIMCOORD') |
130 | 1 | tkerber | |
131 | 1 | tkerber | natoms = int(readline().split()[0]) |
132 | 1 | tkerber | numbers = [] |
133 | 1 | tkerber | positions = [] |
134 | 1 | tkerber | for a in range(natoms): |
135 | 1 | tkerber | line = readline().split() |
136 | 1 | tkerber | numbers.append(int(line[0])) |
137 | 1 | tkerber | positions.append([float(x) for x in line[1:]]) |
138 | 1 | tkerber | |
139 | 1 | tkerber | positions = np.array(positions) |
140 | 1 | tkerber | if len(positions[0]) == 3: |
141 | 1 | tkerber | forces = None
|
142 | 1 | tkerber | else:
|
143 | 1 | tkerber | positions = positions[:, :3]
|
144 | 1 | tkerber | forces = positions[:, 3:] * Hartree
|
145 | 1 | tkerber | |
146 | 1 | tkerber | image = Atoms(numbers, positions, cell=cell, pbc=pbc) |
147 | 1 | tkerber | |
148 | 1 | tkerber | if forces is not None: |
149 | 1 | tkerber | image.set_calculator(SinglePointCalculator(None, forces, None, |
150 | 1 | tkerber | None, image))
|
151 | 1 | tkerber | images.append(image) |
152 | 1 | tkerber | |
153 | 1 | tkerber | return images[index] |