|
| 1 | +# DeltaQS 统一框架实现文档 |
| 2 | + |
| 3 | +## 概述 |
| 4 | + |
| 5 | +本文档记录了将 DeltaSpin(自旋约束 DFT)扩展为 DeltaQS(电荷-自旋联合约束 DFT)的完整实现。DeltaQS 将 DeltaSpin 和 DeltaQ 统一为同一 Lagrange 框架在两个正交子空间上的投影,实现了电荷和磁矩的联合约束与基态优化。 |
| 6 | + |
| 7 | +## 理论基础 |
| 8 | + |
| 9 | +### 统一 Lagrange 泛函 |
| 10 | + |
| 11 | +$$E_{\text{total}} = E_{KS} + \sum_I \mu_I (N_I - N_I^{\text{target}}) + \sum_I \lambda_I (M_I - M_I^{\text{target}})$$ |
| 12 | + |
| 13 | +有效势: |
| 14 | +$$v_{\text{eff}}^\alpha = v_{KS}^\alpha + \sum_I (\mu_I + \lambda_I) w_I$$ |
| 15 | +$$v_{\text{eff}}^\beta = v_{KS}^\beta + \sum_I (\mu_I - \lambda_I) w_I$$ |
| 16 | + |
| 17 | +其中 μ_I 是电荷 Lagrange 乘子,λ_I 是自旋 Lagrange 乘子。 |
| 18 | + |
| 19 | +### 三个模式的关系 |
| 20 | + |
| 21 | +| 模式 | μ | λ | 有效势修正 | |
| 22 | +|------|---|---|-----------| |
| 23 | +| DeltaSpin | 0 | λ | α: +λw, β: -λw | |
| 24 | +| DeltaQ | μ | 0 | α: +μw, β: +μw | |
| 25 | +| DeltaQS | μ | λ | α: (μ+λ)w, β: (μ-λ)w | |
| 26 | + |
| 27 | +### 梯度信息(包络定理) |
| 28 | + |
| 29 | +$$\frac{\partial E}{\partial N_I^{\text{target}}} = -\mu_I, \qquad \frac{\partial E}{\partial M_I^{\text{target}}} = -\lambda_I$$ |
| 30 | + |
| 31 | +一次 SCF 计算同时给出 E 和梯度 (−μ, −λ),不需要有限差分。 |
| 32 | + |
| 33 | +## 文件变更清单 |
| 34 | + |
| 35 | +### 新增文件 |
| 36 | + |
| 37 | +| 文件 | 说明 | |
| 38 | +|------|------| |
| 39 | +| `source/source_lcao/module_deltaspin/deltaqs.cpp` | DeltaQS 全部 S1-S6 功能实现 | |
| 40 | + |
| 41 | +### 修改文件 |
| 42 | + |
| 43 | +| 文件 | 变更说明 | |
| 44 | +|------|---------| |
| 45 | +| `source/source_io/module_parameter/input_parameter.h` | 新增 9 个 DeltaQS INPUT 参数 | |
| 46 | +| `source/source_io/module_parameter/read_input_item_other.cpp` | 注册新参数的解析、验证和文档 | |
| 47 | +| `source/source_cell/atom_spec.h` | Atom 结构体新增 `target_charge`, `mu`, `constrain_charge` 字段 | |
| 48 | +| `source/source_cell/read_atoms_helper.cpp` | 分配新字段 + STRU 解析 `tc`/`cq`/`mu` 关键词 | |
| 49 | +| `source/source_cell/unitcell.h` | 新增 3 个 getter 方法声明 | |
| 50 | +| `source/source_cell/unitcell.cpp` | 实现 `get_target_charge()`, `get_mu()`, `get_constrain_charge()` | |
| 51 | +| `source/source_lcao/module_deltaspin/spin_constrain.h` | SpinConstrain 类扩展:数据成员、方法声明 | |
| 52 | +| `source/source_lcao/module_deltaspin/spin_constrain.cpp` | `cal_escon()` 增加电荷约束能量项 | |
| 53 | +| `source/source_lcao/module_deltaspin/deltaspin_lcao.cpp` | Facade 层集成 DeltaQS 初始化和联合循环 | |
| 54 | +| `source/source_lcao/module_deltaspin/template_helpers.cpp` | `double` 特化的所有新方法 no-op stubs | |
| 55 | +| `source/source_lcao/module_deltaspin/CMakeLists.txt` | 添加 `deltaqs.cpp` | |
| 56 | +| `source/source_lcao/module_operator_lcao/dspin_lcao.h` | 新增 `mu_save` 成员 | |
| 57 | +| `source/source_lcao/module_operator_lcao/dspin_lcao.cpp` | `contributeHR()` 支持 (μ+λ, μ-λ) 势 | |
| 58 | + |
| 59 | +## 分阶段实现详情 |
| 60 | + |
| 61 | +### S1: DeltaQS SCF 核心模块 |
| 62 | + |
| 63 | +#### S1.1 SpinConstrain 类扩展 |
| 64 | + |
| 65 | +新增数据成员(`spin_constrain.h`): |
| 66 | + |
| 67 | +```cpp |
| 68 | +// 电荷约束数据(每原子) |
| 69 | +std::vector<double> mu_; // 电荷 Lagrange 乘子 (Ry/e) |
| 70 | +std::vector<double> target_charge_; // 目标投影电荷 (electrons) |
| 71 | +std::vector<double> Ni_; // 当前计算投影电荷 |
| 72 | +std::vector<int> constrain_charge_; // 电荷约束标志 (0=free, 1=constrained) |
| 73 | + |
| 74 | +// 配置参数 |
| 75 | +bool charge_constraint_enabled_; |
| 76 | +std::string qs_mode_; // "deltaspin", "deltaq", "deltaqs", "auto" |
| 77 | +double sc_charge_thr_; // 电荷收敛阈值 |
| 78 | +double charge_alpha_trial_; // μ 更新步长 (Ry/e²) |
| 79 | +double charge_restrict_current_; // μ 最大步长 (Ry/e) |
| 80 | +bool ground_state_search_; |
| 81 | +int outer_max_iter_; |
| 82 | +double outer_thr_; |
| 83 | +bool gradient_output_; |
| 84 | +``` |
| 85 | + |
| 86 | +#### S1.2 Operator 修改(dspin_lcao.cpp) |
| 87 | + |
| 88 | +核心变更:`contributeHR()` 中的增量势计算。 |
| 89 | + |
| 90 | +**原 DeltaSpin (nspin=2):** |
| 91 | +``` |
| 92 | +coeff_up = +delta_lambda_z |
| 93 | +coeff_down = -delta_lambda_z |
| 94 | +``` |
| 95 | + |
| 96 | +**DeltaQS (nspin=2):** |
| 97 | +``` |
| 98 | +coeff_up = delta_mu + delta_lambda_z |
| 99 | +coeff_down = delta_mu - delta_lambda_z |
| 100 | +``` |
| 101 | + |
| 102 | +新增 `cal_coeff_lambda_qs()` 函数,同时对 nspin=2 (double) 和 nspin=4 (complex) 提供重载。`contributeHR()` 中通过 `sc.is_charge_constraint_enabled()` 判断是否使用 QS 系数。 |
| 103 | + |
| 104 | +`mu_save` 向量用于增量更新:`delta_mu = mu_current - mu_save`,与 `lambda_save` 平行管理。 |
| 105 | + |
| 106 | +#### S1.3 联合 Lambda 循环 |
| 107 | + |
| 108 | +`run_qs_lambda_loop()` 实现交替优化策略: |
| 109 | + |
| 110 | +1. 先运行标准 `run_lambda_loop()` 收敛自旋约束 (λ) |
| 111 | +2. 计算电荷投影 `cal_ni_lcao()` |
| 112 | +3. 梯度下降更新 μ:`μ_I += κ_μ · (N_I - N_I^target)` |
| 113 | +4. 重新对角化,检查电荷 RMS |
| 114 | +5. 迭代直到电荷 RMS < sc_charge_thr |
| 115 | + |
| 116 | +#### S1.4 电荷投影计算 |
| 117 | + |
| 118 | +`cal_ni_lcao()` 复用 DeltaSpin 的 `pre_hr` 投影框架: |
| 119 | + |
| 120 | +- nspin=2: 使用总密度矩阵 `switch_dmr(0)` + `cal_moment()` |
| 121 | +- nspin=4: 使用旋量密度矩阵,求迹得到总电荷 |
| 122 | + |
| 123 | +#### S1.5 约束能量修正 |
| 124 | + |
| 125 | +`cal_escon()` 扩展: |
| 126 | + |
| 127 | +``` |
| 128 | +E_scon = -Σ_I (λ_I · Mi_I) - Σ_I (μ_I · Ni_I) |
| 129 | +``` |
| 130 | + |
| 131 | +#### S1.6 INPUT 参数 |
| 132 | + |
| 133 | +| 参数 | 类型 | 默认值 | 说明 | |
| 134 | +|------|------|--------|------| |
| 135 | +| `sc_charge_switch` | bool | false | 启用电荷约束 | |
| 136 | +| `sc_qs_mode` | string | "auto" | 模式选择 | |
| 137 | +| `sc_charge_thr` | double | 1e-4 | 电荷收敛阈值 (e) | |
| 138 | +| `sc_charge_alpha` | double | 0.01 | μ 步长 (eV/e²) | |
| 139 | +| `sc_charge_sccut` | double | 3.0 | μ 最大步长 (eV/e) | |
| 140 | +| `sc_ground_state_search` | bool | false | 外层优化开关 | |
| 141 | +| `sc_outer_max_iter` | int | 50 | 外层最大迭代 | |
| 142 | +| `sc_outer_thr` | double | 1e-4 | 外层收敛阈值 (eV) | |
| 143 | +| `sc_gradient_output` | bool | false | 梯度输出开关 | |
| 144 | + |
| 145 | +#### S1.7 STRU 格式扩展 |
| 146 | + |
| 147 | +``` |
| 148 | +ATOMIC_POSITIONS |
| 149 | +Direct |
| 150 | +Fe |
| 151 | +0.0 |
| 152 | +2 |
| 153 | +0.00 0.00 0.00 mag 2.0 sc 1 1 1 tc 6.5 cq 1 mu 0.0 |
| 154 | +``` |
| 155 | + |
| 156 | +新增关键词: |
| 157 | +- `tc <value>`: 目标电荷 (electrons) |
| 158 | +- `cq <flag>`: 电荷约束标志 (0=free, 1=constrained) |
| 159 | +- `mu <value>`: 初始电荷乘子 (eV/e,内部转为 Ry/e) |
| 160 | + |
| 161 | +#### S1.8 SCF 集成 |
| 162 | + |
| 163 | +Facade 函数 `init_deltaspin_lcao()` 在 `init_sc()` 后调用 `init_deltaqs()` 初始化电荷约束数据。`run_deltaspin_lambda_loop_lcao()` 根据 `is_charge_constraint_enabled()` 选择调用 `run_lambda_loop()` 或 `run_qs_lambda_loop()`。 |
| 164 | + |
| 165 | +### S2: 梯度提取与输出 |
| 166 | + |
| 167 | +#### 梯度文件输出 |
| 168 | + |
| 169 | +`write_gradient_file()` 输出 `deltaqs_gradient_<step>.dat`: |
| 170 | + |
| 171 | +``` |
| 172 | +# Atom Ni Mi_z target_N target_M mu(Ry) lambda_z(Ry) mu(eV) lambda_z(eV) |
| 173 | +Fe_0 6.52 2.01 6.50 2.00 0.012 0.003 0.163 0.041 |
| 174 | +``` |
| 175 | + |
| 176 | +#### 打印函数 |
| 177 | + |
| 178 | +- `print_Ni()`: 输出各原子的 Ni、目标值、偏差 |
| 179 | +- `print_Charge_Force()`: 输出各原子的 μ 乘子 |
| 180 | +- `cal_charge_escon()`: 电荷约束能量修正 |
| 181 | + |
| 182 | +### S3: 网格扫描框架 |
| 183 | + |
| 184 | +`run_qs_grid_scan()` 实现 2D E(N, M) 势能面映射: |
| 185 | + |
| 186 | +``` |
| 187 | +输入: scan_atom, N_min, N_max, N_step, M_min, M_max, M_step |
| 188 | +输出: deltaqs_grid_scan.dat |
| 189 | +``` |
| 190 | + |
| 191 | +对每个 (N, M) 网格点: |
| 192 | +1. 设置 target_charge 和 target_mag |
| 193 | +2. 运行 `run_qs_lambda_loop()` 收敛 |
| 194 | +3. 记录 E, μ, λ, Ni, Mi |
| 195 | + |
| 196 | +输出文件包含完整势能面数据,可直接用于 CP-3 验证。 |
| 197 | + |
| 198 | +### S4: 梯度下降优化器 |
| 199 | + |
| 200 | +`run_qs_gradient_descent()` 实现 2D 势能面上的梯度下降: |
| 201 | + |
| 202 | +``` |
| 203 | +输入: max_steps, step_size, conv_thr |
| 204 | +输出: deltaqs_gradient_descent.dat |
| 205 | +``` |
| 206 | + |
| 207 | +每步: |
| 208 | +1. 运行 DeltaQS SCF → 得到 E, μ, λ |
| 209 | +2. 构造梯度: g_N = -μ_I + μ_ref, g_M = -λ_I |
| 210 | +3. 检查收敛: max|grad| < conv_thr |
| 211 | +4. 更新目标: N_target += step_size · μ, M_target += step_size · λ |
| 212 | + |
| 213 | +### S5: L-BFGS 优化器 |
| 214 | + |
| 215 | +`run_qs_lbfgs()` 实现高维 L-BFGS 优化: |
| 216 | + |
| 217 | +``` |
| 218 | +输入: max_steps, conv_thr, history_size=5 |
| 219 | +输出: deltaqs_lbfgs.dat |
| 220 | +``` |
| 221 | + |
| 222 | +优化变量: x = (N_1, ..., N_{k-1}, M_1, ..., M_k),其中原子 k 为电荷缓冲池。 |
| 223 | + |
| 224 | +算法流程: |
| 225 | +1. 运行 DeltaQS SCF → 得到 E, μ, λ |
| 226 | +2. 构造梯度向量(维度 = active_charge - 1 + active_spin) |
| 227 | +3. L-BFGS two-loop recursion 计算搜索方向 |
| 228 | +4. 线搜索步长 α = 0.1(可配置) |
| 229 | +5. 更新目标值,维护历史 {s_k, y_k} 对 |
| 230 | + |
| 231 | +支持配置历史窗口大小(默认 m=5)。 |
| 232 | + |
| 233 | +### S6: 差异归因工具 |
| 234 | + |
| 235 | +`run_qs_attribution()` 实现 CP-6 差异归因分析: |
| 236 | + |
| 237 | +输出 `deltaqs_attribution.dat`,包含: |
| 238 | +- 各原子的 Ni, Mi, μ, λ 详细数据 |
| 239 | +- 总磁矩 S* = Σ Mi |
| 240 | +- 归因分类判断: |
| 241 | + - **A**: 同一 M,不同磁构型(FM vs AFM) |
| 242 | + - **B**: M 不在扫描范围内 |
| 243 | + - **C**: 多体效应(分数自旋态) |
| 244 | + |
| 245 | +## 使用指南 |
| 246 | + |
| 247 | +### 基本 DeltaQS 计算 |
| 248 | + |
| 249 | +INPUT 文件: |
| 250 | +``` |
| 251 | +sc_mag_switch 1 |
| 252 | +sc_charge_switch 1 |
| 253 | +sc_qs_mode auto |
| 254 | +sc_charge_thr 1e-4 |
| 255 | +sc_charge_alpha 0.01 |
| 256 | +sc_scf_thr_mode immediate |
| 257 | +``` |
| 258 | + |
| 259 | +STRU 文件: |
| 260 | +``` |
| 261 | +V |
| 262 | +0.0 |
| 263 | +2 |
| 264 | +0.00 0.00 0.00 mag 1.0 sc 1 tc 3.5 cq 1 |
| 265 | +0.00 0.00 3.00 mag 1.0 sc 1 tc 3.5 cq 1 |
| 266 | +``` |
| 267 | + |
| 268 | +### 基态搜索 |
| 269 | + |
| 270 | +``` |
| 271 | +sc_ground_state_search true |
| 272 | +sc_outer_max_iter 50 |
| 273 | +sc_outer_thr 1e-4 |
| 274 | +sc_gradient_output true |
| 275 | +``` |
| 276 | + |
| 277 | +### 网格扫描(CP-3 验证) |
| 278 | + |
| 279 | +通过代码调用: |
| 280 | +```cpp |
| 281 | +sc.run_qs_grid_scan(scan_atom, N_min, N_max, N_step, M_min, M_max, M_step); |
| 282 | +``` |
| 283 | + |
| 284 | +## 验证检查点 |
| 285 | + |
| 286 | +| 检查点 | 验证内容 | 判据 | |
| 287 | +|--------|---------|------| |
| 288 | +| CP-0 | DeltaQS 与标准 SCF 等价性 | |E_QS - E_ref| < 1e-5 Ha | |
| 289 | +| CP-1 | 电荷梯度 μ 验证 | |g_FD - (-μ)| / (|g_FD| + η) < 0.01 | |
| 290 | +| CP-2 | 自旋梯度 λ 验证 | |g_FD^M - (-λ)| / (|g_FD^M| + η) < 0.01 | |
| 291 | +| CP-3 | 2D E(N,M) 势能面 | 无断崖,最小值处 μ₁≈μ₂, λ≈0 | |
| 292 | +| CP-4 | 梯度下降轨迹 | ≥90% 轨迹收敛到全局最小 | |
| 293 | +| CP-5 | 高维 L-BFGS | E_global ≤ E_M-scan^min | |
| 294 | +| CP-6 | 差异归因 | 每个 ΔE<0 案例可归入 A/B/C | |
| 295 | + |
| 296 | +## 向后兼容性 |
| 297 | + |
| 298 | +- 当 `sc_charge_switch = false` 时,所有 DeltaQS 代码路径不执行,行为与原 DeltaSpin 完全一致 |
| 299 | +- `sc_qs_mode = "auto"` 自动根据开关推断模式 |
| 300 | +- 现有测试用例不受影响 |
| 301 | + |
| 302 | +## 单位系统 |
| 303 | + |
| 304 | +| 量 | 内部单位 | INPUT 单位 | 转换 | |
| 305 | +|----|---------|-----------|------| |
| 306 | +| μ | Ry/e | eV/e | × Ry_to_eV | |
| 307 | +| λ | Ry/μB | eV/μB | × Ry_to_eV | |
| 308 | +| Ni | electrons | electrons | - | |
| 309 | +| Mi | μB | μB | - | |
| 310 | +| E | Ry | Ry | - | |
| 311 | + |
| 312 | +## 后续开发方向 |
| 313 | + |
| 314 | +1. **PW 基组支持**: 当前 `cal_ni_lcao()` 仅支持 LCAO,需添加 `cal_ni_pw()` 路径 |
| 315 | +2. **nspin=4 联合优化**: `run_qs_lambda_loop()` 中的 nspin=4 分支需要完善 |
| 316 | +3. **子空间加速集成**: DeltaQS 的 μ 更新与 LCAO subspace acceleration 的兼容 |
| 317 | +4. **自动步长选择**: L-BFGS 中的 Armijo/Wolfe 线搜索替代固定步长 |
| 318 | +5. **MPI 并行**: 网格扫描和 L-BFGS 多起点的 MPI 任务分配 |
0 commit comments