atomppgen.kb
Kleinman-Bylander 可分离非局域势转换
将半局域势 {V_l(r)} 转换为可分离形式:
V_NL = Σ_l |β_l⟩ D_l ⟨β_l|
其中投影子 β_l(r) 和耦合系数 D_l 通过以下方式构造:
选择局域道 V_loc(r) = V_l*(r)(通常选择未占据的高角动量通道,如 d)
构造未归一化投影子:χ_l(r) = [V_l(r) - V_loc(r)] · φ_l(r)
归一化:β_l(r) = χ_l(r) / √⟨χ_l|χ_l⟩,使得 ⟨β_l|β_l⟩ = 1
耦合系数:D_l = ⟨χ_l|χ_l⟩ / ⟨φ_l|ΔV|φ_l⟩ 其中 ΔV = V_l - V_loc
技术要点
局域道选择:优先选择无占据态的高 l 通道(如 Al 的 d 通道)
径向规约波函数:φ_l(r) = u_l(r)/r
数值稳定:r→0 时 u_l ~ r^{l+1},φ_l ~ r^l,β_l 在原点有限
耦合系数:采用归一化投影子形式,D = W/Z 保证物理等价性
主要功能
kb_transform : 半局域势到 KB 可分离形式的转换 KBResult : 存储 KB 转换结果的数据类
参考文献
Kleinman & Bylander, PRL 48, 1425 (1982) Giannozzi, Notes on pseudopotential generation (2019)
Functions
|
将半局域势转换为 Kleinman-Bylander 可分离形式 |
Classes
|
Kleinman-Bylander 转换结果 |
- class atomppgen.kb.KBResult(V_loc, beta_l, D_l, loc_channel, r, diagnostics)[源代码]
Kleinman-Bylander 转换结果
- 参数:
- V_loc
局域势 V_loc(r)(Hartree)
- Type:
np.ndarray
- r
径向网格(Bohr)
- Type:
np.ndarray
- diagnostics
诊断信息: - n_channels : 通道数 - projector_norms : 归一化前的投影子模 {l: ⟨β_l|β_l⟩} - coupling_strengths : 耦合强度 {l: D_l} - loc_potential_max : 局域势最大值 - loc_potential_min : 局域势最小值
- Type:
Dict
- atomppgen.kb.kb_transform(invert_results, u_by_l, r, w, loc_channel=2)[源代码]
将半局域势转换为 Kleinman-Bylander 可分离形式
对于每个非局域通道 l ≠ l*,构造投影子:
β_l(r) = [V_l(r) - V_loc(r)] · φ_l(r)
其中 φ_l(r) = u_l(r)/r 是径向规约波函数。
归一化条件:⟨β_l|β_l⟩ = 1,耦合系数 D_l = ⟨β_l|[V_l - V_loc]|β_l⟩。 在归一化投影子的情况下,D_l = 1/⟨β_l(原始)|β_l(原始)⟩。
- 参数:
invert_results (Dict[int, InvertResult]) -- 半局域势反演结果 {l: InvertResult}
u_by_l (Dict[int, np.ndarray]) -- 径向波函数 {l: u_l(r)}
r (np.ndarray) -- 径向网格(Bohr)
w (np.ndarray) -- 积分权重
loc_channel (int, default=2) -- 局域通道 l*,默认为 d 通道(l=2)
- 返回:
包含局域势、投影子、耦合系数和诊断信息
- 返回类型:
- 抛出:
ValueError -- 如果局域通道不在 invert_results 中 如果网格长度不匹配
备注
局域道选择:优先选择无占据态的高角动量通道(如 Al 的 d)。 占据通道作为局域道会引入额外的数值问题。
径向规约波函数:φ_l(r) = u_l(r)/r,满足径向薛定谔方程。 在 r→0 时,u_l ~ r^{l+1},因此 φ_l ~ r^l 有限。
耦合系数公式: 标准 KB 形式:V_NL = |χ⟩ D ⟨χ|,其中 D = 1/⟨φ|ΔV|φ⟩ 本实现使用归一化投影子 β = χ/√⟨χ|χ⟩,因此: D_l = ⟨χ|χ⟩ / ⟨φ|ΔV|φ⟩ = W / Z 其中 W = ∫ |χ|² w dr,Z = ∫ ΔV · φ² w dr
数值稳定:原点附近 r→0 时使用 np.maximum(r, r_min) 保护除法。
示例
>>> from atomppgen import solve_ae_atom, tm_pseudize, invert_semilocal_potential >>> ae = solve_ae_atom(Z=13, spin_mode='LDA', lmax=2) >>> invert_results = {} >>> for l in [0, 1, 2]: ... tm = tm_pseudize(ae.r, ae.w, ae.u_by_l[l][-1], ae.eps_by_l[l][-1], l, rc=2.0+0.1*l) ... invert_results[l] = invert_semilocal_potential(tm, ae.r) >>> kb = kb_transform(invert_results, {l: ae.u_by_l[l][-1] for l in [0,1,2]}, ... ae.r, ae.w, loc_channel=2) >>> print(kb.diagnostics['n_channels']) # 3 (s, p, d)