Ejemplo n.º 1
0
def distribute_fc3(fc3,
                   first_disp_atoms,
                   target_atoms,
                   lattice,
                   rotations,
                   permutations,
                   s2compact,
                   verbose=False):
    """Distribute fc3

    fc3[i, :, :, 0:3, 0:3, 0:3] where i=indices done are distributed to
    symmetrically equivalent fc3 elements by tensor rotations.

    Search symmetry operation (R, t) that performs
        i_target -> i_done
    and
        atom_mapping[i_target] = i_done
        fc3[i_target, j_target, k_target] = R_inv[i_done, j, k]

    Parameters
    ----------

    target_atoms: list or ndarray
        Supercell atom indices to which fc3 are distributed.
    s2compact: ndarray
        Maps supercell index to compact index. For full-fc3,
        s2compact=np.arange(n_satom).
        shape=(n_satom,)
        dtype=intc

    """

    n_satom = fc3.shape[1]
    for i_target in target_atoms:
        for i_done in first_disp_atoms:
            rot_indices = np.where(permutations[:, i_target] == i_done)[0]
            if len(rot_indices) > 0:
                atom_mapping = np.array(permutations[rot_indices[0]],
                                        dtype='intc')
                rot = rotations[rot_indices[0]]
                rot_cart_inv = np.array(similarity_transformation(
                    lattice, rot).T,
                                        dtype='double',
                                        order='C')
                break

        if len(rot_indices) == 0:
            print("Position or symmetry may be wrong.")
            raise RuntimeError

        if verbose > 2:
            print("    [ %d, x, x ] to [ %d, x, x ]" %
                  (i_done + 1, i_target + 1))
            sys.stdout.flush()

        try:
            import phono3py._phono3py as phono3c
            phono3c.distribute_fc3(fc3, int(s2compact[i_target]),
                                   int(s2compact[i_done]), atom_mapping,
                                   rot_cart_inv)
        except ImportError:
            print("Phono3py C-routine is not compiled correctly.")
            for j in range(n_satom):
                j_rot = atom_mapping[j]
                for k in range(n_satom):
                    k_rot = atom_mapping[k]
                    fc3[i_target, j, k] = third_rank_tensor_rotation(
                        rot_cart_inv, fc3[i_done, j_rot, k_rot])
Ejemplo n.º 2
0
def distribute_fc3(fc3_least_atoms,
                   first_disp_atoms,
                   lattice,
                   positions,
                   rotations,
                   translations,
                   symprec,
                   overwrite=True,
                   verbose=False):
    num_atom = len(positions)
    atom_mapping = np.zeros(num_atom, dtype='intc')

    if overwrite:
        fc3 = fc3_least_atoms
    else:
        fc3 = np.zeros((num_atom, num_atom, num_atom, 3, 3, 3), dtype='double')

    for i in range(num_atom):
        # if i in first_disp_atoms:
        #     continue

        for atom_index_done in first_disp_atoms:
            rot_num = get_atom_mapping_by_symmetry(positions, i,
                                                   atom_index_done, rotations,
                                                   translations, symprec)
            if rot_num > -1:
                i_rot = atom_index_done
                rot = rotations[rot_num]
                trans = translations[rot_num]
                break

        if rot_num < 0:
            print("Position or symmetry may be wrong.")
            raise ValueError

        for j in range(num_atom):
            atom_mapping[j] = get_atom_by_symmetry(positions, rot, trans, j,
                                                   symprec)

        rot_cart_inv = np.array(similarity_transformation(lattice, rot).T,
                                dtype='double',
                                order='C')

        if not (overwrite and i == i_rot):
            if verbose > 2:
                print("    [ %d, x, x ] to [ %d, x, x ]" % (i_rot + 1, i + 1))
                sys.stdout.flush()

            try:
                import phono3py._phono3py as phono3c
                phono3c.distribute_fc3(fc3, fc3_least_atoms, i, atom_mapping,
                                       rot_cart_inv)

            except ImportError:
                for j in range(num_atom):
                    j_rot = atom_mapping[j]
                    for k in range(num_atom):
                        k_rot = atom_mapping[k]
                        fc3[i, j, k] = third_rank_tensor_rotation(
                            rot_cart_inv, fc3_least_atoms[i_rot, j_rot, k_rot])

    if not overwrite:
        return fc3