atomppgen.kb

Kleinman-Bylander 可分离非局域势转换

将半局域势 {V_l(r)} 转换为可分离形式:

其中投影子 β_l(r) 和耦合系数 D_l 通过以下方式构造:

  1. 选择局域道 V_loc(r) = V_l*(r)(通常选择未占据的高角动量通道,如 d)

  2. 构造未归一化投影子:χ_l(r) = [V_l(r) - V_loc(r)] · φ_l(r)

  3. 归一化:β_l(r) = χ_l(r) / √⟨χ_l|χ_l⟩,使得 ⟨β_l|β_l⟩ = 1

  4. 耦合系数: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

kb_transform(invert_results, u_by_l, r, w[, ...])

将半局域势转换为 Kleinman-Bylander 可分离形式

Classes

KBResult(V_loc, beta_l, D_l, loc_channel, r, ...)

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

beta_l

投影子 {l: β_l(r)}(Bohr^{-3/2},已归一化)

Type:

Dict[int, np.ndarray]

D_l

耦合系数 {l: D_l}(Hartree)

Type:

Dict[int, float]

loc_channel

局域通道角动量量子数 l*

Type:

int

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

V_loc: ndarray
beta_l: Dict[int, ndarray]
D_l: Dict[int, float]
loc_channel: int
r: ndarray
diagnostics: Dict
__init__(V_loc, beta_l, D_l, loc_channel, r, diagnostics)
参数:
返回类型:

None

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)

返回:

包含局域势、投影子、耦合系数和诊断信息

返回类型:

KBResult

抛出:

ValueError -- 如果局域通道不在 invert_results 中 如果网格长度不匹配

备注

  1. 局域道选择:优先选择无占据态的高角动量通道(如 Al 的 d)。 占据通道作为局域道会引入额外的数值问题。

  2. 径向规约波函数:φ_l(r) = u_l(r)/r,满足径向薛定谔方程。 在 r→0 时,u_l ~ r^{l+1},因此 φ_l ~ r^l 有限。

  3. 耦合系数公式: 标准 KB 形式:V_NL = |χ⟩ D ⟨χ|,其中 D = 1/⟨φ|ΔV|φ⟩ 本实现使用归一化投影子 β = χ/√⟨χ|χ⟩,因此: D_l = ⟨χ|χ⟩ / ⟨φ|ΔV|φ⟩ = W / Z 其中 W = ∫ |χ|² w dr,Z = ∫ ΔV · φ² w dr

  4. 数值稳定:原点附近 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)