Abinit SCF 波函数收敛过程:原理与代码实现详解

May 19, 2026
Published in 计算物理

Abstract

本文详细介绍了Abinit的SCF计算过程中波函数收敛的过程。

Keywords: Abinit, DFT, SCF, 波函数优化, 共轭梯度, LOBPCG, Chebyshev 滤波

Abinit SCF 波函数收敛过程:原理 + 代码实现详解

基于 Abinit 10.4.7 源码分析 核心模块:src/94_scfcv/m_scfcv_core.F90src/79_seqpar_mpi/m_vtorho.F90src/79_seqpar_mpi/m_vtowfk.F90、各对角化器 m_cgwf.F90 / m_lobpcg2.F90 / m_chebfi.F90 / m_rmm_diis.F90src/56_mixing/m_ab7_mixing.F90


引言:SCF 波函数收敛是什么?

DFT-Kohn-Sham 方程

$$\Bigl[ -\tfrac{1}{2}\nabla^2 + V_{\text{loc}}(\mathbf{r}) + V_{\text{nl}} + V_{\text{H}}[n] + V_{\text{xc}}[n] \Bigr],\psi_{n\mathbf{k}} = \epsilon_{n\mathbf{k}},\psi_{n\mathbf{k}}$$

非线性特征值方程:哈密顿量本身依赖于通过 $\psi$ 构造出的电子密度 $n(\mathbf{r}) = \sum_{n\mathbf{k}} f_{n\mathbf{k}}|\psi_{n\mathbf{k}}|^2$。Abinit 用自洽场(SCF)迭代来求解:

固定 V → 解 H ψ = ε ψ → 由 ψ 算新密度 n → 算新势 V → ... 直到收敛

每次迭代里要做两件相互嵌套的事:

  1. 外循环(SCF 大循环):在当前 $V$ 下重新求一组 ${\psi_{n\mathbf{k}}}$,更新密度,再用混合算法把新密度 / 新势"安全地"代入下一轮。
  2. 内循环(波函数优化):在每个 k 点上对固定的 $H_\mathbf{k}$,迭代极小化 Rayleigh 商 $\langle\psi|H|\psi\rangle/\langle\psi|\psi\rangle$,得到最低的若干本征对。

外循环的稳定性由"密度/势混合"决定;内循环的速度由"对角化器"决定。两者共同决定 SCF 收敛性。


输入参数总览

下表列出影响波函数收敛过程的所有关键变量(位置 abimkdocs/variables_abinit.py)。

输入变量默认值控制对象含义
nstep30外循环SCF 最大迭代次数
iscf7(NC)/ 17(PAW)外循环混合方案(2 simple, 3/4 Anderson, 7 Pulay;+10 表示密度混合)
tolvrs0外循环势残差平方收敛阈值
toldfe0外循环总能差收敛阈值
toldff0外循环最大原子力变化阈值
tolrff0外循环力的相对变化阈值
tolwfr0外循环波函数残差阈值(非自洽强制选)
diemix1.0(NC)/ 0.7(PAW)外循环混合因子 α
diemac1e6外循环模型介电函数(介质常数)
dielng1.08外循环介电模型的长波截断
npulayit7外循环Pulay 混合保留的历史步数
iprcel0外循环介电预条件器类型
wfoptalg0(NC)/ 10(PAW)/ 114(kgb)内循环对角化算法选择
nline4内循环单条带的最大 line minimization 次数
nnsclo0(auto)内循环每个 SCF 步内的非自洽循环次数
nbdblock1内循环LOBPCG / CG 的能带块大小
mdeg_filter6内循环Chebyshev 滤波多项式最大阶
rmm_diis0内循环启用 RMM-DIIS(>0 在第 N 步后切换)
tolrde0.005内循环单步 CG 改善阈值(早退条件)
ortalg-2内循环正交化算法选择
nbdbuf0内循环波函数收敛检查的"缓冲带"(顶部不算)
mffmem1内循环是否把波函数缓存到磁盘
densfor_pred6几何步几何步间的密度外推方案

wfoptalg 取值(mod(wfoptalg, 10) 决定主算法):

算法适用
0标准 CG(Payne 1992)NC 默认
10CG + Kresse 改进(修正动能 + 改进预处理)PAW 默认
1 / 111Chebyshev 滤波(ChebFi,Levitt 2015)大规模并行
4 / 14 / 114LOBPCG(Knyazev 2001)中等并行 / paral_kgb=1 默认
2 / 3Residual minimization w.r.t. shift非自洽

iscf 取值(mod(iscf,10) 决定混合算法,iscf>=10 表示混合密度而非势):

算法
2 / 12简单线性混合
3 / 13Anderson(用 1 步历史)
4 / 14Anderson 2 阶(用 2 步历史)
5 / 6 / 15 / 16CG 能量极小化
7 / 17Pulay(用 npulayit 步历史)

整体调用链

m_gstate (顶层 SCF 驱动)
  └─ scfcv (m_scfcv.F90)
       └─ scfcv_core (m_scfcv_core.F90:263)         ← SCF 外循环主体
            ├─ ab7_mixing_new (m_ab7_mixing.F90:161)     ← 初始化混合器

            └─ do istep = 1, nstep                       ← SCF 大循环
                ├─ vtorho (m_vtorho.F90)                 ← 由 V 求新 ρ
                │   └─ do isppol, do ikpt               ← 自旋 × k 点循环
                │       └─ vtowfk (m_vtowfk.F90:177)    ← 单 k 点波函数优化
                │           ├─ cgwf      (CG)
                │           ├─ lobpcgwf2 (LOBPCG)
                │           ├─ chebfi    (Chebyshev 滤波)
                │           ├─ rmm_diis  (RMM-DIIS)
                │           └─ subdiago (子空间对角化)

                ├─ newocc (m_occ.F90)                    ← 更新占据数 + Fermi 能级
                │                                          (见 smearing 报告)
                ├─ rhotoxc → vhartre → setvtr           ← 由 ρ 算新 V
                ├─ etotfor (m_scfcv_core.F90:2561)       ← 算总能、力、应力
                ├─ scprqt (m_common.F90:183)             ← 检查收敛
                ├─ if (quit) exit
                └─ ab7_mixing_eval (m_ab7_mixing.F90:623)← 用历史信息生成下一轮 V/ρ

外循环:SCF 主体(scfcv_core

代码位置:src/94_scfcv/m_scfcv_core.F90:1034-2300

SCF 主循环骨架

do istep = 1, max(1, nstep)
   ! ----- 1. 几何相关的一次性准备(仅 istep=1 或原子移动后)-----
   if (moved_atm_inside == 1 .or. istep == 1) then
      call symmetrize_xred(...)
      call getcut(...)         ! G 球截断
      call getph(...)          ! 结构因子
      ! PAW 时还要做 nhatgrid 等
   end if

   ! ----- 2. 由当前 V 求新 ρ:vtorho 内含 k 点循环 -----
   call vtorho(... eigen, occ, rhog, rhor, residm, ...)
   !   返回最大波函数残差 residm

   if (dtset%iscf < 0) exit    ! 非自洽:vtorho 内已经迭代完,单步退出

   ! ----- 3. 在密度混合情况下,先算总能 -----
   if (iscf >= 10) then
      call etotfor(... etotal, deltae, ...)
   end if

   ! ----- 4. 检查收敛 -----
   call scprqt(... tollist, ... quit, conv_retcode)
   if (quit == 1) exit

   ! ----- 5. 用历史信息混合(生成下一步的 V 或 ρ)-----
   call ab7_mixing_eval(mix, ... istep, ...)

   ! ----- 6. 在势混合情况下,用混合后的 ρ 重算 V,再算总能 -----
   if (iscf < 10) then
      call rhotoxc(... rhor → vxc)
      call hartre  (rhog → vhartr)
      call etotfor(... etotal, deltae, ...)
      call scprqt(... quit ...)   ! 再检查一次
   end if
end do

收敛判据:scprqt

位置:src/67_common/m_common.F90:183。从 tollist(1:8) 数组中读 5 个判据(详见之前的 SCF convergence 报告):

tolwfr = tollist(2)   ! 最大波函数残差
toldff = tollist(3)   ! 最大力变化
toldfe = tollist(4)   ! 总能差
tolvrs = tollist(6)   ! 势/密度残差²
tolrff = tollist(7)   ! 相对力变化

只允许选一个(5 个里只有 1 个非零)。监控变量:

  • residm:所有 k 点和带的最大波函数残差 $\max_{n\mathbf{k}}|(H-\epsilon)\psi|^2$
  • deltae = E_total(istep) - E_total(istep-1)
  • res2:势/密度残差范数 $|V_{\text{new}}-V_{\text{old}}|^2$
  • diffor:原子力最大变化

当对应判据连续满足 2 次(避免假阳性)时 quit = 1,跳出循环。


内循环:波函数优化(vtowfk

代码位置:src/79_seqpar_mpi/m_vtowfk.F90:177-700

分发器骨架

subroutine vtowfk(...)
   wfoptalg = mod(dtset%wfoptalg, 100)
   wfopta10 = mod(wfoptalg, 10)
   ...

   ! 把波函数过滤:动能 > huge 的 G 分量置零(防止"高频污染")
   do iband, do ipw
      if (kinpw(ipw) > huge*1d-11) cwavef(:, ipw) = 0
   end do

   ! 非自洽循环:每次 SCF 大步内可能多次调对角化器
   do inonsc = 1, nnsclo_now

      ! 根据 wfopta10 派发到不同对角化器
      if (wfopta10 == 4) then
         call lobpcgwf2(...)
      else if (wfopta10 == 1) then
         call chebfi/chebfiwf2(...)
      else                              ! wfopta10 = 0 或 10
         if (.not. use_rmm_diis) then
            call cgwf(...)              ! 标准 CG
         else
            call rmm_diis(...)          ! 切换到 RMM-DIIS
         end if
      end if

      ! 子空间对角化(Rayleigh-Ritz):在已找到的 nband 维子空间中做精确对角化
      if (do_subdiago) call subdiago(...)

      ! 正交化(部分算法跳过)
      if (do_ortho) call zorthonormalize(...)

   end do
end subroutine

nnsclo_now(非自洽循环次数)由 nnsclo 决定,自洽计算通常 = 1(每 SCF 步只调一次对角化器);非自洽计算 = nstep(在固定 V 下反复优化波函数直到收敛)。

标准共轭梯度(CG,cgwf

代码位置:src/67_common/m_cgwf.F90:488-1300。这是 Abinit 历史最悠久的算法,Teter–Allan–Payne 1992 的实现。

算法概要

对每个能带 $n$,逐一地求解:

$$\min_{|\psi_n\rangle;\perp;|\psi_1\rangle,\ldots,|\psi_{n-1}\rangle,;|\psi_n|=1} \langle\psi_n|H|\psi_n\rangle$$

用预条件 CG 在单位球面 + 正交补空间上做线搜索。

关键步骤(cgwf 第 488-1000 行)

对每个 iband = 1..nband

  1. 归一化 $|\psi_n\rangle$
  2. 计算梯度 $|H\psi_n\rangle$:call getghc(...),这一步是整个 DFT 的 Hot Spot(每条 band 一次 FFT × 2 + 非局域投影)
  3. 进入 line minimization 循环(最多 nline 次):
do iline = 1, nline
   ! a) Rayleigh quotient
   chc = <ψ|H|ψ>                                 ! 当前能量
   lam0 = chc

   ! b) 残差向量与残差范数
   |vresid> = |Hψ> - chc * |ψ>
   resid(iband) = ‖vresid‖²

   ! c) 检查收敛 (tolwfr 是单 band 残差阈值)
   if (resid(iband) < tolwfr) exit

   ! d) 投影到正交子空间:投掉前面 n-1 个 band
   |direc> = |vresid> - Σ_{m<n} |ψ_m><ψ_m|vresid>

   ! e) Teter 多项式预处理(关键!)
   call cg_precon(ψ, 0, ..., kinpw, ..., pcon, direc, ...)
   ! 预条件矩阵 K:在 G 空间对角,K(G) = (27+18x+12x²+8x³)/(27+18x+12x²+8x³+16x⁴)
   ! 其中 x = (k+G)²/⟨ψ|T|ψ⟩,⟨ψ|T|ψ⟩ 是当前能带的动能平均
   |direc> ← K |direc>

   ! f) Polak-Ribière / Fletcher-Reeves: 加入历史方向
   dotgg = <direc|H|ψ>
   if (iline == 1) then
      γ = 0
      |conjgr> = |direc>
   else
      γ = dotgg / dotgp     ! Fletcher-Reeves 系数
      |conjgr> = |direc> + γ |conjgr>
   end if
   dotgp = dotgg

   ! g) 把 conjgr 投影到 ψ 的正交补 → direc
   <ψ|conjgr> 投掉

   ! h) 在 span{ψ, direc} 平面内做精确二维 Rayleigh quotient 极小化
   compute <ψ|H|ψ>, <direc|H|direc>, <ψ|H|direc>
   tan(2θ) = 2 <ψ|H|direc> / (<ψ|H|ψ> - <direc|H|direc>)
   ψ_new = cos(θ) * ψ + sin(θ) * direc
end do

关键点

  • Teter 多项式预处理:Abinit 招牌技术。预条件器 $K(G)$ 在小 $|G|$ 处近似 1(不改动低频信号),在大 $|G|$ 处近似 $1/T(G)$(压制高频)。代码 cg_preconsrc/44_abitools/m_cgtools.F90:3651-3740。这一步把 CG 收敛速度从 $O(\kappa)$ 提到 $O(\sqrt{\kappa})$ 级别,是平面波 DFT 的标配。
  • 解析的二维 line minimization:因为 Rayleigh quotient 在 2 维平面内是有理函数,可解析求其最优 θ(avoid bracket-and-search),效率最高。
  • 单条带串行:CG 不能在 band 维度并行(每条带依赖前面的正交化结果)。这是其唯一劣势。

LOBPCG(Locally Optimal Block PCG)

代码位置:src/48_diago/m_lobpcg2.F90:340-700src/79_seqpar_mpi/m_lobpcgwf.F90

算法概要

把 $nband$ 条带分成大小为 blockdim 的若干块,每块一起优化(block iteration):

对一块 $X \in \mathbb{C}^{N_{\text{pw}}\times b}$:

  1. 计算 $W = K\cdot R$,其中 $R = AX - BX\Lambda$(残差,$\Lambda$ 是 Rayleigh-Ritz 给出的本征值矩阵)
  2. 构造增广子空间 $V = [X, W, P]$($P$ 是上一步的"惯性方向")
  3. 在 $V$ 上做 Rayleigh-Ritz:求 $V^\dagger A V$ 与 $V^\dagger B V$ 的广义本征对,取最低 $b$ 个
  4. 更新 $X_{\text{new}}$,$P_{\text{new}} = $ 新 $X$ 在 $W,P$ 子空间的分量

代码骨架(m_lobpcg2.F90:456-700

do iblock = 1, nblock
   call lobpcg_getX0(...)                  ! 取当前块初始波函数
   call lobpcg_orthoXwrtBlocks(...)        ! 与之前所有 iblock 块 B-正交化
   call getAX_BX(X, AX, BX)                ! AX = H·X, BX = S·X
   call xg_Borthonormalize(X, BX, AX)      ! B-正交化 X
   call xg_RayleighRitz(X, AX, BX, λ)      ! 初始 RR,给出本征值估计 λ

   do iline = 1, nline
      ! 1. 残差
      W = AX - BX·diag(λ)
      maxResidu = max ‖W_i‖
      if (maxResidu < tolerance) exit

      ! 2. 预条件
      W = K·W

      ! 3. 与之前块正交化
      W = W - X_prev (X_prev^† B W)

      ! 4. 算 AW, BW
      call getAX_BX(W, AW, BW)

      ! 5. Rayleigh-Ritz on [X, W, P] (or [X, W] in first iter)
      if (iline == 1) then
         call xg_Borthonormalize(XW, BXW, AXW)
         call xg_RayleighRitz(X, AX, BX, λ, XW=XW, AW=AW, BW=BW, P, AP, BP, ...)
      else
         call xg_Borthonormalize(XWP, BXWP, AXWP)
         call xg_RayleighRitz(X, AX, BX, λ, XW, AW, BW, P, AP, BP, XWP, ...)
      end if
   end do
end do

关键点

  • 块运算:所有矩阵-向量乘法变成矩阵-矩阵乘法(BLAS-3),缓存友好,能用 OpenMP/SIMD 加速。
  • MPI 友好:不同块可以分到不同进程(paral_kgb=1 下),bandfft 转置(xgTransposer)使本征值问题在小子空间内做。
  • 数值技巧:当残差降到 ~ 1e-27 时,$P$ 矩阵会出现 catastrophic cancellation;代码用 if minResidu < 1e-27 重新做 $[X,W]$ 子空间的 RR 而不是 $[X,W,P]$。
  • 推荐用法wfoptalg 114,配 paral_kgb 1 使用 band+FFT 并行。

Chebyshev 滤波(ChebFi)

代码位置:src/66_wfs/m_chebfi.F90:300-450。Levitt-Torrent 2015。

算法概要

不直接迭代单个本征对,而是用 Chebyshev 多项式 $T_m(H)$ 作为滤波器:对感兴趣谱区放大,其余压制。

设感兴趣区间 $[\lambda_{\min}, \mu]$(μ ≈ 当前最高占据本征值),让滤波器在区间外 $[\mu, \lambda_{\max}]$ 上小、区间内大:

$$\psi_{\text{new}} = T_m!\Bigl(\frac{2H - (\mu+\lambda_{\max})}{\lambda_{\max} - \mu}\Bigr);\psi_{\text{old}}$$

代码核心(m_chebfi.F90:340-440

filter_center = (ecut + filter_low) / 2     ! μ 中心
filter_radius = (ecut - filter_low) / 2     ! μ 半径

do ideg = 1, mdeg_filter
   ! 应用 H
   call getghc(cg, ghc, ...)                ! H·ψ
   ! PAW 时还要应用 S^{-1}
   if (paw) call apply_invovl(ghc, gsm1hc, ...)
   else gsm1hc = ghc

   ! Chebyshev 递推:
   ! T_0(x) = 1, T_1(x) = x, T_{n+1}(x) = 2x T_n(x) - T_{n-1}(x)
   if (ideg == 1) then
      cg_next = 1/filter_radius * (gsm1hc - filter_center * cg)
   else
      cg_next = 2/filter_radius * (gsm1hc - filter_center * cg) - cg_prev
   end if
   cg_prev = cg ; cg = cg_next
end do

! 滤波完后做 Rayleigh-Ritz:在 nband 维子空间精确对角化
call subdiago(...)

关键点

  • 不做正交化也不做线搜索!整套 nband 条带"被同一个多项式作用",对角化只在最后一步做。
  • 多项式阶 mdeg_filter(默认 6)控制滤波质量。阶越高,滤波越锐利,但每步只多做几次 FFT,开销可控。
  • 不可使用预条件:因为多项式作用是显式的。这导致它对 ecutsm 不敏感,Pulay 应力无法修正(必须靠加大 ecut)。
  • 适合超大规模:每步 nband × mdeg_filter 次 FFT,可完美并行;当 LOBPCG 内部 RR 成为瓶颈时(>1000 bands),ChebFi 更优。
  • 顶部几条 band 难收敛(多项式在尾部弱),代码强烈建议配 nbdbuf 多算几条 band。

RMM-DIIS

代码位置:src/66_wfs/m_rmm_diis.F90,由 m_vtowfk.F90:465 调用。

Residual Minimization with Direct Inversion in Iterative Subspace(来自 VASP 工作)。在 CG 稳定后期切换可大幅加速。当 rmm_diis > 0istep > 3 + rmm_diis 时启用:

use_rmm_diis = istep > 3 + dtset%rmm_diis

DIIS 思想:保留若干个 (波函数, 残差) 历史对,求一组系数 $c_i$ 使线性组合 $\sum c_i R_i$ 范数最小,然后用同样系数组合波函数得到新解。


关键工具:getghc 与预条件器

getghc:$|H\psi\rangle$ 的核心算子

所有对角化器最贵的一步都是计算 $H|\psi\rangle$。Abinit 的 getghc 完成:

H |ψ> = T|ψ>                   <- G 空间对角,O(N_pw)
      + V_loc(r) ψ(r)          <- 需要 FFT: r ←→ G
      + V_nl |ψ>               <- 投影到原子基(nonlop),O(N_pw·N_proj)
      + V_Fock |ψ>             <- 仅杂化泛函;最贵 O(N_pw² ln)

时间分配(典型):FFT ≈ 40%, nonlop ≈ 40%, 其他 20%。

Teter 预条件器

代码:src/44_abitools/m_cgtools.F90:3651-3740。在 G 空间对角,每个 G 用一个标量:

! 计算当前条带的平均动能
ek0 = Σ_G kinpw(G) |ψ(G)|²

! 对每个 G:
x = kinpw(G) / ek0
poly = 27 + x(18 + x(12 + x·8))         ! Teter 三阶多项式
fac  = poly / (poly + 16·x⁴)            ! 关键比率
pcon(G) = fac

! 应用到方向向量
vect(G) = (vect(G) - eval·ψ(G)) · fac

数学上 $K(x)$ 在 $x\to 0$ 时 $\to 1$(保留低频),在 $x\to\infty$ 时 $\to (27+18x+...) / 16x^4 \to 0$(压制高频)。这把 Hessian 的条件数从 $E_{\text{cut}}/E_{\text{gap}}$(典型 1000)压到 $O(1)$。


密度/势混合算法

代码位置:src/56_mixing/m_ab7_mixing.F90

混合的物理意义

设 SCF 输入势 $V_{\text{in}}^{(i)}$,由 KS 方程算得输出势 $V_{\text{out}}^{(i)} = F[V_{\text{in}}^{(i)}]$。SCF 不动点条件是 $V_{\text{out}} = V_{\text{in}}$。残差是 $R^{(i)} = V_{\text{out}}^{(i)} - V_{\text{in}}^{(i)}$。

朴素地令 $V_{\text{in}}^{(i+1)} = V_{\text{out}}^{(i)}$(不混合)会振荡发散(因为电子云对势变化反应过激)。需要"减速":

$$V_{\text{in}}^{(i+1)} = V_{\text{in}}^{(i)} + \alpha,K,R^{(i)}$$

其中 $\alpha = $ diemix、$K = $ 模型介电预条件器。

七种混合算法(按 iscf 取值)

简单线性混合(iscf=2/12

V_in[i+1] = V_in[i] + diemix * K_prec * R[i]

代码(scfopt 第 1956-1960 行):

f_fftgr(:, :, i_vstore) = vtrial(:, :)            ! 存当前 V_in
vtrial(:, :) = vtrial(:, :) + f_fftgr(:, :, i_vrespc(1))  ! V_in + 预条件残差

最稳定但收敛最慢。diemix 通常 0.3-1.0。

Anderson 1 阶(iscf=3/13

代码(scfopt 第 1964-2018 行)。用上一步信息构造最优线性组合:

$$V_{\text{in}}^{(i+1)} = (1-\lambda)(V_{\text{in}}^{(i)} + R^{(i)}) + \lambda(V_{\text{in}}^{(i-1)} + R^{(i-1)})$$

其中

$$\lambda = \frac{\langle R^{(i)}, R^{(i)} - R^{(i-1)}\rangle}{|R^{(i)} - R^{(i-1)}|^2}$$

是直线段上极小化残差范数的最优系数。代码:

lambda = (resid_new - prod_resid) / (resid_new + resid_old - 2*prod_resid)

Anderson 2 阶(iscf=4/14

用 2 步历史,2×2 线性方程组。代码 m_ab7_mixing.F90:2021-2089

det = aa1*aa2 - bb*bb
lambda  = (aa2*cc1 - bb*cc2) / det
lambda2 = (aa1*cc2 - bb*cc1) / det

Pulay 混合(iscf=7/17Abinit 默认

代码 m_ab7_mixing.F90:2092-2200。用 npulayit(默认 7)步历史,求 $n$ 维线性方程组:

$$\min_{{\alpha_i}} \Bigl|\sum_{i=1}^n \alpha_i R^{(i)}\Bigr|^2,\qquad \sum \alpha_i = 1$$

构造 Pulay 矩阵 $A_{ij} = \langle R^{(i)}, R^{(j)}\rangle$,解约束线性方程组:

! 构造 A 矩阵
do ii = 1, niter
   call dotprodm_v(... amat(ii, niter) ...)        ! A_{i,n} = <R_i, R_n>
end do

! 求逆
call dgetrf(niter, niter, amatinv, ...)
call dgetri(niter, amatinv, ...)

! 取 alpha_i = A^{-1}[:, 1] 行和归一
alpha(:) = sum(amatinv, dim=2) / sum(amatinv)

! 新的混合势:
V_in[i+1] = Σ alpha_i (V_in[i] + R[i])

Pulay 与 Anderson(npulayit) 等价:npulayit = 1 即 Anderson 1 阶,= 2 即 Anderson 2 阶。

CG 能量极小化(iscf=5/6/15/16

把 $V$(或 $\rho$)当成无约束变量,用 CG 极小化 $E_{\text{tot}}[V]$。需要计算 $\partial E/\partial V$,开销大但理论上单调下降。仅 DEVELOP 用。

介电模型预条件 $K_{\text{prec}}$

在做混合前,先把残差 $R$ 用模型介电函数 $K = \varepsilon_{\text{model}}^{-1}$ 处理一遍(iprcel 控制类型):

$$K(\mathbf{G}) = \frac{1}{\varepsilon_{\text{model}}(|\mathbf{G}|)}$$

最简单(iprcel=0)的 Thomas-Fermi 模型:

$$\varepsilon(G) = 1 + (\varepsilon_\infty - 1),\frac{G_{\text{TF}}^2}{G^2 + G_{\text{TF}}^2}$$

diemac($\varepsilon_\infty$)和 dielng(Thomas-Fermi 长度的倒数)控制。对金属:diemac = 1e6;对半导体:diemac ≈ 10;对分子(真空):diemac = 1


SCF 一次完整迭代的逐步追踪

设输入:FCC Si, 4×4×4 k 点 → 10 IBZ 点, 8 bands, ecut=15 Ha, occopt=1, iscf=7, tolvrs=1e-12, wfoptalg=0 (CG), nstep=30。

Step 0: 初始化(istep=0 前)

  1. 读 WFK 或随机初始化 $\psi^{(0)}_{n\mathbf{k}}$
  2. 由 $\psi^{(0)}$ 算初始密度 $\rho^{(0)}$
  3. 算初始势 $V^{(0)}{\text{loc}} = V{\text{ion}} + V_H[\rho^{(0)}] + V_{xc}[\rho^{(0)}]$
  4. ab7_mixing_new(mix, iscf=7, ...) 分配 Pulay 历史空间

Step 1(istep=1

进入 vtorho

  • 对自旋通道 isppol=1(非极化)
  • 对每个 k 点 ikpt = 1..10(本进程负责的):

在 k=1 处调 vtowfk

  • wfopta10 = 0 → 走 CG 分支 cgwf

cgwf 内对每条 band(1..8):

  • band 1:

    • 归一化 $\psi$
    • getghc → $|H\psi\rangle$(一次 FFT 正反 + nonlop)
    • 计算 $\langle H\rangle = \langle\psi|H|\psi\rangle$
    • 残差 $|R\rangle = |H\psi\rangle - \langle H\rangle|\psi\rangle$,$|R|^2 = ?$
    • 若 $|R|^2 < $ tolwfr_diago(默认 1e-22)→ skip
    • 否则 line minimization 循环(最多 nline=4 次):
      1. 投影:$|R\rangle \to |R\rangle - \sum_{m<1} |\psi_m\rangle\langle\psi_m|R\rangle$(band 1 时无前导)
      2. Teter 预处理:$|D\rangle = K\cdot|R\rangle$
      3. CG 合并方向:$|C\rangle = |D\rangle + \gamma|C_{\text{prev}}\rangle$
      4. 投影 $|C\rangle \perp |\psi\rangle$
      5. getghc 算 $|HC\rangle$
      6. 解析求 $\theta$:$\tan(2\theta) = 2\langle\psi|H|C\rangle/(\langle\psi|H|\psi\rangle - \langle C|H|C\rangle)$
      7. $|\psi_{\text{new}}\rangle = \cos\theta|\psi\rangle + \sin\theta|C\rangle$
  • band 2: 相同流程,但每步都先把 band 1 投掉

  • ...

  • band 8

子空间对角化(Rayleigh-Ritz)

CG 收敛到正交基附近,但不严格在最优旋转上。subdiago 在 8 维子空间精确对角化:

$$H_{nm} = \langle\psi_n|H|\psi_m\rangle,\quad \text{对角化};H_{nm} \to \epsilon_n,;\psi_n^{\text{new}} = \sum_m c_{nm}\psi_m$$

累加 ρ 与能量

do iband = 1, 8
   ρ(r) += wtk(1) · occ(iband) · |ψ_{iband,k=1}(r)|²
   E_band += wtk(1) · occ(iband) · ε(iband)
end do

循环回 k=2, 3, ..., 10 重复 1.2-1.5

vtorho 结束,得到 residm

residm = max over all (k, n) of resid_k(n)

算总能、新势

call newocc(... → fermie, occ)             ! 占据数 + Fermi 能(见 smearing 报告)
call rhotoxc(rho → vxc)
call hartre(rho → vhartr)
V_out = vpsp + vhartr + vxc
R = V_out - V_in
res2 = ‖R‖²
deltae = E_total[istep=1] - E_total[istep=0]

检查收敛(scprqt

if (tolvrs > 0 .and. res2 < tolvrs) then
   tolvrs_ok = tolvrs_ok + 1
   if (tolvrs_ok >= 2) quit = 1  ! 连续 2 次满足才退出
end if

istep=1 通常远未收敛,res2 ≈ 1e-2,继续。

Pulay 混合(ab7_mixing_eval

istep=1 时还没有历史,退化为简单混合:

V_in[2] = V_in[1] + diemix * K_prec * R[1]

存:f_fftgr(:, :, i_vrespc(1)) = R[1], f_fftgr(:, :, i_vtrial(1)) = V_in[1]

Step 2(istep=2

同样调 vtorho,但已经有 V_in[2]

  • 用上一步收敛的 $\psi^{(1)}_{n\mathbf{k}}$ 作初值(很好的猜测)
  • 每条 band 只需 1-2 次 line minimization 即可收敛到当前 V

Pulay 混合:1 步历史 = Anderson 1 阶

λ = <R[2], R[2]-R[1]> / ‖R[2]-R[1]‖²
V_in[3] = (1-λ)(V_in[2]+R[2]) + λ(V_in[1]+R[1])

Step 3..7(istep=3-7

每步 Pulay 历史增加,第 7 步用 7 步历史的 Pulay。res2 通常每步缩小 1-2 个数量级。

istep    res2          deltae       residm
  1      1e-2          —            1e-3
  2      3e-4         -0.012        2e-5
  3      8e-7         -1.2e-4       3e-7
  ...
  7      5e-13        -1e-10        2e-12

Step 8(收敛退出)

res2 = 5e-13 < tolvrs = 1e-12 第二次满足 → quit = 1 → 退出 SCF 循环。

Step 后处理

  • 写 WFK:${\psi_{n\mathbf{k}}}$ 完整谱
  • 写 EIG:${\epsilon_{n\mathbf{k}}}$
  • 算力、应力(如需)
  • 报告 conv_retcode = 0

典型坑与诊断

SCF 不收敛振荡

  • 金属体系 + diemix 过大 → 调小 diemix 到 0.3-0.5
  • diemac 错误:金属用 1e6,绝缘体用 6-10。给绝缘体设 1e6 会过预处理。
  • k 点不够密:金属需要 ≥ 16³ 配 smearing。

SCF 单调下降但极慢

  • 切到 Pulay (iscf 7 / 17) + 增大 npulayit 到 10-15
  • 启用 iprcel 45 用更好的预条件器
  • 几何步间用 densfor_pred 6 做密度外推

本征值求解器选择

场景推荐 wfoptalg理由
小系统 (<100 原子),单进程0(CG)最稳定,开销低
中等系统,MPI ≤ 32114(LOBPCG)块运算高效
大系统 (>500 原子),MPI > 64111(ChebFi)RR 不再瓶颈
PAW 计算10(CG)/ 114改进预条件器
难收敛/磁性0 + nline 6-8CG 鲁棒性最好

tolwfr_diago vs tolwfr

  • tolwfr_diago:单 k 点内对角化器的目标残差。默认与 nstep 有关。
  • tolwfr:作为 SCF 收敛判据(仅非自洽必填)。
  • 两者别混淆:自洽计算中 SCF 用 tolvrs,内部用 tolwfr_diago 控制对角化精度。

关键代码地图

模块 / 子程序文件行号作用
scfcv_coresrc/94_scfcv/m_scfcv_core.F90263SCF 外循环主体
etotfor同上2561总能 + 力
scprqtsrc/67_common/m_common.F90183收敛判据
vtorhosrc/79_seqpar_mpi/m_vtorho.F90由 V 求 ρ + k 点循环
vtowfksrc/79_seqpar_mpi/m_vtowfk.F90177单 k 点对角化器分发
cgwfsrc/67_common/m_cgwf.F90197标准共轭梯度
lobpcgwf2src/79_seqpar_mpi/m_lobpcgwf.F9082LOBPCG 高层
lobpcg_runsrc/48_diago/m_lobpcg2.F90340LOBPCG 核心算法
chebfisrc/66_wfs/m_chebfi.F90102Chebyshev 滤波
rmm_diissrc/66_wfs/m_rmm_diis.F90RMM-DIIS
getghcsrc/66_wfs/m_getghc.F90$H\psi$ 算子(FFT + nonlop)
cg_preconsrc/44_abitools/m_cgtools.F903651Teter 多项式预条件
ab7_mixing_newsrc/56_mixing/m_ab7_mixing.F90161混合器初始化
ab7_mixing_eval同上623混合主入口
scfopt同上1868势混合算法(包括 Pulay/Anderson)
xg_RayleighRitzsrc/45_xgTools/m_xg_ortho_RR.F90Rayleigh-Ritz 子空间对角化

SCF 收敛全景图(一图流总结)

┌──────────────────────────────────────────────────────────────────────────┐
│                       SCF 外循环(scfcv_core)                          │
│                                                                          │
│   ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐         │
│   │  V_in    │ →  │ vtorho    │ →  │ etotfor   │ →  │ scprqt   │         │
│   │ (势)     │    │ 求 ψ, ρ   │    │ E, F, σ   │    │ 收敛?   │         │
│   └──────────┘    └──────────┘    └──────────┘    └──────────┘         │
│        ↑              │                                  │              │
│        │              │                                  │              │
│        │         ┌────────────────────────────────┐      │              │
│        │         │      内循环(vtowfk)          │      ↓              │
│        │         │                                │     收敛?           │
│        │         │  对每个 (isppol, ikpt):        │     /     \         │
│        │         │     CG / LOBPCG / ChebFi       │   是       否        │
│        │         │                                │    │        │        │
│        │         │  每条/每块 band:               │    ↓        │        │
│        │         │     getghc → 预条件 → RR       │   退出      │        │
│        │         └────────────────────────────────┘             │        │
│        │                                                        ↓        │
│        │         ┌────────────────────────────────┐  ┌────────────────┐ │
│        │         │   ρ_out → vxc, vhartre → V_out │  │ ab7_mixing_eval│ │
│        │         └────────────────────────────────┘  │ Pulay/Anderson │ │
│        │                          │                  └────────────────┘ │
│        └──────────────────────────┴──────────────────────┘              │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘
                  最贵的步骤:getghc (FFT × 2 + nonlop)
                  收敛速度由:预条件器 + 混合算法 决定
                  鲁棒性由:tolerance + 历史长度 决定

报告生成于 2026-05-19,基于 Abinit 10.4.7。

References

Anderson, Donald G. "Iterative Procedures for Nonlinear Integral Equations." Journal of the ACM, vol. 12, no. 4, 1965, pp. 547–560. link

Gonze, Xavier, et al. "The Abinit Project: Impact, Environment and Recent Developments." Computer Physics Communications, vol. 248, 2020, p. 107042. link

Knyazev, Andrew V. "Toward the Optimal Preconditioned Eigensolver: Locally Optimal Block Preconditioned Conjugate Gradient Method." SIAM Journal on Scientific Computing, vol. 23, no. 2, 2001, pp. 517–541. link

Levitt, Antoine, and Marc Torrent. "Parallel Eigensolvers in Plane-Wave Density Functional Theory." Computer Physics Communications, vol. 187, 2015, pp. 98–105. link

Payne, M. C., et al. "Iterative Minimization Techniques for Ab Initio Total-Energy Calculations: Molecular Dynamics and Conjugate Gradients." Reviews of Modern Physics, vol. 64, no. 4, 1992, pp. 1045–1097. link

Pulay, Peter. "Convergence Acceleration of Iterative Sequences. The Case of SCF Iteration." Chemical Physics Letters, vol. 73, no. 2, 1980, pp. 393–398. link

Teter, Michael P., Michael C. Payne, and Douglas C. Allan. "Solution of Schrödinger's Equation for Large Systems." Physical Review B, vol. 40, no. 18, 1989, pp. 12255–12263. link

The Abinit Code. Version 10.4.7, 2024. link