1# -*- coding: utf-8 -*- 2# Copyright (C) 2011 Atsushi Togo 3# All rights reserved. 4# 5# This file is part of phonopy. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 11# * Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 14# * Redistributions in binary form must reproduce the above copyright 15# notice, this list of conditions and the following disclaimer in 16# the documentation and/or other materials provided with the 17# distribution. 18# 19# * Neither the name of the phonopy project nor the names of its 20# contributors may be used to endorse or promote products derived 21# from this software without specific prior written permission. 22# 23# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34# POSSIBILITY OF SUCH DAMAGE. 35 36import numpy as np 37 38class Atoms: 39 """Atoms class compatible with the ASE Atoms class 40 Only the necessary stuffs to phonpy are implemented. """ 41 42 def __init__(self, 43 symbols=None, 44 positions=None, 45 numbers=None, 46 masses=None, 47 magmoms=None, 48 scaled_positions=None, 49 cell=None, 50 pbc=None): 51 52 # cell 53 if cell is None: 54 self.cell = None 55 else: 56 self.cell = np.array(cell, dtype='double', order='C') 57 58 # position 59 self.scaled_positions = None 60 if (not self.cell is None) and (not positions is None): 61 self.set_positions(positions) 62 if (not scaled_positions is None): 63 self.set_scaled_positions(scaled_positions) 64 65 # Atom symbols 66 self.symbols = symbols 67 68 # Atomic numbers 69 if numbers is None: 70 self.numbers = None 71 else: 72 self.numbers = np.array(numbers, dtype='intc') 73 74 # masses 75 self.set_masses(masses) 76 77 # (initial) magnetic moments 78 self.set_magnetic_moments(magmoms) 79 80 # number --> symbol 81 if not self.numbers is None: 82 self._numbers_to_symbols() 83 84 # symbol --> number 85 elif not self.symbols is None: 86 self._symbols_to_numbers() 87 88 # symbol --> mass 89 if self.symbols and (self.masses is None): 90 self._symbols_to_masses() 91 92 93 def set_cell(self, cell): 94 self.cell = np.array(cell, dtype='double', order='C') 95 96 def get_cell(self): 97 return self.cell.copy() 98 99 def set_positions(self, cart_positions): 100 self.scaled_positions = np.array( 101 np.dot(cart_positions, np.linalg.inv(self.cell)), 102 dtype='double', order='C') 103 104 def get_positions(self): 105 return np.dot(self.scaled_positions, self.cell) 106 107 def set_scaled_positions(self, scaled_positions): 108 self.scaled_positions = np.array(scaled_positions, 109 dtype='double', order='C') 110 111 def get_scaled_positions(self): 112 return self.scaled_positions.copy() 113 114 def set_masses(self, masses): 115 if masses is None: 116 self.masses = None 117 else: 118 self.masses = np.array(masses, dtype='double') 119 120 def get_masses(self): 121 if self.masses is None: 122 return None 123 else: 124 return self.masses.copy() 125 126 def set_magnetic_moments(self, magmoms): 127 if magmoms is None: 128 self.magmoms = None 129 else: 130 self.magmoms = np.array(magmoms, dtype='double') 131 132 def get_magnetic_moments(self): 133 if self.magmoms is None: 134 return None 135 else: 136 return self.magmoms.copy() 137 138 def set_chemical_symbols(self, symbols): 139 self.symbols = symbols 140 141 def get_chemical_symbols(self): 142 return self.symbols[:] 143 144 def get_number_of_atoms(self): 145 return len(self.scaled_positions) 146 147 def get_atomic_numbers(self): 148 return self.numbers.copy() 149 150 def get_volume(self): 151 return np.linalg.det(self.cell) 152 153 def copy(self): 154 return Atoms(cell=self.cell, 155 scaled_positions=self.scaled_positions, 156 masses=self.masses, 157 magmoms=self.magmoms, 158 symbols=self.symbols, 159 pbc=True) 160 161 def _numbers_to_symbols(self): 162 self.symbols = [atom_data[n][1] for n in self.numbers] 163 164 def _symbols_to_numbers(self): 165 self.numbers = np.array([symbol_map[s] 166 for s in self.symbols], dtype='intc') 167 168 def _symbols_to_masses(self): 169 masses = [atom_data[symbol_map[s]][3] for s in self.symbols] 170 if None in masses: 171 self.masses = None 172 else: 173 self.masses = np.array(masses, dtype='double') 174 175atom_data = [ 176 [ 0, "X", "X", None], # 0 177 [ 1, "H", "Hydrogen", 1.00794], # 1 178 [ 2, "He", "Helium", 4.002602], # 2 179 [ 3, "Li", "Lithium", 6.941], # 3 180 [ 4, "Be", "Beryllium", 9.012182], # 4 181 [ 5, "B", "Boron", 10.811], # 5 182 [ 6, "C", "Carbon", 12.0107], # 6 183 [ 7, "N", "Nitrogen", 14.0067], # 7 184 [ 8, "O", "Oxygen", 15.9994], # 8 185 [ 9, "F", "Fluorine", 18.9984032], # 9 186 [ 10, "Ne", "Neon", 20.1797], # 10 187 [ 11, "Na", "Sodium", 22.98976928], # 11 188 [ 12, "Mg", "Magnesium", 24.3050], # 12 189 [ 13, "Al", "Aluminium", 26.9815386], # 13 190 [ 14, "Si", "Silicon", 28.0855], # 14 191 [ 15, "P", "Phosphorus", 30.973762], # 15 192 [ 16, "S", "Sulfur", 32.065], # 16 193 [ 17, "Cl", "Chlorine", 35.453], # 17 194 [ 18, "Ar", "Argon", 39.948], # 18 195 [ 19, "K", "Potassium", 39.0983], # 19 196 [ 20, "Ca", "Calcium", 40.078], # 20 197 [ 21, "Sc", "Scandium", 44.955912], # 21 198 [ 22, "Ti", "Titanium", 47.867], # 22 199 [ 23, "V", "Vanadium", 50.9415], # 23 200 [ 24, "Cr", "Chromium", 51.9961], # 24 201 [ 25, "Mn", "Manganese", 54.938045], # 25 202 [ 26, "Fe", "Iron", 55.845], # 26 203 [ 27, "Co", "Cobalt", 58.933195], # 27 204 [ 28, "Ni", "Nickel", 58.6934], # 28 205 [ 29, "Cu", "Copper", 63.546], # 29 206 [ 30, "Zn", "Zinc", 65.38], # 30 207 [ 31, "Ga", "Gallium", 69.723], # 31 208 [ 32, "Ge", "Germanium", 72.64], # 32 209 [ 33, "As", "Arsenic", 74.92160], # 33 210 [ 34, "Se", "Selenium", 78.96], # 34 211 [ 35, "Br", "Bromine", 79.904], # 35 212 [ 36, "Kr", "Krypton", 83.798], # 36 213 [ 37, "Rb", "Rubidium", 85.4678], # 37 214 [ 38, "Sr", "Strontium", 87.62], # 38 215 [ 39, "Y", "Yttrium", 88.90585], # 39 216 [ 40, "Zr", "Zirconium", 91.224], # 40 217 [ 41, "Nb", "Niobium", 92.90638], # 41 218 [ 42, "Mo", "Molybdenum", 95.96], # 42 219 [ 43, "Tc", "Technetium", None], # 43 220 [ 44, "Ru", "Ruthenium", 101.07], # 44 221 [ 45, "Rh", "Rhodium", 102.90550], # 45 222 [ 46, "Pd", "Palladium", 106.42], # 46 223 [ 47, "Ag", "Silver", 107.8682], # 47 224 [ 48, "Cd", "Cadmium", 112.411], # 48 225 [ 49, "In", "Indium", 114.818], # 49 226 [ 50, "Sn", "Tin", 118.710], # 50 227 [ 51, "Sb", "Antimony", 121.760], # 51 228 [ 52, "Te", "Tellurium", 127.60], # 52 229 [ 53, "I", "Iodine", 126.90447], # 53 230 [ 54, "Xe", "Xenon", 131.293], # 54 231 [ 55, "Cs", "Caesium", 132.9054519], # 55 232 [ 56, "Ba", "Barium", 137.327], # 56 233 [ 57, "La", "Lanthanum", 138.90547], # 57 234 [ 58, "Ce", "Cerium", 140.116], # 58 235 [ 59, "Pr", "Praseodymium", 140.90765], # 59 236 [ 60, "Nd", "Neodymium", 144.242], # 60 237 [ 61, "Pm", "Promethium", None], # 61 238 [ 62, "Sm", "Samarium", 150.36], # 62 239 [ 63, "Eu", "Europium", 151.964], # 63 240 [ 64, "Gd", "Gadolinium", 157.25], # 64 241 [ 65, "Tb", "Terbium", 158.92535], # 65 242 [ 66, "Dy", "Dysprosium", 162.500], # 66 243 [ 67, "Ho", "Holmium", 164.93032], # 67 244 [ 68, "Er", "Erbium", 167.259], # 68 245 [ 69, "Tm", "Thulium", 168.93421], # 69 246 [ 70, "Yb", "Ytterbium", 173.054], # 70 247 [ 71, "Lu", "Lutetium", 174.9668], # 71 248 [ 72, "Hf", "Hafnium", 178.49], # 72 249 [ 73, "Ta", "Tantalum", 180.94788], # 73 250 [ 74, "W", "Tungsten", 183.84], # 74 251 [ 75, "Re", "Rhenium", 186.207], # 75 252 [ 76, "Os", "Osmium", 190.23], # 76 253 [ 77, "Ir", "Iridium", 192.217], # 77 254 [ 78, "Pt", "Platinum", 195.084], # 78 255 [ 79, "Au", "Gold", 196.966569], # 79 256 [ 80, "Hg", "Mercury", 200.59], # 80 257 [ 81, "Tl", "Thallium", 204.3833], # 81 258 [ 82, "Pb", "Lead", 207.2], # 82 259 [ 83, "Bi", "Bismuth", 208.98040], # 83 260 [ 84, "Po", "Polonium", None], # 84 261 [ 85, "At", "Astatine", None], # 85 262 [ 86, "Rn", "Radon", None], # 86 263 [ 87, "Fr", "Francium", None], # 87 264 [ 88, "Ra", "Radium", None], # 88 265 [ 89, "Ac", "Actinium", None], # 89 266 [ 90, "Th", "Thorium", 232.03806], # 90 267 [ 91, "Pa", "Protactinium", 231.03588], # 91 268 [ 92, "U", "Uranium", 238.02891], # 92 269 [ 93, "Np", "Neptunium", None], # 93 270 [ 94, "Pu", "Plutonium", None], # 94 271 [ 95, "Am", "Americium", None], # 95 272 [ 96, "Cm", "Curium", None], # 96 273 [ 97, "Bk", "Berkelium", None], # 97 274 [ 98, "Cf", "Californium", None], # 98 275 [ 99, "Es", "Einsteinium", None], # 99 276 [100, "Fm", "Fermium", None], # 100 277 [101, "Md", "Mendelevium", None], # 101 278 [102, "No", "Nobelium", None], # 102 279 [103, "Lr", "Lawrencium", None], # 103 280 [104, "Rf", "Rutherfordium", None], # 104 281 [105, "Db", "Dubnium", None], # 105 282 [106, "Sg", "Seaborgium", None], # 106 283 [107, "Bh", "Bohrium", None], # 107 284 [108, "Hs", "Hassium", None], # 108 285 [109, "Mt", "Meitnerium", None], # 109 286 [110, "Ds", "Darmstadtium", None], # 110 287 [111, "Rg", "Roentgenium", None], # 111 288 [112, "Cn", "Copernicium", None], # 112 289 [113, "Uut", "Ununtrium", None], # 113 290 [114, "Uuq", "Ununquadium", None], # 114 291 [115, "Uup", "Ununpentium", None], # 115 292 [116, "Uuh", "Ununhexium", None], # 116 293 [117, "Uus", "Ununseptium", None], # 117 294 [118, "Uuo", "Ununoctium", None], # 118 295 ] 296 297symbol_map = { 298 "H":1, 299 "He":2, 300 "Li":3, 301 "Be":4, 302 "B":5, 303 "C":6, 304 "N":7, 305 "O":8, 306 "F":9, 307 "Ne":10, 308 "Na":11, 309 "Mg":12, 310 "Al":13, 311 "Si":14, 312 "P":15, 313 "S":16, 314 "Cl":17, 315 "Ar":18, 316 "K":19, 317 "Ca":20, 318 "Sc":21, 319 "Ti":22, 320 "V":23, 321 "Cr":24, 322 "Mn":25, 323 "Fe":26, 324 "Co":27, 325 "Ni":28, 326 "Cu":29, 327 "Zn":30, 328 "Ga":31, 329 "Ge":32, 330 "As":33, 331 "Se":34, 332 "Br":35, 333 "Kr":36, 334 "Rb":37, 335 "Sr":38, 336 "Y":39, 337 "Zr":40, 338 "Nb":41, 339 "Mo":42, 340 "Tc":43, 341 "Ru":44, 342 "Rh":45, 343 "Pd":46, 344 "Ag":47, 345 "Cd":48, 346 "In":49, 347 "Sn":50, 348 "Sb":51, 349 "Te":52, 350 "I":53, 351 "Xe":54, 352 "Cs":55, 353 "Ba":56, 354 "La":57, 355 "Ce":58, 356 "Pr":59, 357 "Nd":60, 358 "Pm":61, 359 "Sm":62, 360 "Eu":63, 361 "Gd":64, 362 "Tb":65, 363 "Dy":66, 364 "Ho":67, 365 "Er":68, 366 "Tm":69, 367 "Yb":70, 368 "Lu":71, 369 "Hf":72, 370 "Ta":73, 371 "W":74, 372 "Re":75, 373 "Os":76, 374 "Ir":77, 375 "Pt":78, 376 "Au":79, 377 "Hg":80, 378 "Tl":81, 379 "Pb":82, 380 "Bi":83, 381 "Po":84, 382 "At":85, 383 "Rn":86, 384 "Fr":87, 385 "Ra":88, 386 "Ac":89, 387 "Th":90, 388 "Pa":91, 389 "U":92, 390 "Np":93, 391 "Pu":94, 392 "Am":95, 393 "Cm":96, 394 "Bk":97, 395 "Cf":98, 396 "Es":99, 397 "Fm":100, 398 "Md":101, 399 "No":102, 400 "Lr":103, 401 "Rf":104, 402 "Db":105, 403 "Sg":106, 404 "Bh":107, 405 "Hs":108, 406 "Mt":109, 407 "Ds":110, 408 "Rg":111, 409 "Cn":112, 410 "Uut":113, 411 "Uuq":114, 412 "Uup":115, 413 "Uuh":116, 414 "Uus":117, 415 "Uuo":118, 416 } 417 418