Libxc专题

Libxc自旋meta-GGA:九变量数组与r²SCAN实例

完整C程序演示自旋r²SCAN的一阶势、9×9二阶矩阵、自旋互换和零极化对照。

更新于 2026-11-05约 5 分钟阅读按任务与环境选择适用配置
阅读本篇目录

上一份导数接口教程使用自旋PBE和非自旋r²SCAN。本篇继续展示共线自旋r²SCAN:输入从4个独立变量增加为9个,不能再按非自旋数组长度调用。只需要通过VASP使用r²SCAN的用户,无需编写这些代码,可先看Libxc的VASP实操。

下载完整C程序、三个版本的真实CSV与绘图程序。

1 下载、执行、查看#

将资料包保存为libxc-spin.zip,在允许使用的CPU环境中执行:

unzip libxc-spin.zip -d libxc-spin
cd libxc-spin
bash run.sh

入口加载oneAPI 2024.2,用icx分别链接libraries.json里的Libxc 6.2.2、7.0.0、7.1.2既有私有库。程序串行运行,不需要GPU,不修改宿主库。需在新目录运行,已有results时退出;绘图默认使用集群ASE Python中的Matplotlib,也可通过PLOTPY指定自己的绘图Python。

head results/7.1.2/derivatives.csv
cat results/7.1.2/spin-controls.csv
ls figures

每版得到3600行导数数据、8行自旋对照。reference保存实际结果;results/VALIDATION.json列出17,088项检查和每个步长的误差。这里计算的是局域泛函函数值,不是某个材料的自洽能量或磁化率。

2 九个变量如何排列#

本例使用以下顺序,所有量采用原子单位:

索引 变量 基准点示例
0、1 rho_up, rho_down 0.12、0.08
2、3、4 sigma_uu, sigma_ud, sigma_dd 0.012、0.003、0.008
5、6 lapl_up, lapl_down 0、0
7、8 tau_up, tau_down 0.3、0.2

sigma_uu和sigma_dd分别为两个自旋密度梯度的平方;sigma_ud为两个梯度的点积,不能额外乘2。tau为相应自旋通道的动能密度,不能用一个长度为1的数组代替。

double rho[2] = {0.12, 0.08};
double sigma[3] = {0.012, 0.003, 0.008};
double lapl[2] = {0.0, 0.0};
double tau[2] = {0.3, 0.2};
xc_func_type f;
xc_func_init(&f, 497, XC_POLARIZED);
/* 完整输出数组和调用见spin_mgga.c */

497是r²SCAN交换,498是r²SCAN关联,程序分别计算,不把单个分量称作完整XC。四个局域点使用缩放因子0.5、0.8、1、1.5构造;每次求偏导只扰动一个变量,其他变量固定。

3 二阶输出为什么有这么多块#

xc_mgga_exc_vxc_fxc分别返回9个一阶分量和下列二阶块:

二阶块 输出长度
rho–rho 3
rho–sigma 6
rho–lapl、rho–tau 各4
sigma–sigma 6
sigma–lapl、sigma–tau 各6
lapl–lapl、tau–tau 各3
lapl–tau 4

合计45个独立分量,展开后为9×9对称矩阵。同组变量的对称块按上三角逐行展开,混合块按行优先展开。例如rho–sigma的6个数,先给出rho_up对应三个sigma的导数,再给出rho_down对应的三个。

完整程序的rect和sym只负责按照接口排列展开,随后用一阶输出的独立有限差分核对9×9全部位置,不以展开后的对称性本身证明正确。

r²SCAN不使用拉普拉斯,因此本例索引5、6相关的一阶、二阶位置都应为0。调用前输出数组全部清零,调用后对这些位置再做严格零检查。其他依赖拉普拉斯的meta-GGA仍需保留对应导数。

4 数值差分核对什么#

一阶导数应来自能量密度:

F = (rho_up + rho_down) × epsilon_xc

库返回的exc是每电子能量,不是这个能量密度。二阶则由一阶势对各变量做中心差分得到。相对步长从1e-3扫描到1e-7;实际扰动为相对步长 × max(abs(变量值), 0.01)。

自旋meta-GGA差分步长扫描与实际局域分量

每个独立分量至少有两个步长满足1e-7 + 3e-5 × abs(解析值)的比较尺度。粗步长的截断误差、很小步长的舍入误差都会增大;图中保留所有步长的结果,不表示每一个点都同样精确。

python3 - <<'PY'
import csv
p = 'results/7.1.2/derivatives.csv'
for row in csv.DictReader(open(p)):
    if row['id'] == '497' and row['point'] == '2':
        if row['step'] == '2' and row['row'] == '0' and row['col'] == '1':
            print(row)
PY

这条命令提取交换分量基准点上rho_up–rho_down的交叉二阶导数,以及相对步长1e-5的差分值。

5 两个自旋对照,帮助排除数组混用#

第一组把上下自旋完全互换:密度、拉普拉斯和动能密度对应交换,sigma_uu与sigma_dd交换,sigma_ud保留。没有外部自旋方向偏好的局域泛函,其每电子能量应不变。本例在三个版本的全部8个交换/关联局域点逐项比较,绝对差不超过1e-12 Ha。

第二组将同一个非自旋输入拆成零极化自旋输入:

rho_up = rho_down = rho / 2
sigma_uu = sigma_ud = sigma_dd = sigma / 4
lapl_up = lapl_down = lapl / 2
tau_up = tau_down = tau / 2

三个sigma项都是四分之一,因为梯度各为总密度梯度的一半。程序分别调用非自旋和自旋接口,本例能量差均在1e-12 Ha以内;真实结果在spin-controls.csv,不是预先填入的参考常数。

6 怎样读二阶结果#

r²SCAN交换、关联的自旋密度二阶块

图中只画rho–rho块,三条曲线具有相同量纲Ha·bohr³,可直接比较。横轴表示所选局域输入点的总密度;sigma和tau也随各基准点变化,因此曲线不是“固定其他局域量、连续对rho求导”的路径。

rho–sigma、sigma–tau等块的量纲不同,不与rho–rho混在同一个物理纵轴上。矩阵分量也不直接等于材料的磁化率、声子或介电常数;宿主软件还需完成相应响应方程。

本篇覆盖共线自旋r²SCAN的局域一阶/二阶接口,不延伸为非共线、自旋流或任意泛函的专有参数。高阶导数的运行时查询及宿主边界见Libxc导数接口,名称与编号见版本和组合泛函。接口定义参考Libxc官方手册及各安装前缀的include/xc.h。

需要根据你的体系选择资源?联系讨论计算需求。实际可用软件与权限,以当前账户和运行环境为准。

查看配图

放大后可滚动查看细节,按 Esc 关闭。

100%查看原图 ↗