pub fn phonopy_displacements(
    settings: &cfg::Phonons,
    prim_coords: &Coords,
    prim_meta: HList2<
        meta::SiteElements,
        meta::SiteMasses,
    >,
    sc: &SupercellToken,
    // supercell coordinates in rsp2's ordering convention, as created by `sc`
    our_super_coords: &Coords,
) -> FailResult<PhonopyDisplacements> {
    let displacement_distance = settings.displacement_distance.expect("(bug) missing displacement-distance should have been caught earlier");
    let symmetry_tolerance = settings.symmetry_tolerance.expect("(bug) missing symmetry-tolerance should have been caught earlier");
    let dir = {
        let mut builder = {
            builder::Builder::new()
                // HACK: Give phonopy a slightly smaller symprec to ensure that, in case
                // rsp2 and phonopy find different spacegroups, phonopy should find the
                // smaller one.
                .symmetry_tolerance(symmetry_tolerance * 0.99)
                .conf("DISPLACEMENT_DISTANCE", format!("{:e}", displacement_distance))
                .supercell_dim(settings.supercell.dim_for_unitcell(prim_coords.lattice()))
        };
        if let cfg::PhononDispFinder::Phonopy { diag } = settings.disp_finder {
            builder = builder.diagonal_disps(diag);
        }
        builder.displacements(prim_coords, prim_meta.sift())?
    };
    let sc_dims = sc.periods();
    assert_eq!(settings.supercell.dim_for_unitcell(prim_coords.lattice()), sc_dims);

    // cmon, big money, big money....
    // if these assertions always succeed, it will save us a
    // good deal of implementation work.
    let perm_from_phonopy;
    {
        let phonopy_super_coords = Poscar::load(dir.join("SPOSCAR"))?.coords;

        perm_from_phonopy = phonopy_super_coords.perm_to_match(&our_super_coords, 1e-10)?;

        // make phonopy match us
        let phonopy_super_coords = phonopy_super_coords.clone().permuted_by(&perm_from_phonopy);

        let err_msg = "\
            phonopy's superstructure does not match rsp2's conventions! \
            Unfortunately, support for this scenario is not yet implemented.\
        ";
        assert_close!(
            abs=1e-10,
            our_super_coords.lattice(), phonopy_super_coords.lattice(),
            "{}", err_msg,
        );
        let lattice = our_super_coords.lattice();
        let diffs = {
            zip_eq!(our_super_coords.to_carts(), phonopy_super_coords.to_carts())
                .map(|(a, b)| (a - b) / lattice)
                .map(|v| v.map(|x| x - x.round()))
                .map(|v| v * lattice)
                .collect::<Vec<_>>()
        };
        assert_close!(
            abs=1e-10,
            vec![[0.0; 3]; diffs.len()],
            diffs.unvee(),
            "{}", err_msg,
        );
    }

    let prim_displacements = {
        let primitive_atoms = sc.atom_primitive_atoms();
        dir.displacements().iter()
            .map(|&(phonopy_idx, disp)| {
                let our_super_idx = perm_from_phonopy.permute_index(phonopy_idx);
                let our_prim_idx = primitive_atoms[our_super_idx];
                (our_prim_idx, disp)
            })
            .collect::<Vec<_>>()
    };

    Ok(PhonopyDisplacements {
        prim_displacements,
        coperm_from_phonopy: perm_from_phonopy,
        phonopy_super_displacements: dir.displacements().to_vec(),
        spacegroup_op_count: dir.phonopy_sg_op_count()?,
    })
}
/// Produce a variety of data describing the displacements in terms of rsp2's conventions
/// (whereas most other methods on `DirWithDisps` use phonopy's conventions).
Produce a variety of data describing the displacements in terms of rsp2's conventions
(whereas most other methods on `DirWithDisps` use phonopy's conventions).
Produce a variety of data describing the displacements in terms of rsp2 ' s conventions ( whereas most other methods on ` DirWithDisps ` use phonopy ' s conventions ) .
pub fn phonopy_displacements(
    settings: &cfg::Phonons,
    prim_coords: &Coords,
    prim_meta: HList2<
        meta::SiteElements,
        meta::SiteMasses,
    >,
    sc: &SupercellToken,
    // supercell coordinates in rsp2's ordering convention, as created by `sc`
    our_super_coords: &Coords,
) -> FailResult<PhonopyDisplacements> {
    let displacement_distance = settings.displacement_distance.expect("(bug) missing displacement-distance should have been caught earlier");
    let symmetry_tolerance = settings.symmetry_tolerance.expect("(bug) missing symmetry-tolerance should have been caught earlier");
    let dir = {
        let mut builder = {
            builder::Builder::new()
                // HACK: Give phonopy a slightly smaller symprec to ensure that, in case
                // rsp2 and phonopy find different spacegroups, phonopy should find the
                // smaller one.
                .symmetry_tolerance(symmetry_tolerance * 0.99)
                .conf("DISPLACEMENT_DISTANCE", format!("{:e}", displacement_distance))
                .supercell_dim(settings.supercell.dim_for_unitcell(prim_coords.lattice()))
        };
        if let cfg::PhononDispFinder::Phonopy { diag } = settings.disp_finder {
            builder = builder.diagonal_disps(diag);
        }
        builder.displacements(prim_coords, prim_meta.sift())?
    };
    let sc_dims = sc.periods();
    assert_eq!(settings.supercell.dim_for_unitcell(prim_coords.lattice()), sc_dims);
    // cmon, big money, big money....
    // if these assertions always succeed, it will save us a
    // good deal of implementation work.
    let perm_from_phonopy;
    {
        let phonopy_super_coords = Poscar::load(dir.join("SPOSCAR"))?.coords;
        perm_from_phonopy = phonopy_super_coords.perm_to_match(&our_super_coords, 1e-10)?;
        // make phonopy match us
        let phonopy_super_coords = phonopy_super_coords.clone().permuted_by(&perm_from_phonopy);
        let err_msg = "\
            phonopy's superstructure does not match rsp2's conventions! \
            Unfortunately, support for this scenario is not yet implemented.\
        ";
        assert_close!(
            abs=1e-10,
            our_super_coords.lattice(), phonopy_super_coords.lattice(),
            "{}", err_msg,
        );
        let lattice = our_super_coords.lattice();
        let diffs = {
            zip_eq!(our_super_coords.to_carts(), phonopy_super_coords.to_carts())
                .map(|(a, b)| (a - b) / lattice)
                .map(|v| v.map(|x| x - x.round()))
                .map(|v| v * lattice)
                .collect::<Vec<_>>()
        };
        assert_close!(
            abs=1e-10,
            vec![[0.0; 3]; diffs.len()],
            diffs.unvee(),
            "{}", err_msg,
        );
    }
    let prim_displacements = {
        let primitive_atoms = sc.atom_primitive_atoms();
        dir.displacements().iter()
            .map(|&(phonopy_idx, disp)| {
                let our_super_idx = perm_from_phonopy.permute_index(phonopy_idx);
                let our_prim_idx = primitive_atoms[our_super_idx];
                (our_prim_idx, disp)
            })
            .collect::<Vec<_>>()
    };
    Ok(PhonopyDisplacements {
        prim_displacements,
        coperm_from_phonopy: perm_from_phonopy,
        phonopy_super_displacements: dir.displacements().to_vec(),
        spacegroup_op_count: dir.phonopy_sg_op_count()?,
    })
}
pub fn phonopy_displacements ( settings : & cfg :: Phonons , prim_coords : & Coords , prim_meta : HList2 < meta :: SiteElements , meta :: SiteMasses , > , sc : & SupercellToken , // supercell coordinates in rsp2's ordering convention, as created by `sc` our_super_coords : & Coords , ) -> FailResult < PhonopyDisplacements > { let displacement_distance = settings . displacement_distance . expect ( " " ) ; let symmetry_tolerance = settings . symmetry_tolerance . expect ( " " ) ; let dir = { let mut builder = { builder :: Builder :: new ( ) // HACK: Give phonopy a slightly smaller symprec to ensure that, in case // rsp2 and phonopy find different spacegroups, phonopy should find the // smaller one. . symmetry_tolerance ( symmetry_tolerance * 0.99 ) . conf ( " " , format ! ( " " displacement_distance ) ) . supercell_dim ( settings . supercell . dim_for_unitcell ( prim_coords . lattice ( ) ) ) } ; if let cfg :: PhononDispFinder :: Phonopy { diag } = settings . disp_finder { builder = builder . diagonal_disps ( diag ) ; } builder . displacements ( prim_coords , prim_meta . sift ( ) ) ? } ; let sc_dims = sc . periods ( ) ; assert_eq ! ( settings supercell dim_for_unitcell ( prim_coords lattice ( ) ) sc_dims ) ; // cmon, big money, big money.... // if these assertions always succeed, it will save us a // good deal of implementation work. let perm_from_phonopy ; { let phonopy_super_coords = Poscar :: load ( dir . join ( " " ) ) ? . coords ; perm_from_phonopy = phonopy_super_coords . perm_to_match ( & our_super_coords , 1e-10 ) ? ; // make phonopy match us let phonopy_super_coords = phonopy_super_coords . clone ( ) . permuted_by ( & perm_from_phonopy ) ; let err_msg = " \
 \
 \
 " ; assert_close ! ( abs 1e-10 our_super_coords lattice ( ) phonopy_super_coords lattice ( ) " " err_msg ) ; let lattice = our_super_coords . lattice ( ) ; let diffs = { zip_eq ! ( our_super_coords to_carts ( ) phonopy_super_coords to_carts ( ) ) . map ( | ( a , b ) | ( a - b ) / lattice ) . map ( | v | v . map ( | x | x - x . round ( ) ) ) . map ( | v | v * lattice ) . collect :: < Vec < _ > > ( ) } ; assert_close ! ( abs 1e-10 vec [ [ 0.0 3 ] diffs len ( ) ] diffs unvee ( ) " " err_msg ) ; } let prim_displacements = { let primitive_atoms = sc . atom_primitive_atoms ( ) ; dir . displacements ( ) . iter ( ) . map ( | & ( phonopy_idx , disp ) | { let our_super_idx = perm_from_phonopy . permute_index ( phonopy_idx ) ; let our_prim_idx = primitive_atoms [ our_super_idx ] ; ( our_prim_idx , disp ) } ) . collect :: < Vec < _ > > ( ) } ; Ok ( PhonopyDisplacements { prim_displacements , coperm_from_phonopy : perm_from_phonopy , phonopy_super_displacements : dir . displacements ( ) . to_vec ( ) , spacegroup_op_count : dir . phonopy_sg_op_count ( ) ? , } ) }
Produce a variety of data describing the displacements in terms of rsp2's conventions
(whereas most other methods on `DirWithDisps` use phonopy's conventions).
Produce a variety of data describing the displacements in terms of rsp2 ' s conventions ( whereas most other methods on ` DirWithDisps ` use phonopy ' s conventions ) .
settings
&cfg::Phonons
prim_coords
&Coords
prim_meta
HList2<
        meta::SiteElements,
        meta::SiteMasses,
    >
sc
&SupercellToken
our_super_coords
&Coords
settings
&cfg::Phonons
prim_coords
&Coords
prim_meta
HList2<
        meta::SiteElements,
        meta::SiteMasses,
    >
sc
&SupercellToken
our_super_coords
&Coords