diff --git a/src/project-to-mode.cpp b/src/project-to-mode.cpp index 022f0b9..09fa3af 100644 --- a/src/project-to-mode.cpp +++ b/src/project-to-mode.cpp @@ -3,11 +3,12 @@ void ufo::project_to_mode(std::string config_file) { // 将选定的超胞中的某一个 q 点上的每一个模式到反折叠后的某个 q 点的投影,投射到单胞中的对应 q 点的模式上 - + // 与 unfold 的方法类似,只有一个重要的区别: + // 组成基矢的平面波的波矢的两个部分中,第二个部分不再需要。因为这个部分的结果已经算出来了,只需要将结果乘上 WeightOnUnfold 即可。 struct Config { // 在单胞内取几个平面波的基矢 - Eigen::Vector PrimativeCellBasisNumber; + Eigen::Vector3i PrimativeCellBasisNumber; // 要选定的超胞中的 q 点,sub qpoint,以及单胞中的 q 点 std::size_t SuperQpointIndex, SubQpointIndex, PrimativeQpointIndex; // 输入输出文件的路径,直接输出 yaml,因为这些数据不再需要后处理 @@ -38,18 +39,16 @@ void ufo::project_to_mode(std::string config_file) auto primative_basis = [&] { biu::Logger::Guard log; - std::vector basis(config.PrimativeCellBasisNumber.array().prod()); - for (auto [xyz_of_basis, i_of_basis] - : biu::sequence(config.PrimativeCellBasisNumber)) + std::vector basis((config.PrimativeCellBasisNumber.array() * 2 - 1).prod()); + for (auto [xyz_of_basis, i_of_basis] : biu::sequence + ((-config.PrimativeCellBasisNumber + Eigen::Vector3i::Ones()).eval(), config.PrimativeCellBasisNumber)) { // 波矢就是 xyz_of_basis, 单位为单胞的倒格矢 // 将它的单位转换成埃^-1 auto wavevector = - (xyz_of_basis.transpose().cast() * input.Primative.Cell.inverse().transpose()).transpose().eval(); - log.debug("xyz_of_basis: {}"_f(xyz_of_basis)); - log.debug("wavevector: {:.3f}"_f(fmt::join(wavevector, ", "))); + (xyz_of_basis.transpose().cast() * input.Primative.Cell.inverse().transpose()).transpose(); // 将原子坐标单位也转换为埃 - auto atom_position = (input.Primative.AtomPosition * input.Primative.Cell).eval(); + auto atom_position = input.Primative.AtomPosition * input.Primative.Cell; // 计算基矢 basis[i_of_basis] = (2i * std::numbers::pi_v * (atom_position * wavevector)).array().exp(); } @@ -59,7 +58,7 @@ void ufo::project_to_mode(std::string config_file) auto super_basis = [&] { biu::Logger::Guard log; - std::vector basis(config.PrimativeCellBasisNumber.array().prod()); + std::vector basis((config.PrimativeCellBasisNumber.array() * 2 - 1).prod()); auto diff_of_sub_qpoint_by_reciprocal_modified_super_cell = [&] { for @@ -70,23 +69,21 @@ void ufo::project_to_mode(std::string config_file) if (i_of_sub_qpoint == config.SubQpointIndex) return diff_of_sub_qpoint_by_reciprocal_modified_super_cell; std::unreachable(); }(); - log.debug("diff_of_sub_qpoint_by_reciprocal_modified_super_cell: {}"_f - (diff_of_sub_qpoint_by_reciprocal_modified_super_cell)); - for (auto [xyz_of_basis, i_of_basis] - : biu::sequence(config.PrimativeCellBasisNumber.cast().eval())) + for (auto [xyz_of_basis, i_of_basis] : biu::sequence + ((-config.PrimativeCellBasisNumber + Eigen::Vector3i::Ones()).eval(), config.PrimativeCellBasisNumber)) { // 计算波矢, 单位为单胞的倒格矢 auto wavevector_by_reciprocal_primative_cell = xyz_of_basis.cast() + input.Super.CellMultiplier.cast().cwiseInverse().asDiagonal() * diff_of_sub_qpoint_by_reciprocal_modified_super_cell.cast(); // 将单位转换为埃^-1 - auto wavevector = input.Primative.Cell.inverse() * wavevector_by_reciprocal_primative_cell; - log.debug("wavevector: {}"_f(wavevector)); + auto wavevector = + (wavevector_by_reciprocal_primative_cell.transpose() * input.Primative.Cell.inverse().transpose()).transpose(); // 将原子坐标单位也转换为埃 auto atom_translation = (input.Super.AtomTranslation.value_or(std::array{0., 0., 0.}) | biu::toEigen<>) .transpose().replicate(input.Super.AtomPosition.rows(), 1).eval(); - Eigen::MatrixX3d atom_position = (input.Super.AtomPosition - atom_translation) + auto atom_position = (input.Super.AtomPosition - atom_translation) * (input.Super.CellDeformation * input.Super.CellMultiplier.cast().asDiagonal() * input.Primative.Cell); // 计算基矢 basis[i_of_basis] = (2i * std::numbers::pi_v * (atom_position * wavevector)).array().exp(); diff --git a/src/unfold.cpp b/src/unfold.cpp index b6e66e8..d3a8b76 100644 --- a/src/unfold.cpp +++ b/src/unfold.cpp @@ -31,7 +31,7 @@ void ufo::unfold(std::string config_file) std::optional> AtomTranslation; // 在单胞内取几个平面波的基矢 - Eigen::Vector PrimativeCellBasisNumber; + Eigen::Vector3i PrimativeCellBasisNumber; // 单胞的 phonopy 输出的 phonopy.yaml,用来读入单胞的晶格、原子坐标、原子类型、原子质量 std::string PrimativePhonopy; @@ -95,7 +95,7 @@ void ufo::unfold(std::string config_file) for (auto l : std::views::iota(0u, 3u)) eigenvector(k, l) = eigenvector_vector[i][k * 3 + l][j]; // 原则上讲,需要对读入的原子运动状态作相位转换, 使得它们与我们的约定一致(对超胞周期性重复),但这个转换 phonopy 已经做了 - // 这里还要需要做归一化处理 (指将数据简单地作为向量处理的归一化) + // 这里还要需要做归一化处理 (指将数据简单地作为向量处理的归一化),但似乎 phonopy 也已经做了,但我们也再做一次,也没什么坏处 data.Qpoint[i].Mode[j].EigenVector = eigenvector / eigenvector.norm(); } } @@ -130,7 +130,7 @@ void ufo::unfold(std::string config_file) auto construct_basis = [] ( Eigen::Matrix3d primative_cell, Eigen::Vector3i super_cell_multiplier, - Eigen::Vector primative_cell_basis_number, Eigen::MatrixX3d atom_position + Eigen::Vector3i primative_cell_basis_number, Eigen::MatrixX3d atom_position ) { biu::Logger::Guard log; @@ -139,16 +139,17 @@ void ufo::unfold(std::string config_file) for (auto [diff_of_sub_qpoint_by_reciprocal_modified_super_cell, i_of_sub_qpoint] : biu::sequence(super_cell_multiplier)) { - basis[i_of_sub_qpoint].resize(primative_cell_basis_number.prod()); - for (auto [xyz_of_basis, i_of_basis] - : biu::sequence(primative_cell_basis_number)) + basis[i_of_sub_qpoint].resize((primative_cell_basis_number.array() * 2 - 1).prod()); + for (auto [xyz_of_basis, i_of_basis] : biu::sequence + ((-primative_cell_basis_number + Eigen::Vector3i::Ones()).eval(), primative_cell_basis_number)) { // 计算波矢, 单位为单胞的倒格矢 auto wavevector_by_reciprocal_primative_cell = xyz_of_basis.cast() + super_cell_multiplier.cast().cwiseInverse().asDiagonal() * diff_of_sub_qpoint_by_reciprocal_modified_super_cell.cast(); // 将单位转换为埃^-1 - auto wavevector = primative_cell.inverse() * wavevector_by_reciprocal_primative_cell; + auto wavevector = + (wavevector_by_reciprocal_primative_cell.transpose() * primative_cell.inverse().transpose()).transpose(); // 计算基矢 basis[i_of_sub_qpoint][i_of_basis] = (2i * std::numbers::pi_v * (atom_position * wavevector)).array().exp(); @@ -257,7 +258,7 @@ void ufo::unfold(std::string config_file) log.info("Done."); std::clog << "Calculating projection coefficient... " << std::flush; - // 将所有模式放到一维来处理 + // 将所有q点的模式flatten一下,放到一个一维数组中,方便并行计算 { auto modes = output.Super.Qpoint | ranges::views::transform([](const auto& qpoint) diff --git a/test/project-to-atom/input.zpp b/test/project-to-atom/input.zpp index 321c74e..aec9d5f 100644 --- a/test/project-to-atom/input.zpp +++ b/test/project-to-atom/input.zpp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee28fae9b62c0c1f754294a662ba81e7de0e32cd09b8c60db1aae274b8522765 +oid sha256:e4847d0aeb4df342436b028b2acafa9b3f9c51cfb6527402a624ab82af84ae5b size 2921536 diff --git a/test/project-to-mode/data.zpp b/test/project-to-mode/data.zpp index 321c74e..aec9d5f 100644 --- a/test/project-to-mode/data.zpp +++ b/test/project-to-mode/data.zpp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee28fae9b62c0c1f754294a662ba81e7de0e32cd09b8c60db1aae274b8522765 +oid sha256:e4847d0aeb4df342436b028b2acafa9b3f9c51cfb6527402a624ab82af84ae5b size 2921536 diff --git a/test/raman-apply-contribution/data.zpp b/test/raman-apply-contribution/data.zpp index 321c74e..aec9d5f 100644 --- a/test/raman-apply-contribution/data.zpp +++ b/test/raman-apply-contribution/data.zpp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee28fae9b62c0c1f754294a662ba81e7de0e32cd09b8c60db1aae274b8522765 +oid sha256:e4847d0aeb4df342436b028b2acafa9b3f9c51cfb6527402a624ab82af84ae5b size 2921536 diff --git a/test/raman-create-displacement/data.zpp b/test/raman-create-displacement/data.zpp index 321c74e..aec9d5f 100644 --- a/test/raman-create-displacement/data.zpp +++ b/test/raman-create-displacement/data.zpp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee28fae9b62c0c1f754294a662ba81e7de0e32cd09b8c60db1aae274b8522765 +oid sha256:e4847d0aeb4df342436b028b2acafa9b3f9c51cfb6527402a624ab82af84ae5b size 2921536 diff --git a/test/zpp-to-yaml/data.zpp b/test/zpp-to-yaml/data.zpp index 321c74e..aec9d5f 100644 --- a/test/zpp-to-yaml/data.zpp +++ b/test/zpp-to-yaml/data.zpp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee28fae9b62c0c1f754294a662ba81e7de0e32cd09b8c60db1aae274b8522765 +oid sha256:e4847d0aeb4df342436b028b2acafa9b3f9c51cfb6527402a624ab82af84ae5b size 2921536