Statistiques
| Révision :

root / ase / io / aims.py @ 17

Historique | Voir | Annoter | Télécharger (10,59 ko)

1

    
2
def read_aims(filename):
3
    """Import FHI-aims geometry type files.
4

5
    Reads unitcell, atom positions and constraints from
6
    a geometry.in file.
7
    """
8

    
9
    from ase import Atoms
10
    from ase.constraints import FixAtoms, FixCartesian
11
    import numpy as np
12

    
13
    atoms = Atoms()
14
    fd = open(filename, 'r')
15
    lines = fd.readlines()
16
    fd.close()
17
    positions = []
18
    cell = []
19
    symbols = []
20
    fix = []
21
    fix_cart = []
22
    xyz = np.array([0, 0, 0])
23
    i = -1
24
    n_periodic = -1
25
    periodic = np.array([False, False, False])
26
    for n, line in enumerate(lines):
27
        inp = line.split()
28
        if inp == []:
29
            continue
30
        if inp[0] == 'atom':
31
            if xyz.all():
32
                fix.append(i)
33
            elif xyz.any():
34
                print 1
35
                fix_cart.append(FixCartesian(i, xyz))
36
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
37
            positions.append(floatvect)
38
            symbols.append(inp[-1])
39
            i += 1
40
            xyz = np.array([0, 0, 0])
41
        elif inp[0] == 'lattice_vector':
42
            floatvect = float(inp[1]), float(inp[2]), float(inp[3])
43
            cell.append(floatvect)
44
            n_periodic = n_periodic + 1
45
            periodic[n_periodic] = True
46
        if inp[0] == 'constrain_relaxation':
47
            if inp[1] == '.true.':
48
                fix.append(i)
49
            elif inp[1] == 'x':
50
                xyz[0] = 1
51
            elif inp[1] == 'y':
52
                xyz[1] = 1
53
            elif inp[1] == 'z':
54
                xyz[2] = 1
55
    if xyz.all():
56
        fix.append(i)
57
    elif xyz.any():
58
        fix_cart.append(FixCartesian(i, xyz))
59
    atoms = Atoms(symbols, positions)
60
    if periodic.all():
61
        atoms.set_cell(cell)
62
        atoms.set_pbc(periodic)
63
    if len(fix):
64
        atoms.set_constraint([FixAtoms(indices=fix)]+fix_cart)
65
    else:
66
        atoms.set_constraint(fix_cart)
67
    return atoms
68

    
69
def write_aims(filename, atoms):
70
    """Method to write FHI-aims geometry files.
71

72
    Writes the atoms positions and constraints (only FixAtoms is
73
    supported at the moment). 
74
    """
75

    
76
    from ase.constraints import FixAtoms, FixCartesian
77
    import numpy as np
78

    
79
    if isinstance(atoms, (list, tuple)):
80
        if len(atoms) > 1:
81
            raise RuntimeError("Don't know how to save more than "+
82
                               "one image to FHI-aims input")
83
        else:
84
            atoms = atoms[0]
85

    
86
    fd = open(filename, 'w')
87
    fd.write('#=======================================================\n')
88
    fd.write('#FHI-aims file: '+filename+'\n')
89
    fd.write('#Created using the Atomic Simulation Environment (ASE)\n')
90
    fd.write('#=======================================================\n')
91
    i = 0
92
    if atoms.get_pbc().any():
93
        for n, vector in enumerate(atoms.get_cell()):
94
            fd.write('lattice_vector ')
95
            for i in range(3):
96
                fd.write('%16.16f ' % vector[i])
97
            fd.write('\n')
98
    fix_cart = np.zeros([len(atoms),3]) 
99

    
100
    if atoms.constraints:
101
        for constr in atoms.constraints:
102
            if isinstance(constr, FixAtoms):
103
                fix_cart[constr.index] = [1,1,1]
104
            elif isinstance(constr, FixCartesian):
105
                fix_cart[constr.a] = -constr.mask+1
106

    
107
    for i, atom in enumerate(atoms):
108
        fd.write('atom ')
109
        for pos in atom.get_position():
110
            fd.write('%16.16f ' % pos)
111
        fd.write(atom.symbol)
112
        fd.write('\n')
113
# (1) all coords are constrained:
114
        if fix_cart[i].all():
115
            fd.write('constrain_relaxation .true.\n')
116
# (2) some coords are constrained:
117
        elif fix_cart[i].any():
118
            xyz = fix_cart[i]
119
            for n in range(3):
120
                if xyz[n]:
121
                    fd.write('constrain_relaxation %s\n' % 'xyz'[n])
122
        if atom.charge:
123
            fd.write('initial_charge %16.6f\n' % atom.charge)
124
        if atom.magmom:
125
            fd.write('initial_moment %16.6f\n' % atom.magmom)
126
# except KeyError:
127
#     continue
128

    
129
def read_energy(filename):
130
    for line in open(filename, 'r'):
131
        if line.startswith('  | Total energy corrected'):
132
            E = float(line.split()[-2])
133
    return E
134

    
135
def read_aims_output(filename, index = -1):
136
    """  Import FHI-aims output files with all data available, i.e. relaxations, 
137
    MD information, force information etc etc etc. """
138
    from ase import Atoms, Atom 
139
    from ase.calculators.singlepoint import SinglePointCalculator
140
    from ase.units import Ang, fs
141
    molecular_dynamics = False
142
    fd = open(filename, 'r')
143
    cell = []
144
    images = []
145
    n_periodic = -1
146
    f = None
147
    pbc = False
148
    found_aims_calculator = False
149
    v_unit = Ang/(1000.0*fs)
150
    while True:
151
        line = fd.readline()
152
        if not line:
153
            break
154
        if "List of parameters used to initialize the calculator:" in line:
155
            fd.readline()
156
            calc = read_aims_calculator(fd)
157
            calc.out = filename
158
            found_aims_calculator = True
159
        if "Number of atoms" in line:
160
            inp = line.split()
161
            n_atoms = int(inp[5])
162
        if "| Unit cell:" in line:
163
            if not pbc:
164
                pbc = True
165
                for i in range(3):
166
                    inp = fd.readline().split()
167
                    cell.append([inp[1],inp[2],inp[3]])
168
        if "Atomic structure:" in line and not molecular_dynamics:
169
            fd.readline()
170
            atoms = Atoms()
171
            for i in range(n_atoms):
172
                inp = fd.readline().split()
173
                atoms.append(Atom(inp[3],(inp[4],inp[5],inp[6])))
174
        if "Complete information for previous time-step:" in line:
175
            molecular_dynamics = True
176
        if "Updated atomic structure:" in line and not molecular_dynamics:
177
            fd.readline()
178
            atoms = Atoms()
179
            velocities = []
180
            for i in range(n_atoms):
181
                inp = fd.readline().split()
182
                atoms.append(Atom(inp[4],(inp[1],inp[2],inp[3])))  
183
                if molecular_dynamics:
184
                    inp = fd.readline().split()
185
        if "Atomic structure (and velocities)" in line:
186
            fd.readline()
187
            atoms = Atoms()
188
            velocities = []
189
            for i in range(n_atoms):
190
                inp = fd.readline().split()
191
                atoms.append(Atom(inp[4],(inp[1],inp[2],inp[3])))  
192
                inp = fd.readline().split()
193
                velocities += [[float(inp[1])*v_unit,float(inp[2])*v_unit,float(inp[3])*v_unit]]
194
            atoms.set_velocities(velocities)
195
            images.append(atoms)
196
        if "Total atomic forces" in line:
197
            f = []
198
            for i in range(n_atoms):
199
                inp = fd.readline().split()
200
                f.append([float(inp[2]),float(inp[3]),float(inp[4])])
201
            if not found_aims_calculator:
202
                e = images[-1].get_potential_energy()
203
                images[-1].set_calculator(SinglePointCalculator(e,f,None,None,atoms))
204
            e = None
205
            f = None
206
        if "Total energy corrected" in line:
207
            e = float(line.split()[5])
208
            if pbc:
209
                atoms.set_cell(cell)
210
                atoms.pbc = True
211
            if not found_aims_calculator:
212
                atoms.set_calculator(SinglePointCalculator(e,None,None,None,atoms))
213
            if not molecular_dynamics: 
214
                images.append(atoms)
215
            e = None
216
            if found_aims_calculator:
217
                calc.set_results(images[-1])
218
                images[-1].set_calculator(calc)
219
    fd.close()
220
    if molecular_dynamics:
221
        images = images[1:]
222

    
223
    # return requested images, code borrowed from ase/io/trajectory.py
224
    if isinstance(index, int):
225
        return images[index]
226
    else:
227
        step = index.step or 1
228
        if step > 0:
229
            start = index.start or 0
230
            if start < 0:
231
                start += len(images)
232
            stop = index.stop or len(images)
233
            if stop < 0:
234
                stop += len(images)
235
        else:
236
            if index.start is None:
237
                start = len(images) - 1
238
            else:
239
                start = index.start
240
                if start < 0:
241
                    start += len(images)
242
            if index.stop is None:
243
                stop = -1
244
            else:
245
                stop = index.stop
246
                if stop < 0:
247
                    stop += len(images)
248
        return [images[i] for i in range(start, stop, step)]
249

    
250
def read_aims_calculator(file):
251
    """  found instructions for building an FHI-aims calculator in the output file, 
252
    read its specifications and return it. """
253
    from ase.calculators.aims import Aims
254
    calc = Aims()
255
    while True:
256
        line = file.readline()
257
        if "=======================================================" in line:
258
            break
259
        else:
260
            args = line.split()
261
            key = args[0]
262
            if key == '#':
263
                comment = True   
264
            elif calc.float_params.has_key(key):
265
                calc.float_params[key] = float(args[1])
266
            elif calc.exp_params.has_key(key):
267
                calc.exp_params[key] = float(args[1])
268
            elif calc.string_params.has_key(key):
269
                calc.string_params[key] = args[1]
270
                if len(args) > 2:
271
                    for s in args[2:]:
272
                        calc.string_params[key] += " "+s
273
            elif calc.int_params.has_key(key):
274
                calc.int_params[key] = int(args[1])
275
            elif calc.bool_params.has_key(key):
276
                try:
277
                    calc.bool_params[key] = bool(args[1])
278
                except:
279
                    if key == 'vdw_correction_hirshfeld':
280
                        calc.bool_params[key] = True
281
            elif calc.list_params.has_key(key):
282
                if key == 'output':
283
                    # build output string from args:
284
                    out_option = ''
285
                    for arg in args[1:]:
286
                        out_option +=str(arg)+' '
287
                    if calc.list_params['output'] is not None:
288
                        calc.list_params['output'] += [out_option]
289
                    else:
290
                        calc.list_params['output'] = [out_option]
291
                else:
292
                    calc.list_params[key] = list(args[1:])
293
            elif '#' in key:
294
                key = key[1:]
295
                if calc.input_parameters.has_key(key):
296
                    calc.input_parameters[key] = args[1]
297
                    if len(args) > 2: 
298
                        for s in args[2:]:
299
                            calc.input_parameters[key] += " "+s                
300
            else:
301
                raise TypeError('FHI-aims keyword not defined in ASE: ' + key + '. Please check.')
302
    return calc