Пример #1
0
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"),
    )
Пример #2
0
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])
Пример #3
0
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])
Пример #4
0
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])