Source code for generate_symm_ops

# Authors: Arash Dehghan Banadaki <adehgha@ncsu.edu>, Srikanth Patala <spatala@ncsu.edu>
# Copyright (c) 2015,  Arash Dehghan Banadaki and Srikanth Patala.
# License: GNU-GPL Style.
# How to cite GBpy:
# Banadaki, A. D. & Patala, S. "An efficient algorithm for computing the primitive bases of a general lattice plane",
# Journal of Applied Crystallography 48, 585-588 (2015). doi:10.1107/S1600576715004446


import numpy as np
import sys
import pickle
import os
import shutil
import quaternion as quat
import tools as trans
# -----------------------------------------------------------------------------------------------------------


[docs]def generate_symm_mats(cryst_ptgrp, tol=1e-10): """ Give crystallographic point group, this function generates all the symmetry operations (as matrices) that belong to the point group using 'generators' Parameters ----------------- cryst_ptgrp: string Crystallogrphic point group in Schoenflies notation tol: float The tolerance used to check if two matrices are the same Returns ------------ symm_mat: numpy array Size: n x 3 x3 \v Symmetry operations as matrices for the corresponding point group """ prop_grps = ['C1', 'C2', 'C3', 'C4', 'C6', 'D2', 'D3', 'D4', 'D6', 'T', 'O'] laue_grps = ['Ci', 'C2h', 'C3i', 'C4h', 'C6h', 'D2h', 'D3d', 'D4h', 'D6h', 'Th', 'Oh'] # noncentro_grps = ['Cs', 'S4', 'S6', 'C2v', 'C3v', 'C4v', 'C6v', 'D2d', # 'D3h', 'Td'] if cryst_ptgrp in prop_grps: if cryst_ptgrp == 'C1': n = 1 gsz = 1 order_ptgrp = n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C2': n = 2 gsz = 2 order_ptgrp = n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C3': n = 3 gsz = 2 order_ptgrp = n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C4': n = 4 gsz = 2 order_ptgrp = n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C6': n = 6 gsz = 2 order_ptgrp = n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D2': n = 2 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D3': n = 3 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D4': n = 4 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D6': n = 6 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'T': gsz = 3 order_ptgrp = 12 # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/2, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 1, 1, 2*np.pi/3, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'O': gsz = 3 order_ptgrp = 24 # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, np.pi/2, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi/2, 1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators if cryst_ptgrp in laue_grps: if cryst_ptgrp == 'Ci': n = 1 gsz = 2 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C2h': n = 2 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C3i': n = 3 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C4h': n = 4 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'C6h': n = 6 gsz = 3 order_ptgrp = 2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D2h': n = 2 gsz = 4 order_ptgrp = 2*2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) generators[3, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D3d': n = 3 gsz = 4 order_ptgrp = 2*2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) generators[3, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D4h': n = 4 gsz = 4 order_ptgrp = 2*2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) generators[3, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'D6h': n = 6 gsz = 4 order_ptgrp = 2*2*n # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi, 1])) generators[3, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'Td': gsz = 4 order_ptgrp = 2*12 # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 2*np.pi/2, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 1, 1, 2*np.pi/3, 1])) generators[3, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators elif cryst_ptgrp == 'Oh': gsz = 4 order_ptgrp = 2*24 # Generators generators = np.zeros((gsz, 3, 3)) generators[0, :, :] = trans.vrrotvec2mat(np.array([0, 0, 1, 0, 1])) generators[1, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, np.pi/2, 1])) generators[2, :, :] = trans.vrrotvec2mat( np.array([1, 0, 0, np.pi/2, 1])) generators[3, :, :] = trans.vrrotvec2mat( np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_mat = np.zeros([order_ptgrp, 3, 3]) symm_mat[:gsz, :, :] = generators count1 = 1 numops = gsz-1 while numops < order_ptgrp-1: initsize = numops for ct1 in np.arange(count1, initsize+1): t1 = np.copy(symm_mat[ct1, :, :]) t2 = np.copy(symm_mat[count1, :, :]) tM1 = np.dot(t1, t2) tcheck = 0 # for ct2 in np.arange(0, numops+1): ct2 = np.arange(0, numops+1) if trans.eq(tM1, symm_mat[ct2, :, :], tol): tcheck = 1 if tcheck == 0: symm_mat[numops+1, :, :] = np.copy(tM1) numops = numops + 1 if numops == initsize: count1 = count1+1 return symm_mat # -----------------------------------------------------------------------------------------------------------
[docs]def generate_symm_quats(cryst_ptgrp, tol=1e-10): """ Give crystallographic point group, this function generates all the symmetry operations (as quaternions) that belong to the point group using 'generators' Parameters ----------------- cryst_ptgrp: string Crystallogrphic point group in Schoenflies notation tol: float The tolerance used to check if two matrices are the same Returns ------------ symm_quat: quaternion array Size: n x 5 \v Symmetry operations as matrices for the corresponding point group """ prop_grps = ['C1', 'C2', 'C3', 'C4', 'C6', 'D2', 'D3', 'D4', 'D6', 'T', 'O'] laue_grps = ['Ci', 'C2h', 'C3i', 'C4h', 'C6h', 'D2h', 'D3d', 'D4h', 'D6h', 'Th', 'Oh'] # noncentro_grps = ['Cs', 'S4', 'S6', 'C2v', 'C3v', 'C4v', 'C6v', 'D2d', # 'D3h', 'Td'] # if cryst_ptgrp in prop_grps: # rot_type = 'proper' # elif cryst_ptgrp in laue_grps: # rot_type = 'improper' # else: # raise Exception('Wrong Input for crystal point group') if cryst_ptgrp in prop_grps: if cryst_ptgrp == 'C1': n = 1 gsz = 1 order_ptgrp = n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C2': n = 2 gsz = 2 order_ptgrp = n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C3': n = 3 gsz = 2 order_ptgrp = n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C4': n = 4 gsz = 2 order_ptgrp = n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C6': n = 6 gsz = 2 order_ptgrp = n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D2': n = 2 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D3': n = 3 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D4': n = 4 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D6': n = 6 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'T': gsz = 3 order_ptgrp = 12 # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/2, 1])) generators[:, 2] = trans.axang2quat( np.array([1, 1, 1, 2*np.pi/3, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'O': gsz = 3 order_ptgrp = 24 # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, np.pi/2, 1])) generators[:, 2] = trans.axang2quat( np.array([1, 0, 0, np.pi/2, 1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators if cryst_ptgrp in laue_grps: if cryst_ptgrp == 'Ci': n = 1 gsz = 2 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C2h': n = 2 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C3i': n = 3 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C4h': n = 4 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'C6h': n = 6 gsz = 3 order_ptgrp = 2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D2h': n = 2 gsz = 4 order_ptgrp = 2*2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) generators[:, 3] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D3d': n = 3 gsz = 4 order_ptgrp = 2*2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) generators[:, 3] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D4h': n = 4 gsz = 4 order_ptgrp = 2*2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) generators[:, 3] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'D6h': n = 6 gsz = 4 order_ptgrp = 2*2*n # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/n, 1])) generators[:, 2] = trans.axang2quat(np.array([1, 0, 0, np.pi, 1])) generators[:, 3] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'Td': gsz = 4 order_ptgrp = 2*12 # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, 2*np.pi/2, 1])) generators[:, 2] = trans.axang2quat( np.array([1, 1, 1, 2*np.pi/3, 1])) generators[:, 3] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators elif cryst_ptgrp == 'Oh': gsz = 4 order_ptgrp = 2*24 # Generators generators = quat.quaternion(np.zeros((5, gsz))) generators[:, 0] = trans.axang2quat(np.array([0, 0, 1, 0, 1])) generators[:, 1] = trans.axang2quat( np.array([0, 0, 1, np.pi/2, 1])) generators[:, 2] = trans.axang2quat( np.array([1, 0, 0, np.pi/2, 1])) generators[:, 3] = trans.axang2quat(np.array([0, 0, 1, 0, -1])) # Symmetry Operations symm_quat = quat.quaternion(np.zeros([5, order_ptgrp])) symm_quat[:, :gsz] = generators count1 = 1 numops = gsz-1 while numops < order_ptgrp-1: initsize = numops for ct1 in np.arange(count1, initsize+1): t1 = symm_quat[:, ct1] t2 = symm_quat[:, count1] tM1 = quat.mtimes(t1, t2) tcheck = 0 ct2 = np.arange(0, numops+1) if quat.eq(tM1, symm_quat[:, ct2], tol): tcheck = 1 if tcheck == 0: symm_quat[:, numops+1] = tM1 numops += 1 if numops == initsize: count1 += 1 symm_quat = quat.antipodal(symm_quat) return symm_quat # -----------------------------------------------------------------------------------------------------------
[docs]def save_symm_pkl(cryst_ptgrp, op_type): """ A pkl file with the symmetry operations of op_type (matrices or quaternions) are created and stored in the 'pkl_files' directory Parameters ----------------- cryst_ptgrp: string Crystallogrphic point group in Schoenflies notation op_type: {'matrices', 'quats'} Creates matrices or quaternion symmetry operations depending on op_type """ tol = 1e-10 if op_type == 'matrices': symm_ops = generate_symm_mats(cryst_ptgrp, tol) fstr = 'mats' elif op_type == 'quats': symm_ops = generate_symm_quats(cryst_ptgrp, tol) fstr = 'quats' pkl_file = 'symm_' + fstr + '_' + cryst_ptgrp + '.pkl' jar = open(pkl_file, 'wb') pickle.dump(symm_ops, jar) jar.close() # Move to pkl_files shutil.move(pkl_file, 'pkl_files/') # -----------------------------------------------------------------------------------------------------------