EN

光阴极与注入器的程序,等等

六年博士只问一件事,光阴极微波电子枪的发射度能压到多低,为此写了四个程序。

博士论文的每一章都卡在同一个地方。手里有一个物理问题,要回答它,得先把能提这个问题的程序写出来。所有问题背后其实只有一个。200 pC 下 0.2 mm·mrad 的切片发射度(电子在位置和角度上散开的程度),是当时注入器测到过的最好成绩。它到底是不是底?一把枪能不能做到 0.1?在清华跟着唐传祥老师的六年,就这么出来了四个程序。2016 年 12 月答辩。2018 年在 SLAC 的求职报告,题目就叫「How Many Codes Does It Take to Get an Accelerator Physics PhD」(拿一个加速器物理博士要写几个程序)。

一块粗糙的铜阴极

Dowell 的光电发射公式,算量子效率 QE 和实验对得上,算发射度却不行。好几个实验室测到的值都比它预测的大 2 倍左右。大家头一个怀疑的是粗糙度。可是要模拟粗糙度,前面有两道墙。铜的 QE 只有 104 量级,往表面打光子、再问有没有电子出来,几乎全部白打。而随机表面上方的电场,一般得拿一张跟着每个起伏走的网格去解。

于是我从成像里借来点扩散函数(Point Spread Function,PSF),围着它写了 PyPES。算下来 PSF 的 rms 半径在纳米以下,出了这个范围,幅度很快衰减到零。所以表面上不管哪一点,喂给它的那一小片激光都可以当成常量。点 𝐏 处发出的相空间就能拆开,D|𝐏I(x0,y0)fp,即激光在落点 (x0,y0) 的功率密度,乘上一个动量分布。剩下要抽样的,只有动量那一半。

fp(px,py,pz)=Cppzpz2+pm2px2+py2+pz2+pm2

fp 是把落点位置积分掉之后的 PSF,也即动量点扩散函数。Cp 是归一化系数,由反射率、两个平均自由程和光子能量凑出来。pz 是离开表面方向的动量,pm 是电子要逃出表面至少得有的动量。(让电子只往前走、给总动量封顶的两个阶跃函数没有写出来。)

采样器先从激光光斑里抽一个位置,再按上面的分布抽这一点的动量,按那一点的坡度转一下。六次里大约能成一次。场是一阶傅里叶展开,一层一层薄薄地往上算;龙格库塔法把每个电子一步一步往上推,推到横向场消失为止。

在 x = 57.47 µm 处切开阴极,约 130 µm 长、60 nm 高:表面上方的电势用颜色画,实测的表面轮廓是黑线,电势的零等值线是贴着它走的白线。
表面的一个截面,近似电势的零等值线(白)贴在实测轮廓(黑)上。

同一个函数还能把统计意义上的发射度恰好劈成两半。一半就是 Dowell 公式,另一半自然是它的误差。算出来是一个长度,0.40 nm,而激光光斑是 100 µm 上下。

接下来才是粗糙度本身。表面不平,会发生两件事。每一小片表面都朝自己歪着的方向发射(表面离散效应);起伏上方的场又多出一个横向分量,电子往外爬的整个过程它都在推(横向电场效应)。我把两者写进同一个式子,对象是随机缓变粗糙表面,先做二维,再做三维。两项落在同一个平方里。它们同时作用在同一个电子上,拆成两项相加会把交叉项丢掉。

εx2=εD,x2[1(xR)2+(pzxR+jmπA2dkxdkykxkR(kx,ky)ej(kxx+kyy))2px2]

εx 是带粗糙度的发射度,εD,x 是光滑阴极上的值。(xR)2 是表面 R 沿 x 方向的坡度均方。带撇的动量是那一小片表面在自己坐标系里发出的动量,j 是虚数单位,A=eE/m 里的 E 是外加场。带积分的那一项,是电子脱离起伏时表面场已经给它的横向动量,由同一个表面的傅里叶系数 R(kx,ky) 组出来,k(kx,ky) 的长度。

我拿一块真实的铜阴极跑了模拟(W. Li 帮我测了表面形貌)。增长因子比别的实验室测到的 1.5 到 2 小得多(IPAC'15),解析公式在同一个束团上也对上了,只是方向反了。模拟本该落在解析值下面一点,再慢慢爬上去。它却落到了上面,4.826 对 4.822 µm·keV/c。我猜是步长太大:龙格库塔每一步用的都是电子上一个位置的场,场又随高度衰减,每步的横向踢劲都算多了。我和唐老师把它写进了 PRAB(2015 年,当时刊名还是 Phys. Rev. ST Accel. Beams)。

一块机加工铜阴极的高度图,约 170 × 130 µm,竖条纹深几十纳米,模拟用的激光光斑画成一团圆点叠在上面。
实测的铜表面,激光光斑叠在上面。
上:阴极表面处和表面上方 5000 nm 处的横向相空间,后者被表面扭出了波纹。下:发射度随离表面高度的变化,50 MV/m 下从约 4.62 慢慢爬到 4.83 µm·keV/c,两端标着解析值。
表面处和往上 5 µm 处的相空间,以及中间这段慢慢爬的发射度(三角是解析值)。

解析公式便宜,我就拿它扫外加场。这块表面即使到 120 MV/m,增长因子也不到 1.1。机器精细打磨的阴极,表面 rms 起伏不超过 30 nm,rms 坡度不大于 3 mrad。在 S 波段枪常用的 50 MV/m 下,它的粗糙度可以忽略不计。那多出来的一倍,得另找原因。阴极要尽量避免手工打磨,它留下的粗糙度在百 nm 量级。

发射度增长因子随阴极表面场从 0 到 200 MV/m 的变化。实测的三维铜表面从 1.0 慢慢升到约 1.12;粗糙度参数与它匹配的二维正弦面刚好在它上方;打磨阴极典型微观粗糙度(200 nm 一个周期、4 nm 起伏)的正弦面再高一点;典型宏观粗糙度(16 µm 一个周期、100 nm 起伏)的那条爬到约 1.78。
增长因子随阴极场的变化:实测的三维表面,与它匹配的二维正弦面,以及按打磨阴极典型微观和宏观粗糙度取的两条正弦面。

UCLA 的银纳米小孔

2014 年我在 UCLA 的 Pegasus 组(Pietro Musumeci)待了大半年,做的是反过来的事:故意给阴极刻上图案。在银上刻一片纳米小孔阵列,尺寸调到和 800 nm 激光谐振,它吸收的激光就比平整的金属多。

一万倍的 SEM 图:银上一片规则的方形小孔阵列,表面有细划痕;比例尺 5 µm。
SEM(扫描电子显微镜)下的小孔,一万倍。

检验图案的办法,是一个波长一个波长地照它,每照一次拍一张。图案那一小块在亮闪闪的平整银面上显得暗,反射率就是图案的亮度除以背景的亮度。事后再处理这些照片很慢,我想在扫描的时候就看到曲线。于是我用 PyQt 写了 NPC Analyzer,NPC 就是纳米表面阴极(Nano-Patterned Cathode)。它用 scikit-image 的边缘检测找到图案,再在图案里面和周围放取样框。每个框放大或缩小,直到框里的亮度平得可信为止。反射率对波长的表格就这么一行一行攒出来。

NPC Analyzer 的窗口:一帧相机画面,暗色的图案区被描出轮廓,里面一个绿色取样框,周围几个蓝色的;右侧是文件选择、边缘和线条滑块、波长与反射率表格,还有导出和预览按钮。
NPC Analyzer 处理一帧真实画面,图案边缘已经描出,取样框在里面(绿)和周围(蓝)。
相对反射率随波长(730 到 850 nm)的变化:短波端 0.6 上下,约 801 nm 处凹到 0.45,长波端升过 0.8,数据点周围是分析误差的阴影带。
反射率谱,阴影是分析误差。

谐振峰落在约 801 nm,设计值是 800。但它很浅,只凹到 45%,设计说的是 0.63%。组里拿 SEM 实测的尺寸重跑了一遍 Lumerical,峰位一样,深度也差不多一样浅。剩下的差别来自聚焦离子蚀刻(Focused Ion Beam,FIB)加工时每个孔尺寸和间距的不一致,还有谱仪本身探测的波段太宽。

纳米结构没能从枪里活着出来。高功率测试做完,晶片放回谱仪一测,800 nm 的谐振峰没了,几乎整个波段的反射率都掉了。结构毁了,表面粗糙到开始漫反射。最可能是测多光子光电发射曲线那一轮,激光一档一档往上加,那是晶片见过的最高功率,而损伤阈值没人测过。

银阴极在 730 到 850 nm 的两条反射率曲线。高功率测试前,曲线在 800 nm 附近凹到约 0.45,长波端升过 0.8;测试后凹陷没了,整个波段都在约 0.62 以下。
同一片晶片,高功率测试前后。

孔阵的尺寸是我在模拟里定的,定在 800 nm 谐振上。晶片是组里做的,反射率装置和高功率测试用的 cathode-plug 也是组里搭的,都写进了我一作的 NIM A 文章

产额图上,图案区只比旁边的银高 10 倍左右。可是激光光斑 1.3 mm,图案只有 0.2 mm,图上平均掉的大部分是平整金属。把光斑平均反过来扣掉,图案本身还要再乘 40,也即约 400 倍。产额图上还有一个亮环,在晶片边缘,那是 cathode-plug 的缘故。晶片比铜板低 1.5 mm,边缘的场因此变强,晶片面上只剩约三分之二的正常场。于是发射相位漂了,对空间电荷的压制也不如齐平的阴极。

这笔账是这么算的。红外激光下电荷多得多,热发射度却是平整铜的近两倍,所以它更适合要大电荷的机器,不适合追求超低发射度的。不过我们在那篇文章里挨着这个结论写了一句提醒。表面形貌对发射度影响很强,结构被打坏可能就是发射度偏大的原因之一。晶片往里凹是另一件事,这种测法我不会再来第二次。

扁平束和笔形束

接下来是一个靠代数就能回答的问题。给阴极打光有两种打法,短而胖的脉冲叫扁平束(pancake),长而细的叫笔形束(cigar)。给定场强,两种打法的热发射度各有一个下限。下限出现在发射把自己掐断的地方,已经飞出去的电荷把表面屏蔽住,下一个电子出不来了。两个下限我都推了出来。(提高场强能压低下限,前提是光子能量得先越过逸出功。266 nm 的光打铜,多出 0.35 eV,够。)

有一处修正得先做。肖特基效应造成的逸出功降低,是按干净表面前面只有一个电子推的。在束团里,每个切片都隔着比它先走的电荷往外看,所以每个切片有自己的有效逸出功,也有自己的发射度。不做这个平均,空间电荷限处的答案会低 20% 左右。50 MV/m 下的铜,这个限在 222 pC 上下。

50 MV/m 下铜阴极的归一化热发射度随发射电荷量的变化。精确和近似两条曲线从 0.636 缓缓下降,在约 222 pC 的空间电荷限处与代入九分之四场强的未修正线相遇;不管切片差异的那条在两者下方,还在往下走。
束团热发射度随电荷量的变化,画了精确解、近似解、不管切片差异因而总是偏低的那条,还有代入九分之四场强的未修正公式(精确解在空间电荷限处和它碰头)。

扁平束的下限直接从空间电荷限的条件推出来,电荷量和场强一定,式子里就没有可变参数了。50 MV/m、200 pC 下算出来是 0.11 mm·mrad,对应的激光半径 379 µm。

εmin=123mc2ε0πQωϕwE0+13eeπε01E0

Q 是束团电荷量,E0 是阴极表面场强,ϕw 是不带修正的逸出功。肖特基降低单独写成了根号下的第二项,取的是 E0 的九分之四,也即切片平均后在空间电荷限处剩下的场。ε0 是真空介电常数,不是发射度。

笔形束才有意思。脉冲一长,屏蔽只深入束团约一个激光半径,下限就不再跟着总电荷走,改跟阴极饱和电流走。电荷一定时脉冲越长越占便宜。(饱和电流和「只深入一个激光半径」是 Filippetto 等人的结果,搭在上面的切片物理图像是我的。)200 pC、10 ps 下算出来 0.09 mm·mrad,半径 390 µm。

εmin=(916πε0me)2/3ωϕw3mc2(Qτ)2/31E0

τ 是阴极上的脉冲长度,所以下限跟着走的是发射电流 Q/τ。这里的逸出功 ϕw 不带肖特基降低。到了极限,已经飞出去的电荷把表面场抵消干净了。

脉冲也不能无限拉长。长束团占着实实在在的一段微波相位,高阶项就上来了,它们在下游添的发射度再也收不回来。这一节全是推导,没有一处测量。

一分为二的枪

算出来的底,得有一把枪去够。笔形束太长,直接用不了。自由电子激光(FEL)的注入器要在出口拿到 20 到 50 A,得有东西压缩它。拿一个普通的正弦场去压长束团,流强分布会压得很偏。文献里的办法是把基模和三次谐波放进同一个腔,凑出一段平的场让束流骑上去(这个想法来自 PSI 的 Raguin,也来自 Dowell)。纸上很漂亮。代价是两个耦合器、一个模式过滤器,还要在同一块铜里把两个模式同时调谐、调平。

我们反过来,把两个模式拆开,一个模式一个腔。再往一起推,推到场渗透率受不了为止。具体是一把 BNL 型 1.6 cell S 波段电子枪,紧跟着一个 X 波段腔(四次谐波,不是三次),目标 200 pC 下 30 A(IPAC'16)。合作者有唐老师、LBL 的 Houjun Qian,还有一位 Zhen Zhang,名字只比我多一个字母,不是我。我们试了两种布局。合并型,X 波段腔紧贴枪,螺线管线圈放在两者之后。分离型,螺线管线圈放中间,后面再接一个 C 波段聚束腔(buncher)。这些全都只在 Superfish 和 Astra 里做过,一个腔也没造。

动力学之前,两个腔得先调好。能动的有三个半径,X 波段腔一个,S 波段枪两个。要打中的也是三个,两个频率,加上 S 波段场的场平。两边都是三个,因为雅可比矩阵得先是方阵,才谈得上可逆。Superfish 给响应,有限差分在它周围凑出雅可比矩阵。

𝐱=𝐱+η𝐌1𝚫,η=12

𝐌 是雅可比矩阵,𝚫 是离目标还差的距离。那个二分之一是我一次次减半试出来的。四次 Superfish 换一步,一个腔型十来次就出来。

调腔还得能无人值守地跑。渗进枪里的场取决于 X 波段腔放在哪,而动力学模拟以后可能要它挪地方,整个腔型优化就得重来。这个循环也不按精度停。尺寸到了 10 µm 以下就没有意义(机加工就这个精度)。迭代几轮后新算出来的尺寸四舍五入和上一轮一样,它就停了,不管目标到没到。出来的枪频率对上了,S 波段枪两个 cell 的场平到 0.04% 以内,X 波段场渗进枪里的只有 3.02×104,目标是千分之一。

之后每个问题都得跑一轮 Astra 扫描。PyGAS 里驱动 Astra 的那个类,文档字符串至今写着我当时的心情:「A tool that eases the painful scans in ASTRA simulations.」(一个让 Astra 扫描不那么痛苦的工具)。NSGA-II 和 SPEA2 这两个遗传算法(Genetic Algorithm,GA)的算子是 DEAP 的。我写的是管道,把每个个体变成一次 Astra 运行,再把运行结果变回两个数。SCOOP 把个体分发出去并行跑(Christos Papadopoulos 在遗传算法和并行计算上帮了我)。框架画的时候留了口子,模拟器和优化器都能换,但真正接进去的只有 Astra 和这两个 GA。

PyGAS 走一代的流程,遗传算法(算子是 DEAP 的 NSGA-II 或 SPEA2)把每个个体交给输入文件改写器,改写器把它的输入变量写进自己的 Astra 输入文件,个体用 SCOOP 并行评估(先跑 Astra 自带的粒子分布生成器,再跑 Astra),IPAC'16 的计算跑在 LBL 与清华的集群上,出口的 100% 发射度和 rms 束长是两个目标变量,作为适应度送回下一代。下方是被模拟的 S/C 分离型注入器,电子枪,螺线管线圈,C 波段聚束腔和两节 S 波段加速管。 遗传算法 输入文件改写器 生成器 + Astra 出口统计 NSGA-II 或 SPEA2 (算子来自 DEAP) 每一代都存盘 一个个体一个文件夹 它的输入变量写进 Astra 输入文件 多个并行跑(SCOOP) IPAC'16 的计算跑在 LBL 与清华的集群 100% 发射度 rms 束长 (两个目标变量) 适应度排序,出下一代 电子枪 螺线管线圈 C 波段聚束腔 S 波段加速管 S 波段加速管 Astra 模拟的 S/C 分离型注入器
PyGAS 走一代的流程,和它模拟的那条注入器。

分离型最好。合并型走了同一套优化,它的 Pareto 前沿落在无聚束腔和 C 波段两条中间。rms 束长 0.65 mm 以下贴着无聚束腔那条,往上则慢慢靠向 C 波段那条。两者为什么不一样,我没分析。

有一件事得交代,是激光脉冲。优化器手里有 15 ps 可用,它没用满,最长只到 13 ps 上下,30 A 那个解只用了 10 ps。整个方案的前提就是长脉冲,它却不肯拉长,这很怪,论文里我也这么写了。我猜是色差:长束团在 RF 里攒下的能散,到螺线管线圈就变成发射度。论文没给答案。

它还干了第二件我没解释的事。加了聚束腔,它要的脉冲翻了一倍,从 5 ps 到 10 ps,半径却只从 0.4 mm 降到 0.32 mm。按笔形束饱和发射的公式,脉冲翻倍,半径该缩 37%,它只缩了 20%。也就是说,束线里一旦有聚束腔,把阴极调到亮度最高,出口的亮度就不再是最高的。没有聚束腔时,两者是一回事。

注入器出口 100% 投影 rms 发射度对 rms 束长的散点,三条 Pareto 前沿:无聚束腔、X 波段聚束腔、C 波段聚束腔;C 波段那条最低,点线标着 0.65 mm。
遗传算法在发射度和束长之间找到的最优折中,无聚束腔、X 波段和 C 波段各一条。
沿束团的切片发射度,三种情形:无聚束腔约 0.2 mm·mrad,C 波段聚束腔约 0.15,C 波段聚束腔加 0.5 µm/mm 的热发射度约 0.10;核心部分平坦,两头翘起。
沿束团的切片发射度:无聚束腔、C 波段,以及 C 波段配一块更冷的阴极。

在清华的集群上一次模拟半小时到一小时,一次完整的优化要好几天。这一章的结尾,写的是没做成的那部分。聚束腔的压缩能力大半没用上,初始束团也始终没有拉到我预期的长度。最优解里没有一个是在空间电荷限发射的,所以束流从来没有靠近过我在这一章开头推出来的下限。能回答的是 30 A 下核心切片发射度 0.15 mm·mrad。0.1 只在我给优化器换了一块更冷的阴极之后才出现,热发射度从 0.9 µm/mm 降到 0.5。这不算作弊,论文里我是这么说的。200 pC 下的 0.1,谁都拿得到,只要有一块 0.5 µm/mm 以下的阴极(某些工作在低 QE 模式下的半导体阴极就是)、一个笔形束脉冲,再在束线里放一个谐波腔。

PyeGun

2017 年 2 月,答辩之后,我把那个调腔的循环从注入器的工作里抠出来,单独开了一个仓库,PyeGun。输入两个数,频率和 cell 数。剩下的交给 Superfish 和牛顿法,一步一步挪半径,直到频率和场平都落到位。它停在了原型阶段。

暑期实践项目里的光斑网格

标题末尾那个「等等」。哈特曼-夏克波前传感器(Hartmann-Shack wavefront sensor,HS WFS)在相机前面放一片小透镜阵列,光就成了一格一格的光斑,每个光斑的偏移给出波前在那一点的倾斜。HS WFS Toolbox 给每个光斑找到它的行和列,画面拉丝、断成几块、缺一角都行。办法是往 x 和 y 投影再找峰(找峰用的是别人从 MATLAB 脚本 peakdet 移植的 Python 版)。把画面切成条,每条各找各的峰,网格就能跟着画面弯。然后每个光斑做一次高斯拟合,得到中心和亮度。

四帧光斑阵列并排:稀疏拉丝的光斑(缺光斑的地方用空心圆标出预期位置),断成三块竖条的阵列,顶边缺了一大口的圆阵列,圆角的方阵列。
四帧普通网格算法会认错的画面。
原始光斑画面:密密的红色光斑填满一块不规则、有缺失的区域。
光斑填了一块不规则区域的画面。
同一帧,黄色网格穿过检测到的光斑,顺着参差的上边缘走。
工具箱在上面描出的网格。

数字出自博士论文(清华,2016 年)和它的代码附录,2015 年的两篇粗糙度文章,NIM A 文章和 IPAC'16。