简介:Octopus 4.1.0 资源包面向量子化学、凝聚态物理及材料设计领域的科研人员与研究生,提供基于密度泛函理论(DFT)与时间依赖密度泛函理论(TDDFT)的第一性原理电子结构计算工具。包内通常包含源码、编译脚本、官方文档与示例输入文件,可支撑基态预计算、TDDFT 参数设置、激发态响应分析以及吸收/荧光光谱模拟等完整流程,帮助使用者快速搭建本地计算环境并复现典型算例。资源包为 gz 压缩格式,整体大小约 4.58MB,便于下载与部署。该资源目前已有 409 人浏览学习,适合正在入门 TDDFT 模拟或需要了解 Octopus 实际用法的研究者。通过配置与运行示例,读者可以逐步理解交换关联泛函选择、频率网格设置、输出文件解析及电子密度可视化等关键环节,从而将软件应用到太阳能电池材料、光催化机制等前沿课题中。
1. Octopus 做 TDDFT 模拟计算:实空间实时演化,能算出什么、适合算什么
做激发态动力学和光谱模拟的人,多半都听过 Octopus 这个名字。它是一套以实空间网格为基组的开源 DFT/TDDFT 程序,长项不是算基态能带,而是直接把含时 Kohn-Sham 方程扔到格点上做实时演化,得到吸收谱、等离激元、电荷转移过程这类平面波程序不擅长的东西。TDDFT 模拟计算里,Octopus 和常见的 GPAW、cp2k 思路并不一样,它不靠平面波截断,而是靠实空间格点间距和盒子大小控制精度,这个差异决定了它既灵活又容易翻车。这篇文章想讲清楚一件事:你在终端里敲完octopus回车之后,那个黑匣子里到底发生了什么,以及怎么把它调成能落地、能复现、能写进论文支撑材料的结果。
这套代码适合三类人:做分子激发态吸收谱的、做纳米团簇等离激元的、做超快电荷转移动力学的。如果你只是算一个孤立分子的基态能级,Octopus 不是最顺手的选择;但凡是需要“光场进来之后体系怎么响应”的问题,就值得在这里把流程和参数摸透。下面按我自己的使用习惯,从选型逻辑开始,一路走到避坑和验证。
2. 为什么选实时实空间方案:Octopus 的 TDDFT 原理与输入文件骨架
2.1 实时 TDDFT 与线性响应:两种形态,两种代价
TDDFT 模拟计算大体分两条路线:一条是线性响应路线,比如 Casida 方程,直接从基态出发解出激发能和振子强度;另一条是实时路线,也叫 RT-TDDFT,给体系加一个微扰场,再让波函数在时间轴上往前传播,最后对偶极矩做傅里叶变换得到光谱。
Octopus 两条都支持,但它的招牌是实时路线。原因在于它的实空间离散方式很适合做含时演化,每一步都是稀疏矩阵乘向量,不需要像平面波那样频繁做 FFT 换空间。常见做法是给体系一个非常短的 delta 脉冲电场,相当于一次性“踢”所有频率,观察体系自由演化几飞秒到几十飞秒。这里有个选择分叉点:如果你只关心低能激发态,线性响应更快;如果你想看强场下的非线性响应、等离激元衰减、载流子动力学,实时路线几乎是必须的。
Octopus 默认的数值方案里,有两点直接决定成败:一是 Kohn-Sham 波函数在实空间格点上的表示,二是传播子对时间步长极其敏感。前者影响空间分辨率,后者影响能量守恒。这两条也是后面所有坑的根源,先记住这个判断,后面调参就有一条主线。
2.2 从源码构建 Octopus:最少依赖组合和一条能跑通的路
拿到手的第一步是编译。虽然各发行版可能有现成的包,但 TDDFT 模拟计算经常要改编译选项,我倾向于自己编。构建顺序常见是这样:
# 准备依赖:libxc、lapack/blas、可选mpi和fftw ./autogen.sh ./configure --prefix=$HOME/octopus-install \ --enable-mpi --with-libxc \ --with-blas=-lblas --with-lapack=-llapack make -j4 make install逻辑说明:autogen.sh生成 configure 脚本,--prefix指定安装目录,不污染系统路径。MPI 开关能让多核并行,但首次验证功能建议先关掉,否则并行化引入的通信开销会干扰你判断问题出在物理还是并行。libxc是必需的交换关联泛函库,没有它就是空壳。
参数说明:--with-libxc要确保系统里已装好 libxc 头文件,否则 configure 会报错。检查依赖是否满足最快的方式是看configure输出末尾的Configuration summary,确认xc一栏不是no。
装完先跑一下octopus --version,如果提示找不到动态库,把$HOME/octopus-install/lib加进LD_LIBRARY_PATH。第一次运行建议进入一个空目录,放一个最简单的输入文件,让程序生成一个octopus主目录结构,这样你就能看清restart/、td.general/、static/这些子目录分别承担什么职责。这一步跑通了,后面的问题才谈得上有排查入口。
2.3 输入文件骨架:10 个核心变量一张表说清
Octopus 的输入文件叫inp,不是常见的INPUT或*.inp,而且变量名区分大小写。我一般会把基态和含时计算拆成两套输入,用CalculationMode切换。TDDFT 模拟计算最核心的变量集中在盒子、网格、时间传播三块:
| 变量名 | 典型值 | 作用 | 失败症状 |
|---|---|---|---|
CalculationMode | gs/td | 切换基态和含时模式 | 模式不对直接报错或算出基态能量 |
Spacing | 0.2 | 实空间格点间距 | 间距太大会出现原子间电子密度“漏掉” |
Radius | 8.0 | 盒子半径 | 太小会把波函数截断,总能量不收敛 |
BoxShape | sphere/parallelepiped | 模拟盒形状 | 分子长轴方向超出盒子,出现伪限制效应 |
TheoryLevel | dft/independent | 是否包含电子相互作用 | independent用于测试网格,不用于真实结果 |
Species | `"C" | species_pseudo | ...` |
TDExternalFields | "delta_pulse" | 外加含时场 | 不设定则“实时演化但没有激发” |
TDDeltaStrength | 0.01 | 微扰强度 | 太强进入非线性区,太弱信噪比差 |
TDPropagator | aetrs | 传播算法 | 选错传播子会能量漂移 |
DeltaT | 0.0015 | 含时演化时间步长 | 太大直接能量爆炸 |
第一份测试输入建议只做基态,等基态收敛再说 TD 的事。基态没算准,TDDFT 就是空中楼阁,这个顺序我建议新人别跳。常见做法是先在盒子参数上粗抛一组,跑通后加密网格,看总能量变化趋势,这是后话,但这里先说一句:Spacing每减半一次,网格点数大概涨 8 倍,内存和耗时都跳一个量级,从一开始就要有“这是一笔计划内的开销”的预期。
3. 亲手跑通一条 TDDFT 工作流:基态到 delta 脉冲到吸收谱
3.1 第一步:先把基态跑干净
TDDFT 模拟计算不可能跳过基态。用最小输入把基态跑通,这个阶段适合验证伪势和盒子是否匹配。示例输入如下:
CalculationMode = gs FromScratch = yes Spacing = 0.25 Radius = 8.0 BoxShape = sphere TheoryLevel = dft %Species "C" | species_pseudo | "C.psf" "H" | species_pseudo | "H.psf" % PseudopotentialSet = pseudo_dojo ConvAbsDens = 1e-8逻辑说明:species_pseudo表示用程序内置的伪势处理方式,后面的字符串是伪势文件名。pseudo_dojo是常见的推荐选择,它提供了带范数守恒的赝势,适合在 Octopus 的实空间网格中直接使用。ConvAbsDens是密度收敛精度,我通常先放 1e-8,跑不动再退到 1e-6,但心里要知道后面所有谱线都建立在密度基本收敛的前提上。
参数说明:Radius和Spacing是一对。比如碳原子形成的杂化体系,0.25 的间距已经能给出合理趋势,但要出可发表的数据,通常要加密到 0.2 甚至更小。FromScratch = yes表示忽略已有 restart 文件,改参数后要重新算,这是个操作陷阱,改了几何或网格后忘记设FromScratch,Octopus 很可能沿用旧 restart 给出一个看似合理但牛头不对马嘴的结果。
跑完看两个东西:终端里有没有出现SCF converged,以及static/info文件里的总能量。这里有个玄学经验:总能量数值本身没有绝对意义,关键是换个网格参数后它是否稳定在某个区间内。如果你发现 0.25 和 0.22 两种间距下总能量差超过 0.01 Ha,继续加细之前别提物理结论。
3.2 第二步:在基态上加载 delta 脉冲并做实时演化
基态收敛后,新建一个目录,把restart文件软链或拷贝过来,然后把CalculationMode改成td。常见输入如下:
CalculationMode = td FromScratch = no Spacing = 0.22 Radius = 9.0 BoxShape = sphere T = 25.0 DeltaT = 0.0015 TDPropagator = aetrs TDEvolutionMethod = 0 %TDExternalFields "delta_pulse" | "electric_field" | "beta" % TDDeltaStrength = 0.01 %TDOutput "dipole" %逻辑说明:FromScratch = no让它读取基态的 restart 目录,这一步做错最常见的结果是程序从头开始重新 SCF,你等半天以为是传播慢,其实人家在重新做基态。T = 25.0的单位是原子单位(1 a.u. ≈ 0.0242 飞秒),25 个原子单位大概对应 0.6 飞秒,对分子吸收谱往往不够,后面进阶部分会讲怎么加长。TDOutput = "dipole"会把偶极矩记录到td.general/multipoles文件,这是后续所有光谱分析的数据源。
参数说明:TDDeltaStrength = 0.01单位也是原子单位,大约对应 5 mV/埃 级别的电场,对大多数分子处于线性响应区。如果是大体系,delta 脉冲响应信噪比会变差,这时常见做法是稍微增强到 0.02–0.03,但你要知道这个值再往上提,光谱峰位会向红移,因为非线性效应开始出现。TDEvolutionMethod = 0在目前版本里对应 Magnus 类传播子之一,我习惯于先固定这个值,遇到能量守恒问题再换。
3.3 第三步:从偶极矩到吸收光谱,不是直接画 FFT
TDDFT 模拟计算里,最容易被误读的一步是把偶极矩数据丢进任意 FFT 工具直接出谱。实际上你拿到的是含时偶极矩 μ(t),要得到极化率张量 α(ω),需要用微扰论公式做傅里叶变换,再乘上 4πω/c 得到吸收截面。Octopus 自带工具能处理这个转换,常见做法是:
oct-fourier td.general/multipoles然后看输出的极化率张量,或者直接导出虚部来画吸收谱。这个工具的名字在不同版本里有出入,最新的版本可能叫oct-dielectric_function一类,我的习惯是oct-fourier --help先确认参数,不要凭记忆乱敲。它默认会做 damping,把长时间段的噪声压低,这个参数叫gamma,通常取 0.005 到 0.05 之间,天然对应谱线展宽。
这里有一个需要立刻记在脑子里的坑:偶极矩数据的采样间隔由DeltaT决定,而傅里叶变换的频率分辨率和总时长T成反比。25 原子单位的总时长只能给出非常粗的峰形,如果你在光谱里看到一个峰感觉“半宽”特别大,不要先怀疑物理,先去检查T是不是太短了。这个点后面避坑章再展开。
4. 伪势、网格间距与传播参数:三个决定命运的黑匣子
4.1 伪势选择:实空间网格对振荡区很敏感
Octopus 的实空间有限差分和平面波代码有个关键差异:它没有一个天然的“截断能量”来过滤芯态波函数的快速振荡,所以伪势的选择更加敏感。常见做法是使用范数守恒类伪势,而pseudo_dojo是社区里相对可靠的一个集合。需要注意,不同伪势对应的推荐最小网格间距是不一样的,你必须做收敛测试而不是只信 README。
具体踩到的经验是:同一元素换了一组伪势,原来 0.25 的间距下总能量收敛看着没问题,换了以后同样的间距直接出现虚频或 SCF 震荡。这不是代码坏了,是新的势在实空间下需要更细的网格才能解析。遇到这种“换了伪势一切都变”的情况,不要急着怀疑输入,先用更小的Spacing跑一维扫描,看能量趋势能不能拉平。
伪势文件路径出了问题,Octopus 的报错也很直接,提示找不到某个.psf或者.vps文件。这个时候先检查PseudopotentialSet是否指明了它该找的目录,再把Species行里的名字和实际文件名对齐。这属于 80% 新手会遇到的第一个启动失败,10 秒能修好,但没见过的人常常卡半小时。
4.2 重新理解 Spacing:它就是你的“基组大小”
平面波程序里,你写ENCUT = 400 eV,心里有谱;Octopus 里你写Spacing = 0.2,就得自己算等价截断能量。实空间格点法里,格点间距 a 可解析的波矢量上限约是 k_max = π/a,这个值对应平面波截断 E_cut ∝ (π/a)²。所以 0.2 的间距和 0.25 的间距差距不是 20%,是 56%,这是血泪教训。
收敛测试的基本套路是固定盒子半径,从 0.25 开始,逐步加密到 0.2、0.17、0.15,记录总能量和 HOMO-LUMO 间隙。把它们画在一张对数坐标图上,能量差呈线性下降,说明你进入了可外推区;如果曲线还在剧烈抖动,继续加密网格,顺便检查是不是盒子太小了。这里的判断标准是总能量变化小于 1 mHa,同时 HOMO-LUMO 变化小于 0.1 eV,多数光物理问题在这个精度下有讨论意义。
内存开销也要提一嘴:三维网格点数正比于 (R/a)³,Radius 从 8 加到 12,点数是 2 倍多;Spacing 从 0.25 减到 0.17,点数是 3 倍多。TDDFT 模拟计算还涉及多处数组备份,内存峰值比你想象的更早到来。跑之前用ulimit看一下硬限制,别等跑了两小时直接 OOM。
4.3 DeltaT 和传播子:能量守恒是底线
实时演化的能量守恒是 TDDFT 模拟计算里最直观的健康指标。每次Octopus的td模式跑完,终端日志里都有总能量的跟踪,你去看最后一个值和初始值之间的差。差在 1e-5 Ha 以内是合格的,差到 1e-2 就要停手,谱线在高频段会出现非物理的毛刺。
解决办法有好几层。第一层是减小DeltaT,经验法则是满足 CFL 条件的一半以下才算“解耦时间步”。第二层是换传播子,把TDEvolutionMethod从 0 换到 1 或 2,同时把TDPropagator换成etrs,计算代价会涨,但长时稳定性好很多。第三层是检查施加的场是否守恒体系的对称性。一个对称性被破坏的外场可能让能量你看起来是“守恒”的,实际只是漂移得比较均匀,这就更阴险。
对有金属性的体系,电子占据数的热尾巴特别考验传播子,因为高能态在小DeltaT下依然有非零占据,相位演化误差积累得很快。这种情况下我建议换用split或高阶级数传播子前先跑一个短时程测试,用 5 个原子单位的演化来看能量漂移的斜率,而不是跑完 20 甚至 100 个原子单位再回头后悔。
5. 避坑指南:TDDFT 运行中最常见的五类翻车现场
5.1 基态 SCF 振荡,能量永远收敛不了
现象:基态 SCF 跑了几百步,ConvAbsDens一直达不到,能量在两个值之间来回跳,像在甩呼啦圈。
原因:最常见的是交换关联泛函和伪势不匹配,或者格点间距太大导致实空间离散引入的噪声,让 SCF 在非物理的吸引势井里波动。另一条是体系本身有简并或接近简并的电子态,自旋限制出问题。
解决:先加密网格,0.3 的间距直接跳到 0.2 看情况;再换伪势集合,从pseudo_dojo换成程序内置的其他范数守恒势;还不行就把Smearing打开,给占据数一点温度展宽。最后再考虑是不是几何结构本身不合理,比如原子间距设得比化学键短太多。
5.2 含时演化总能量线性漂移
现象:TD 跑得很好,速度也快,但日志里的总能量随时间单调下跌,下跌速度肉眼可见。
原因:DeltaT 太大,传播子的幺正性被离散误差破坏,常见于包含高能未占据态体系。也有可能是加了TDDeltaStrength之后的场和基态 Hamiltonian 不兼容,导致初始时刻就有能量台阶。
解决:把DeltaT减半再跑一次,对比漂移斜率是否减半。如果减半无效,换TDEvolutionMethod。另外检查基态的restart是否来自于相同精度,别拿 0.25 的基态冷启动 0.17 间距的 TD。
5.3 吸收谱出现负强度
现象:光谱的虚部出现明显负峰,尤其在低频端。
原因:偶极矩符号定义和极化率公式符号不匹配。Octopus 输出的偶极矩有方向和相位约定,如果你用自写脚本做傅里叶变换,符号容易搞反。
解决:先直接用oct-fourier工具出谱,它内部实现了正确符号约定。自写脚本时确认偶极矩是电子贡献还是总电荷贡献,再把 μ(0) 扣除再变换,避免零频直流分量污染低频。
5.4 光谱峰又胖又平,看不清任何精细结构
现象:总时长 T 拉到很大,换了 damping,峰还是宽得离谱,想看的振动精细结构都没有。
原因:总演化时间不够,频率分辨率 δω = 2π/T 太大,两个相近激发态混成了一个宽包。另一种可能是 damping 参数取太大,把展宽设成了赝物理效应。
解决:T 从 25 加到 50,你才会看到峰形明显变锐。加腔时如果是金属团簇,注意长时演化后电子热化,谱里低频端会鼓起来一片,那不是吸收峰,是热尾巴。
5.5 运行中报错 Box Too Small 或 boundary 条件干扰
现象:TD 跑到一半崩掉,或轨道密度被“框”在盒子边缘,出现周期性波纹。
原因:盒子的Radius没有覆盖波函数的衰减区,尤其 Rydberg 态或弥散轨道会探到盒子边界。分子断键过程中原子跑出盒子边界也会这样。
解决:基态收敛的检查里就要确认波函数在盒子边界处密度掉到可忽略量级。常用做法是Radius加 2 到 3 个原子单位再看边界密度,代价是网格点数的立方增长。处理长程电荷转移时,还要考虑盒子外的极化,那是更需要设计和技巧的一部分。
6. 进阶验证一步到位:从几条谱到可信的光学响应,值得你多花一天
当一条光谱顺利出峰,别急着截图。真正有价值的是让它能站得住脚。第一件事是验证线性响应区间:把TDDeltaStrength分别设为 0.005、0.01、0.02 跑三组,峰位偏移不应超过 0.01 Ha,否则你看到的是非线性效应,而不是基态光学性质,这种数据放进论文里会直接被挑刺。
第二件事是阻尼扫描。gamma从 0.002 扫到 0.02,记录峰位、半宽和积分面积。真正的物理峰位不会随阻尼变化,变化的只有展宽和面积。如果你发现峰位也跟着走,说明你的时间信号还没衰减到零,傅里叶变换的截断效应还在主导,需要延长T或者加窗函数,再去讨论峰位。这里有个很容易犯的习惯:把实验谱的展宽直接设为阻尼,实际上是偷懒,正确做法是先无阻尼出峰位,再加展宽匹配对比。
第三件事是拿线性响应数据交叉验证。Octopus 也支持直接解 Casida 方程,选一个和实时光谱同样的泛函,算低激发态做对比。两者在同一数量级偏差内一致,你的实时光谱就有底气了。至少挑前三个主要吸收峰做这个验证,这一步能挽回很多后面的大修时间。TDDFT 模拟计算最怕的是“这看起来合理”的谱,交叉验证是它的后悔药。
最后一件事是确认势能面演化是否在你要的时间尺度内。超快电荷转移问题里,原子核运动在几十飞秒内就会参与进来,此时纯电子动力学的偶极矩信号会和振动耦合纠缠,你需要考虑MoveIons = no的合理性。如果一定要原子运动,就得上 Ehrenfest 动力学,那是另一套参数体系和计算量,提前判断值不值得做,好过算到一半再回头。
我自己的习惯是,每次拿到一个新体系跑 Octopus 之前,先用独立电子近似(TheoryLevel = independent)跑一遍 TDDFT 流程,验证网格、传播子、傅里叶变换的管线通不通,在物理复杂度里拆掉一层变量。这个习惯帮我省过无数次排查时间,也希望这次能帮到你。
把管线、参数和避坑点都走通后,Octopus 就能从玄学变成工具。剩下的事情就是不断用短时程测试去逼近那个平衡点:计算量能接受,物理量能守恒,光谱能有说服力。希望这篇能帮你少交几次学费,多出几张说得出口的谱线。
本文还有配套的精品资源,点击获取