Example #1
0
    def _distribute_2(self, disps, forces, first_atom_num, second_atom_num,
                      reduced_site_sym):
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     reduced_site_sym,
                                                     self._symprec)

        sym_cart = None
        rot_atom_map = None
        for i, sym in enumerate(reduced_site_sym):
            if disps[rot_map_syms[i, second_atom_num]] is not None:
                sym_cart = similarity_transformation(self._lattice, sym)
                rot_atom_map = rot_map_syms[i, :]
                break

        assert sym_cart is not None, "Something is wrong."

        forces[second_atom_num] = []
        disps[second_atom_num] = []
        for i in range(self._num_atom):
            forces_2 = [
                np.dot(f[rot_atom_map], sym_cart.T)
                for f in forces[rot_atom_map[second_atom_num]][rot_atom_map[i]]
            ]
            disps_2 = [[
                d3[0], np.dot(sym_cart, d3[1]),
                np.dot(sym_cart, d3[2])
            ] for d3 in disps[rot_atom_map[second_atom_num]][rot_atom_map[i]]]

            forces[second_atom_num].append(forces_2)
            disps[second_atom_num].append(disps_2)
Example #2
0
def solve_fc3(fc3,
              first_atom_num,
              supercell,
              site_symmetry,
              displacements_first,
              delta_fc2s,
              symprec,
              pinv="numpy"):
    lattice = supercell.get_cell().T
    site_sym_cart = [similarity_transformation(lattice, sym)
                     for sym in site_symmetry]
    num_atom = supercell.get_number_of_atoms()
    positions = supercell.get_scaled_positions()
    pos_center = positions[first_atom_num].copy()
    positions -= pos_center
    rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                 site_symmetry,
                                                 symprec)
    
    rot_disps = get_rotated_displacement(displacements_first, site_sym_cart)

    if pinv == "numpy":
        inv_U = np.linalg.pinv(rot_disps)
    else:
        try:
            import anharmonic._phono3py as phono3c
            inv_U = np.zeros((rot_disps.shape[1], rot_disps.shape[0]),
                             dtype='double')
            phono3c.pinv(inv_U, rot_disps, 1e-13)
        except ImportError:
            inv_U = np.linalg.pinv(rot_disps)
            
    for (i, j) in list(np.ndindex(num_atom, num_atom)):
        fc3[first_atom_num, i, j] = np.dot(inv_U, _get_rotated_fc2s(
                i, j, delta_fc2s, rot_map_syms, site_sym_cart)).reshape(3, 3, 3)
Example #3
0
    def _distribute_3(self,
                      disps_3,
                      forces_3,
                      second_atom_num,
                      third_atom_num,
                      reduced_bond_sym):
        positions = self._positions.copy() - self._positions[second_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     reduced_bond_sym,
                                                     self._symprec)

        sym_cart = None
        rot_atom_map = None
        for i, sym in enumerate(reduced_bond_sym):
            if disps_3[rot_map_syms[i, third_atom_num]] is not None:
                sym_cart = similarity_transformation(self._lattice, sym)
                rot_atom_map = rot_map_syms[i, :]
                break

        assert sym_cart is not None, "Something is wrong."

        forces = [np.dot(f[rot_atom_map], sym_cart.T)
                  for f in forces_3[rot_atom_map[third_atom_num]]]
        disps = [[d3[0], d3[1], np.dot(sym_cart, d3[2])]
                 for d3 in disps_3[rot_atom_map[third_atom_num]]]

        disps_3[third_atom_num] = disps
        forces_3[third_atom_num] = forces
Example #4
0
    def _distribute_displacements_and_forces(self,
                                             set_of_disps,
                                             sets_of_forces,
                                             first_atom_num,
                                             disp1,
                                             unique_second_atom_nums):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        direction = np.dot(np.linalg.inv(self._lattice), disp1)
        reduced_site_sym = get_reduced_site_symmetry(
            site_symmetry, direction, self._symprec)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     reduced_site_sym,
                                                     self._symprec)

        disp_pairs = []
        for second_atom_num in range(self._num_atom):
            if set_of_disps[second_atom_num] is None:
                (sets_of_forces_atom2,
                 set_of_disps_atom2) = self._copy_dataset_2nd(
                    second_atom_num,
                    set_of_disps,
                    sets_of_forces,
                    unique_second_atom_nums,
                    reduced_site_sym,
                    rot_map_syms)
                disp_pairs.append(
                    [[disp1, d] for d in set_of_disps_atom2])
                sets_of_forces[second_atom_num] = sets_of_forces_atom2
            else:
                disp_pairs.append(
                    [[disp1, d] for d in set_of_disps[second_atom_num]])

        return disp_pairs, sets_of_forces
Example #5
0
    def _distribute_2(self,
                      disps,
                      forces,
                      first_atom_num,
                      second_atom_num,
                      reduced_site_sym):
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     reduced_site_sym,
                                                     self._symprec)

        sym_cart = None
        rot_atom_map = None
        for i, sym in enumerate(reduced_site_sym):
            if disps[rot_map_syms[i, second_atom_num]] is not None:
                sym_cart = similarity_transformation(self._lattice, sym)
                rot_atom_map = rot_map_syms[i, :]
                break

        assert sym_cart is not None, "Something is wrong."

        forces[second_atom_num] = []
        disps[second_atom_num] = []
        for i in range(self._num_atom):
            forces_2 = [
                np.dot(f[rot_atom_map], sym_cart.T)
                for f in forces[rot_atom_map[second_atom_num]][rot_atom_map[i]]]
            disps_2 = [
                [d3[0], np.dot(sym_cart, d3[1]), np.dot(sym_cart, d3[2])]
                for d3 in disps[rot_atom_map[second_atom_num]][rot_atom_map[i]]]

            forces[second_atom_num].append(forces_2)
            disps[second_atom_num].append(disps_2)
Example #6
0
def _solve_fc4(fc4,
               first_atom_num,
               supercell,
               site_symmetry,
               displacements_first,
               delta_fc3s,
               symprec):
    lattice = supercell.get_cell().T
    site_sym_cart = np.double([similarity_transformation(lattice, sym)
                               for sym in site_symmetry])
    num_atom = supercell.get_number_of_atoms()
    positions = supercell.get_scaled_positions()
    pos_center = positions[first_atom_num].copy()
    positions -= pos_center
    rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                 site_symmetry,
                                                 symprec)
    
    rot_disps = get_rotated_displacement(displacements_first, site_sym_cart)
    inv_U = np.linalg.pinv(rot_disps)

    for (i, j, k) in list(np.ndindex(num_atom, num_atom, num_atom)):
        fc4[first_atom_num, i, j, k] = np.dot(
            inv_U, _rotate_delta_fc3s(
                i, j, k, delta_fc3s, rot_map_syms, site_sym_cart)
            ).reshape(3, 3, 3, 3)
Example #7
0
    def _distribute_displacements_and_forces(self, set_of_disps,
                                             sets_of_forces, first_atom_num,
                                             disp1, unique_second_atom_nums):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        direction = np.dot(np.linalg.inv(self._lattice), disp1)
        reduced_site_sym = get_reduced_site_symmetry(site_symmetry, direction,
                                                     self._symprec)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(self._lattice, positions,
                                                     reduced_site_sym,
                                                     self._symprec)

        disp_pairs = []
        for second_atom_num in range(self._num_atom):
            if set_of_disps[second_atom_num] is None:
                (sets_of_forces_atom2,
                 set_of_disps_atom2) = self._copy_dataset_2nd(
                     second_atom_num, set_of_disps, sets_of_forces,
                     unique_second_atom_nums, reduced_site_sym, rot_map_syms)
                disp_pairs.append([[disp1, d] for d in set_of_disps_atom2])
                sets_of_forces[second_atom_num] = sets_of_forces_atom2
            else:
                disp_pairs.append([[disp1, d]
                                   for d in set_of_disps[second_atom_num]])

        return disp_pairs, sets_of_forces
Example #8
0
    def _distribute_3(self, disps_3, forces_3, second_atom_num, third_atom_num,
                      reduced_bond_sym):
        positions = self._positions.copy() - self._positions[second_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     reduced_bond_sym,
                                                     self._symprec)

        sym_cart = None
        rot_atom_map = None
        for i, sym in enumerate(reduced_bond_sym):
            if disps_3[rot_map_syms[i, third_atom_num]] is not None:
                sym_cart = similarity_transformation(self._lattice, sym)
                rot_atom_map = rot_map_syms[i, :]
                break

        assert sym_cart is not None, "Something is wrong."

        forces = [
            np.dot(f[rot_atom_map], sym_cart.T)
            for f in forces_3[rot_atom_map[third_atom_num]]
        ]
        disps = [[d3[0], d3[1], np.dot(sym_cart, d3[2])]
                 for d3 in disps_3[rot_atom_map[third_atom_num]]]

        disps_3[third_atom_num] = disps
        forces_3[third_atom_num] = forces
Example #9
0
    def _fit(self, first_atom_num, disp_triplets, sets_of_forces):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     site_symmetry,
                                                     self._symprec)
        site_syms_cart = np.array([similarity_transformation(self._lattice, sym)
                                   for sym in site_symmetry],
                                  dtype='double')

        (disp_triplets_rearranged,
         num_triplets) = self._create_displacement_triplets_for_c(disp_triplets)
        max_num_disp = np.amax(num_triplets[:, :, :, 1])

        for second_atom_num in range(self._num_atom):
            print second_atom_num + 1

            rot_disps_set = []
            for third_atom_num in range(self._num_atom):
                try:
                    import anharmonic._forcefit as forcefit
                    rot_disps_set.append(self._create_displacement_matrix_c(
                            second_atom_num,
                            third_atom_num,
                            disp_triplets_rearranged,
                            num_triplets,
                            site_syms_cart,
                            rot_map_syms,
                            max_num_disp))
                except ImportError:
                    rot_disps_set.append(self._create_displacement_matrix(
                            second_atom_num,
                            third_atom_num,
                            disp_triplets,
                            site_syms_cart,
                            rot_map_syms))
                    
                print third_atom_num + 1, rot_disps_set[third_atom_num].shape

            inv_disps_set = self._invert_displacements(rot_disps_set)

            for third_atom_num in range(self._num_atom):
                rot_forces = self._create_force_matrix(
                    second_atom_num,
                    third_atom_num,
                    sets_of_forces,
                    site_syms_cart,
                    rot_map_syms)

                fc = self._solve(inv_disps_set[third_atom_num], rot_forces)

                # For elements with index exchange symmetry 
                fc2 = fc[:, 7:10, :].reshape((self._num_atom, 3, 3))
                fc3 = fc[:, 46:55, :].reshape((self._num_atom, 3, 3, 3))
                fc4 = fc[:, 172:199, :].reshape((self._num_atom, 3, 3, 3, 3))
                self._fc2[third_atom_num] = fc2
                self._fc3[second_atom_num, third_atom_num] = fc3
                self._fc4[first_atom_num, second_atom_num, third_atom_num] = fc4
Example #10
0
def solve_fc3(fc3,
              first_atom_num,
              supercell,
              site_symmetry,
              displacements_first,
              delta_fc2s,
              symprec,
              pinv="numpy",
              verbose=False):

    if verbose:
        text = "Solving fc3[ %d, x, x ] with " % (first_atom_num + 1)
        if len(displacements_first) > 1:
            text += "displacements:"
        else:
            text += "a displacement:"
        print(text)
        for i, v in enumerate(displacements_first):
            print("    [%7.4f %7.4f %7.4f]" % tuple(v))
            sys.stdout.flush()
        if verbose > 2:
            print("  Site symmetry:")
            for i, v in enumerate(site_symmetry):
                print("    [%2d %2d %2d] #%2d" % tuple(list(v[0]) + [i + 1]))
                print("    [%2d %2d %2d]" % tuple(v[1]))
                print("    [%2d %2d %2d]\n" % tuple(v[2]))
                sys.stdout.flush()

    lattice = supercell.get_cell().T
    site_sym_cart = [
        similarity_transformation(lattice, sym) for sym in site_symmetry
    ]
    num_atom = supercell.get_number_of_atoms()
    positions = supercell.get_scaled_positions()
    pos_center = positions[first_atom_num].copy()
    positions -= pos_center
    rot_map_syms = get_positions_sent_by_rot_inv(positions, site_symmetry,
                                                 symprec)

    rot_disps = get_rotated_displacement(displacements_first, site_sym_cart)

    if pinv == "numpy":
        inv_U = np.linalg.pinv(rot_disps)
    else:
        try:
            import phonopy._lapackepy as lapackepy
            inv_U = np.zeros((rot_disps.shape[1], rot_disps.shape[0]),
                             dtype='double')
            lapackepy.pinv(inv_U, rot_disps, 1e-13)
        except ImportError:
            inv_U = np.linalg.pinv(rot_disps)

    for (i, j) in list(np.ndindex(num_atom, num_atom)):
        fc3[first_atom_num, i, j] = np.dot(
            inv_U,
            _get_rotated_fc2s(i, j, delta_fc2s, rot_map_syms,
                              site_sym_cart)).reshape(3, 3, 3)
Example #11
0
def solve_fc3(fc3,
              first_atom_num,
              supercell,
              site_symmetry,
              displacements_first,
              delta_fc2s,
              symprec,
              pinv="numpy",
              verbose=False):

    if verbose:
        text = "Solving fc3[ %d, x, x ] with " % (first_atom_num + 1)
        if len(displacements_first) > 1:
            text += "displacements:"
        else:
            text += "a displacement:"
        print(text)
        for i, v in enumerate(displacements_first):
            print("    [%7.4f %7.4f %7.4f]" % tuple(v))
            sys.stdout.flush()
        if verbose > 2:
            print("  Site symmetry:")
            for i, v in enumerate(site_symmetry):
                print("    [%2d %2d %2d] #%2d" % tuple(list(v[0])+[i + 1]))
                print("    [%2d %2d %2d]" % tuple(v[1]))
                print("    [%2d %2d %2d]\n" % tuple(v[2]))
                sys.stdout.flush()

    lattice = supercell.get_cell().T
    site_sym_cart = [similarity_transformation(lattice, sym)
                     for sym in site_symmetry]
    num_atom = supercell.get_number_of_atoms()
    positions = supercell.get_scaled_positions()
    pos_center = positions[first_atom_num].copy()
    positions -= pos_center
    rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                 site_symmetry,
                                                 symprec)

    rot_disps = get_rotated_displacement(displacements_first, site_sym_cart)

    if pinv == "numpy":
        inv_U = np.linalg.pinv(rot_disps)
    else:
        try:
            import phonopy._lapackepy as lapackepy
            inv_U = np.zeros((rot_disps.shape[1], rot_disps.shape[0]),
                             dtype='double')
            lapackepy.pinv(inv_U, rot_disps, 1e-13)
        except ImportError:
            inv_U = np.linalg.pinv(rot_disps)

    for (i, j) in list(np.ndindex(num_atom, num_atom)):
        fc3[first_atom_num, i, j] = np.dot(inv_U, _get_rotated_fc2s(
                i, j, delta_fc2s, rot_map_syms, site_sym_cart)).reshape(3, 3, 3)
Example #12
0
    def _fit(self, first_atom_num, disp_triplets, sets_of_forces):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(self._lattice, positions,
                                                     site_symmetry,
                                                     self._symprec)
        site_syms_cart = np.array([
            similarity_transformation(self._lattice, sym)
            for sym in site_symmetry
        ],
                                  dtype='double')

        (disp_triplets_rearranged, num_triplets
         ) = self._create_displacement_triplets_for_c(disp_triplets)
        max_num_disp = np.amax(num_triplets[:, :, :, 1])

        for second_atom_num in range(self._num_atom):
            print second_atom_num + 1

            rot_disps_set = []
            for third_atom_num in range(self._num_atom):
                try:
                    import anharmonic._forcefit as forcefit
                    rot_disps_set.append(
                        self._create_displacement_matrix_c(
                            second_atom_num, third_atom_num,
                            disp_triplets_rearranged, num_triplets,
                            site_syms_cart, rot_map_syms, max_num_disp))
                except ImportError:
                    rot_disps_set.append(
                        self._create_displacement_matrix(
                            second_atom_num, third_atom_num, disp_triplets,
                            site_syms_cart, rot_map_syms))

                print third_atom_num + 1, rot_disps_set[third_atom_num].shape

            inv_disps_set = self._invert_displacements(rot_disps_set)

            for third_atom_num in range(self._num_atom):
                rot_forces = self._create_force_matrix(second_atom_num,
                                                       third_atom_num,
                                                       sets_of_forces,
                                                       site_syms_cart,
                                                       rot_map_syms)

                fc = self._solve(inv_disps_set[third_atom_num], rot_forces)

                # For elements with index exchange symmetry
                fc2 = fc[:, 7:10, :].reshape((self._num_atom, 3, 3))
                fc3 = fc[:, 46:55, :].reshape((self._num_atom, 3, 3, 3))
                fc4 = fc[:, 172:199, :].reshape((self._num_atom, 3, 3, 3, 3))
                self._fc2[third_atom_num] = fc2
                self._fc3[second_atom_num, third_atom_num] = fc3
                self._fc4[first_atom_num, second_atom_num,
                          third_atom_num] = fc4
Example #13
0
    def _get_matrices(self, first_atom_num):
        disps = []
        sets_of_forces = []
        for dataset_1st in self._dataset["first_atoms"]:
            if first_atom_num != dataset_1st["number"]:
                continue
            disps.append(dataset_1st["displacement"])
            sets_of_forces.append(dataset_1st["forces"])

        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions, site_symmetry, self._symprec)
        site_sym_cart = [similarity_transformation(self._lattice, sym) for sym in site_symmetry]
        rot_disps = self._create_displacement_matrix(disps, site_sym_cart)
        rot_forces = self._create_force_matrix(sets_of_forces, site_sym_cart, rot_map_syms)
        return rot_disps, rot_forces
Example #14
0
    def _fit(self, first_atom_num, disp_pairs, sets_of_forces):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions, site_symmetry,
                                                     self._symprec)

        for second_atom_num in range(self._num_atom):
            rot_atom_map = rot_map_syms[:, second_atom_num]
            rot_disps = self._create_displacement_matrix(
                disp_pairs, site_symmetry, rot_atom_map)
            rot_forces = self._create_force_matrix(sets_of_forces,
                                                   site_symmetry, rot_atom_map,
                                                   rot_map_syms)
            fc = self._solve(rot_disps, rot_forces)
            fc2 = fc[:, 1:4, :].reshape((self._num_atom, 3, 3))
            fc3 = fc[:, 7:16, :].reshape((self._num_atom, 3, 3, 3))
            self._fc3[first_atom_num, second_atom_num] = fc3
Example #15
0
    def _fit(self, first_atom_num, disp_pairs, sets_of_forces):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     site_symmetry,
                                                     self._symprec)

        for second_atom_num in range(self._num_atom):
            rot_atom_map = rot_map_syms[:, second_atom_num]
            rot_disps = self._create_displacement_matrix(disp_pairs,
                                                         site_symmetry,
                                                         rot_atom_map)
            rot_forces = self._create_force_matrix(sets_of_forces,
                                                   site_symmetry,
                                                   rot_atom_map,
                                                   rot_map_syms)
            fc = self._solve(rot_disps, rot_forces)
            fc2 = fc[:, 1:4, :].reshape((self._num_atom, 3, 3))
            fc3 = fc[:, 7:16, :].reshape((self._num_atom, 3, 3, 3))
            self._fc3[first_atom_num, second_atom_num] = fc3
Example #16
0
    def _fit(self, first_atom_num, disp_pairs, sets_of_forces):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions, site_symmetry,
                                                     self._symprec)

        for second_atom_num in range(self._num_atom):
            rot_atom_map = rot_map_syms[:, second_atom_num]
            rot_disps = self._create_displacement_matrix(
                disp_pairs, site_symmetry, rot_atom_map)
            rot_forces = self._create_force_matrix(sets_of_forces,
                                                   site_symmetry, rot_atom_map,
                                                   rot_map_syms)
            fc = self._solve(rot_disps, rot_forces)
            fc2 = fc[:, 1:4, :].reshape((self._num_atom, 3, 3))
            fc2_2 = fc[:, 5:8, :].reshape((self._num_atom, 3, 3))
            fc3 = fc[:, 7:16, :].reshape((self._num_atom, 3, 3, 3))
            fc3_21 = fc[:, 16:25, :].reshape((self._num_atom, 3, 3, 3))
            for i, j in list(np.ndindex(3, 3)):
                self._fc3[first_atom_num, second_atom_num, :, i,
                          j, :] = (fc3[:, i, j, :] + fc3_21[:, j, i, :]) / 2
Example #17
0
    def _get_matrices(self, first_atom_num):
        disps = []
        sets_of_forces = []
        for dataset_1st in self._dataset['first_atoms']:
            if first_atom_num != dataset_1st['number']:
                continue
            disps.append(dataset_1st['displacement'])
            sets_of_forces.append(dataset_1st['forces'])

        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = (self._positions.copy() - self._positions[first_atom_num])
        rot_map_syms = get_positions_sent_by_rot_inv(positions, site_symmetry,
                                                     self._symprec)
        site_sym_cart = [
            similarity_transformation(self._lattice, sym)
            for sym in site_symmetry
        ]
        rot_disps = self._create_displacement_matrix(disps, site_sym_cart)
        rot_forces = self._create_force_matrix(sets_of_forces, site_sym_cart,
                                               rot_map_syms)
        return rot_disps, rot_forces
Example #18
0
def solve_fc3(fc3,
              first_atom_num,
              supercell,
              site_symmetry,
              displacements_first,
              delta_fc2s,
              symprec,
              pinv="numpy"):
    lattice = supercell.get_cell().T
    site_sym_cart = [
        similarity_transformation(lattice, sym) for sym in site_symmetry
    ]
    num_atom = supercell.get_number_of_atoms()
    positions = supercell.get_scaled_positions()
    pos_center = positions[first_atom_num].copy()
    positions -= pos_center
    rot_map_syms = get_positions_sent_by_rot_inv(positions, site_symmetry,
                                                 symprec)

    rot_disps = get_rotated_displacement(displacements_first, site_sym_cart)

    if pinv == "numpy":
        inv_U = np.linalg.pinv(rot_disps)
    else:
        try:
            import anharmonic._phono3py as phono3c
            inv_U = np.zeros((rot_disps.shape[1], rot_disps.shape[0]),
                             dtype='double')
            phono3c.pinv(inv_U, rot_disps, 1e-13)
        except ImportError:
            inv_U = np.linalg.pinv(rot_disps)

    for (i, j) in list(np.ndindex(num_atom, num_atom)):
        fc3[first_atom_num, i, j] = np.dot(
            inv_U,
            _get_rotated_fc2s(i, j, delta_fc2s, rot_map_syms,
                              site_sym_cart)).reshape(3, 3, 3)
Example #19
0
    def _fit(self, first_atom_num, disp_pairs, sets_of_forces):
        site_symmetry = self._symmetry.get_site_symmetry(first_atom_num)
        positions = self._positions.copy() - self._positions[first_atom_num]
        rot_map_syms = get_positions_sent_by_rot_inv(positions,
                                                     site_symmetry,
                                                     self._symprec)

        for second_atom_num in range(self._num_atom):
            rot_atom_map = rot_map_syms[:, second_atom_num]
            rot_disps = self._create_displacement_matrix(disp_pairs,
                                                         site_symmetry,
                                                         rot_atom_map)
            rot_forces = self._create_force_matrix(sets_of_forces,
                                                   site_symmetry,
                                                   rot_atom_map,
                                                   rot_map_syms)
            fc = self._solve(rot_disps, rot_forces)
            fc2 = fc[:, 1:4, :].reshape((self._num_atom, 3, 3))
            fc2_2 = fc[:, 5:8, :].reshape((self._num_atom, 3, 3))
            fc3 = fc[:, 7:16, :].reshape((self._num_atom, 3, 3, 3))
            fc3_21 = fc[:, 16:25, :].reshape((self._num_atom, 3, 3, 3))
            for i, j in list(np.ndindex(3, 3)):
                self._fc3[first_atom_num, second_atom_num, :, i, j, :] = (
                    fc3[:, i, j, :] + fc3_21[:, j, i, :]) / 2
Example #20
0
def solve_fc3(first_atom_num,
              supercell,
              site_symmetry,
              displacements_first,
              delta_fc2s,
              symprec,
              pinv_solver="numpy",
              verbose=False):

    logger.debug("solve_fc3")

    if pinv_solver == "numpy":
        solver = "numpy.linalg.pinv"
    else:
        try:
            import phono3py._lapackepy as lapackepy
            solver = "lapacke-dgesvd"
        except ImportError:
            print("Phono3py C-routine is not compiled correctly.")
            solver = "numpy.linalg.pinv"

    if verbose:
        text = ("Computing fc3[ %d, x, x ] using %s with " %
                (first_atom_num + 1, solver))
        if len(displacements_first) > 1:
            text += "displacements:"
        else:
            text += "a displacement:"
        print(text)
        for i, v in enumerate(displacements_first):
            print("    [%7.4f %7.4f %7.4f]" % tuple(v))
            sys.stdout.flush()
        if verbose > 2:
            print("  Site symmetry:")
            for i, v in enumerate(site_symmetry):
                print("    [%2d %2d %2d] #%2d" % tuple(list(v[0]) + [i + 1]))
                print("    [%2d %2d %2d]" % tuple(v[1]))
                print("    [%2d %2d %2d]\n" % tuple(v[2]))
                sys.stdout.flush()

    lattice = supercell.get_cell().T
    site_sym_cart = np.array(
        [similarity_transformation(lattice, sym) for sym in site_symmetry],
        dtype='double',
        order='C')
    num_atom = supercell.get_number_of_atoms()
    positions = supercell.get_scaled_positions()
    pos_center = positions[first_atom_num].copy()
    positions -= pos_center

    logger.debug("get_positions_sent_by_rot_inv")

    rot_map_syms = get_positions_sent_by_rot_inv(lattice, positions,
                                                 site_symmetry, symprec)
    rot_disps = get_rotated_displacement(displacements_first, site_sym_cart)

    logger.debug("pinv")

    if "numpy" in solver:
        inv_U = np.array(np.linalg.pinv(rot_disps), dtype='double', order='C')
    else:
        inv_U = np.zeros((rot_disps.shape[1], rot_disps.shape[0]),
                         dtype='double',
                         order='C')
        lapackepy.pinv(inv_U, rot_disps, 1e-13)

    fc3 = np.zeros((num_atom, num_atom, 3, 3, 3), dtype='double', order='C')

    logger.debug("rotate_delta_fc2s")

    try:
        import phono3py._phono3py as phono3c
        phono3c.rotate_delta_fc2s(fc3, delta_fc2s, inv_U, site_sym_cart,
                                  rot_map_syms)
    except ImportError:
        for i, j in np.ndindex(num_atom, num_atom):
            fc3[i, j] = np.dot(
                inv_U,
                _get_rotated_fc2s(i, j, delta_fc2s, rot_map_syms,
                                  site_sym_cart)).reshape(3, 3, 3)

    return fc3