From bf3c8430ed419bf98105b82054517914ea2748b3 Mon Sep 17 00:00:00 2001 From: chn Date: Tue, 3 Dec 2024 17:56:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/ufo.hpp | 3 ++- src/project-to-mode.cpp | 42 +++++++++++++++++++++++--------- src/unfold.cpp | 2 ++ test/project-to-mode/config.yaml | 2 +- test/project-to-mode/data.zpp | 4 +-- test/unfold/config.yaml | 1 + test/zpp-to-yaml/data.zpp | 4 +-- 7 files changed, 40 insertions(+), 18 deletions(-) diff --git a/include/ufo.hpp b/include/ufo.hpp index 7bde046..30966f9 100644 --- a/include/ufo.hpp +++ b/include/ufo.hpp @@ -59,6 +59,7 @@ namespace ufo Eigen::Matrix3d CellDeformation; std::vector> AtomType; Eigen::MatrixX3d AtomPosition; + std::optional> AtomTranslation; struct QpointType { Eigen::Vector3d Qpoint; @@ -77,7 +78,7 @@ namespace ufo using serialize = zpp::bits::members<3>; }; std::vector Qpoint; - using serialize = zpp::bits::members<6>; + using serialize = zpp::bits::members<7>; } Super; // 选择的原子 diff --git a/src/project-to-mode.cpp b/src/project-to-mode.cpp index 0737b71..326646b 100644 --- a/src/project-to-mode.cpp +++ b/src/project-to-mode.cpp @@ -29,7 +29,7 @@ void ufo::project_to_mode(std::string config_file) .SubQpoint = input.Super.Qpoint[config.SuperQpointIndex].SubQpoint[config.SubQpointIndex], .PrimativeQpoint = input.Primative.Qpoint[config.PrimativeQpointIndex].Qpoint, .Coefficient = std::vector>(input.Super.Qpoint[config.SuperQpointIndex].Mode.size(), - std::vector(input.Primative.Qpoint[config.PrimativeQpointIndex].Mode.size())) + std::vector(input.Primative.Qpoint[config.PrimativeQpointIndex].Mode.size(), 0)) }; if ((output.SubQpoint - output.PrimativeQpoint).norm() > 0.01) log.error("sub qpoint {} != primative qpoint {}"_f(output.SubQpoint, output.PrimativeQpoint)); @@ -38,19 +38,25 @@ void ufo::project_to_mode(std::string config_file) auto primative_basis = [&] { biu::Logger::Guard log; - std::vector basis(config.PrimativeCellBasisNumber.prod()); + std::vector basis((config.PrimativeCellBasisNumber.array() * 2 - 1).prod()); for (auto [xyz_of_basis, i_of_basis] - : biu::sequence(config.PrimativeCellBasisNumber)) + : biu::sequence + ( + (-config.PrimativeCellBasisNumber.cast().array() + 1).matrix().eval(), + config.PrimativeCellBasisNumber.cast().eval() + )) { // 波矢就是 xyz_of_basis, 单位为单胞的倒格矢 // 将它的单位转换成埃^-1 - auto wavevector = input.Primative.Cell.inverse() * xyz_of_basis.cast(); + Eigen::Vector3cd wavevector = input.Primative.Cell.inverse() * xyz_of_basis.cast(); log.debug("xyz_of_basis: {}"_f(xyz_of_basis)); log.debug("wavevector: {:.3f}"_f(fmt::join(wavevector, ", "))); // 将原子坐标单位也转换为埃 - auto atom_position = input.Primative.AtomPosition * input.Primative.Cell; + Eigen::MatrixX3d atom_position = input.Primative.AtomPosition * input.Primative.Cell; + log.debug("first atom: {}"_f(atom_position.row(0))); // 计算基矢 basis[i_of_basis] = (2i * std::numbers::pi_v * (atom_position * wavevector)).array().exp(); + if (i_of_basis == 1) log.debug("basis: {}"_f(basis[i_of_basis])); } return basis; }(); @@ -58,7 +64,7 @@ void ufo::project_to_mode(std::string config_file) auto super_basis = [&] { biu::Logger::Guard log; - std::vector basis(config.PrimativeCellBasisNumber.prod()); + std::vector basis((config.PrimativeCellBasisNumber.array() * 2 - 1).prod()); auto diff_of_sub_qpoint_by_reciprocal_modified_super_cell = [&] { for @@ -72,19 +78,30 @@ void ufo::project_to_mode(std::string config_file) 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)) + : biu::sequence + ( + (-config.PrimativeCellBasisNumber.cast().array() + 1).matrix().eval(), + config.PrimativeCellBasisNumber.cast().eval() + )) { // 计算波矢, 单位为单胞的倒格矢 - auto wavevector_by_reciprocal_primative_cell = xyz_of_basis.cast() + Eigen::Vector3cd 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; + Eigen::Vector3cd wavevector = input.Primative.Cell.inverse() * wavevector_by_reciprocal_primative_cell; + log.debug("wavevector: {}"_f(wavevector)); // 将原子坐标单位也转换为埃 - auto atom_position = input.Super.AtomPosition + Eigen::MatrixX3d atom_position = input.Super.AtomPosition * (input.Super.CellDeformation * input.Super.CellMultiplier.cast().asDiagonal() * input.Primative.Cell); + log.debug("first atom: {}"_f(atom_position.row(0))); // 计算基矢 - basis[i_of_basis] = (2i * std::numbers::pi_v * (atom_position * wavevector)).array().exp(); + basis[i_of_basis] = + ( + 2i * std::numbers::pi_v * + ((atom_position - (input.Super.AtomTranslation.value_or(std::array{0, 0, 0}) | biu::toEigen<>).transpose().replicate(atom_position.rows(), 1) ) * wavevector) + ).array().exp(); + if (i_of_basis == 1) log.debug("basis: {}"_f(basis[i_of_basis])); } return basis; }(); @@ -94,12 +111,13 @@ void ufo::project_to_mode(std::string config_file) | ranges::views::transform([&](const auto& mode) { return primative_basis - | ranges::views::transform([&](const auto& basis) + | ranges::views::transform([&](const auto& basis) -> std::array, 3> { return (basis.transpose().conjugate() * mode.EigenVector).eval() | biu::fromEigen; }) | ranges::to_vector | biu::toEigen<>; }) | ranges::to_vector; + log.debug("primitive_projection_coefficient: {}"_f(nameof::nameof_full_type())); for (auto i_of_primative_mode : std::views::iota(0u, primative_projection_coefficient.size())) for (auto i_of_direction : std::array{0, 1, 2}) { diff --git a/src/unfold.cpp b/src/unfold.cpp index d8ffcbd..b6e66e8 100644 --- a/src/unfold.cpp +++ b/src/unfold.cpp @@ -28,6 +28,7 @@ void ufo::unfold(std::string config_file) // = ReciprocalPositionToPrimativeCell(line vector) * ReciprocalPrimativeCell Eigen::Vector3i SuperCellMultiplier; Eigen::Matrix3d SuperCellDeformation; + std::optional> AtomTranslation; // 在单胞内取几个平面波的基矢 Eigen::Vector PrimativeCellBasisNumber; @@ -202,6 +203,7 @@ void ufo::unfold(std::string config_file) (config.SuperPhonopy, config.SuperQpoint, output.Super)); output.Super.CellDeformation = config.SuperCellDeformation; output.Super.CellMultiplier = config.SuperCellMultiplier; + output.Super.AtomTranslation = config.AtomTranslation; // 填充 SubQpoint for (auto i_of_super_qpoint : std::views::iota(0u, output.Super.Qpoint.size())) for diff --git a/test/project-to-mode/config.yaml b/test/project-to-mode/config.yaml index f7842e1..ac34bf8 100644 --- a/test/project-to-mode/config.yaml +++ b/test/project-to-mode/config.yaml @@ -1,4 +1,4 @@ -PrimativeCellBasisNumber: [ 16, 16, 16 ] +PrimativeCellBasisNumber: [ 4, 4, 4 ] SuperQpointIndex: 0 SubQpointIndex: 0 PrimativeQpointIndex: 0 diff --git a/test/project-to-mode/data.zpp b/test/project-to-mode/data.zpp index 65ce6cd..321c74e 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:b1d66dad782f3070af08e8eb1357aa81b4d37404a3ac189df8d92cf6fba8587d -size 2921511 +oid sha256:ee28fae9b62c0c1f754294a662ba81e7de0e32cd09b8c60db1aae274b8522765 +size 2921536 diff --git a/test/unfold/config.yaml b/test/unfold/config.yaml index e6e2ef4..e7ef16a 100644 --- a/test/unfold/config.yaml +++ b/test/unfold/config.yaml @@ -3,6 +3,7 @@ SuperCellDeformation: - [ 1, 0, 0 ] - [ 0.5, 1, 0 ] - [ 0, 0, 1 ] +AtomTranslation: [ 0, 0, 5.0548836 ] PrimativeCellBasisNumber: [ 8, 8, 8 ] PrimativePhonopy: primitive-phonopy.yaml PrimativeQpoint: primitive-band.hdf5 diff --git a/test/zpp-to-yaml/data.zpp b/test/zpp-to-yaml/data.zpp index 65ce6cd..321c74e 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:b1d66dad782f3070af08e8eb1357aa81b4d37404a3ac189df8d92cf6fba8587d -size 2921511 +oid sha256:ee28fae9b62c0c1f754294a662ba81e7de0e32cd09b8c60db1aae274b8522765 +size 2921536