def _get_fc3_done(supercell, disp_dataset, symmetry, array_shape): num_atom = supercell.get_number_of_atoms() fc3_done = np.zeros(array_shape, dtype='byte') symprec = symmetry.get_symmetry_tolerance() lattice = supercell.get_cell().T positions = supercell.get_scaled_positions() rotations = symmetry.get_symmetry_operations()['rotations'] translations = symmetry.get_symmetry_operations()['translations'] atom_mapping = [] for rot, trans in zip(rotations, translations): atom_indices = [ _get_atom_by_symmetry(lattice, positions, rot, trans, i, symprec) for i in range(num_atom) ] atom_mapping.append(atom_indices) for dataset_first_atom in disp_dataset['first_atoms']: first_atom_num = dataset_first_atom['number'] site_symmetry = symmetry.get_site_symmetry(first_atom_num) direction = np.dot(dataset_first_atom['displacement'], np.linalg.inv(supercell.get_cell())) reduced_site_sym = get_reduced_site_symmetry(site_symmetry, direction, symprec) least_second_atom_nums = [] for second_atoms in dataset_first_atom['second_atoms']: if 'included' in second_atoms: if second_atoms['included']: least_second_atom_nums.append(second_atoms['number']) elif 'cutoff_distance' in disp_dataset: min_vec = get_equivalent_smallest_vectors( first_atom_num, second_atoms['number'], supercell, symprec)[0] min_distance = np.linalg.norm(np.dot(lattice, min_vec)) if 'pair_distance' in second_atoms: assert (abs(min_distance - second_atoms['pair_distance']) < 1e-4) if min_distance < disp_dataset['cutoff_distance']: least_second_atom_nums.append(second_atoms['number']) positions_shifted = positions - positions[first_atom_num] least_second_atom_nums = np.unique(least_second_atom_nums) for red_rot in reduced_site_sym: second_atom_nums = [ _get_atom_by_symmetry(lattice, positions_shifted, red_rot, np.zeros(3, dtype='double'), i, symprec) for i in least_second_atom_nums ] second_atom_nums = np.unique(second_atom_nums) for i in range(len(rotations)): rotated_atom1 = atom_mapping[i][first_atom_num] for j in second_atom_nums: fc3_done[rotated_atom1, atom_mapping[i][j]] = 1 return fc3_done
def cutoff_fc3_by_zero(fc3, supercell, cutoff_distance, symprec=1e-5): num_atom = supercell.get_number_of_atoms() lattice = supercell.get_cell().T min_distances = np.zeros((num_atom, num_atom), dtype='double') for i in range(num_atom): # run in supercell for j in range(num_atom): # run in primitive min_distances[i, j] = np.linalg.norm( np.dot(lattice, get_equivalent_smallest_vectors( i, j, supercell, symprec)[0])) for i, j, k in np.ndindex(num_atom, num_atom, num_atom): for pair in ((i, j), (j, k), (k, i)): if min_distances[pair] > cutoff_distance: fc3[i, j, k] = 0 break