☰
MPB算能带的时候如何确定特定频率区间波导带的序号
2026/10/11 1:58:52 网站建设 项目流程

在计算投影能带图的时候,一个重要的问题就是能带太多了,每个K点都有一大堆能带,如果想要画出某个频率区间内波导态的场图,必须确定这个波导态在对应K点的序号,这个序号可以用这个脚本查阅:

# ================= 找到特定k下,波导态所在的BAND序号 =================

# 1. 选一个 k 点索引(比如 Γ 是 0,Y 是 len(k_points)-1)
k_index =4 # 例如 Y 点,可改成你要看的点

# 2. 设定你感兴趣的频率窗口
f_min, f_max = 0.3, 0.4 # 根据你的能带图调整

# 3. 在该 k 点找出落在这个窗口内的 band
target_bands = []
for band in range(tm_freqs.shape[1]):
f = tm_freqs[k_index, band]
if f_min <= f <= f_max:
target_bands.append(band)

print(f"在 k 点索引 {k_index},频率窗口 [{f_min}, {f_max}] 内找到 band: {target_bands}")

比方说,结果显示找到能带14.

具体的频率范围由我们肉眼通过观察法确定。

但是这个方法有个陷坑,就是后面画场图分布的时候,比如:

band_1based = 15

XXXX

field = ms.get_efield(band_1based, bloch_phase=True)
Ez = field[..., 0, 2]

这个波导态的序号需要加一。

原因(AI说):

具体发生了什么

你的查找代码用的是 numpy 下标(0 起)

range(tm_freqs.shape[1])生成的band是0, 1, 2, ...,所以target_bands = [14]里的 14 是numpy 数组的列索引,对应tm_freqs[:, 14]这条能带。

output_at_kpoint回调里的band是 1 起

MPB 底层是 C/Fortran 写的,能带编号从1开始。Python 封装在回调里把 C 的编号直接传了进来,所以这个band是1-indexed。

  • 回调里band = 1↔ numpy 数组的tm_freqs[:, 0]

  • 回调里band = 15↔ numpy 数组的tm_freqs[:, 14]

你设band_index = 14,在回调里匹配到的其实是 numpy 数组的tm_freqs[:, 13],也就是相邻的另一条能带,所以场图不对。改成band_index = 15就对了。

为什么get_efield(band)本身没问题

ms.get_efield(band)用的也是同一个 1-indexed 编号,所以只要你在回调里匹配对了,传给get_efield的band就是正确的。问题只出在你用来比较的那个band_index是从 0 起的数组下标,两边编号体系不一致。

如果你在画场图的时候指定画序号0波导态能带的场图,那么程序会立即报错,因为画场图的时候不存在序号0的能带,能带是从1开始数的。

但是最上头的那个脚本,能带是从0开始数的,这一点是个重要的容易忽略的坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询