Пример #1
0
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
Пример #2
0
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