packages.ufo: 编写例子的前两步

This commit is contained in:
陈浩南 2024-09-03 16:22:54 +08:00
parent 1c4a3eea53
commit 3895c35f5e
11 changed files with 279 additions and 45 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ outputs
build build
.vscode .vscode
.cache .cache
.ccls-cache

View File

@ -186,7 +186,7 @@
ufo = pkgs.mkShell.override { stdenv = pkgs.gcc14Stdenv; } ufo = pkgs.mkShell.override { stdenv = pkgs.gcc14Stdenv; }
{ {
inputsFrom = [ (inputs.self.packages.x86_64-linux.ufo.override { version = null; }) ]; inputsFrom = [ (inputs.self.packages.x86_64-linux.ufo.override { version = null; }) ];
packages = [ pkgs.clang-tools_18 ]; packages = [ pkgs.ccls ];
CMAKE_EXPORT_COMPILE_COMMANDS = "1"; CMAKE_EXPORT_COMPILE_COMMANDS = "1";
}; };
chn-bsub = pkgs.mkShell chn-bsub = pkgs.mkShell

View File

@ -1,3 +0,0 @@
CompileFlags:
Add: [ -Wall, -Wextra, -std=c++26 ]
Compiler: g++

View File

@ -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

View File

@ -0,0 +1,5 @@
3X3X3
0
Gamma
3 3 3
0 0 0

View File

@ -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

View File

@ -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 ]
```
大致在草稿纸上画个图,可以确认这个结果是合理的。

View File

@ -5,18 +5,11 @@ namespace ufo
FoldSolver::InputType::InputType(std::string config_file) FoldSolver::InputType::InputType(std::string config_file)
{ {
auto input = YAML::LoadFile(config_file); auto input = YAML::LoadFile(config_file);
for (unsigned i = 0; i < 3; i++) SuperCellMultiplier = input["SuperCellMultiplier"].as<std::array<unsigned, 3>>() | biu::toEigen<>;
SuperCellMultiplier(i) = input["SuperCellMultiplier"][i].as<unsigned>();
if (input["SuperCellDeformation"]) if (input["SuperCellDeformation"])
{ SuperCellDeformation = input["SuperCellDeformation"].as<std::array<std::array<double, 3>, 3>>() | biu::toEigen<>;
SuperCellDeformation.emplace(); for (auto& qpoint : input["Qpoints"].as<std::vector<std::array<double, 3>>>())
for (unsigned i = 0; i < 3; i++) Qpoints.push_back(qpoint | biu::toEigen<>);
for (unsigned j = 0; j < 3; j++)
(*SuperCellDeformation)(i, j) = input["SuperCellDeformation"][i][j].as<double>();
}
for (auto& qpoint : input["Qpoints"].as<std::vector<std::vector<double>>>())
Qpoints.push_back(Eigen::Vector3d
{{qpoint.at(0)}, {qpoint.at(1)}, {qpoint.at(2)}});
OutputFile = DataFile(input["OutputFile"], {"yaml"}, config_file); OutputFile = DataFile(input["OutputFile"], {"yaml"}, config_file);
} }
void FoldSolver::OutputType::write(std::string filename) const void FoldSolver::OutputType::write(std::string filename) const
@ -55,32 +48,28 @@ namespace ufo
std::optional<Eigen::Matrix<double, 3, 3>> super_cell_deformation std::optional<Eigen::Matrix<double, 3, 3>> super_cell_deformation
) )
{ {
// 首先需要将 q 点转移到 ModifiedSuperCell 的倒格子中
// 将 q 点坐标扩大, 然后取小数部分, 就可以了
auto qpoint_by_reciprocal_modified_super_cell = super_cell_multiplier.cast<double>().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 ModifiedSuperCell
q SuperCell , . QpointByReciprocalModifiedSuperCell = SuperCellMultiplier * QpointByReciprocalPrimitiveCell;
ModifiedSuperCell = SuperCellMultiplier * PrimativeCell q SuperCell
SuperCell = SuperCellDeformation * ModifiedSuperCell ModifiedSuperCell = SuperCellMultiplier * PrimativeCell;
ReciprocalModifiedSuperCell = ModifiedSuperCell.inverse().transpose() SuperCell = SuperCellDeformation * ModifiedSuperCell;
ReciprocalSuperCell = SuperCell.inverse().transpose() ReciprocalModifiedSuperCell = ModifiedSuperCell.inverse().transpose();
Qpoint = QpointByReciprocalModifiedSuperCell.transpose() * ReciprocalModifiedSuperCell ReciprocalSuperCell = SuperCell.inverse().transpose();
Qpoint = QpointByReciprocalSuperCell.transpose() * ReciprocalSuperCell 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 = auto qpoint_by_reciprocal_super_cell = (super_cell_deformation.value_or(Eigen::Matrix3d::Identity())
(*super_cell_deformation * qpoint_in_reciprocal_modified_super_cell_by_reciprocal_modified_super_cell).eval(); * super_cell_multiplier.cast<double>().asDiagonal()
auto qpoint_in_reciprocal_super_cell_by_reciprocal_super_cell = * qpoint_in_reciprocal_primitive_cell_by_reciprocal_primitive_cell).eval();
qpoint_in_reciprocal_modified_super_cell_by_reciprocal_super_cell.array() /*
- qpoint_in_reciprocal_modified_super_cell_by_reciprocal_super_cell.array().floor(); q ReciprocalSuperCell
return qpoint_in_reciprocal_super_cell_by_reciprocal_super_cell; QpointByReciprocalSuperCell - QpointByReciprocalSuperCell.floor()
*/
return (qpoint_by_reciprocal_super_cell.array() - qpoint_by_reciprocal_super_cell.array().floor()).matrix();
} }
} }

View File

@ -1,10 +1,19 @@
SuperCellMultiplier: [ 2, 2, 2 ] SuperCellMultiplier: [ 3, 4, 1 ]
SuperCellDeformation:
- [ 1, 0, 0 ]
- [ 0.6666666, 1, 0 ]
- [ 0, 0, 1 ]
Qpoints: Qpoints:
- [0, 0, 0] - [0, 0, 0]
- [0.05, 0, 0]
- [0.1, 0, 0] - [0.1, 0, 0]
- [0.15, 0, 0]
- [0.2, 0, 0] - [0.2, 0, 0]
- [0.25, 0, 0]
- [0.3, 0, 0] - [0.3, 0, 0]
- [0.35, 0, 0]
- [0.4, 0, 0] - [0.4, 0, 0]
- [0.45, 0, 0]
- [0.5, 0, 0] - [0.5, 0, 0]
OutputFile: OutputFile:
Filename: fold-output.yaml Filename: fold-output.yaml

View File

@ -1,7 +1,12 @@
Qpoints: Qpoints:
- [ 0.00000000, 0.00000000, 0.00000000 ] - [ 0.00000000, 0.00000000, 0.00000000 ]
- [ 0.20000000, 0.00000000, 0.00000000 ] - [ 0.15000000, 0.09999999, 0.00000000 ]
- [ 0.40000000, 0.00000000, 0.00000000 ] - [ 0.30000000, 0.19999998, 0.00000000 ]
- [ 0.60000000, 0.00000000, 0.00000000 ] - [ 0.45000000, 0.29999997, 0.00000000 ]
- [ 0.80000000, 0.00000000, 0.00000000 ] - [ 0.60000000, 0.39999996, 0.00000000 ]
- [ 0.00000000, 0.00000000, 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 ]

View File

@ -0,0 +1,2 @@
在 4H-SiC 超胞中,存在一个 C 空位,计算它的声子。