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])
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