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