Statistiques
| Révision :

root / ase / calculators / turbomole.py @ 1

Historique | Voir | Annoter | Télécharger (6,95 ko)

1 1 tkerber
"""This module defines an ASE interface to Turbomole
2 1 tkerber

3 1 tkerber
http://www.turbomole.com/
4 1 tkerber
"""
5 1 tkerber
6 1 tkerber
7 1 tkerber
import os, sys, string
8 1 tkerber
9 1 tkerber
from ase.data import chemical_symbols
10 1 tkerber
from ase.units import Hartree, Bohr
11 1 tkerber
from ase.io.turbomole import write_turbomole
12 1 tkerber
13 1 tkerber
import numpy as np
14 1 tkerber
15 1 tkerber
class Turbomole:
16 1 tkerber
    """Class for doing Turbomole calculations.
17 1 tkerber
    """
18 1 tkerber
    def __init__(self, label='turbomole'):
19 1 tkerber
        """Construct TURBOMOLE-calculator object.
20 1 tkerber

21 1 tkerber
        Parameters
22 1 tkerber
        ==========
23 1 tkerber
        label: str
24 1 tkerber
            Prefix to use for filenames (label.txt, ...).
25 1 tkerber
            Default is 'turbomole'.
26 1 tkerber

27 1 tkerber
        Examples
28 1 tkerber
        ========
29 1 tkerber
        This is poor man's version of ASE-Turbomole:
30 1 tkerber

31 1 tkerber
        First you do a normal turbomole preparation using turbomole's
32 1 tkerber
        define-program for the initial and final states.
33 1 tkerber

34 1 tkerber
        (for instance in subdirectories Initial and Final)
35 1 tkerber

36 1 tkerber
        Then relax the initial and final coordinates with desired constraints
37 1 tkerber
        using standard turbomole.
38 1 tkerber

39 1 tkerber
        Copy the relaxed initial and final coordinates
40 1 tkerber
        (initial.coord and final.coord)
41 1 tkerber
        and the turbomole related files (from the subdirectory Initial)
42 1 tkerber
        control, coord, alpha, beta, mos, basis, auxbasis etc to the directory
43 1 tkerber
        you do the diffusion run.
44 1 tkerber

45 1 tkerber
        For instance:
46 1 tkerber
        cd $My_Turbomole_diffusion_directory
47 1 tkerber
        cd Initial; cp control alpha beta mos basis auxbasis ../;
48 1 tkerber
        cp coord ../initial.coord;
49 1 tkerber
        cd ../;
50 1 tkerber
        cp Final/coord ./final.coord;
51 1 tkerber
        mkdir Gz ; cp * Gz ; gzip -r Gz
52 1 tkerber

53 1 tkerber
        from ase.io import read
54 1 tkerber
        from ase.calculators.turbomole import Turbomole
55 1 tkerber
        a = read('coord', index=-1, format='turbomole')
56 1 tkerber
        calc = Turbomole()
57 1 tkerber
        a.set_calculator(calc)
58 1 tkerber
        e = a.get_potential_energy()
59 1 tkerber

60 1 tkerber
        """
61 1 tkerber
62 1 tkerber
        # get names of executables for turbomole energy and forces
63 1 tkerber
        # get the path
64 1 tkerber
65 1 tkerber
        os.system('rm -f sysname.file; sysname > sysname.file')
66 1 tkerber
        f = open('sysname.file')
67 1 tkerber
        architechture = f.readline()[:-1]
68 1 tkerber
        f.close()
69 1 tkerber
        tmpath = os.environ['TURBODIR']
70 1 tkerber
        pre = tmpath + '/bin/' + architechture + '/'
71 1 tkerber
72 1 tkerber
73 1 tkerber
        if os.path.isfile('control'):
74 1 tkerber
            f = open('control')
75 1 tkerber
        else:
76 1 tkerber
            print 'File control is missing'
77 1 tkerber
            raise RuntimeError, \
78 1 tkerber
                'Please run Turbomole define and come thereafter back'
79 1 tkerber
        lines = f.readlines()
80 1 tkerber
        f.close()
81 1 tkerber
        self.tm_program_energy=pre+'dscf'
82 1 tkerber
        self.tm_program_forces=pre+'grad'
83 1 tkerber
        for line in lines:
84 1 tkerber
            if line.startswith('$ricore'):
85 1 tkerber
                self.tm_program_energy=pre+'ridft'
86 1 tkerber
                self.tm_program_forces=pre+'rdgrad'
87 1 tkerber
88 1 tkerber
        self.label = label
89 1 tkerber
        self.converged = False
90 1 tkerber
        #clean up turbomole energy file
91 1 tkerber
        os.system('rm -f energy; touch energy')
92 1 tkerber
93 1 tkerber
        #turbomole has no stress
94 1 tkerber
        self.stress = np.empty((3, 3))
95 1 tkerber
96 1 tkerber
97 1 tkerber
    def update(self, atoms):
98 1 tkerber
        """Energy and forces are calculated when atoms have moved
99 1 tkerber
        by calling self.calculate
100 1 tkerber
        """
101 1 tkerber
        if (not self.converged or
102 1 tkerber
            len(self.numbers) != len(atoms) or
103 1 tkerber
            (self.numbers != atoms.get_atomic_numbers()).any()):
104 1 tkerber
            self.initialize(atoms)
105 1 tkerber
            self.calculate(atoms)
106 1 tkerber
        elif ((self.positions != atoms.get_positions()).any() or
107 1 tkerber
              (self.pbc != atoms.get_pbc()).any() or
108 1 tkerber
              (self.cell != atoms.get_cell()).any()):
109 1 tkerber
            self.calculate(atoms)
110 1 tkerber
111 1 tkerber
    def initialize(self, atoms):
112 1 tkerber
        self.numbers = atoms.get_atomic_numbers().copy()
113 1 tkerber
        self.species = []
114 1 tkerber
        for a, Z in enumerate(self.numbers):
115 1 tkerber
            self.species.append(Z)
116 1 tkerber
        self.converged = False
117 1 tkerber
118 1 tkerber
    def get_potential_energy(self, atoms):
119 1 tkerber
        self.update(atoms)
120 1 tkerber
        return self.etotal
121 1 tkerber
122 1 tkerber
    def get_forces(self, atoms):
123 1 tkerber
        self.update(atoms)
124 1 tkerber
        return self.forces.copy()
125 1 tkerber
126 1 tkerber
    def get_stress(self, atoms):
127 1 tkerber
        self.update(atoms)
128 1 tkerber
        return self.stress.copy()
129 1 tkerber
130 1 tkerber
    def calculate(self, atoms):
131 1 tkerber
        """Total Turbomole energy is calculated (to file 'energy'
132 1 tkerber
        also forces are calculated (to file 'gradient')
133 1 tkerber
        """
134 1 tkerber
        self.positions = atoms.get_positions().copy()
135 1 tkerber
        self.cell = atoms.get_cell().copy()
136 1 tkerber
        self.pbc = atoms.get_pbc().copy()
137 1 tkerber
138 1 tkerber
        #write current coordinates to file 'coord' for Turbomole
139 1 tkerber
        write_turbomole('coord', atoms)
140 1 tkerber
141 1 tkerber
142 1 tkerber
        #Turbomole energy calculation
143 1 tkerber
        os.system('rm -f output.energy.dummy; \
144 1 tkerber
                      '+ self.tm_program_energy +'> output.energy.dummy')
145 1 tkerber
146 1 tkerber
        #check that the energy run converged
147 1 tkerber
        if os.path.isfile('dscf_problem'):
148 1 tkerber
            print 'Turbomole scf energy calculation did not converge'
149 1 tkerber
            print 'issue command t2x -c > last.xyz'
150 1 tkerber
            print 'and check geometry last.xyz and job.xxx or statistics'
151 1 tkerber
            raise RuntimeError, \
152 1 tkerber
                'Please run Turbomole define and come thereafter back'
153 1 tkerber
154 1 tkerber
155 1 tkerber
        self.read_energy()
156 1 tkerber
157 1 tkerber
        #Turbomole atomic forces calculation
158 1 tkerber
        #killing the previous gradient file because
159 1 tkerber
        #turbomole gradients are affected by the previous values
160 1 tkerber
        os.system('rm -f gradient; rm -f output.forces.dummy; \
161 1 tkerber
                      '+ self.tm_program_forces +'> output.forces.dummy')
162 1 tkerber
163 1 tkerber
        self.read_forces(atoms)
164 1 tkerber
165 1 tkerber
        self.converged = True
166 1 tkerber
167 1 tkerber
168 1 tkerber
    def read_energy(self):
169 1 tkerber
        """Read Energy from Turbomole energy file."""
170 1 tkerber
        text = open('energy', 'r').read().lower()
171 1 tkerber
        lines = iter(text.split('\n'))
172 1 tkerber
173 1 tkerber
        # Energy:
174 1 tkerber
        for line in lines:
175 1 tkerber
            if line.startswith('$end'):
176 1 tkerber
                break
177 1 tkerber
            elif line.startswith('$'):
178 1 tkerber
                pass
179 1 tkerber
            else:
180 1 tkerber
                #print 'LINE',line
181 1 tkerber
                energy_tmp = float(line.split()[1])
182 1 tkerber
        #print 'energy_tmp',energy_tmp
183 1 tkerber
        self.etotal = energy_tmp * Hartree
184 1 tkerber
185 1 tkerber
186 1 tkerber
    def read_forces(self,atoms):
187 1 tkerber
        """Read Forces from Turbomole gradient file."""
188 1 tkerber
189 1 tkerber
        file = open('gradient','r')
190 1 tkerber
        line=file.readline()
191 1 tkerber
        line=file.readline()
192 1 tkerber
        tmpforces = np.array([[0, 0, 0]])
193 1 tkerber
        while line:
194 1 tkerber
            if 'cycle' in line:
195 1 tkerber
                for i, dummy in enumerate(atoms):
196 1 tkerber
                            line=file.readline()
197 1 tkerber
                forces_tmp=[]
198 1 tkerber
                for i, dummy in enumerate(atoms):
199 1 tkerber
                            line=file.readline()
200 1 tkerber
                            line2=string.replace(line,'D','E')
201 1 tkerber
                            #tmp=np.append(forces_tmp,np.array\
202 1 tkerber
                            #      ([[float(f) for f in line2.split()[0:3]]]))
203 1 tkerber
                            tmp=np.array\
204 1 tkerber
                                ([[float(f) for f in line2.split()[0:3]]])
205 1 tkerber
                            tmpforces=np.concatenate((tmpforces,tmp))
206 1 tkerber
            line=file.readline()
207 1 tkerber
208 1 tkerber
209 1 tkerber
        #note the '-' sign for turbomole, to get forces
210 1 tkerber
        self.forces = (-np.delete(tmpforces, np.s_[0:1], axis=0))*Hartree/Bohr
211 1 tkerber
212 1 tkerber
        #print 'forces', self.forces
213 1 tkerber
214 1 tkerber
    def read(self):
215 1 tkerber
        """Dummy stress for turbomole"""
216 1 tkerber
        self.stress = np.empty((3, 3))