Révision 2

ase/optimize/optimize.py (revision 2)
9 9
import numpy as np
10 10

  
11 11
from ase.parallel import rank, barrier
12
from ase.io.trajectory import PickleTrajectory
12
#from ase.io.trajectory import PickleTrajectory
13 13

  
14 14

  
15 15
class Dynamics:
ase/svnversion.py (revision 2)
1
svnversion = "1765"
1
svnversion = "4M"
ase/embed.py (revision 2)
1
from ase import Atom, Atoms
2
from ase.data import covalent_radii, atomic_numbers
3

  
4
import numpy as np
5

  
6
class Embed(Atoms):
7
    #--- constructor of the Embed class ---
8
    def __init__(self, system=None, cluster=None):
9
        super(Embed, self).__init__()
10
        # define the atom map
11
        self.atom_map_sys_cl = []
12
        self.linkatoms = []
13
        # cluster dimensions
14
        self.xyz_cl_min = None
15
        self.xyz_cl_max = None
16
        # set the search radius for link atoms
17
        self.d = 10        
18
        # define the systems for calculations
19
        self.set_system(system)
20
        self.set_cluster(cluster)
21
        #
22
        self.set_cell([10, 10, 10])
23
        return
24
                
25
    #--- set the cluster ---        
26
    def set_cluster(self, atoms):
27
        import copy
28
        # set the min/max cluster dimensions
29
        self.xyz_cl_min = atoms[0].get_position()
30
        self.xyz_cl_max = atoms[0].get_position()
31
        for atom in atoms:
32
            # assign the label "Cluster (10)" in atom.TAG
33
            atom.set_tag(10)
34
            xyz=atom.get_position()
35
            for i in xrange(3):
36
                # set the min/max cluster dimensions
37
                if xyz[i] < self.xyz_cl_min[i]:
38
                    self.xyz_cl_min[i] = xyz[i]
39
                if xyz[i] > self.xyz_cl_max[i]:
40
                    self.xyz_cl_max[i] = xyz[i]
41
                
42
        # add self.d around min/max cluster dimensions
43
        self.xyz_cl_min -= [self.d, self.d, self.d]
44
        self.xyz_cl_max += [self.d, self.d, self.d]       
45
        # set the cluster for low and high level calculation
46
        self.atoms_cluster = atoms
47
        return
48

  
49
    #--- set the system ---
50
    def set_system(self, atoms):
51
        self.atoms_system = atoms        
52
        # assign the label "Cluster (10)" in atom.TAG
53
        for atom in atoms:
54
            atom.set_tag(0)
55
        # update search radius for link atoms
56
        dx = 0
57
        for atom in atoms:
58
            r = covalent_radii[atom.get_atomic_number()]
59
            if (r > dx):
60
                dx = r
61
        self.d = dx * 2.1
62
        return
63
        
64
    #--- return cluster ---
65
    def get_cluster(self):
66
        return self.atoms_cluster
67
        
68
    def get_system(self):
69
        return self.atoms_system
70
        
71
    #--- Embedding ---
72
    def embed(self):
73
        # is the cluster and the host system definied ?
74
        if self.atoms_cluster is None or self.atoms_system is None:
75
            return
76
        self.find_cluster()
77
        self.set_linkatoms()
78
        print "link atoms found: ", len(self.linkatoms)
79

  
80
    def find_cluster(self):
81
        # set tolerance
82
        d = 0.001
83
        #atoms
84
        xyzs_cl=[]
85
        for atom_cl in self.atoms_cluster:
86
            xyzs_cl.append(atom_cl.get_position())
87
        xyzs_sys=[]
88
        for atom_sys in self.atoms_system:
89
            xyzs_sys.append(atom_sys.get_position())
90
        
91
        self.atom_map_sys_cl=np.zeros(len(self.atoms_system), int)
92
        # loop over cluster atoms atom_sys                
93
        for iat_sys in xrange(len(self.atoms_system)):
94
            # get the coordinates of the system atom atom_sys
95
            xyz_sys = xyzs_sys[iat_sys]
96
            # bSysOnly: no identical atom has been found
97
            bSysOnly = True
98
            # loop over system atoms atom_cl
99
            for iat_cl in xrange(len(self.atoms_cluster)):
100
                # difference vector between both atoms
101
                xyz_diff = np.abs(xyzs_sys[iat_sys]-xyzs_cl[iat_cl])
102
                # identical atoms
103
                if xyz_diff[0] < d and xyz_diff[1] < d and xyz_diff[2] < d:
104
                    # set tag (CLUSTER+HOST: 10) to atom_sys
105
                    self.atoms_system[iat_sys].set_tag(10)
106
                    # map the atom in the atom list
107
                    self.atom_map_sys_cl[iat_sys]=iat_cl
108
                    # atom has been identified
109
                    bSysOnly = False
110
                    break
111
            if bSysOnly:
112
                self.atom_map_sys_cl[iat_sys] = -1
113

  
114
    def set_linkatoms(self, tol=15., linkAtom=None, debug=False):
115
        # local copies of xyz coordinates to avoid massive copying of xyz objects
116
        xyzs_cl=[]
117
        for atom_cl in self.atoms_cluster:
118
            xyzs_cl.append(atom_cl.get_position())
119
        xyzs_sys=[]
120
        for atom_sys in self.atoms_system:
121
            xyzs_sys.append(atom_sys.get_position())        
122
        # FIXME: mapping does not work when cluster atoms are outside of the box
123
        # set the standard link atom
124
        if linkAtom is None:
125
            linkAtom ='H'
126
        # number of atoms in the cluster and the system
127
        nat_cl=len(self.atoms_cluster)
128
        nat_sys=len(self.atoms_system)
129
        # system has pbc?
130
        pbc = self.get_pbc()        
131
        # set the bond table
132
        bonds = []
133
        # set the 27 cell_vec, starting with the (0,0,0) vector for the unit cell
134
        cells_L = [(0.0,  0.0,  0.0)]
135
        # get the cell vectors
136
        cell = self.get_cell()
137
        # TODO: check 0D, 1D, 2D, 3D
138
        if False:
139
         for ix in xrange(-1, 2):
140
            for iy in xrange(-1, 2):
141
                for iz in xrange(-1, 2):
142
                    if ix == 0 and iy == 0 and iz == 0:
143
                        continue
144

  
145
                    cells_L.append(np.dot([ix, iy, iz], cell))
146
        # save the radius of system atoms
147
        rs_sys = []
148
        for atom in self.atoms_system:
149
            rs_sys.append(covalent_radii[atom.get_atomic_number()])
150
        # sum over cluster atoms (iat_cl)
151
        for iat_cl in xrange(nat_cl):
152
            # get the cluster atom
153
            atom_cl=self.atoms_cluster[iat_cl]
154
            # ignore link atoms
155
            if atom_cl.get_tag() == 50:
156
                continue
157
            # xyz coordinates and covalent radius of the cluster atom iat_cl
158
            xyz_cl = xyzs_cl[iat_cl]
159
            r_cl = covalent_radii[atom_cl.get_atomic_number()]
160
            
161
            # sum over system atoms (iat_sys)
162
            for iat_sys in xrange(nat_sys):
163
                # avoid cluster atoms
164
                if self.atoms_system[iat_sys].get_tag()==10:
165
                    continue
166
                # sum over all cell_L
167
                for cell_L in cells_L:
168
                    # xyz coordinates and covalent radius of the system atom iat_sys
169
                    xyz_sys = xyzs_sys[iat_sys]+cell_L
170
                    # go only in distance self.d around the cluster
171
                    lcont = True
172
                    for i in xrange(3):
173
                        if (xyz_sys[i] < self.xyz_cl_min[i] or 
174
                            xyz_sys[i] > self.xyz_cl_max[i]):
175
                            lcont = False
176
                            break
177
                    if not lcont:
178
                        continue
179
                    # xyz coordinates and covalent radius of the system atom iat_sys
180
                    r_sys = rs_sys[iat_sys]
181
                    # diff vector
182
                    xyz_diff = xyz_sys - xyz_cl
183
                    # distance between the atoms
184
                    r = np.sqrt(np.dot(xyz_diff, xyz_diff))
185
                    # ratio of the distance to the sum of covalent radius
186
                    f = r / (r_cl + r_sys)
187
                    if debug:
188
                        print "Covalent radii = ",r_cl, r_sys
189
                        print "Distance ", f
190
                        print "tol = ",(1+tol/100.),(1-tol/100.),(1-2*tol/100.)
191
                    if f <= (1+tol/100.) and f >= (1-2*tol/100.):
192
                        s = cell_L, iat_cl, iat_sys, r_cl
193
                        bonds.append(s)
194
                        break
195
                    if f <= (1-2*tol/100.):
196
                        raise RuntimeError("QMX: The cluster atom", iat_cl, " and the system atom", iat_sys, "came too close")
197
        
198
        r_h = covalent_radii[atomic_numbers[linkAtom]]
199
        for bond in bonds:
200
            cell_L, iat_cl, iat_sys, r_cl = bond
201
            # assign the tags for the border atoms
202
            atom_sys.set_tag(1)
203
            atom_cl.set_tag(11)
204
            #difference vector for the link atom, scaling
205
            xyz_diff = xyzs_sys[iat_sys] + cell_L - xyzs_cl[iat_cl]
206
            r = (r_cl + r_h)
207
            xyz_diff *=  r / np.sqrt(np.dot(xyz_diff, xyz_diff))
208
            # determine position of the link atom
209
            xyz_diff += xyzs_cl[iat_cl]
210
            # create link atom
211
            atom = Atom(symbol=linkAtom, position=xyz_diff, tag=50)
212
            # add atom to cluster
213
            self.atoms_cluster.append(atom)
214
            # add atom to the linkatoms
215
            s = cell_L, iat_cl, iat_sys, r, len(self.atoms_cluster)-1
216
            self.linkatoms.append(s)
217
        return
218
        
219
    def set_positions(self, positions_new):
220
        # number of atoms
221
        nat_sys=len(self.atoms_system)
222
        # go over all pairs of atoms
223
        for iat_sys in xrange(nat_sys):
224
            xyz = positions_new[iat_sys]
225
            iat_cl = self.atom_map_sys_cl[iat_sys]
226
            self.atoms_system[iat_sys].set_position(xyz)
227
            if iat_cl > -1:
228
                self.atoms_cluster[iat_cl].set_position(xyz)
229
                
230
        for cell_L, iat_cl, iat_sys, r, iat in self.linkatoms:
231
            # determine position of the link atom
232
            xyz_cl = self.atoms_cluster[iat_cl].get_position()
233
            xyz = self.atoms_system[iat_sys].get_position() - xyz_cl + cell_L
234
            xyz *= r / np.sqrt(np.dot(xyz, xyz))
235
            xyz += xyz_cl
236
            # update xyz coordinates of the cluster
237
            self.atoms_cluster[iat].set_position(xyz)
238
            
239
    def __getitem__(self, i):
240
        return self.atoms_system.__getitem__(i)
241

  
242
    def get_positions(self):
243
        return self.atoms_system.get_positions()
244
        
245
    def __add__(self, other):
246
        return self.atoms_system.__add__(other)
247
        
248
    def __delitem__(self, i):
249
        return self.atoms_system.__delitem__(i)
250
    
251
    def __len__(self):
252
        return self.atoms_system.__len__()
ase/atoms.py (revision 2)
285 285
        """Add new array.
286 286

  
287 287
        If *shape* is not *None*, the shape of *a* will be checked."""
288
        
289 288
        if dtype is not None:
290 289
            a = np.array(a, dtype)
291 290
        else:
......
311 310

  
312 311
        Returns a copy unless the optional argument copy is false.
313 312
        """
313

  
314 314
        if copy:
315 315
            return self.arrays[name].copy()
316 316
        else:
ase/calculators/__init__.py (revision 2)
14 14
from ase.calculators.dftb import Dftb
15 15
from ase.calculators.singlepoint import SinglePointCalculator
16 16
from ase.calculators.test import numeric_force, numeric_forces, TestPotential
17
from ase.calculators.qmx import Qmx
17 18

  
18 19
if _deprecate_things_from_ase_module:
19 20
    from ase.utils.deprecate import Deprecate
20 21
    _locals = locals()
21 22
    for name in ['LennardJones', 'EMT', 'Siesta', 'Dacapo', 'Vasp',
22
                 'Aims', 'AimsCube', 'Turbomole', 'Exciting', 'Dftb',
23
                 'Aims', 'AimsCube', 'Turbomole', 'Exciting', 'Dftb', 'Qmx', 
23 24
                 'SinglePointCalculator', 'numeric_force', 'numeric_forces',
24 25
                 'TestPotential']:
25 26
        obj = _locals[name]
ase/calculators/qmx.py (revision 2)
1
""" This is a QM:MM embedded system for ASE
2

  
3
torsten.kerber@ens-lyon.fr
4
"""
5

  
6
import ase
7
import ase.atoms
8
import numpy as np
9
from general import Calculator
10
from ase.embed import Embed
11

  
12
import sys, os
13

  
14
class Qmx(Calculator):
15
    def __init__(self, calculator_low, calculator_high):
16
        self.string_params = {}
17
        
18
        self.forces=np.zeros((2,2))
19
        self._constraints=None
20
        
21
        self.calculator_low = calculator_low
22
        self.calculator_high = calculator_high
23
                
24
    def get_energy_subsystem(self, path, calculator, atoms, force_consistent):
25
        os.chdir(path)
26
        calculator.set_atoms(atoms)
27
        energy = calculator.get_potential_energy(atoms)
28
        os.chdir("..")
29
        return energy
30
        
31
    def get_forces_subsystem(self, path, calculator, atoms):
32
        os.chdir(path)
33
        calculator.set_atoms(atoms)
34
        forces = calculator.get_forces(atoms)
35
        os.chdir("..")
36
        return forces
37
        
38
        
39
    def get_potential_energy(self, embed, force_consistent=False):
40
        # perform energy calculations 
41
        e_sys_lo = self.get_energy_subsystem("system.low-level", self.calculator_low, embed.get_system(), force_consistent)
42
        e_cl_lo  = self.get_energy_subsystem("cluster.low-level", self.calculator_low, embed.get_cluster(), force_consistent)
43
        e_cl_hi  = self.get_energy_subsystem("cluster.high-level", self.calculator_high, embed.get_cluster(), force_consistent)
44
        # calculate energies
45
        energy = e_sys_lo - e_cl_lo + e_cl_hi
46
        print "%20s=%15s - %15s + %15s" %("E(C:S)", "E(S-MM)", "E(C-MM)", "E(C-QM)")
47
        print "%20f=%15f - %15f + %15f" %(energy, e_sys_lo, e_cl_lo, e_cl_hi)
48
        if force_consistent:
49
            self.energy_free = energy
50
            return self.energy_free
51
        else:
52
            self.energy_zero = energy
53
            return self.energy_zero
54

  
55
    def get_forces(self, embed):
56
        atom_map_sys_cl = embed.atom_map_sys_cl
57
        # get forces for the three systems
58
        f_sys_lo = self.get_forces_subsystem("system.low-level", self.calculator_low, embed.get_system())
59
        f_cl_lo  = self.get_forces_subsystem("cluster.low-level", self.calculator_low, embed.get_cluster())
60
        f_cl_hi  = self.get_forces_subsystem("cluster.high-level", self.calculator_high, embed.get_cluster())
61
        # forces correction for the atoms
62
        f_cl = f_cl_hi - f_cl_lo
63
        #number of atoms
64
        nat_sys = len(embed)
65
        # lo-sys + (hi-lo)
66
        for iat_sys in xrange(nat_sys):
67
            iat_cl = atom_map_sys_cl[iat_sys]
68
            if iat_cl > -1:
69
                f_sys_lo[iat_sys] += f_cl[iat_cl]
70
        
71
        # correct gradients
72
        # Reference: Eichler, Koelmel, Sauer, J. of Comput. Chem., 18(4). 1997, 463-477.
73
        for cell_L, iat_cl, iat_sys, r, iat_link in embed.linkatoms:
74
            # calculate the bond distance (r_bond) at the border
75
            xyz = embed[iat_sys].get_position() - embed.get_cluster()[iat_cl].get_position() + cell_L
76
            
77
            # calculate the bond lenght and the factor f
78
            rbond = np.sqrt(np.dot(xyz, xyz))
79
            f = r / rbond
80
            #normalize xyz
81
            xyz /= rbond
82
            
83
            # receive the gradients for the link atom
84
            fH = f_cl[iat_link]
85
            # Skalarprodukt fH, xyz
86
            fs = np.dot(xyz, fH)
87
            
88
            for idir in xrange(3):
89
                # correct the atom in the system
90
                f_sys_lo[iat_sys][idir] += f*fH[idir] - f*fs*xyz[idir]
91
                # correct the atom in the cluster
92
                f_sys_lo[iat_cl][idir] += (1-f)*fH[idir] + f*fs*xyz[idir]
93
        return f_sys_lo
94

  
95
    def set_atoms(self, atoms):
96
        return
97
           
98
            
99

  
ase/calculators/turbomole.py (revision 2)
9 9
from ase.data import chemical_symbols
10 10
from ase.units import Hartree, Bohr
11 11
from ase.io.turbomole import write_turbomole
12
from general import Calculator
12 13

  
13 14
import numpy as np
14 15

  
15
class Turbomole:
16
class Turbomole(Calculator):
16 17
    """Class for doing Turbomole calculations.
17 18
    """
18 19
    def __init__(self, label='turbomole'):
ase/calculators/vasp.py (revision 2)
149 149
]
150 150

  
151 151
class Vasp(Calculator):
152
    def __init__(self, restart=None, output_template='vasp', track_output=False, 
152
    def __init__(self, restart=None, output_template='vasp', track_output=False, write_input = True, 
153 153
                 **kwargs):
154
        self.bool_write_input = write_input
154 155
        self.name = 'Vasp'
155 156
        self.float_params = {}
156 157
        self.exp_params = {}
......
358 359
        from ase.io.vasp import write_vasp
359 360
        self.initialize(atoms)
360 361
        write_vasp('POSCAR', self.atoms_sorted, symbol_count = self.symbol_count)
361
        self.write_incar(atoms)
362
        self.write_potcar()
363
        self.write_kpoints()
362
        if self.bool_write_input:
363
            self.write_incar(atoms)
364
            self.write_potcar()
365
            self.write_kpoints()
364 366
        self.write_sort_file()
365 367
        
366 368
        # Execute VASP
ase/__init__.py (revision 2)
6 6

  
7 7
from ase.atom import Atom
8 8
from ase.atoms import Atoms
9
from ase.embed import Embed
9 10

  
10 11
_deprecate_things_from_ase_module = True
11 12

  

Formats disponibles : Unified diff