Statistiques
| Révision :

root / ase / io / wien2k.py @ 18

Historique | Voir | Annoter | Télécharger (5,68 ko)

1
from math import sin, cos, pi, sqrt
2

    
3
import numpy as np
4

    
5
from ase.atoms import Atoms, Atom
6
from ase.units import Bohr, Ry
7

    
8
def read_scf(filename):
9
    try:
10
        f = open(filename + '.scf', 'r')
11
        pip = f.readlines()
12
        ene = []
13
        for line in pip:
14
            if line[0:4] == ':ENE':
15
                ene.append(float(line[43:59]) * Ry)
16
        f.close()
17
        return ene
18
    except:
19
        return None
20

    
21
def read_struct(filename, ase = True):
22
    f = open(filename, 'r')
23
    pip = f.readlines()
24
    lattice = pip[1][0:3]
25
    nat = int(pip[1][27:30])
26
    cell = np.zeros(6)
27
    for i in range(6):
28
        cell[i] = float(pip[3][0 + i * 10:10 + i * 10])
29
    cell[0:3] = cell[0:3] * Bohr
30
    if lattice == 'P  ':
31
        lattice = 'P'
32
    elif lattice == 'H  ':
33
        lattice = 'P'
34
        cell[3:6] = [90.0, 90.0, 120.0]
35
    elif lattice == 'R  ':
36
        lattice = 'R'
37
    elif lattice == 'F  ':
38
        lattice = 'F'
39
    elif lattice == 'B  ':
40
        lattice = 'I'
41
    elif lattice == 'CXY':
42
        lattice = 'C'
43
    elif lattice == 'CXZ':
44
        lattice = 'B'
45
    elif lattice == 'CYZ':
46
        lattice = 'A'
47
    else:
48
        print 'TEST needed'
49
    pos = np.array([])
50
    atomtype = []
51
    rmt = []
52
    neq = np.zeros(nat)
53
    iline = 4
54
    indif = 0
55
    for iat in range(nat):
56
        indifini = indif
57
        if len(pos) == 0:
58
            pos = np.array([[float(pip[iline][12:22]),
59
                             float(pip[iline][25:35]),
60
                             float(pip[iline][38:48])]])
61
        else:
62
            pos = np.append(pos, np.array([[float(pip[iline][12:22]),
63
                                            float(pip[iline][25:35]),
64
                                            float(pip[iline][38:48])]]),
65
                            axis = 0)
66
        indif += 1
67
        iline += 1
68
        neq[iat] = int(pip[iline][15:17])
69
        iline += 1
70
        for ieq in range(1, int(neq[iat])):
71
            pos = np.append(pos, np.array([[float(pip[iline][12:22]),
72
                                            float(pip[iline][25:35]),
73
                                            float(pip[iline][38:48])]]),
74
                            axis = 0)
75
            indif += 1
76
            iline += 1
77
        for i in range(indif - indifini):
78
            atomtype.append(pip[iline][0:2].replace(' ', ''))
79
            rmt.append(float(pip[iline][43:48]))
80
        iline += 4
81
    if ase:
82
        cell2 = coorsys(cell)
83
        atoms = Atoms(atomtype, pos, pbc = True)
84
        atoms.set_cell(cell2, scale_atoms = True)
85
        cell2 = np.dot(c2p(lattice), cell2)
86
        if lattice == 'R':
87
            atoms.set_cell(cell2, scale_atoms = True)
88
        else:
89
            atoms.set_cell(cell2)
90
        return atoms
91
    else:
92
        return cell, lattice, pos, atomtype, rmt
93

    
94
def write_struct(filename, atoms2 = None, rmt = None, lattice = 'P'):
95
    atoms=atoms2.copy()
96
    atoms.set_scaled_positions(atoms.get_scaled_positions())
97
    f = file(filename, 'w')
98
    f.write('ASE generated\n')
99
    nat = len(atoms)
100
    if rmt == None:
101
        rmt = [2.0] * nat
102
    f.write(lattice+'   LATTICE,NONEQUIV.ATOMS:%3i\nMODE OF CALC=RELA\n'%nat)
103
    cell = atoms.get_cell()
104
    metT = np.dot(cell, np.transpose(cell))
105
    cell2 = cellconst(metT)
106
    cell2[0:3] = cell2[0:3] / Bohr
107
    f.write(('%10.6f' * 6) % tuple(cell2) + '\n')
108
    #print atoms.get_positions()[0]
109
    for ii in range(nat):
110
        f.write('ATOM %3i: ' % (ii + 1))
111
        pos = atoms.get_scaled_positions()[ii]
112
        f.write('X=%10.8f Y=%10.8f Z=%10.8f\n' % tuple(pos))
113
        f.write('          MULT= 1          ISPLIT= 1\n')
114
        zz = atoms.get_atomic_numbers()[ii]
115
        if zz > 71:
116
            ro = 0.000005 
117
        elif zz > 36:
118
            ro = 0.00001
119
        elif zz > 18:
120
            ro = 0.00005
121
        else:
122
            ro = 0.0001
123
        f.write('%-10s NPT=%5i  R0=%9.8f RMT=%10.4f   Z:%10.5f\n' %
124
                (atoms.get_chemical_symbols()[ii], 781, ro, rmt[ii], zz))
125
        f.write('LOCAL ROT MATRIX:    %9.7f %9.7f %9.7f\n' % (1.0, 0.0, 0.0))
126
        f.write('                     %9.7f %9.7f %9.7f\n' % (0.0, 1.0, 0.0))
127
        f.write('                     %9.7f %9.7f %9.7f\n' % (0.0, 0.0, 1.0))
128
    f.write('   0\n')
129

    
130
def cellconst(metT):
131
    aa = np.sqrt(metT[0, 0])
132
    bb = np.sqrt(metT[1, 1])
133
    cc = np.sqrt(metT[2, 2])
134
    gamma = np.arccos(metT[0, 1] / (aa * bb)) / np.pi * 180.0
135
    beta  = np.arccos(metT[0, 2] / (aa * cc)) / np.pi * 180.0
136
    alpha = np.arccos(metT[1, 2] / (bb * cc)) / np.pi * 180.0
137
    return np.array([aa, bb, cc, alpha, beta, gamma])
138

    
139
def coorsys(latconst):
140
    a = latconst[0]
141
    b = latconst[1]
142
    c = latconst[2]
143
    cal = np.cos(latconst[3] * np.pi / 180.0)
144
    cbe = np.cos(latconst[4] * np.pi / 180.0)
145
    cga = np.cos(latconst[5] * np.pi / 180.0)
146
    sal = np.sin(latconst[3] * np.pi / 180.0)
147
    sbe = np.sin(latconst[4] * np.pi / 180.0)
148
    sga = np.sin(latconst[5] * np.pi / 180.0)
149
    return np.array([[a, b * cga, c * cbe],
150
                     [0, b * sga, c * (cal - cbe * cga) / sga],
151
                     [0, 0, c * np.sqrt(1 - cal**2 - cbe**2 - cga**2 + 2 * cal * cbe * cga) / sga]]).transpose()
152

    
153
def c2p(lattice):
154
    # apply as eg. cell2 = np.dot(ct.c2p('F'), cell)
155
    if lattice == 'P':
156
        cell = np.eye(3)
157
    elif lattice == 'F':
158
        cell = np.array([[0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]])
159
    elif lattice == 'I':
160
        cell = np.array([[-0.5, 0.5, 0.5], [0.5, -0.5, 0.5], [0.5, 0.5, -0.5]])
161
    elif lattice == 'C':
162
        cell = np.array([[0.5, 0.5, 0.0], [0.5, -0.5, 0.0], [0.0, 0.0, -1.0]])
163
    elif lattice == 'R':
164
        cell = np.array([[2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0], [-1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0], [-1.0 / 3.0, -2.0/3.0, 1.0 / 3.0]])
165

    
166
    else:
167
        print 'lattice is ' + lattice + '!'
168
    return cell