From 3895c35f5ed275e22802f0b221c2301bf8ef6e73 Mon Sep 17 00:00:00 2001 From: chn Date: Tue, 3 Sep 2024 16:22:54 +0800 Subject: [PATCH] =?UTF-8?q?packages.ufo:=20=E7=BC=96=E5=86=99=E4=BE=8B?= =?UTF-8?q?=E5=AD=90=E7=9A=84=E5=89=8D=E4=B8=A4=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + flake.nix | 2 +- packages/ufo/.clangd | 3 - packages/ufo/example/3/INCAR | 33 +++++++++ packages/ufo/example/3/KPOINTS | 5 ++ packages/ufo/example/3/POSCAR | 103 +++++++++++++++++++++++++++++ packages/ufo/example/README.md | 90 +++++++++++++++++++++++++ packages/ufo/src/fold.cpp | 59 +++++++---------- packages/ufo/test/fold/config.yaml | 11 ++- packages/ufo/test/fold/output.yaml | 15 +++-- packages/ufo/test/unfold/README.md | 2 + 11 files changed, 279 insertions(+), 45 deletions(-) delete mode 100644 packages/ufo/.clangd create mode 100644 packages/ufo/example/3/INCAR create mode 100644 packages/ufo/example/3/KPOINTS create mode 100644 packages/ufo/example/3/POSCAR create mode 100644 packages/ufo/example/README.md create mode 100644 packages/ufo/test/unfold/README.md diff --git a/.gitignore b/.gitignore index 585943d8..4c8c34bf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ outputs build .vscode .cache +.ccls-cache diff --git a/flake.nix b/flake.nix index 86ba7dd7..971e8636 100644 --- a/flake.nix +++ b/flake.nix @@ -186,7 +186,7 @@ ufo = pkgs.mkShell.override { stdenv = pkgs.gcc14Stdenv; } { inputsFrom = [ (inputs.self.packages.x86_64-linux.ufo.override { version = null; }) ]; - packages = [ pkgs.clang-tools_18 ]; + packages = [ pkgs.ccls ]; CMAKE_EXPORT_COMPILE_COMMANDS = "1"; }; chn-bsub = pkgs.mkShell diff --git a/packages/ufo/.clangd b/packages/ufo/.clangd deleted file mode 100644 index 31d7203a..00000000 --- a/packages/ufo/.clangd +++ /dev/null @@ -1,3 +0,0 @@ -CompileFlags: - Add: [ -Wall, -Wextra, -std=c++26 ] - Compiler: g++ diff --git a/packages/ufo/example/3/INCAR b/packages/ufo/example/3/INCAR new file mode 100644 index 00000000..6193c62d --- /dev/null +++ b/packages/ufo/example/3/INCAR @@ -0,0 +1,33 @@ +# write many output files +LWAVE = F +LCHARG = F +LELF = F +LEPSILON = F +LCALCEPS = F + +# use high precision +PREC = Accurate +EDIFF = 1E-7 +EDIFFG = -1E-3 + +# enough ionic steps +NSW = 100 + +# calculate forces and stress tensor, and allow all degrees of freedom (atom positions, cell shape, and cell volume) +ISIF = 3 + +# use conjugate gradient algorithm to do ionic relaxation +IBRION = 2 + +# use Gaussian smearing to set partial occupancies for each orbital, commonly suggested +ISMEAR = 0 + +# use Vosko-Wilk-Nusair interpolation to enchange the estimation of magnetic moments and energies +VOSKOWN = 1 + +# set symmetry +ISYM = 2 + +# projection done in reciprocal space for small unit cells, +# in real space for large unit cells +LREAL = F diff --git a/packages/ufo/example/3/KPOINTS b/packages/ufo/example/3/KPOINTS new file mode 100644 index 00000000..18a8e579 --- /dev/null +++ b/packages/ufo/example/3/KPOINTS @@ -0,0 +1,5 @@ +3X3X3 + 0 +Gamma + 3 3 3 + 0 0 0 diff --git a/packages/ufo/example/3/POSCAR b/packages/ufo/example/3/POSCAR new file mode 100644 index 00000000..bd6ae3f8 --- /dev/null +++ b/packages/ufo/example/3/POSCAR @@ -0,0 +1,103 @@ +POSCAR file written by Ovito 3.7.11 +1 +9.2397000789 0.0 0.0 +0.0 10.6690864562 0.0 +0.0 0.0 10.0822000504 +Si C +48 47 +Direct +0.1666666667 0.083333336 0.25 +0.1666666567 0.4166666865 0.75 +0.0 0.0 0.0 +0.0 0.0 0.5 +0.0 0.3333333135 0.25 +0.0 0.1666666715 0.75 +0.1666666567 0.25 0.0 +0.1666666567 0.25 0.5 +0.1666666667 0.583333336 0.25 +0.1666666567 0.9166666865 0.75 +0.0 0.5 0.0 +0.0 0.5 0.5 +0.0 0.8333333135 0.25 +0.0 0.6666666715 0.75 +0.1666666567 0.75 0.0 +0.1666666567 0.75 0.5 +0.5 0.083333336 0.25 +0.49999999 0.4166666865 0.75 +0.3333333333 0.0 0.0 +0.3333333333 0.0 0.5 +0.3333333333 0.3333333135 0.25 +0.3333333333 0.1666666715 0.75 +0.49999999 0.25 0.0 +0.49999999 0.25 0.5 +0.5 0.583333336 0.25 +0.49999999 0.9166666865 0.75 +0.3333333333 0.5 0.0 +0.3333333333 0.5 0.5 +0.3333333333 0.8333333135 0.25 +0.3333333333 0.6666666715 0.75 +0.49999999 0.75 0.0 +0.49999999 0.75 0.5 +0.8333333333 0.083333336 0.25 +0.8333333233 0.4166666865 0.75 +0.6666666667 0.0 0.0 +0.6666666667 0.0 0.5 +0.6666666667 0.3333333135 0.25 +0.6666666667 0.1666666715 0.75 +0.8333333233 0.25 0.0 +0.8333333233 0.25 0.5 +0.8333333333 0.583333336 0.25 +0.8333333233 0.9166666865 0.75 +0.6666666667 0.5 0.0 +0.6666666667 0.5 0.5 +0.6666666667 0.8333333135 0.25 +0.6666666667 0.6666666715 0.75 +0.8333333233 0.75 0.0 +0.8333333233 0.75 0.5 +0.1666666667 0.083333336 0.435380012 +0.1666666567 0.4166666865 0.935379982 +0.0 0.0 0.189610004 +0.0 0.0 0.689610004 +0.0 0.3333333135 0.435380012 +0.0 0.1666666715 0.935379982 +0.1666666567 0.25 0.189610004 +0.1666666567 0.25 0.689610004 +0.1666666667 0.583333336 0.435380012 +0.1666666567 0.9166666865 0.935379982 +0.0 0.5 0.189610004 +0.0 0.5 0.689610004 +0.0 0.8333333135 0.435380012 +0.0 0.6666666715 0.935379982 +0.1666666567 0.75 0.189610004 +0.1666666567 0.75 0.689610004 +0.5 0.083333336 0.435380012 +0.49999999 0.4166666865 0.935379982 +0.3333333333 0.0 0.189610004 +0.3333333333 0.0 0.689610004 +0.3333333333 0.3333333135 0.435380012 +0.3333333333 0.1666666715 0.935379982 +0.49999999 0.25 0.189610004 +0.49999999 0.25 0.689610004 +0.5 0.583333336 0.435380012 +0.49999999 0.9166666865 0.935379982 +0.3333333333 0.5 0.189610004 +0.3333333333 0.5 0.689610004 +0.3333333333 0.8333333135 0.435380012 +0.3333333333 0.6666666715 0.935379982 +0.49999999 0.75 0.189610004 +0.49999999 0.75 0.689610004 +0.8333333333 0.083333336 0.435380012 +0.8333333233 0.4166666865 0.935379982 +0.6666666667 0.0 0.189610004 +0.6666666667 0.0 0.689610004 +0.6666666667 0.3333333135 0.435380012 +0.6666666667 0.1666666715 0.935379982 +0.8333333233 0.25 0.189610004 +0.8333333233 0.25 0.689610004 +0.8333333333 0.583333336 0.435380012 +0.8333333233 0.9166666865 0.935379982 +0.6666666667 0.5 0.189610004 +0.6666666667 0.5 0.689610004 +0.6666666667 0.8333333135 0.435380012 +0.6666666667 0.6666666715 0.935379982 +0.8333333233 0.75 0.189610004 diff --git a/packages/ufo/example/README.md b/packages/ufo/example/README.md new file mode 100644 index 00000000..60536cb6 --- /dev/null +++ b/packages/ufo/example/README.md @@ -0,0 +1,90 @@ +本例子演示,计算一个包含 95 个原子且带有一个 C 空位的 4H-SiC 超胞的声子谱,并将它近似反折叠到原胞(8 原子)的声子谱中。 +每一步用到的文件已经在当前目录中给出。简单起见,我们将仅仅计算 Gamma-M 线上的声子谱。 + +# 第一步:建立模型 + +我们首先准备一个 4H-SiC 原胞的模型,并将它弛豫: + +```{{ filename = "4H-SiC.in" }} +1.0 + 3.0799000263 0.0000000000 0.0000000000 + -1.5399500132 2.6672716639 0.0000000000 + 0.0000000000 0.0000000000 10.0822000504 + Si C + 4 4 +Direct + 0.333333343 0.666666687 0.250000000 + 0.666666627 0.333333313 0.750000000 + 0.000000000 0.000000000 0.000000000 + 0.000000000 0.000000000 0.500000000 + 0.333333343 0.666666687 0.435380012 + 0.666666627 0.333333313 0.935379982 + 0.000000000 0.000000000 0.189610004 + 0.000000000 0.000000000 0.689610004 +``` + +再准备一个含有 C 空位的 4H-SiC 超胞的模型。 +注意到超胞模型中已经被提前扣掉了一个 C 原子。 + +记下弛豫后的晶胞尺寸,稍后会用到。 + +TODO: 有必要弛豫原胞吗? + +```yaml +PrimitiveCell: + - [ 3.0799, 0, 0 ] + - [ -1.53995, 2.66727, 0 ] + - [ 0, 0, 10.0822 ] +SuperCell: + - [ 9.2397, 0, 0 ] + - [ -4.61985, 8.00181, 0 ] + - [ 0, 0, 10.0822 ] +``` + +# 第二步:计算超胞中的 Q 点坐标 + +为了得到原胞中 Gamma-M 线上的声子模式,我们需要计算超胞中哪些 Q 点处的模式? +这个问题不仅看上去似乎有些难以回答,而且实际上人手算起来也一点不简单。 +因此我写了功能来处理这个问题: + +```yaml +SuperCellMultiplier: [ 3, 4, 1 ] +SuperCellDeformation: + - [ 1, 0, 0 ] + - [ 0.66666, 1, 0 ] + - [ 0, 0, 1 ] +Qpoints: + - [0, 0, 0] + - [0.05, 0, 0] + - [0.1, 0, 0] + - [0.15, 0, 0] + - [0.2, 0, 0] + - [0.25, 0, 0] + - [0.3, 0, 0] + - [0.35, 0, 0] + - [0.4, 0, 0] + - [0.45, 0, 0] + - [0.5, 0, 0] +OutputFile: + Filename: fold-output.yaml + Format: yaml +``` + +得到: + +```yaml +Qpoints: + - [ 0.00000000, 0.00000000, 0.00000000 ] + - [ 0.15000000, 0.09999999, 0.00000000 ] + - [ 0.30000000, 0.19999998, 0.00000000 ] + - [ 0.45000000, 0.29999997, 0.00000000 ] + - [ 0.60000000, 0.39999996, 0.00000000 ] + - [ 0.75000000, 0.49999995, 0.00000000 ] + - [ 0.90000000, 0.59999994, 0.00000000 ] + - [ 0.05000000, 0.69999993, 0.00000000 ] + - [ 0.20000000, 0.79999992, 0.00000000 ] + - [ 0.35000000, 0.89999991, 0.00000000 ] + - [ 0.50000000, 0.99999990, 0.00000000 ] +``` + +大致在草稿纸上画个图,可以确认这个结果是合理的。 diff --git a/packages/ufo/src/fold.cpp b/packages/ufo/src/fold.cpp index fa7caf11..9a5cf1fd 100644 --- a/packages/ufo/src/fold.cpp +++ b/packages/ufo/src/fold.cpp @@ -5,18 +5,11 @@ namespace ufo FoldSolver::InputType::InputType(std::string config_file) { auto input = YAML::LoadFile(config_file); - for (unsigned i = 0; i < 3; i++) - SuperCellMultiplier(i) = input["SuperCellMultiplier"][i].as(); + SuperCellMultiplier = input["SuperCellMultiplier"].as>() | biu::toEigen<>; if (input["SuperCellDeformation"]) - { - SuperCellDeformation.emplace(); - for (unsigned i = 0; i < 3; i++) - for (unsigned j = 0; j < 3; j++) - (*SuperCellDeformation)(i, j) = input["SuperCellDeformation"][i][j].as(); - } - for (auto& qpoint : input["Qpoints"].as>>()) - Qpoints.push_back(Eigen::Vector3d - {{qpoint.at(0)}, {qpoint.at(1)}, {qpoint.at(2)}}); + SuperCellDeformation = input["SuperCellDeformation"].as, 3>>() | biu::toEigen<>; + for (auto& qpoint : input["Qpoints"].as>>()) + Qpoints.push_back(qpoint | biu::toEigen<>); OutputFile = DataFile(input["OutputFile"], {"yaml"}, config_file); } void FoldSolver::OutputType::write(std::string filename) const @@ -55,32 +48,28 @@ namespace ufo std::optional> super_cell_deformation ) { - // 首先需要将 q 点转移到 ModifiedSuperCell 的倒格子中 - // 将 q 点坐标扩大, 然后取小数部分, 就可以了 - auto qpoint_by_reciprocal_modified_super_cell = super_cell_multiplier.cast().asDiagonal() - * qpoint_in_reciprocal_primitive_cell_by_reciprocal_primitive_cell; - auto qpoint_in_reciprocal_modified_super_cell_by_reciprocal_modified_super_cell = - (qpoint_by_reciprocal_modified_super_cell.array() - qpoint_by_reciprocal_modified_super_cell.array().floor()) - .matrix(); - if (!super_cell_deformation) - return qpoint_in_reciprocal_modified_super_cell_by_reciprocal_modified_super_cell; /* - 对 q 点平移数个 SupreCell, 直到它落在超胞的倒格子中 - 这等价于直接将 q 点坐标用 SuperCell 的倒格子表示, 然后取小数部分. - ModifiedSuperCell = SuperCellMultiplier * PrimativeCell - SuperCell = SuperCellDeformation * ModifiedSuperCell - ReciprocalModifiedSuperCell = ModifiedSuperCell.inverse().transpose() - ReciprocalSuperCell = SuperCell.inverse().transpose() - Qpoint = QpointByReciprocalModifiedSuperCell.transpose() * ReciprocalModifiedSuperCell - Qpoint = QpointByReciprocalSuperCell.transpose() * ReciprocalSuperCell + 首先需要将 q 点坐标的单位转换为 ModifiedSuperCell 的格矢,可知: + QpointByReciprocalModifiedSuperCell = SuperCellMultiplier * QpointByReciprocalPrimitiveCell; + 接下来考虑将 q 点坐标的单位转换为 SuperCell 的格矢 + ModifiedSuperCell = SuperCellMultiplier * PrimativeCell; + SuperCell = SuperCellDeformation * ModifiedSuperCell; + ReciprocalModifiedSuperCell = ModifiedSuperCell.inverse().transpose(); + ReciprocalSuperCell = SuperCell.inverse().transpose(); + Qpoint = QpointByReciprocalModifiedSuperCell.transpose() * ReciprocalModifiedSuperCell; + Qpoint = QpointByReciprocalSuperCell.transpose() * ReciprocalSuperCell; 整理可以得到: - QpointByReciprocalSuperCell = SuperCellDeformation * QpointByReciprocalModifiedSuperCell + QpointByReciprocalSuperCell = SuperCellDeformation * QpointByReciprocalModifiedSuperCell; + 两个式子结合,可以得到: + QpointByReciprocalSuperCell = SuperCellDeformation * SuperCellMultiplier * QpointByReciprocalPrimitiveCell; */ - auto qpoint_in_reciprocal_modified_super_cell_by_reciprocal_super_cell = - (*super_cell_deformation * qpoint_in_reciprocal_modified_super_cell_by_reciprocal_modified_super_cell).eval(); - auto qpoint_in_reciprocal_super_cell_by_reciprocal_super_cell = - qpoint_in_reciprocal_modified_super_cell_by_reciprocal_super_cell.array() - - qpoint_in_reciprocal_modified_super_cell_by_reciprocal_super_cell.array().floor(); - return qpoint_in_reciprocal_super_cell_by_reciprocal_super_cell; + auto qpoint_by_reciprocal_super_cell = (super_cell_deformation.value_or(Eigen::Matrix3d::Identity()) + * super_cell_multiplier.cast().asDiagonal() + * qpoint_in_reciprocal_primitive_cell_by_reciprocal_primitive_cell).eval(); + /* + 到目前为止,我们还没有移动过 q 点的坐标。现在,我们将它移动整数个 ReciprocalSuperCell,直到它落在超胞的倒格子中。 + 这等价于直接取 QpointByReciprocalSuperCell - QpointByReciprocalSuperCell.floor()。 + */ + return (qpoint_by_reciprocal_super_cell.array() - qpoint_by_reciprocal_super_cell.array().floor()).matrix(); } } diff --git a/packages/ufo/test/fold/config.yaml b/packages/ufo/test/fold/config.yaml index d4065318..eb3f2652 100644 --- a/packages/ufo/test/fold/config.yaml +++ b/packages/ufo/test/fold/config.yaml @@ -1,10 +1,19 @@ -SuperCellMultiplier: [ 2, 2, 2 ] +SuperCellMultiplier: [ 3, 4, 1 ] +SuperCellDeformation: + - [ 1, 0, 0 ] + - [ 0.6666666, 1, 0 ] + - [ 0, 0, 1 ] Qpoints: - [0, 0, 0] + - [0.05, 0, 0] - [0.1, 0, 0] + - [0.15, 0, 0] - [0.2, 0, 0] + - [0.25, 0, 0] - [0.3, 0, 0] + - [0.35, 0, 0] - [0.4, 0, 0] + - [0.45, 0, 0] - [0.5, 0, 0] OutputFile: Filename: fold-output.yaml diff --git a/packages/ufo/test/fold/output.yaml b/packages/ufo/test/fold/output.yaml index 0e18a140..68a5e23d 100644 --- a/packages/ufo/test/fold/output.yaml +++ b/packages/ufo/test/fold/output.yaml @@ -1,7 +1,12 @@ Qpoints: - [ 0.00000000, 0.00000000, 0.00000000 ] - - [ 0.20000000, 0.00000000, 0.00000000 ] - - [ 0.40000000, 0.00000000, 0.00000000 ] - - [ 0.60000000, 0.00000000, 0.00000000 ] - - [ 0.80000000, 0.00000000, 0.00000000 ] - - [ 0.00000000, 0.00000000, 0.00000000 ] + - [ 0.15000000, 0.09999999, 0.00000000 ] + - [ 0.30000000, 0.19999998, 0.00000000 ] + - [ 0.45000000, 0.29999997, 0.00000000 ] + - [ 0.60000000, 0.39999996, 0.00000000 ] + - [ 0.75000000, 0.49999995, 0.00000000 ] + - [ 0.90000000, 0.59999994, 0.00000000 ] + - [ 0.05000000, 0.69999993, 0.00000000 ] + - [ 0.20000000, 0.79999992, 0.00000000 ] + - [ 0.35000000, 0.89999991, 0.00000000 ] + - [ 0.50000000, 0.99999990, 0.00000000 ] diff --git a/packages/ufo/test/unfold/README.md b/packages/ufo/test/unfold/README.md new file mode 100644 index 00000000..e89192c9 --- /dev/null +++ b/packages/ufo/test/unfold/README.md @@ -0,0 +1,2 @@ +在 4H-SiC 超胞中,存在一个 C 空位,计算它的声子。 +