Ejemplo n.º 1
0
def check_sigma_rots(r_g1tog2_g1, sigma):
    """
    The sigma transformation matrix has the property that sigma is the
    smallest integer such that sigma*T is an integer matrix. This condition
    is checked and the numerator and denominatr(sigma) matrices are
    returned

    Parameters
    ----------------
    r_g1tog2_g1: numpy array (n x 3 x 3)
        Transformation matrices in g1 reference frame

    sigma: float
        sigma number

    Returns
    ----------
    {'N': rots_n, 'D': rots_d}: dictionary
    rots_n: numpy array
        numerator matrices n x 3 x3
    rots_d: numpy array
        denominator matrices n x 3 x3
    """
    rots_n = np.zeros(np.shape(r_g1tog2_g1))
    rots_d = np.zeros(np.shape(r_g1tog2_g1))

    msz = np.shape(r_g1tog2_g1)[0]
    for i in range(msz):
        tmat = r_g1tog2_g1[i, :, :]
        mult1 = int_man.int_mult(tmat, 1e-06)
        if abs(mult1[0]-sigma) > 1e-06:
            t_check = 0
            tol_arr = np.array([1e-05, 1e-06, 1e-07,
                                1e-08, 1e-09, 1e-10, 1e-4])
            for tols in tol_arr:
                mult1 = int_man.int_mult(tmat, tols)
                if abs(mult1[0]-sigma) < 1e-04:
                    t_check = 1
                    break
            if t_check == 0:
                raise Exception('Not a sigma rotation')

        rots_n[i, :, :] = mult1[1]
        rots_d[i, :, :] = int(np.round(mult1[0]))*np.ones(np.shape(tmat))

    if np.size(np.where(rots_d != sigma)[0]) > 0:
        raise Exception('Not a sigma rotation')

    return {'N': rots_n, 'D': rots_d}
def check_sigma_rots(r_g1tog2_g1, sigma):
    """
    The sigma transformation matrix has the property that sigma is the
    smallest integer such that sigma*T is an integer matrix. This condition
    is checked and the numerator and denominatr(sigma) matrices are
    returned

    Parameters
    ----------------
    r_g1tog2_g1: numpy array (n x 3 x 3)
        Transformation matrices in g1 reference frame

    sigma: float
        sigma number

    Returns
    ----------
    {'N': rots_n, 'D': rots_d}: dictionary
    rots_n: numpy array
        numerator matrices n x 3 x3
    rots_d: numpy array
        denominator matrices n x 3 x3
    """
    rots_n = np.zeros(np.shape(r_g1tog2_g1))
    rots_d = np.zeros(np.shape(r_g1tog2_g1))

    msz = np.shape(r_g1tog2_g1)[0]
    for i in range(msz):
        tmat = r_g1tog2_g1[i, :, :]
        mult1 = int_man.int_mult(tmat, 1e-06)
        if abs(mult1[0] - sigma) > 1e-06:
            t_check = 0
            tol_arr = np.array(
                [1e-05, 1e-06, 1e-07, 1e-08, 1e-09, 1e-10, 1e-4])
            for tols in tol_arr:
                mult1 = int_man.int_mult(tmat, tols)
                if abs(mult1[0] - sigma) < 1e-04:
                    t_check = 1
                    break
            if t_check == 0:
                raise Exception('Not a sigma rotation')

        rots_n[i, :, :] = mult1[1]
        rots_d[i, :, :] = int(np.round(mult1[0])) * np.ones(np.shape(tmat))

    if np.size(np.where(rots_d != sigma)[0]) > 0:
        raise Exception('Not a sigma rotation')

    return {'N': rots_n, 'D': rots_d}
Ejemplo n.º 3
0
def csl_finder_smith(r_g1tog2_g1):
    """
    This funciton extracts the CSL basis when transformation between the two
    lattices is given (r_g1tog2_g1). The algorithms used are based on the
    following article: doi:10.1107/S056773947601231X)

    Parameters
    ----------------
    r_g1tog2_g1: numpy array
        The 3x3 transformation matrix in g1 reference frame

    Returns
    -----------
    l_csl_g1: numpy array
        3 x 3 matrix with the csl basis vectors as columns

    Notes
    ---------
    The "Reduced" refer to the use of LLL algorithm to compute a
    basis that is as close to orthogonal as possible.
    (Refer to http://en.wikipedia.org/wiki/Lattice_reduction) for further
    detials on the concept of Lattice Reduction
    """
    R_G1ToG2_G1 = np.array(r_g1tog2_g1)
    L_G2_G1 = R_G1ToG2_G1

    # Obtain N1 and N2
    N1, _ = int_man.int_mult(L_G2_G1)
    A = np.dot(N1, L_G2_G1)

    # Check that A is an integer matrix
    if int_man.int_check(A, 12).all():
        A = np.around(A)
    else:
        raise Exception('L_G2_G1 is not a Sigma Transformation')
    # Smith Normal Form of A
    # A = U*E*V'
    U, E, _ = smith_nf(A)
    L_G1n_G1 = U
    # L_G1_G1n = np.linalg.inv(L_G1n_G1)

    # CSL Bases
    l_csl_g1 = csl_elem_div_thm_l1(E / N1, L_G1n_G1)

    if(int_man.int_check(l_csl_g1, 1e-08)).all():
        l_csl_g1 = np.around(l_csl_g1)
    else:
        raise Exception('l_csl_g1 is not defined in L_G1_G1 axis')

    # Reduced CSL bases using the LLL algorithm
    # Actually don't reduce yet because the matrix is in "g1" reference frame!
    # l_csl_g1 = lll_reduction((l_csl_g1))
    return l_csl_g1
Ejemplo n.º 4
0
def test_int_mult():
    """
    Test cases for the int_mult function in integer_manipulations
    """
    Mat = np.zeros(5, dtype=[('Matrix', '(3,3)float64')])
    Mat['Matrix'][0] = np.array(([1, 2.0e-5, 0], [-4, 5, 6], [7, 8, 15]))
    Mat['Matrix'][1] = np.array(([-1, 2.5, 3], [-4, 0, 6.5], [1. / 3, 0, 0]))
    Mat['Matrix'][2] = np.array(([1, 2. / 5, 0], [-4, 5, 1.0 / 6], [3, 0, -1]))
    Mat['Matrix'][3] = np.array(([1, 2, 3], [-4, 5.5, 6], [2, -2, 1]))
    Mat['Matrix'][4] = np.array(([1, 2, 25], [-4, 5, 6], [3, -2, 1e-7]))
    for i in range(Mat.shape[0]):
        a, b = int_man.int_mult(Mat['Matrix'][i])
        print(Mat['Matrix'][i], '\nIntegral Form: \n', b, '\nMultiplier:\n', a,
              '\n-------\n')
Ejemplo n.º 5
0
def csl_finder_2d(l_pl1_g1, l_pl2_g1):
    """
    Given two plane bases, the 2D CSL bases are obtined by utilizing the
    smith normal form of the transformation between the two bases

    Parameters
    ---------------
    l_pl1_g1, l_pl2_g1: numpy array
        Basis vectors of planes 1 and 2 expressed in g1 reference frame

    Returns
    ---------------
    l_2d_csl_g1: numpy array
        The basis vectors of the 2D CSL expressed in g1 reference frame
    """

    l1 = np.array(l_pl1_g1)
    l2 = np.array(l_pl2_g1)

    # L2 = L1*T (T := T_Pl1ToPl2_Pl1)
    l1_linv = np.dot(np.linalg.inv(np.dot(l1.T, l1)), l1.T)
    t = np.dot(l1_linv, l2)

    # # Obtain N1 and N2
    n1, a = int_man.int_mult(t)

    if int_man.int_check(a, 12).all:
        a = np.around(a)

    # A = U*E*V'; E is a diagonal matrix
    u, e, v = smith_nf(a)

    l2_n = np.dot(l2, np.linalg.inv(v.T))
    l_2d_csl_g1 = fcd.csl_elem_div_thm_l2(e/n1, l2_n)

    if int_man.int_check(l_2d_csl_g1, 10).all():
        l_2d_csl_g1 = np.around(l_2d_csl_g1)
    else:
        raise Exception('Wrong CSL computation')

    l_2d_csl_g1 = lll_reduction(l_2d_csl_g1[:, 0:2])

    return l_2d_csl_g1
Ejemplo n.º 6
0
def find_csl_dsc(L_G1_GO1, R_G1ToG2_G1):
    """
    This function calls the csl_finder and dsc_finder and returns
    the CSL and DSC basis vectors in 'g1' reference frame.

    Parameters
    -----------------
    L_G1_GO1: numpy array
        The three basis vectors for the primitive unit cell
        (as columns) are given with respect to the GO1 reference
        frame.

    R_G1ToG2_G1: 3X3 numpy array
        The rotation matrix defining the
        transformation in 'G1' reference frame. The subscript 'G1' refers
        to the primitive unit cell of G lattice.

    Returns
    l_csl_g1, l_dsc_g1: numpy arrays
        The basis vectors of csl and dsc lattices in the g1 reference frame
    """

    R_G1ToG2_G1 = np.array(R_G1ToG2_G1)
    L_G1_GO1 = np.array(L_G1_GO1)

    L_CSL_G1 = csl_finder_smith(R_G1ToG2_G1)
    print np.dot(np.linalg.inv(R_G1ToG2_G1), L_CSL_G1)

    L_CSL_G1 = bpb.reduce_go1_mat(L_CSL_G1, L_G1_GO1)

    Sigma, _ =  int_man.int_mult(R_G1ToG2_G1)
    check_csl_finder_smith(R_G1ToG2_G1, Sigma, L_G1_GO1, L_CSL_G1)

    # Finding the DSC lattice from the obtained CSL.
    L_DSC_G1 = dsc_finder(R_G1ToG2_G1, L_G1_GO1)

    L_CSL_G1 = make_right_handed(L_CSL_G1, L_G1_GO1)
    L_DSC_G1 = make_right_handed(L_DSC_G1, L_G1_GO1)

    return L_CSL_G1, L_DSC_G1
Ejemplo n.º 7
0
def compute_sig_rots(csl_rots, l1, sig_type):
    [tau, kmax] = csl_util.compute_inp_params(l1, sig_type)
    csl_rots_m = csl_rots['rots']
    k1 = list(csl_rots_m.keys())
    sig_inds = {}
    for ct1 in k1:
        if ct1[-1] in string.ascii_lowercase:
            tstr1 = ct1[0:-1]
        else:
            tstr1 = ct1
        if tstr1 in list(sig_inds.keys()):
            sig_inds[tstr1] += 1
        else:
            sig_inds[tstr1] = 1

    sig_rots_m = {}
    sig_inds1 = {}
    for ct1 in list(sig_inds.keys()):
        sig_rots_m[ct1] = np.zeros((sig_inds[ct1], 3, 3))
        sig_rots_m[ct1][:] = np.NAN

    for ct1 in k1:
        if ct1[-1] in string.ascii_lowercase:
            tstr1 = ct1[0:-1]
        else:
            tstr1 = ct1

        if tstr1 in list(sig_inds1.keys()):
            sig_inds1[tstr1] += 1
            if csl_rots['type'] == 'quads':
                if l1.pearson[0:2] == 'hR':
                    m = csl_rots_m[ct1][0]
                    u = csl_rots_m[ct1][1]
                    v = csl_rots_m[ct1][2]
                    w = csl_rots_m[ct1][3]
                    U = (2 * u + v + w) / 3.0
                    V = (-u + v + w) / 3.0
                    W = (w - u - 2 * v) / 3.0
                else:
                    m = csl_rots_m[ct1][0]
                    U = csl_rots_m[ct1][1]
                    V = csl_rots_m[ct1][2]
                    W = csl_rots_m[ct1][3]
                sig_rots_m[tstr1][sig_inds1[tstr1], :, :] = \
                                                    csl_util.compute_tmat(np.array([m,U,V,W]).reshape(4, 1), tau, l1)
            elif csl_rots['type'] == 'matrices':
                sig_rots_m[tstr1][sig_inds1[tstr1], :, :] = csl_rots_m[ct1]
        else:
            sig_inds1[tstr1] = 0
            if csl_rots['type'] == 'quads':
                if l1.pearson[0:2] == 'hR':
                    m = csl_rots_m[ct1][0]
                    u = csl_rots_m[ct1][1]
                    v = csl_rots_m[ct1][2]
                    w = csl_rots_m[ct1][3]
                    U = (2 * u + v + w) / 3.0
                    V = (-u + v + w) / 3.0
                    W = (w - u - 2 * v) / 3.0
                else:
                    m = csl_rots_m[ct1][0]
                    U = csl_rots_m[ct1][1]
                    V = csl_rots_m[ct1][2]
                    W = csl_rots_m[ct1][3]
                sig_rots_m[tstr1][sig_inds1[tstr1], :, :] = \
                                                    csl_util.compute_tmat(np.array([m,U,V,W]).reshape(4, 1), tau, l1)
            elif csl_rots['type'] == 'matrices':
                sig_rots_m[tstr1][sig_inds1[tstr1], :, :] = csl_rots_m[ct1]

    sig_rots_m1 = {}
    for ct1 in list(sig_rots_m.keys()):
        sig_rots_m1[ct1] = {}
        if csl_rots['type'] == 'quads':
            mats1 = sig_rots_m[ct1]
            msz1 = np.shape(mats1)[0]
            sig_rots_m1[ct1]['N'] = np.zeros((msz1, 3, 3))
            sig_rots_m1[ct1]['D'] = np.zeros((msz1, 3, 3))
            for ct2 in range(msz1):
                [mult, num_mat] = int_man.int_mult(mats1[ct2, :, :], 1e-06)
                if int_man.int_check(mult):
                    mult = np.round(mult)
                    if int(mult) != int(ct1):
                        raise Exception('Not a sigma rotation')
                else:
                    raise Exception('Not a sigma rotation')

                sig_rots_m1[ct1]['N'][ct2, :, :] = num_mat
                sig_rots_m1[ct1]['D'][ct2, :, :] = mult * np.ones(
                    np.shape(num_mat))
        elif csl_rots['type'] == 'matrices':
            sig_rots_m1[ct1]['N'] = sig_rots_m[ct1]
            sig_rots_m1[ct1]['D'] = \
                            float(ct1)*np.ones(np.shape(sig_rots_m[ct1]))

    return sig_rots_m1