1# Copyright (C) 2011 Atsushi Togo 2# All rights reserved. 3# 4# This file is part of phonopy. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 10# * Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 13# * Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in 15# the documentation and/or other materials provided with the 16# distribution. 17# 18# * Neither the name of the phonopy project nor the names of its 19# contributors may be used to endorse or promote products derived 20# from this software without specific prior written permission. 21# 22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33# POSSIBILITY OF SUCH DAMAGE. 34 35import numpy as np 36import spglib 37from spglib import get_pointgroup 38from phonopy.interface.calculator import ( 39 write_crystal_structure, get_default_cell_filename) 40from phonopy.structure.atoms import PhonopyAtoms 41from phonopy.structure.cells import guess_primitive_matrix, get_primitive 42 43 44def check_symmetry(phonon, optional_structure_info): 45 # Assumed that primitive cell is the cell that user is interested in. 46 print(_get_symmetry_yaml(phonon.primitive, 47 phonon.primitive_symmetry, 48 phonon.version)) 49 50 if phonon.unitcell.magnetic_moments is None: 51 base_fname = get_default_cell_filename(phonon.calculator) 52 symprec = phonon.primitive_symmetry.get_symmetry_tolerance() 53 (bravais_lattice, 54 bravais_pos, 55 bravais_numbers) = spglib.refine_cell(phonon.primitive, symprec) 56 bravais = PhonopyAtoms(numbers=bravais_numbers, 57 scaled_positions=bravais_pos, 58 cell=bravais_lattice) 59 filename = 'B' + base_fname 60 print("# Symmetrized conventional unit cell is written into %s." 61 % filename) 62 trans_mat = guess_primitive_matrix(bravais, symprec=symprec) 63 primitive = get_primitive(bravais, trans_mat, symprec=symprec) 64 write_crystal_structure( 65 filename, 66 bravais, 67 interface_mode=phonon.calculator, 68 optional_structure_info=optional_structure_info) 69 70 filename = 'P' + base_fname 71 print("# Symmetrized primitive is written into %s." % filename) 72 write_crystal_structure( 73 filename, 74 primitive, 75 interface_mode=phonon.calculator, 76 optional_structure_info=optional_structure_info) 77 78 79def _get_symmetry_yaml(cell, symmetry, phonopy_version=None): 80 rotations = symmetry.get_symmetry_operations()['rotations'] 81 translations = symmetry.get_symmetry_operations()['translations'] 82 83 atom_sets = symmetry.get_map_atoms() 84 independent_atoms = symmetry.get_independent_atoms() 85 wyckoffs = symmetry.get_Wyckoff_letters() 86 87 lines = [] 88 89 if phonopy_version is not None: 90 lines.append("phonopy_version: '%s'" % phonopy_version) 91 92 if cell.get_magnetic_moments() is None: 93 spg_symbol, spg_number = symmetry.get_international_table().split() 94 spg_number = int(spg_number.replace('(', '').replace(')', '')) 95 lines.append("space_group_type: '%s'" % spg_symbol) 96 lines.append("space_group_number: %d" % spg_number) 97 lines.append("point_group_type: '%s'" % symmetry.get_pointgroup()) 98 lines.append("space_group_operations:") 99 for i, (r, t) in enumerate(zip(rotations, translations)): 100 lines.append("- rotation: # %d" % (i + 1)) 101 for vec in r: 102 lines.append(" - [%2d, %2d ,%2d]" % tuple(vec)) 103 line = " translation: [" 104 for j, x in enumerate(t): 105 if abs(x - np.rint(x)) < 1e-5: 106 line += " 0.00000" 107 else: 108 line += "%8.5f" % x 109 if j < 2: 110 line += ", " 111 else: 112 line += " ]" 113 lines.append(line) 114 lines.append("atom_mapping:") 115 for i, atom_num in enumerate(atom_sets): 116 lines.append(" %d: %d" % (i + 1, atom_num + 1)) 117 lines.append("site_symmetries:") 118 for i in independent_atoms: 119 sitesym = symmetry.get_site_symmetry(i) 120 lines.append("- atom: %d" % (i + 1)) 121 122 if cell.get_magnetic_moments() is None: 123 lines.append(" Wyckoff: '%s'" % wyckoffs[i]) 124 site_pointgroup = get_pointgroup(sitesym) 125 lines.append(" site_point_group: '%s'" % site_pointgroup[0].strip()) 126 lines.append(" orientation:") 127 for v in site_pointgroup[2]: 128 lines.append(" - [%2d, %2d, %2d]" % tuple(v)) 129 130 lines.append(" rotations:") 131 for j, r in enumerate(sitesym): 132 lines.append(" - # %d" % (j + 1)) 133 for vec in r: 134 lines.append(" - [%2d, %2d, %2d]" % tuple(vec)) 135 136 return "\n".join(lines) 137