# showcase_transform_xc **Repository Path**: ajz34/showcase_transform_xc ## Basic Information - **Project Name**: showcase_transform_xc - **Description**: 简单理解 transform_xc 与演示程序 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-04-23 - **Last Updated**: 2025-06-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 简单理解 transform_xc 与演示程序 这个 Rust crate 应该可以处理与 `pyscf.dft.xc_deriv.transform_xc` 相似 (弱化) 的问题。 当前可以处理的 DFT 导数上至 3 阶 (PySCF 实际上可以处理任意阶导数)。更高阶导数显然是可行的,但需要进行额外测试;且目前在一段时间内,更高阶导数在我们的应用情景中还暂时没有需求。 当前具有主要功能的函数是 `transform_xc::transform_xc_inner`。该函数由于传入与传出 RSTSR 张量,未来可能需要对此作修改。 我认为 transform_xc 任务通常并非瓶颈 (稍大的 $O(n_\mathrm{grid})$ 的运算与存储),因此这一段程序效率应不是关键的。 ## 如何测试该程序 参考 Github Action 自动脚本: 1. 安装 PySCF (尽量 > 2.5); 2. 在 repo 根目录执行 `gen_test_manifests.sh` 以通过 PySCF 生成测试用例的输入与输出; 3. 在 repo 根目录执行 `cargo test`。 ## 简问简答 ### 为什么有些情况下会倾向于 transform_xc,而不直接使用 libxc 或 xcfun 的导出结果? 我认为 transform_xc 的目的是将 DFT 格点 (及其偏导) 从一种标准形式 (libxc, xcfun 等程序的输出): $$ f(\rho, \gamma, \tau) $$ 转到另一种标准形式: $$ f(\rho, \partial_x \rho, \partial_y \rho, \partial_z \rho, \tau) $$ 其中 (依 PySCF 代码习惯,$\gamma$ 在程序中称为 `sigma`) $$ \gamma = \nabla \rho \cdot \nabla \rho $$ $\gamma$ 这一项在写程序或者推公式的时候具有一个非常不好的性质:它是密度矩阵 (或密度相关量) 的二次项;这与 $\rho$ 本身或者动能密度 $\tau$ 都是一次项不同。在处理涉及 $\gamma$ 的导数、特别是二阶导数以上的高阶导数时,这种二次性质会在实现方法时引入不少麻烦。transform_xc 将这些麻烦前置到 $f$ 格点积分的导数表达式上,而后续计算化学家在实现自己的方法时则只需要处理一次的变量 $(\rho, \partial_x \rho, \partial_y \rho, \partial_z \rho, \tau)$。 但对于导数阶数较小的情景 (譬如自洽场计算),由于 $\gamma$ 的二次性质导致的表达式复杂程度并不大,是容易处理的。在这种情景下,选择 transform_xc 与否,单纯取决于偏好哪一种标准形式。 ### 一定要将张量库引入依赖吗? 我一开始也不想用张量库。 - 表面原因是,张量库毕竟是一个额外的依赖;会增加编译、调用难度,降低函数接口的一致性; - 深层原因是,张量库在一些情形下是伪需求。Python 之所以必须要张量库 (NumPy 为代表),是因为如果不用它,再简单的问题效率都有可能一塌糊涂。NumPy 之于 Python 是对效率稍微有那么一点点要求的情况就必须要上的库。但对于 Rust,张量库的使用很多时候未必就比手写循环更快 (特指 element-wise 运算;线性代数和张量缩并问题不是我等脚本玩家随便优化优化就能搞的);如果张量库不能提供 API 使用上的便捷性,那么它本身就是个伪需求。事实上,在当前问题中,除了最后的主程序 `transform_xc_inner` 之外,其余的部分不用张量库也一样能处理。 仍然使用张量库原因是 - 在中间过程,可以方便地进行 transpose, diagonal_mut, basic indexing, (col-major based) broadcasting,以及一部分 elementwise 运算。其他的编写模式 (手动计算内存位置、宏展开等) 都会大幅增加编写与维护难度。 - 在函数传入与传出参量中,比较方便地嵌入维度信息。 我认为中间过程的运算上,使用 RSTSR 张量 (或者具有等价功能的其他高维张量库) 某种程度上是必要的;但传入传出参数是可以避免使用 RSTSR 张量的。 张量库是否是一个伪需求?我认为这需要看情况讨论;并认为一般来说并不是伪需求,只是必须要使用的情景会比 Python 等语言要少一些。