启动CST并新建项目
cst超表面仿真 异常反射 异常透射 超透镜 OAM
前阵子蹲实验室啃超表面的时候,被CST的仿真逻辑整得头大,本来以为调几个参数就能出结果,结果搞到凌晨三点才搞懂异常反射那点事儿,今天把踩过的坑和摸出来的门道唠唠。
简单说超表面就是一层指甲盖大小的人工结构阵列,能把入射的电磁波掰成奇奇怪怪的方向——比如异常反射、异常透射,做超透镜甚至生成OAM涡旋波这些花活,比传统光学元件薄太多还能玩出更多花样。
先从最基础的CST建模说起吧,我最开始上来就直接拉阵列,结果连单元模型都没调对,后来才知道得先从单个周期单元开始仿真,用Floquet端口和周期边界把“这是重复阵列”告诉CST。给大家贴一段我常用的Python快速搭单元的脚本:
import win32com.client import math cstApp = win32com.client.Dispatch('CSTStudio.Application') proj = cstApp.NewProject() modeler = proj.Modeler bc = proj.BoundaryConditions # 清空现有模型 modeler.DeleteAll() # 定义单元参数:周期10mm,衬底厚度0.5mm,覆铜厚度0.05mm unit_period = 10 sub_thick = 0.5 patch_thick = 0.05 # 画衬底 modeler.AddBox([0,0,0], [unit_period, unit_period, sub_thick]) # 画金属贴片,先默认边长4mm,后面可以改 patch_size = 4 modeler.AddRectangle( [(unit_period-patch_size)/2, (unit_period-patch_size)/2, sub_thick], [(unit_period+patch_size)/2, (unit_period+patch_size)/2, sub_thick+patch_thick] ) # 设置周期边界和Floquet端口,x/y方向周期都是10mm,上下入射电磁波 bc.SetPeriodicBoundary(1, 0, 0, unit_period, unit_period) bc.SetFloquetPort(1, [0,0,-1], [0,0,1])这段脚本就是快速搭一个最基础的矩形贴片超表面单元,我最开始抄网上模板的时候直接把周期边界的参数写成0,结果CST一直报错说“你这单元咋还能跑出去呢”,后来才知道那俩参数是x/y方向的周期长度,不是随便填的。
接下来聊异常反射,也就是打破了“入射角等于反射角”的常规操作。正常情况下电磁波反射都是规规矩矩的,但超表面能通过每个单元的相位突变,让反射波拐到离谱的角度,这就是广义斯涅尔定律。要做这个得先算每个贴片尺寸对应的反射相位,比如我要做一个线性渐变的相位分布,相邻单元相位差固定,就能让反射波偏折到指定角度。
给大家贴一段CST宏脚本,用来扫频导出每个贴片尺寸下的反射相位:
' 导出反射相位到txt文件 Sub ExportReflectPhase() Dim freq As Double Dim s11_re As Double, s11_im As Double Dim phase As Double Open "reflection_phase_10GHz.txt" For Output As #1 ' 扫10GHz附近的频率,也可以改范围 For freq = 9.5 To 10.5 Step 0.05 proj.Frequency = freq * 1e9 ' 运行仿真,这里可以改成只算一次不每次跑 proj.StartSimulation ' 获取S11的实部和虚部 s11_re = proj.GetSParameterReal(1,1) s11_im = proj.GetSParameterImag(1,1) ' 用Atn2算连续相位,避免断崖跳变 phase = Atn2(s11_im, s11_re) * 180 / 3.14159 Print #1, freq & " " & phase Next freq Close #1 End Sub我最开始没用Atn2,直接用了Atn,结果画出来的相位图跟锯齿似的,跳变的时候直接从180蹦到-180,强迫症直接犯了,后来查了半天文档才知道Atn2能处理象限问题,拿到连续的相位曲线。
cst超表面仿真 异常反射 异常透射 超透镜 OAM
然后是异常透射,也就是大家说的EOT效应,本来亚波长金属孔的透射率低得可怜,但加上超表面结构之后能把透射率拉到很高。我之前做过一个带通孔的超表面,一开始以为最多能有10%的透射率,结果调了孔径和贴片尺寸之后居然到了60%,当时直接跳起来拍了导师桌子一下,把他正在改的论文都弄掉了。仿真这个的时候只需要把Floquet端口反过来,从下面入射,上面收透射波,算S21参数就行,没啥特别难的,就是网格剖分要细一点,不然透射率算出来忽高忽低。
再说说超透镜,说白了就是让超表面的相位分布做成抛物线型,把平行入射的电磁波聚成一个点,比传统玻璃透镜薄太多,还能做消色差的。我之前做过一个焦距200mm的超透镜,最开始手动一个个画单元,画了50个就烦了,后来写了个Python脚本批量生成:
import math # 超透镜参数:尺寸100x100mm,周期10mm,焦距200mm lens_size = 100 period = 10 focal = 200 # 10GHz对应的自由空间波长大概30mm,这里简化计算 lambda0 = 0.03 # 提前拟合好的相位到贴片尺寸的映射,这里用插值函数代替 def phase_to_patch(phase): # 假设已经通过之前的仿真拟合好了,比如phase从0到2pi对应patch从2到6mm return 2 + (phase/(2*math.pi))*4 # 批量生成每个单元 for x in range(-lens_size//2, lens_size//2, period): for y in range(-lens_size//2, lens_size//2, period): # 计算每个位置需要的相位补偿 r = math.sqrt(x**2 + y**2) required_phase = 2*math.pi*(focal - math.sqrt(r**2 + focal**2))/lambda0 # 反推对应的贴片尺寸 patch_size = phase_to_patch(required_phase % (2*math.pi)) # 画贴片 modeler.AddRectangle( [x + (period-patch_size)/2, y + (period-patch_size)/2, 0.5], [x + (period+patch_size)/2, y + (period+patch_size)/2, 0.55] )这个脚本跑起来之后一键生成100个单元,比我手动画快了不止十倍,就是反推贴片尺寸的时候卡了好久,因为相位和贴片尺寸不是线性的,得提前用之前的反射相位数据做插值拟合。
最后聊聊OAM涡旋波,这个是我最近才折腾的,简单说就是电磁波的波前是螺旋状的,像个甜甜圈,每个不同的螺旋状态都可以当成一个通信信道,能大幅提升通信容量。要生成OAM只需要让超表面的相位分布是螺旋型的,也就是每个位置的相位和方位角θ成正比,φ = lθ,l是拓扑荷数。
还是用刚才的脚本改一下就行,只需要改相位计算的部分:
# 生成拓扑荷为2的OAM超表面 topo_charge = 2 for x in range(-lens_size//2, lens_size//2, period): for y in range(-lens_size//2, lens_size//2, period): # 计算方位角theta theta = math.atan2(y, x) required_phase = topo_charge * theta patch_size = phase_to_patch(required_phase % (2*math.pi)) modeler.AddRectangle( [x + (period-patch_size)/2, y + (period-patch_size)/2, 0.5], [x + (period+patch_size)/2, y + (period+patch_size)/2, 0.55] )仿真完之后去远场看场分布,真的能看到螺旋状的波前,当时把场图拉出来看,居然真的有个甜甜圈的形状,直接截图发了朋友圈,被导师评论说“终于搞出点东西了”。
最后唠两句踩过的坑:CST的网格剖分真的是玄学,一开始我用自动网格,结果金属贴片的网格太粗,仿真出来的相位完全不对,后来改成手动剖分,把贴片的网格设成1mm以下,结果仿真时间翻了三倍,但结果准多了;还有一定要记得给模型加材料属性,我最开始忘了给衬底加介质参数,结果仿真出来的反射率全是1,相当于完全反射,尴尬死了。
其实超表面仿真不是光调参数就行,得懂一点电磁波的基本原理,不然连报错都看不懂,不过搞出来的时候真的很有成就感,尤其是看到仿真出来的异常反射波束偏折了30度,或者OAM的涡旋波场图,感觉之前熬的夜都值了。
