def distribute_force_constants( force_constants, atom_list_done, lattice, # column vectors rotations, # scaled (fractional) permutations, atom_list=None, ): """Fill force constants elements by symmetry.""" map_atoms, map_syms = _get_sym_mappings_from_permutations( permutations, atom_list_done) rots_cartesian = np.array( [similarity_transformation(lattice, r) for r in rotations], dtype="double", order="C", ) if atom_list is None: targets = np.arange(force_constants.shape[1], dtype="intc") else: targets = np.array(atom_list, dtype="intc") import phonopy._phonopy as phonoc phonoc.distribute_fc2( force_constants, targets, rots_cartesian, permutations, np.array(map_atoms, dtype="intc"), np.array(map_syms, dtype="intc"), )
def _distribute_fc2_part(force_constants, positions, atom_disp, map_atom_disp, lattice, r, t, symprec): # L R L^-1 rot_cartesian = np.array(similarity_transformation(lattice, r), dtype='double', order='C') try: import phonopy._phonopy as phonoc phonoc.distribute_fc2(force_constants, positions, atom_disp, map_atom_disp, rot_cartesian, np.array(r, dtype='intc', order='C'), np.array(t, dtype='double'), symprec) except ImportError: for i, pos_i in enumerate(positions): rot_pos = np.dot(pos_i, r.T) + t rot_atom = -1 for j, pos_j in enumerate(positions): diff = pos_j - rot_pos if (abs(diff - np.rint(diff)) < symprec).all(): rot_atom = j break if rot_atom < 0: print 'Input forces are not enough to calculate force constants,' print 'or something wrong (e.g. crystal structure does not match).' raise ValueError # R^-1 P R (inverse transformation) force_constants[atom_disp, i] += similarity_transformation( rot_cartesian.T, force_constants[map_atom_disp, rot_atom])
def _distribute_fc2_part(force_constants, positions, atom_disp, map_atom_disp, lattice, # column vectors r, t, symprec): # L R L^-1 rot_cartesian = np.array( similarity_transformation(lattice, r), dtype='double', order='C') try: import phonopy._phonopy as phonoc phonoc.distribute_fc2(force_constants, lattice, positions, atom_disp, map_atom_disp, rot_cartesian, np.array(r, dtype='intc', order='C'), np.array(t, dtype='double'), symprec) except ImportError: for i, pos_i in enumerate(positions): rot_pos = np.dot(pos_i, r.T) + t rot_atom = -1 for j, pos_j in enumerate(positions): diff = pos_j - rot_pos diff -= np.rint(diff) diff = np.dot(diff, lattice.T) if np.linalg.norm(diff) < symprec: rot_atom = j break if rot_atom < 0: print("Input forces are not enough to calculate force constants,") print("or something wrong (e.g. crystal structure does not match).") raise ValueError # R^-1 P R (inverse transformation) force_constants[atom_disp, i] += similarity_transformation( rot_cartesian.T, force_constants[map_atom_disp, rot_atom])
def _distribute_fc2_part(force_constants, positions, atom_disp, map_atom_disp, rot_cartesian, r, t, symprec): try: raise ImportError import phonopy._phonopy as phonoc phonoc.distribute_fc2(force_constants, positions, atom_disp, map_atom_disp, rot_cartesian, r, t, symprec) except ImportError: for i, pos_i in enumerate(positions): rot_pos = np.dot(pos_i, r.T) + t rot_atom = -1 for j, pos_j in enumerate(positions): diff = pos_j - rot_pos if (abs(diff - np.rint(diff)) < symprec).all(): rot_atom = j break if rot_atom < 0: print 'Input forces are not enough to calculate force constants,' print 'or something wrong (e.g. crystal structure does not match).' raise ValueError # R^-1 P R (inverse transformation) # f1 = np.dot(np.kron(rot_cartesian.T, rot_cartesian.T), force_constants[map_atom_disp, rot_atom].flatten()).reshape(3,3) # f2= similarity_transformation(rot_cartesian.T,force_constants[map_atom_disp,rot_atom]) # diff=np.abs(f1-f2) # assert diff.max()<1e-7 force_constants[atom_disp, i] += similarity_transformation( rot_cartesian.T, force_constants[map_atom_disp, rot_atom])