|
12 | 12 | import logging |
13 | 13 | import re |
14 | 14 | from collections import namedtuple |
| 15 | +from math import acos, degrees |
| 16 | +from itertools import combinations |
15 | 17 |
|
16 | 18 | import numpy as np |
17 | 19 |
|
@@ -176,6 +178,56 @@ def get_poscar_content(self, **kwargs): |
176 | 178 |
|
177 | 179 | return content |
178 | 180 |
|
| 181 | + def get_cif_content(self): |
| 182 | + """ |
| 183 | + Get the cif file content. |
| 184 | + """ |
| 185 | + content = 'data_VESTA_phase_1\n\n' |
| 186 | + |
| 187 | + # Phase name |
| 188 | + phase_name = ('xyz {}'*len(self.atom_types)).format(*self.atom_types) |
| 189 | + content += "{:<40s}'{}'\n".format('_pd_phase_name', phase_name) |
| 190 | + |
| 191 | + # Basis vectors lengths. |
| 192 | + length_a, length_b, length_c = [np.linalg.norm(basis) for basis in self.bases] |
| 193 | + content += '{:<40s}{:<.5f}\n'.format('_cell_length_a', length_a) |
| 194 | + content += '{:<40s}{:<.5f}\n'.format('_cell_length_b', length_b) |
| 195 | + content += '{:<40s}{:<.5f}\n'.format('_cell_length_c', length_c) |
| 196 | + |
| 197 | + # Angles between basis vectors. |
| 198 | + angle = lambda X, Y: degrees(acos(np.dot(X, Y)/(np.linalg.norm(X)*np.linalg.norm(Y)))) |
| 199 | + alpha, beta, gamma = [angle(X, Y) for X, Y in combinations(self.bases, 2)] |
| 200 | + content += '{:<40s}{:<.2f}\n'.format('_cell_angle_alpha', alpha) |
| 201 | + content += '{:<40s}{:<.2f}\n'.format('_cell_angle_beta', beta) |
| 202 | + content += '{:<40s}{:<.2f}\n'.format('_cell_angle_gamma', gamma) |
| 203 | + |
| 204 | + # Other info. |
| 205 | + content += "{:<40s}'P 1'\n".format('_symmetry_space_group_name_H-M') |
| 206 | + content += '{:<40s}1\n\n'.format('_symmetry_Int_Tables_number') |
| 207 | + content += "loop_\n_symmetry_equiv_pos_as_xyz\n 'x, y, z'\n\n" |
| 208 | + |
| 209 | + # Atom info. |
| 210 | + content += ('loop_\n' + |
| 211 | + ' _atom_site_label\n' + |
| 212 | + ' _atom_site_occupancy\n' + |
| 213 | + ' _atom_site_fract_x\n' + |
| 214 | + ' _atom_site_fract_y\n' + |
| 215 | + ' _atom_site_fract_z\n' + |
| 216 | + ' _atom_site_adp_type\n' + |
| 217 | + ' _atom_site_B_iso_or_equiv\n' + |
| 218 | + ' _atom_site_type_symbol\n') |
| 219 | + |
| 220 | + # Atom coordinates. |
| 221 | + line_template = ' {:<9s}{:<7.1}{:<13.5f}{:<13.5f}{:<13.5f}{:<6s}{:<7.3f}{:s}\n' |
| 222 | + atom_count = 0 |
| 223 | + for atom_type, coordinates in self.atomco_dict.items(): |
| 224 | + for x, y, z in coordinates: |
| 225 | + atom_count += 1 |
| 226 | + name = '{}{}'.format(atom_type, atom_count) |
| 227 | + content += line_template.format(name, 1.0, x, y, z, 'Biso', 1.0, atom_type) |
| 228 | + |
| 229 | + return content |
| 230 | + |
179 | 231 | def get_volume(self): |
180 | 232 | """ |
181 | 233 | Get volume of slab(Angstrom^3) |
|
0 commit comments