root / ase / io / wien2k.py @ 14
Historique | Voir | Annoter | Télécharger (5,68 ko)
| 1 | 1 | tkerber | from math import sin, cos, pi, sqrt |
|---|---|---|---|
| 2 | 1 | tkerber | |
| 3 | 1 | tkerber | import numpy as np |
| 4 | 1 | tkerber | |
| 5 | 1 | tkerber | from ase.atoms import Atoms, Atom |
| 6 | 1 | tkerber | from ase.units import Bohr, Ry |
| 7 | 1 | tkerber | |
| 8 | 1 | tkerber | def read_scf(filename): |
| 9 | 1 | tkerber | try:
|
| 10 | 1 | tkerber | f = open(filename + '.scf', 'r') |
| 11 | 1 | tkerber | pip = f.readlines() |
| 12 | 1 | tkerber | ene = [] |
| 13 | 1 | tkerber | for line in pip: |
| 14 | 1 | tkerber | if line[0:4] == ':ENE': |
| 15 | 1 | tkerber | ene.append(float(line[43:59]) * Ry) |
| 16 | 1 | tkerber | f.close() |
| 17 | 1 | tkerber | return ene
|
| 18 | 1 | tkerber | except:
|
| 19 | 1 | tkerber | return None |
| 20 | 1 | tkerber | |
| 21 | 1 | tkerber | def read_struct(filename, ase = True): |
| 22 | 1 | tkerber | f = open(filename, 'r') |
| 23 | 1 | tkerber | pip = f.readlines() |
| 24 | 1 | tkerber | lattice = pip[1][0:3] |
| 25 | 1 | tkerber | nat = int(pip[1][27:30]) |
| 26 | 1 | tkerber | cell = np.zeros(6)
|
| 27 | 1 | tkerber | for i in range(6): |
| 28 | 1 | tkerber | cell[i] = float(pip[3][0 + i * 10:10 + i * 10]) |
| 29 | 1 | tkerber | cell[0:3] = cell[0:3] * Bohr |
| 30 | 1 | tkerber | if lattice == 'P ': |
| 31 | 1 | tkerber | lattice = 'P'
|
| 32 | 1 | tkerber | elif lattice == 'H ': |
| 33 | 1 | tkerber | lattice = 'P'
|
| 34 | 1 | tkerber | cell[3:6] = [90.0, 90.0, 120.0] |
| 35 | 1 | tkerber | elif lattice == 'R ': |
| 36 | 1 | tkerber | lattice = 'R'
|
| 37 | 1 | tkerber | elif lattice == 'F ': |
| 38 | 1 | tkerber | lattice = 'F'
|
| 39 | 1 | tkerber | elif lattice == 'B ': |
| 40 | 1 | tkerber | lattice = 'I'
|
| 41 | 1 | tkerber | elif lattice == 'CXY': |
| 42 | 1 | tkerber | lattice = 'C'
|
| 43 | 1 | tkerber | elif lattice == 'CXZ': |
| 44 | 1 | tkerber | lattice = 'B'
|
| 45 | 1 | tkerber | elif lattice == 'CYZ': |
| 46 | 1 | tkerber | lattice = 'A'
|
| 47 | 1 | tkerber | else:
|
| 48 | 1 | tkerber | print 'TEST needed' |
| 49 | 1 | tkerber | pos = np.array([]) |
| 50 | 1 | tkerber | atomtype = [] |
| 51 | 1 | tkerber | rmt = [] |
| 52 | 1 | tkerber | neq = np.zeros(nat) |
| 53 | 1 | tkerber | iline = 4
|
| 54 | 1 | tkerber | indif = 0
|
| 55 | 1 | tkerber | for iat in range(nat): |
| 56 | 1 | tkerber | indifini = indif |
| 57 | 1 | tkerber | if len(pos) == 0: |
| 58 | 1 | tkerber | pos = np.array([[float(pip[iline][12:22]), |
| 59 | 1 | tkerber | float(pip[iline][25:35]), |
| 60 | 1 | tkerber | float(pip[iline][38:48])]]) |
| 61 | 1 | tkerber | else:
|
| 62 | 1 | tkerber | pos = np.append(pos, np.array([[float(pip[iline][12:22]), |
| 63 | 1 | tkerber | float(pip[iline][25:35]), |
| 64 | 1 | tkerber | float(pip[iline][38:48])]]), |
| 65 | 1 | tkerber | axis = 0)
|
| 66 | 1 | tkerber | indif += 1
|
| 67 | 1 | tkerber | iline += 1
|
| 68 | 1 | tkerber | neq[iat] = int(pip[iline][15:17]) |
| 69 | 1 | tkerber | iline += 1
|
| 70 | 1 | tkerber | for ieq in range(1, int(neq[iat])): |
| 71 | 1 | tkerber | pos = np.append(pos, np.array([[float(pip[iline][12:22]), |
| 72 | 1 | tkerber | float(pip[iline][25:35]), |
| 73 | 1 | tkerber | float(pip[iline][38:48])]]), |
| 74 | 1 | tkerber | axis = 0)
|
| 75 | 1 | tkerber | indif += 1
|
| 76 | 1 | tkerber | iline += 1
|
| 77 | 1 | tkerber | for i in range(indif - indifini): |
| 78 | 1 | tkerber | atomtype.append(pip[iline][0:2].replace(' ', '')) |
| 79 | 1 | tkerber | rmt.append(float(pip[iline][43:48])) |
| 80 | 1 | tkerber | iline += 4
|
| 81 | 1 | tkerber | if ase:
|
| 82 | 1 | tkerber | cell2 = coorsys(cell) |
| 83 | 1 | tkerber | atoms = Atoms(atomtype, pos, pbc = True)
|
| 84 | 1 | tkerber | atoms.set_cell(cell2, scale_atoms = True)
|
| 85 | 1 | tkerber | cell2 = np.dot(c2p(lattice), cell2) |
| 86 | 1 | tkerber | if lattice == 'R': |
| 87 | 1 | tkerber | atoms.set_cell(cell2, scale_atoms = True)
|
| 88 | 1 | tkerber | else:
|
| 89 | 1 | tkerber | atoms.set_cell(cell2) |
| 90 | 1 | tkerber | return atoms
|
| 91 | 1 | tkerber | else:
|
| 92 | 1 | tkerber | return cell, lattice, pos, atomtype, rmt
|
| 93 | 1 | tkerber | |
| 94 | 1 | tkerber | def write_struct(filename, atoms2 = None, rmt = None, lattice = 'P'): |
| 95 | 1 | tkerber | atoms=atoms2.copy() |
| 96 | 1 | tkerber | atoms.set_scaled_positions(atoms.get_scaled_positions()) |
| 97 | 1 | tkerber | f = file(filename, 'w') |
| 98 | 1 | tkerber | f.write('ASE generated\n')
|
| 99 | 1 | tkerber | nat = len(atoms)
|
| 100 | 1 | tkerber | if rmt == None: |
| 101 | 1 | tkerber | rmt = [2.0] * nat
|
| 102 | 1 | tkerber | f.write(lattice+' LATTICE,NONEQUIV.ATOMS:%3i\nMODE OF CALC=RELA\n'%nat)
|
| 103 | 1 | tkerber | cell = atoms.get_cell() |
| 104 | 1 | tkerber | metT = np.dot(cell, np.transpose(cell)) |
| 105 | 1 | tkerber | cell2 = cellconst(metT) |
| 106 | 1 | tkerber | cell2[0:3] = cell2[0:3] / Bohr |
| 107 | 1 | tkerber | f.write(('%10.6f' * 6) % tuple(cell2) + '\n') |
| 108 | 1 | tkerber | #print atoms.get_positions()[0]
|
| 109 | 1 | tkerber | for ii in range(nat): |
| 110 | 1 | tkerber | f.write('ATOM %3i: ' % (ii + 1)) |
| 111 | 1 | tkerber | pos = atoms.get_scaled_positions()[ii] |
| 112 | 1 | tkerber | f.write('X=%10.8f Y=%10.8f Z=%10.8f\n' % tuple(pos)) |
| 113 | 1 | tkerber | f.write(' MULT= 1 ISPLIT= 1\n')
|
| 114 | 1 | tkerber | zz = atoms.get_atomic_numbers()[ii] |
| 115 | 1 | tkerber | if zz > 71: |
| 116 | 1 | tkerber | ro = 0.000005
|
| 117 | 1 | tkerber | elif zz > 36: |
| 118 | 1 | tkerber | ro = 0.00001
|
| 119 | 1 | tkerber | elif zz > 18: |
| 120 | 1 | tkerber | ro = 0.00005
|
| 121 | 1 | tkerber | else:
|
| 122 | 1 | tkerber | ro = 0.0001
|
| 123 | 1 | tkerber | f.write('%-10s NPT=%5i R0=%9.8f RMT=%10.4f Z:%10.5f\n' %
|
| 124 | 1 | tkerber | (atoms.get_chemical_symbols()[ii], 781, ro, rmt[ii], zz))
|
| 125 | 1 | tkerber | f.write('LOCAL ROT MATRIX: %9.7f %9.7f %9.7f\n' % (1.0, 0.0, 0.0)) |
| 126 | 1 | tkerber | f.write(' %9.7f %9.7f %9.7f\n' % (0.0, 1.0, 0.0)) |
| 127 | 1 | tkerber | f.write(' %9.7f %9.7f %9.7f\n' % (0.0, 0.0, 1.0)) |
| 128 | 1 | tkerber | f.write(' 0\n')
|
| 129 | 1 | tkerber | |
| 130 | 1 | tkerber | def cellconst(metT): |
| 131 | 1 | tkerber | aa = np.sqrt(metT[0, 0]) |
| 132 | 1 | tkerber | bb = np.sqrt(metT[1, 1]) |
| 133 | 1 | tkerber | cc = np.sqrt(metT[2, 2]) |
| 134 | 1 | tkerber | gamma = np.arccos(metT[0, 1] / (aa * bb)) / np.pi * 180.0 |
| 135 | 1 | tkerber | beta = np.arccos(metT[0, 2] / (aa * cc)) / np.pi * 180.0 |
| 136 | 1 | tkerber | alpha = np.arccos(metT[1, 2] / (bb * cc)) / np.pi * 180.0 |
| 137 | 1 | tkerber | return np.array([aa, bb, cc, alpha, beta, gamma])
|
| 138 | 1 | tkerber | |
| 139 | 1 | tkerber | def coorsys(latconst): |
| 140 | 1 | tkerber | a = latconst[0]
|
| 141 | 1 | tkerber | b = latconst[1]
|
| 142 | 1 | tkerber | c = latconst[2]
|
| 143 | 1 | tkerber | cal = np.cos(latconst[3] * np.pi / 180.0) |
| 144 | 1 | tkerber | cbe = np.cos(latconst[4] * np.pi / 180.0) |
| 145 | 1 | tkerber | cga = np.cos(latconst[5] * np.pi / 180.0) |
| 146 | 1 | tkerber | sal = np.sin(latconst[3] * np.pi / 180.0) |
| 147 | 1 | tkerber | sbe = np.sin(latconst[4] * np.pi / 180.0) |
| 148 | 1 | tkerber | sga = np.sin(latconst[5] * np.pi / 180.0) |
| 149 | 1 | tkerber | return np.array([[a, b * cga, c * cbe],
|
| 150 | 1 | tkerber | [0, b * sga, c * (cal - cbe * cga) / sga],
|
| 151 | 1 | tkerber | [0, 0, c * np.sqrt(1 - cal**2 - cbe**2 - cga**2 + 2 * cal * cbe * cga) / sga]]).transpose() |
| 152 | 1 | tkerber | |
| 153 | 1 | tkerber | def c2p(lattice): |
| 154 | 1 | tkerber | # apply as eg. cell2 = np.dot(ct.c2p('F'), cell)
|
| 155 | 1 | tkerber | if lattice == 'P': |
| 156 | 1 | tkerber | cell = np.eye(3)
|
| 157 | 1 | tkerber | elif lattice == 'F': |
| 158 | 1 | tkerber | cell = np.array([[0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]]) |
| 159 | 1 | tkerber | elif lattice == 'I': |
| 160 | 1 | tkerber | cell = np.array([[-0.5, 0.5, 0.5], [0.5, -0.5, 0.5], [0.5, 0.5, -0.5]]) |
| 161 | 1 | tkerber | elif lattice == 'C': |
| 162 | 1 | tkerber | cell = np.array([[0.5, 0.5, 0.0], [0.5, -0.5, 0.0], [0.0, 0.0, -1.0]]) |
| 163 | 1 | tkerber | elif lattice == 'R': |
| 164 | 1 | tkerber | 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 | 1 | tkerber | |
| 166 | 1 | tkerber | else:
|
| 167 | 1 | tkerber | print 'lattice is ' + lattice + '!' |
| 168 | 1 | tkerber | return cell |