示例#1
0
    def _symmetric(self):

        if abs(self._eigenvalues[0] - self._eigenvalues[1]) < self.tolerance:
            idx = 2
        elif abs(self._eigenvalues[0] - self._eigenvalues[2]) < self.tolerance:
            idx = 1
        else:
            idx = 0

        main_axis = self._eigenvectors[idx, :]
        self.check_order_rot(main_axis)
        self.rot_sym.append((main_axis, self._max_order))

        # Obtain all the c2 vectors perpendicular to main axis
        for ida, axis in enumerate(self._eigenvectors):
            if ida != idx:
                p_axis = axis
                break
        for angle in np.linspace(0, 360, 144, endpoint=False):
            axis = np.matmul(np.array(rotation_matrix(main_axis, angle)),
                             np.array(p_axis))
            c2 = rotation_matrix(axis, 360 / 2)
            if self.check_op(c2):
                self.sym_op.append(c2)
                self.rot_sym.append((axis / np.linalg.norm(axis), 2))

        self.check_consistency()
        if len(self.rot_sym) >= 2:
            self._dihedral()
        elif len(self.rot_sym) == 1:
            self._cyclic()
        else:
            self._no_rot_axis()
示例#2
0
    def check_order_rot(self, axis):

        order = 0
        for i in list(range(2, 9)):
            Cn = rotation_matrix(axis, 360 / i)
            if self.check_op(Cn):
                order = i
                self.sym_op.append(Cn)
        self._max_order = order
示例#3
0
    def _improper_rot(self):

        for axis, order in self.rot_sym:
            if order == 2:
                ref_mat = reflection(axis)
                for n in range(20, 0, -2):
                    Cn = rotation_matrix(axis, 360 / n)
                    Sn = np.dot(Cn, ref_mat)
                    if self.check_op(Sn):
                        self.rot_sym.append((axis, 'S' + str(n)))
                        self.sym_op.append(Sn)
                        break
def orthogonal_c4(c3, c4):
    def calculate_angle(axis1, axis2):
        axis1 /= np.linalg.norm(axis1)
        axis2 /= np.linalg.norm(axis2)
        return np.arccos(
            np.dot(axis1, axis2) /
            (np.linalg.norm(axis1) * np.linalg.norm(axis2))) * 180 / np.pi

    perfect_c3_c4 = 125.26438968275465
    c3 /= np.linalg.norm(c3)
    c4 /= np.linalg.norm(c4)
    angle_c3_c4 = calculate_angle(c3, c4)
    diff_angle = perfect_c3_c4 - angle_c3_c4
    if abs(diff_angle) <= 1E-8:
        new_c4 = c4
    else:
        new_c4 = np.dot(rotation_matrix(np.cross(c3, c4), diff_angle), c4)
        warn('ChangedAxisWarning: Set C4 axis to: {}'.format(new_c4))

    rot_mat = rotation_matrix(c3, 120.0)
    c4_2 = np.dot(rot_mat, new_c4)
    return new_c4, c4_2 / np.linalg.norm(c4_2)
示例#5
0
    def _asymmetric(self):

        for axis in self._eigenvectors:
            c2 = rotation_matrix(axis, 180)
            if self.check_op(c2):
                self.sym_op.append(c2)
                self.rot_sym.append((axis, 2))

        if len(self.sym_op) == 0:
            self._no_rot_axis()
        elif len(self.sym_op) == 1:
            self._cyclic()
        else:
            self._dihedral()
示例#6
0
    def mirror_plane(self, main_axis):

        m_type = ''
        if self.check_op(reflection(main_axis)):
            self.rot_sym.append((main_axis, 'Sh'))
            self.sym_op.append(reflection(main_axis))
            m_type = 'h'
        else:
            # Sv planes #
            p_axis = np.random.randn(3)
            p_axis -= np.dot(p_axis, main_axis) * main_axis
            p_axis /= np.linalg.norm(p_axis)
            for angle in np.linspace(0, 360, 144, endpoint=False):
                axis = np.matmul(np.array(rotation_matrix(main_axis, angle)),
                                 np.array(p_axis))
                possible_mirror = reflection(axis)
                if self.check_op(possible_mirror):
                    m_type = 'v'
                    self.rot_sym.append((axis, 'Sv'))
                    self.sym_op.append(possible_mirror)

            # Sd planes #
            c2_axes, gt_axes = [], []
            for axis, order in self.rot_sym:
                if order == 2:
                    c2_axes.append(axis)
                if order == self._max_order:
                    gt_axes.append(axis)

            for c2_1, c2_2 in itertools.combinations(c2_axes, 2):
                c2_vector = c2_1 + c2_2
                if all(c2_vector < 1e-8):
                    continue
                else:
                    c2_vector /= np.linalg.norm(c2_vector)
                    for gt_vector in gt_axes:
                        p_axis = np.cross(c2_vector, gt_vector)
                        possible_mirror = reflection(p_axis)
                        if self.check_op(reflection(p_axis)):
                            m_type = 'd'
                            self.rot_sym.append(
                                (p_axis / np.linalg.norm(p_axis), 'Sd'))
                            self.sym_op.append(possible_mirror)

        return m_type
示例#7
0
    def _spherical(self):

        # I or Ih
        for axis in self._eigenvectors:
            c5 = rotation_matrix(axis, 360 / 5)
            if self.check_op(c5):
                self.sym_op.append(c5)
                self.rot_sym.append((axis, 5))
                self.schoenflies_symbol = "I"
                self._max_order = 5
        if self.schoenflies_symbol and self.check_op(inversion()):
            self.schoenflies_symbol += 'h'

        # O or Oh
        if not self.schoenflies_symbol:
            for axis in self._eigenvectors:
                c4 = rotation_matrix(axis, 360 / 4)
                if self.check_op(c4):
                    self.sym_op.append(c4)
                    self.rot_sym.append((axis, 4))
                    self.schoenflies_symbol = "O"
                    self._max_order = 4
            if self.schoenflies_symbol and self.check_op(inversion()):
                self.schoenflies_symbol += 'h'

        # Obtain all the c2 vectors and matrices
        for angle1 in np.linspace(0, 360, 72, endpoint=False):
            axis1 = np.matmul(np.array(rotation_matrix([1, 0, 0], angle1)),
                              np.array([0, 0, 1]))
            for angle2 in np.linspace(0, 180, 72, endpoint=False):
                axis2 = np.matmul(np.array(rotation_matrix([0, 1, 0], angle2)),
                                  axis1)
                c2 = rotation_matrix(axis2, 360 / 2)
                if self.check_op(c2):
                    self.sym_op.append(c2)
                    self.rot_sym.append((axis2 / np.linalg.norm(axis2), 2))

        if self.rot_sym:
            self.check_consistency()

        # T or Td, Th
        m_type = ''
        if not self.schoenflies_symbol:
            # Obtain all the c3 vectors and matrices
            for angle1 in np.linspace(0, 360, 72, endpoint=False):
                axis1 = np.matmul(np.array(rotation_matrix([1, 0, 0], angle1)),
                                  np.array([0, 0, 1]))
                for angle2 in np.linspace(0, 180, 72, endpoint=False):
                    axis2 = np.matmul(
                        np.array(rotation_matrix([0, 1, 0], angle2)), axis1)
                    c3 = rotation_matrix(axis2, 360 / 3)
                    if self.check_op(c3):
                        self.sym_op.append(c3)
                        self.rot_sym.append((axis2 / np.linalg.norm(axis2), 3))
            self.schoenflies_symbol = "T"
            self._max_order = 3
            self.check_consistency()
            for axis, order in self.rot_sym:
                if order == 3:
                    m_type = self.mirror_plane(axis)
                    break
            if m_type == '':
                if self.check_op(inversion()):
                    self.rot_sym.append(([0, 0, 0], 'i'))
                    self.sym_op.append(inversion())
                    self.schoenflies_symbol += 'h'
                # else:
                #     self.schoenflies_symbol += 'd'
            else:
                self.schoenflies_symbol += 'd'
            self._improper_rot()