Exemple #1
0
def _get_fc3_one_atom(fc3, supercell, disp_dataset, fc2, first_atom_num,
                      site_symmetry, translational_symmetry_type,
                      is_permutation_symmetry, symprec, verbose):
    displacements_first = []
    delta_fc2s = []
    for dataset_first_atom in disp_dataset['first_atoms']:
        if first_atom_num != dataset_first_atom['number']:
            continue

        displacements_first.append(dataset_first_atom['displacement'])
        if 'delta_fc2' in dataset_first_atom:
            delta_fc2s.append(dataset_first_atom['delta_fc2'])
        else:
            direction = np.dot(dataset_first_atom['displacement'],
                               np.linalg.inv(supercell.get_cell()))
            reduced_site_sym = get_reduced_site_symmetry(
                site_symmetry, direction, symprec)
            delta_fc2s.append(
                get_delta_fc2(dataset_first_atom['second_atoms'],
                              dataset_first_atom['number'], fc2, supercell,
                              reduced_site_sym, translational_symmetry_type,
                              is_permutation_symmetry, symprec))

    solve_fc3(fc3,
              first_atom_num,
              supercell,
              site_symmetry,
              displacements_first,
              delta_fc2s,
              symprec,
              verbose=verbose)
Exemple #2
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
Exemple #3
0
def _get_fc3_done(supercell, disp_dataset, symmetry):
    num_atom = supercell.get_number_of_atoms()
    fc3_done = np.zeros((num_atom, num_atom, num_atom), 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 = []
        for rot_pos in (np.dot(positions, rot.T) + trans):
            diffs = positions - rot_pos
            diffs -= np.rint(diffs)
            diffs = np.dot(diffs, lattice.T)
            dists = np.sqrt(np.sum(diffs**2, axis=1))
            atom_indices.append((np.where(dists < symprec))[0][0])
        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 second_atoms['included']:
                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)

        second_atom_nums = []
        for red_rot in reduced_site_sym:
            for i in least_second_atom_nums:
                second_atom_nums.append(
                    _get_atom_by_symmetry(lattice, positions_shifted, red_rot,
                                          np.zeros(3, dtype='double'), i,
                                          symprec))
        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
Exemple #4
0
def _get_fc3_least_atoms(supercell,
                         primitive,
                         disp_dataset,
                         fc2,
                         symmetry,
                         is_compact_fc=False,
                         verbose=True):
    symprec = symmetry.get_symmetry_tolerance()
    num_satom = supercell.get_number_of_atoms()
    unique_first_atom_nums = np.unique(
        [x['number'] for x in disp_dataset['first_atoms']])

    if is_compact_fc:
        num_patom = primitive.get_number_of_atoms()
        s2p_map = primitive.get_supercell_to_primitive_map()
        p2p_map = primitive.get_primitive_to_primitive_map()
        first_atom_nums = []
        for i in unique_first_atom_nums:
            if i != s2p_map[i]:
                print("Something wrong in disp_fc3.yaml")
                raise RuntimeError
            else:
                first_atom_nums.append(i)
        fc3 = np.zeros((num_patom, num_satom, num_satom, 3, 3, 3),
                       dtype='double',
                       order='C')
    else:
        first_atom_nums = unique_first_atom_nums
        fc3 = np.zeros((num_satom, num_satom, num_satom, 3, 3, 3),
                       dtype='double',
                       order='C')

    for first_atom_num in first_atom_nums:
        site_symmetry = symmetry.get_site_symmetry(first_atom_num)
        displacements_first = []
        delta_fc2s = []
        for dataset_first_atom in disp_dataset['first_atoms']:
            if first_atom_num != dataset_first_atom['number']:
                continue

            displacements_first.append(dataset_first_atom['displacement'])
            if 'delta_fc2' in dataset_first_atom:
                delta_fc2s.append(dataset_first_atom['delta_fc2'])
            else:
                direction = np.dot(dataset_first_atom['displacement'],
                                   np.linalg.inv(supercell.get_cell()))
                reduced_site_sym = get_reduced_site_symmetry(
                    site_symmetry, direction, symprec)
                delta_fc2s.append(
                    get_delta_fc2(dataset_first_atom['second_atoms'],
                                  dataset_first_atom['number'], fc2, supercell,
                                  reduced_site_sym, symprec))

        fc3_first = solve_fc3(first_atom_num,
                              supercell,
                              site_symmetry,
                              displacements_first,
                              np.array(delta_fc2s, dtype='double', order='C'),
                              symprec,
                              verbose=verbose)
        if is_compact_fc:
            fc3[p2p_map[s2p_map[first_atom_num]]] = fc3_first
        else:
            fc3[first_atom_num] = fc3_first

    return fc3
Exemple #5
0
def _get_fc3_done(supercell: PhonopyAtoms, disp_dataset, symmetry: Symmetry,
                  array_shape):
    num_atom = len(supercell)
    fc3_done = np.zeros(array_shape, dtype="byte")
    symprec = symmetry.tolerance
    lattice = supercell.cell.T
    positions = supercell.scaled_positions
    rotations = symmetry.symmetry_operations["rotations"]
    translations = symmetry.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.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_smallest_vector_of_atom_pair(
                    first_atom_num, second_atoms["number"], supercell, symprec)
                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
Exemple #6
0
def _get_fc3_least_atoms(supercell,
                         primitive,
                         disp_dataset,
                         fc2,
                         symmetry,
                         is_compact_fc=False,
                         verbose=True):
    symprec = symmetry.tolerance
    num_satom = len(supercell)
    unique_first_atom_nums = np.unique(
        [x["number"] for x in disp_dataset["first_atoms"]])

    if is_compact_fc:
        num_patom = primitive.get_number_of_atoms()
        s2p_map = primitive.s2p_map
        p2p_map = primitive.p2p_map
        first_atom_nums = []
        for i in unique_first_atom_nums:
            if i != s2p_map[i]:
                print("Something wrong in disp_fc3.yaml")
                raise RuntimeError
            else:
                first_atom_nums.append(i)
        fc3 = np.zeros((num_patom, num_satom, num_satom, 3, 3, 3),
                       dtype="double",
                       order="C")
    else:
        first_atom_nums = unique_first_atom_nums
        fc3 = np.zeros((num_satom, num_satom, num_satom, 3, 3, 3),
                       dtype="double",
                       order="C")

    for first_atom_num in first_atom_nums:
        site_symmetry = symmetry.get_site_symmetry(first_atom_num)
        displacements_first = []
        delta_fc2s = []
        for dataset_first_atom in disp_dataset["first_atoms"]:
            if first_atom_num != dataset_first_atom["number"]:
                continue

            displacements_first.append(dataset_first_atom["displacement"])
            if "delta_fc2" in dataset_first_atom:
                delta_fc2s.append(dataset_first_atom["delta_fc2"])
            else:
                direction = np.dot(
                    dataset_first_atom["displacement"],
                    np.linalg.inv(supercell.cell),
                )
                reduced_site_sym = get_reduced_site_symmetry(
                    site_symmetry, direction, symprec)
                delta_fc2s.append(
                    _get_delta_fc2(
                        dataset_first_atom["second_atoms"],
                        dataset_first_atom["number"],
                        dataset_first_atom["forces"],
                        fc2,
                        supercell,
                        reduced_site_sym,
                        symprec,
                    ))

        fc3_first = _solve_fc3(
            first_atom_num,
            supercell,
            site_symmetry,
            displacements_first,
            np.array(delta_fc2s, dtype="double", order="C"),
            symprec,
            verbose=verbose,
        )
        if is_compact_fc:
            fc3[p2p_map[s2p_map[first_atom_num]]] = fc3_first
        else:
            fc3[first_atom_num] = fc3_first

    return fc3