Statistiques
| Révision :

root / ase / atom.py @ 13

Historique | Voir | Annoter | Télécharger (9,24 ko)

1 1 tkerber
"""This module defines the Atom object."""
2 1 tkerber
3 1 tkerber
import numpy as np
4 1 tkerber
5 1 tkerber
from ase.data import atomic_numbers, chemical_symbols, atomic_masses
6 1 tkerber
7 1 tkerber
8 1 tkerber
#        singular,    plural,     type,  shape
9 1 tkerber
data = {'symbol':   ('symbols',   str,   ()  ),
10 1 tkerber
        'number':   ('numbers',   int,   ()  ),
11 1 tkerber
        'position': ('positions', float, (3,)),
12 1 tkerber
        'tag':      ('tags',      int,   ()  ),
13 1 tkerber
        'momentum': ('momenta',   float, (3,)),
14 1 tkerber
        'mass':     ('masses',    float, ()  ),
15 1 tkerber
        'magmom':   ('magmoms',   float, ()  ),
16 1 tkerber
        'charge':   ('charges',   float, ()  ),
17 1 tkerber
        }
18 1 tkerber
19 1 tkerber
class Atom(object):
20 1 tkerber
    """Class for representing a single atom.
21 1 tkerber

22 1 tkerber
        Parameters:
23 1 tkerber

24 1 tkerber
        symbol: str or int
25 1 tkerber
            Can be a chemical symbol (str) or an atomic number (int).
26 1 tkerber
        position: sequence of 3 floats
27 1 tkerber
            Atomi position.
28 1 tkerber
        tag: int
29 1 tkerber
            Special purpose tag.
30 1 tkerber
        momentum: sequence of 3 floats
31 1 tkerber
            Momentum for atom.
32 1 tkerber
        mass: float
33 1 tkerber
            Atomic mass in atomic units.
34 1 tkerber
        magmom: float
35 1 tkerber
            Magnetic moment.
36 1 tkerber
        charge: float
37 1 tkerber
            Atomic charge.
38 1 tkerber

39 1 tkerber
        Examples:
40 1 tkerber

41 1 tkerber
        >>> a = Atom('O', charge=-2)
42 1 tkerber
        >>> b = Atom(8, charge=-2)
43 1 tkerber
        >>> c = Atom('H', (1, 2, 3), magmom=1)
44 1 tkerber
        >>> print a.charge, a.position
45 1 tkerber
        -2 [ 0. 0. 0.]
46 1 tkerber
        >>> c.x = 0.0
47 1 tkerber
        >>> c.position
48 1 tkerber
        array([ 0.,  2.,  3.])
49 1 tkerber
        >>> b.symbol
50 1 tkerber
        'O'
51 1 tkerber
        >>> c.tag = 42
52 1 tkerber
        >>> c.number
53 1 tkerber
        1
54 1 tkerber
        >>> c.symbol = 'Li'
55 1 tkerber
        >>> c.number
56 1 tkerber
        3
57 1 tkerber

58 1 tkerber
        If the atom object belongs to an Atoms object, then assigning
59 1 tkerber
        values to the atom attributes will change the corresponding
60 1 tkerber
        arrays of the atoms object:
61 1 tkerber

62 1 tkerber
        >>> OH = Atoms('OH')
63 1 tkerber
        >>> OH[0].charge = -1
64 1 tkerber
        >>> OH.get_charges()
65 1 tkerber
        array([-1.,  0.])
66 1 tkerber

67 1 tkerber
        Another example:
68 1 tkerber

69 1 tkerber
        >>> for atom in bulk:
70 1 tkerber
        ...     if atom.symbol = 'Ni':
71 1 tkerber
        ...         atom.magmom = 0.7
72 1 tkerber

73 1 tkerber

74 1 tkerber
        """
75 1 tkerber
76 1 tkerber
    __slots__ = ['_number', '_symbol', '_position', '_tag', '_momentum',
77 1 tkerber
                 '_mass', '_magmom', '_charge', 'atoms', 'index']
78 1 tkerber
79 1 tkerber
    def __init__(self, symbol='X', position=(0, 0, 0),
80 1 tkerber
                 tag=None, momentum=None, mass=None,
81 1 tkerber
                 magmom=None, charge=None,
82 1 tkerber
                 atoms=None, index=None):
83 1 tkerber
        if atoms is None:
84 1 tkerber
            # This atom is not part of any Atoms object:
85 1 tkerber
            if isinstance(symbol, str):
86 1 tkerber
                self._number = atomic_numbers[symbol]
87 1 tkerber
                self._symbol = symbol
88 1 tkerber
            else:
89 1 tkerber
                self._number = symbol
90 1 tkerber
                self._symbol = chemical_symbols[symbol]
91 1 tkerber
            self._position = np.array(position, float)
92 1 tkerber
            self._tag = tag
93 1 tkerber
            if momentum is not None:
94 1 tkerber
                momentum = np.array(momentum, float)
95 1 tkerber
            self._momentum = momentum
96 1 tkerber
            self._mass = mass
97 1 tkerber
            self._magmom = magmom
98 1 tkerber
            self._charge = charge
99 1 tkerber
100 1 tkerber
        self.index = index
101 1 tkerber
        self.atoms = atoms
102 1 tkerber
103 1 tkerber
    def __repr__(self):
104 1 tkerber
        s = "Atom('%s', %s" % (self.symbol, list(self.position))
105 1 tkerber
        for attr in ['tag', 'momentum', 'mass', 'magmom', 'charge']:
106 1 tkerber
            value = getattr(self, attr)
107 1 tkerber
            if value is not None:
108 1 tkerber
                if isinstance(value, np.ndarray):
109 1 tkerber
                    value = value.tolist()
110 1 tkerber
                s += ', %s=%s' % (attr, value)
111 1 tkerber
        if self.atoms is None:
112 1 tkerber
            s += ')'
113 1 tkerber
        else:
114 1 tkerber
            s += ', index=%d)' % self.index
115 1 tkerber
        return s
116 1 tkerber
117 1 tkerber
    def get_data(self):
118 1 tkerber
        """Helper method."""
119 1 tkerber
        return (self.position, self.number,
120 1 tkerber
                self.tag, self.momentum, self.mass,
121 1 tkerber
                self.magmom, self.charge)
122 1 tkerber
123 1 tkerber
    def cut_reference_to_atoms(self):
124 1 tkerber
        """Cut reference to atoms object."""
125 1 tkerber
        data = self.get_data()
126 1 tkerber
        self.index = None
127 1 tkerber
        self.atoms = None
128 1 tkerber
        (self._position,
129 1 tkerber
         self._number,
130 1 tkerber
         self._tag,
131 1 tkerber
         self._momentum,
132 1 tkerber
         self._mass,
133 1 tkerber
         self._magmom,
134 1 tkerber
         self._charge) = data
135 1 tkerber
        self._symbol = chemical_symbols[self._number]
136 1 tkerber
137 1 tkerber
    def _get(self, name):
138 1 tkerber
        if self.atoms is None:
139 1 tkerber
            return getattr(self, '_' + name)
140 1 tkerber
        elif name == 'symbol':
141 1 tkerber
            return chemical_symbols[self.number]
142 1 tkerber
        else:
143 1 tkerber
            plural = data[name][0]
144 1 tkerber
            if plural in self.atoms.arrays:
145 1 tkerber
                return self.atoms.arrays[plural][self.index]
146 1 tkerber
            else:
147 1 tkerber
                return None
148 1 tkerber
149 1 tkerber
    def _get_copy(self, name, copy=False):
150 1 tkerber
        if self.atoms is None:
151 1 tkerber
            return getattr(self, '_' + name)
152 1 tkerber
        elif name == 'symbol':
153 1 tkerber
            return chemical_symbols[self.number]
154 1 tkerber
        else:
155 1 tkerber
            plural = data[name][0]
156 1 tkerber
            if plural in self.atoms.arrays:
157 1 tkerber
                return self.atoms.arrays[plural][self.index].copy()
158 1 tkerber
            else:
159 1 tkerber
                return None
160 1 tkerber
161 1 tkerber
    def _set(self, name, value):
162 1 tkerber
        if self.atoms is None:
163 1 tkerber
            setattr(self, '_' + name, value)
164 1 tkerber
            if name == 'symbol':
165 1 tkerber
                self._number = atomic_numbers[value]
166 1 tkerber
            elif name == 'number':
167 1 tkerber
                self._symbol = chemical_symbols[value]
168 1 tkerber
        elif name == 'symbol':
169 1 tkerber
            self.number = atomic_numbers[value]
170 1 tkerber
        else:
171 1 tkerber
            plural, dtype, shape = data[name]
172 1 tkerber
            if plural in self.atoms.arrays:
173 1 tkerber
                self.atoms.arrays[plural][self.index] = value
174 1 tkerber
            else:
175 1 tkerber
                array = np.zeros((len(self.atoms),) + shape, dtype)
176 1 tkerber
                array[self.index] = value
177 1 tkerber
                self.atoms.new_array(plural, array)
178 1 tkerber
179 1 tkerber
    def get_symbol(self): return self._get('symbol')
180 1 tkerber
    def get_atomic_number(self): return self._get('number')
181 1 tkerber
    def get_position(self): return self._get_copy('position')
182 1 tkerber
    def _get_position(self): return self._get('position')
183 1 tkerber
    def get_tag(self): return self._get('tag')
184 1 tkerber
    def get_momentum(self): return self._get_copy('momentum')
185 1 tkerber
    def _get_momentum(self): return self._get('momentum')
186 1 tkerber
    def get_initial_magnetic_moment(self): return self._get('magmom')
187 1 tkerber
    def get_charge(self): return self._get('charge')
188 1 tkerber
189 1 tkerber
    def set_symbol(self, symbol): self._set('symbol', symbol)
190 1 tkerber
    def set_atomic_number(self, number): self._set('number', number)
191 1 tkerber
    def set_position(self, position):
192 1 tkerber
        self._set('position', np.array(position, float))
193 1 tkerber
    def set_tag(self, tag): self._set('tag', tag)
194 1 tkerber
    def set_momentum(self, momentum): self._set('momentum', momentum)
195 1 tkerber
    def set_initial_magnetic_moment(self, magmom): self._set('magmom', magmom)
196 1 tkerber
    def set_charge(self, charge): self._set('charge', charge)
197 1 tkerber
198 1 tkerber
    def set_magmom(self, magmom):
199 1 tkerber
        "Deprecated, use set_initial_magnetic_moment instead."
200 1 tkerber
        import warnings
201 1 tkerber
        warnings.warn('set_magmom is deprecated. Please use set_initial_magnetic_moment' \
202 1 tkerber
                      ' instead.', DeprecationWarning, stacklevel=2)
203 1 tkerber
        return self.set_initial_magnetic_moment(magmom)
204 1 tkerber
205 1 tkerber
    def get_number(self):
206 1 tkerber
        "Deprecated, use get_atomic_number instead."
207 1 tkerber
        import warnings
208 1 tkerber
        warnings.warn(
209 1 tkerber
            'get_number is deprecated. Please use get_atomic_number instead.',
210 1 tkerber
            DeprecationWarning, stacklevel=2)
211 1 tkerber
        return self.get_atomic_number()
212 1 tkerber
213 1 tkerber
    def set_number(self, number):
214 1 tkerber
        "Deprecated, use set_atomic_number instead."
215 1 tkerber
        import warnings
216 1 tkerber
        warnings.warn(
217 1 tkerber
            'set_number is deprecated. Please use set_atomic_number instead.',
218 1 tkerber
            DeprecationWarning, stacklevel=2)
219 1 tkerber
        return self.set_atomic_number(number)
220 1 tkerber
221 1 tkerber
    def get_mass(self):
222 1 tkerber
        """Get the mass of the atom.
223 1 tkerber

224 1 tkerber
        Returns the mass of the atom, if known.  If unknown, returns the
225 1 tkerber
        atomic mass corresponding to the element.
226 1 tkerber
        """
227 1 tkerber
        m = self._get('mass')
228 1 tkerber
        if m is None:
229 1 tkerber
            m = atomic_masses[self.get_atomic_number()]
230 1 tkerber
        return m
231 1 tkerber
232 1 tkerber
    def set_mass(self, mass):
233 1 tkerber
        """Sets the mass of the atom.
234 1 tkerber

235 1 tkerber
        If the atom is part of a list of atoms, and the atoms do not yet
236 1 tkerber
        have masses, all other atoms are assigned their default masses.
237 1 tkerber
        """
238 1 tkerber
        if self.atoms is None:
239 1 tkerber
            self._mass = mass
240 1 tkerber
        else:
241 1 tkerber
            if 'masses' not in self.atoms.arrays:
242 1 tkerber
                # Assign default masses to all atoms
243 1 tkerber
                self.atoms.set_masses(self.atoms.get_masses())
244 1 tkerber
            self.atoms.arrays['masses'][self.index] = mass
245 1 tkerber
246 1 tkerber
    symbol = property(get_symbol, set_symbol, doc='Chemical symbol')
247 1 tkerber
    number = property(get_atomic_number, set_atomic_number, doc='Atomic number')
248 1 tkerber
    position = property(_get_position, set_position, doc='XYZ-coordinates')
249 1 tkerber
    tag = property(get_tag, set_tag, doc='Integer tag')
250 1 tkerber
    momentum = property(_get_momentum, set_momentum, doc='XYZ-momentum')
251 1 tkerber
    mass = property(get_mass, set_mass, doc='Atomic mass')
252 1 tkerber
    magmom = property(get_initial_magnetic_moment, set_initial_magnetic_moment,
253 1 tkerber
                      doc='Initial magnetic moment')
254 1 tkerber
    charge = property(get_charge, set_charge, doc='Atomic charge')
255 1 tkerber
256 1 tkerber
    def get_x(self): return self.position[0]
257 1 tkerber
    def get_y(self): return self.position[1]
258 1 tkerber
    def get_z(self): return self.position[2]
259 1 tkerber
260 1 tkerber
    def set_x(self, x): self.position[0] = x
261 1 tkerber
    def set_y(self, y): self.position[1] = y
262 1 tkerber
    def set_z(self, z): self.position[2] = z
263 1 tkerber
264 1 tkerber
    x = property(get_x, set_x, doc='X-coordiante')
265 1 tkerber
    y = property(get_y, set_y, doc='Y-coordiante')
266 1 tkerber
    z = property(get_z, set_z, doc='Z-coordiante')