做三维光子晶体能带计算,很多人第一反应是拿平面波展开法或者FDTD,但如果你是COMSOL用户,一定试过频率域模块里“硬算”布洛赫边界那套流程:建好原胞、加周期条件、扫波矢、提取本征频率,最后连成一条能带曲线。这套流程跑二维还好,到了三维就开始吃力——网格数量大,特征值极容易混入伪模,扫几十个k点要跑半天,更别说想换一种材料模型或引入增益、损耗这类非标准物理时,内置物理接口给你留的“可调旋钮”往往不够用。
我后来把整个计算改成COMSOL弱形式来做,相当于在软件里自己搭了一个针对光子晶体本征问题的求解器,折腾过一遍以后,再回头看三维光子晶体的能带结构,很多以前模糊的细节都清楚了。这篇文章把我当时的完整思路、推导过程、软件配置和踩坑记录都整理出来,给同样准备啃这块硬骨头的朋友一个参考。无论你是刚入门COMSOL,还是已经在拿现成模块跑光子晶体,只要想把能带计算做得更稳、更可控,这篇应该能帮你省下不少试错时间。
1. 方案选型:为什么是COMSOL加弱形式
1.1 求解光子晶体能带的常规套路与痛点
光子晶体能带结构本质上就是周期性介质结构里的色散关系,本质是要解周期性介质中的麦克斯韦方程组,找到各个波矢对应的本征频率。做这件事的方法不少,常见的有平面波展开法、时域有限差分法,以及COMSOL为代表的有限元方法。
平面波展开法是最经典的做法,把介电常数和场都展开成傅里叶级数,求解代数本征方程。它在处理简单结构时速度很快,但遇到高介电常数对比、形状复杂的原胞或者材料有频散甚至有损耗时,展开项数和收敛性都会让人头疼。FDTD则是打一个宽频脉冲源,通过傅里叶分析提取谐振频率,思路直观,但做本征值扫描时计算量巨大,而且在三维结构里数值色散不容易控制。
COMSOL这类有限元工具的好处是几何建模灵活、网格自适应成熟、边界条件也方便设置。但直接用电磁波频域接口(Electromagnetic Waves, Frequency Domain)算能带时,有几个非常实际的问题:
- 光子晶体本征问题本质是矢量波动方程,直接求解时会出现大量无物理意义的伪模。
- 内置接口加了较多物理假设,用户想自定义方程时,界面会显得比较“重”。
- 三维模型的自由度高、内存压力大,扫k点时如果不做优化,整个计算流程会异常漫长。
- 特征值排序、模式识别、频率归一化这些后处理,需要自己理清逻辑,否则画出来的能带曲线一条线都对不上。
我在做三维光子晶体时,最开始也是用内置接口,但后来遇到一个高介电对比算例,怎么都去不掉伪模,才下决心切到弱形式。
1.2 弱形式带来的自由度
弱形式的原因说来也简单:内置物理接口已经替你把方程“包装好了”,但包装好的东西必然牺牲一定的可调性。COMSOL的“弱形式偏微分方程”(Weak Form PDE)接口则相当于把一个方程从零开始交给你定义,你写什么,它就解什么。
这样做有几个明显的优势。
第一,能够直接控制本征方程中的每一项。内置电磁接口通常以电场或者磁场为因变量,背后默认了某个固定的变分形式。弱形式里你可以自己选择用什么因变量、加不加惩罚项、保留哪个二阶项,甚至可以将特征值问题的形式改写成对求解器更友好的形态。
第二,能够方便地处理非标准物理。比如想研究非线性介质、增益介质、各项异性材料,或者引入磁光效应,内置接口的修改范围有限,但弱形式里加一个源项、改一个材料张量都不是难事。我做三维光子晶体时顺便做过一个增益介质版本,在那个算例里弱形式的灵活性体现得淋漓尽致。
第三,能够对布洛赫边界和波矢扫描做统一管理。把波矢分量写进全局参数,然后通过参数化扫描批量完成整个布里渊区的计算,整个过程可以形成一套很清晰的工作流,写论文或做工程汇报时也容易复现。
当然,弱形式也有代价:你需要自己理解方程,否则出错了连排查的方向都没有。但恰恰是这个过程,能让你对“光子晶体能带到底是怎么解出来的”有真正的掌握,这也是我愿意花时间写这篇文章的原因。
2. 理论基础:从麦克斯韦方程组到弱形式特征值问题
2.1 光子晶体里的布洛赫定理与不可约布里渊区
周期性结构中的电磁波满足布洛赫定理,这是能带计算的根基。简单说,在一个介电常数满足周期性分布的结构中,电磁场的模式可以写成:
E(r) = u(r) · exp(ik · r)
其中u(r)是与晶格周期相同的函数,k是布洛赫波矢。这个形式可以这样理解:电磁波有一个整体上的相位趋势exp(ik · r),但幅度受到周期性函数u(r)调制。正是这个u(r)的周期性,让我们只需要在一个原胞内求解问题,大大压缩计算规模。
三维光子晶体的原胞由晶格基矢决定。以最简单且最常用来验证算法的简单立方晶格为例,可以用a表示晶格常数,倒格子基矢为b1 = (2π/a, 0, 0)、b2 = (0, 2π/a, 0)、b3 = (0, 0, 2π/a)。在倒空间中,第一布里渊区有若干个高对称点,常见路径是Γ-X-M-R-Γ,其中:
- Γ点为(0, 0, 0)
- X点为(π/a, 0, 0)
- M点为(π/a, π/a, 0)
- R点为(π/a, π/a, π/a)
实际计算时,只要沿这些高对称点连成的路径采样,就能得到完整的能带信息。需要注意的是,波矢k的取值要在倒格子空间中处理,而COMSOL几何建模时用的是实空间坐标,两者之间的换算关系一定要理清。
2.2 时谐麦克斯韦方程推导到弱形式
假定研究的是线性、各向同性、无源介质,且电磁场随时间作时谐振荡,即E(r,t) = E(r)exp(iωt)。从麦克斯韦方程组出发,可以推导出关于电场的矢量波动方程:
∇ × (∇ × E(r)) - k₀² · εr(r) · E(r) = 0
这里的εr(r)是位置相关介电常数,k₀ = ω/c是真空波数,c是真空光速。实际写代码时经常还会用相对磁导率μr,不过对大多数光子晶体材料而言μr近似等于1,后面公式里忽略也问题不大。
要写成有限元能处理的弱形式,做法是对上述方程乘上一个测试函数F,并在原胞体积V内做体积分,然后利用矢量恒等式对旋度项做一次分部积分。最终可以得到:
∫V (∇ × F)·(∇ × E) dV - k₀² ∫V εr F·E dV + 边界项 = 0
在周期边界条件下,原胞相对面上的边界积分正好抵消,边界项可以消去。这里得到的表达式,就是COMSOL弱形式界面里要输入的“弱表达式”的数学基础。
注意一个问题:这个方程关于k₀²是本征值问题,而且左边第一项含有旋度算子。如果我们直接照搬进COMSOL,会发现这是一个矢量本征问题,三个电场分量相互耦合,接下来如何处理需要认真考虑。
2.3 处理矢量场时的伪模问题与惩罚项
三维光子晶体本征计算最大的坑是伪模。原因是有限元里如果用普通的拉格朗日节点基函数来离散电场矢量场,可能无法保证数值解的散度约束。麦克斯韦方程本身要求无源区内∇·(εE) = 0,但离散后的数值空间里,这个条件不自动满足,就会出现一类数值污染模式,它们不会在物理实验中出现,却会混在特征值谱里干扰判断。
最简单的抑制办法是加入一个惩罚项:
∫V β(∇·F)(∇·E) dV
β取一个较小的正值(通常0.01到0.1量级),作用是“惩罚”那些不满足散度条件的模式。也可以把它理解成在方程里加了一条弱约束,让求解器在寻找本征模时更偏好满足无散条件的物理模。这个技巧在早期很多光子晶体计算文章里出现过,如今在商业软件里用弱形式重新实现,效果依然很好。
如果用H场而不是E场来做因变量,也能天然压制一部分伪模,但在介质突变面上磁场的边界条件处理不如电场直观。实际项目里我更推荐用E场加惩罚项的组合,后面小节会给出可直接粘贴到COMSOL里的写法。
3. COMSOL建模实操:从几何到弱形式方程
3.1 确定三维原胞几何与材料参数
为了让流程具体可复现,这里就用最经典的一个三维光子晶体参数做例子:简单立方晶格,晶格常数a设为1(在COMSOL几何里直接以归一化单位建),原胞内放一个球形散射体。散射体介电常数取11.56(常见于硅在近红外波段约3.4折射率的平方),背景介质介电常数取1(空气)。
用COMSOL建模时,在三维组件里建立一个长方体,边长设为1,中心在原点(或者让角点落在原点,习惯不同而已,注意后面边界设置别搞混就行)。然后在原胞正中心加一个半径R = 0.3的球体。这个半径的选取对应一个经典算例:在空气背景中排布高介电球,带隙宽度比较可观,适合验证算法。
在“材料”部分维护两种材料:空气的介电常数设为1,球的介电常数设为11.56。模型里建议开启“自动网格”之前先在心里过一遍:球表面附近场变化最剧烈,网格需要做局部加密,所以后面对球面网格尺寸单独设置;其余区域可以稍稀疏。
这里还要定义若干全局参数。我的习惯是把归一化工作放到参数里完成,而不是靠后处理临时算。需要维护的参数一次性列出来:
参数表
| 参数名 | 表达式 | 说明 |
|---|---|---|
| a | 1 | 晶格常数(无量纲) |
| R | 0.3 | 散射体半径 |
| eps_bg | 1 | 背景介电常数 |
| eps_sc | 11.56 | 散射体介电常数 |
| kx | 0 | 布洛赫波矢x分量(倒空间) |
| ky | 0 | 布洛赫波矢y分量 |
| kz | 0 | 布洛赫波矢z分量 |
| pen | 0.05 | 散度惩罚系数 |
其中kx、ky、kz是后面要扫描的变量,它们的单位要特别注意。COMSOL内置周期条件里如果填的是“波矢分量”,默认单位是rad/m,但当前几何用的是归一化长度,所以给出倒空间坐标时需要乘以2π才能在物理上对得上。更省心的做法是:以倒格子坐标形式定义扫描变量,然后在周期条件的波矢输入里写成“2pikx”,后面扫描kx时其实就是在扫描以(2π/a)为单位的倒格矢。
3.2 因变量与弱形式表达式的具体写法
接下来是核心步骤。在“模型开发器”里添加一个“弱形式偏微分方程”接口,类型选择:因变量是三个电场分量Ex、Ey、Ez。
之所以需要三个分量,是因为方程是矢量方程,需要把所有方向耦合都写进弱表达式里。
COMSOL的弱形式PDE节点里有两个关键输入框:“弱表达式”和“约束”。我们最主要的功夫都花在“弱表达式”里。
先写出旋度算子的分量形式。对一个矢量A=(Ax, Ay, Az),旋度是:
curl(A) = (∂Az/∂y - ∂Ay/∂z, ∂Ax/∂z - ∂Az/∂x, ∂Ay/∂x - ∂Ax/∂y)
弱形式需要的是“curl(E)·curl(F)”这种内积形式,其中F是测试函数。由于F的旋度分量在形式上与E的分量表达式相似,只是把场变量换成对应测试函数,因此可以手工展开所有项。在COMSOL表达式里,∂Ax/∂y这样的一阶偏导一般写成AxY或者d(Ax, y),不同版本语法略有差异,建议以对应版本帮助文档为准。下面给出我常用的基于导函数据语法“d()”书写方式:
curl1 = d(Ez, y) - d(Ey, z)
curl2 = d(Ex, z) - d(Ez, x)
curl3 = d(Ey, x) - d(Ex, y)
同理,测试函数F=(Ex_test, Ey_test, Ez_test)的旋度写为:
tcurl1 = d(test(Ez), y) - d(test(Ey), z)
tcurl2 = d(test(Ex), z) - d(test(Ez), x)
tcurl3 = d(test(Ey), x) - d(test(Ex), y)
于是弱表达式第一部分就可以写成:
curl1 * tcurl1 + curl2 * tcurl2 + curl3 * tcurl3
后面紧接着特征值项:
- eigvarl * epsr * (test(Ex)*Ex + test(Ey)*Ey + test(Ez)*Ez)
其中eigvarl在COMSOL特征值研究里代表要求解的特征值,这里的λ实际上对应公式里的k₀²。epsr需要定义成空间坐标相关的介电常数,最方便的方式是使用COMSOL的“变量”功能加上台阶函数判断,或者直接用材料定义的介电常数变量如epsilon_r_iso。为避免歧义,我习惯单独定义一个变量epsr,表达为:
epsr = eps_bg + (eps_sc - eps_bg) * (xdest(x) + ydest(y) + z*dest(z) <= R^2)(具体写法其实更推荐用阶跃函数,can build from logical expression)
最后加上惩罚项:
pen * (d(Ex, x) + d(Ey, y) + d(Ez, z)) * (d(test(Ex), x) + d(test(Ey), y) + d(test(Ez), z))
把三部分叠加起来,整个弱表达式就是:
curl1 * tcurl1 + curl2 * tcurl2 + curl3 * tcurl3 - eigvarl * epsr * (test(Ex)*Ex + test(Ey)*Ey + test(Ez)*Ez) + pen * divE * div_testE
在特征值研究设置中把“特征值名称”设为eigvarl。由于我们关心的是物理上能传播的实模式,搜索区间放在实轴附近,通常设置10到20个特征值,目标值可以取一个比第一个带边频率略大的数。
这里还有一个细节:COMSOL的弱形式PDE接口默认需要设置因变量的单元阶次。三维矢量电磁问题建议使用“三次”还是“二次”?从精度和自由度平衡考虑,我一般用二次。这个选择在低阶模上精度已经不错,又不至于让网格数量失控。如果你想验证网格收敛性,可以在同一k点下用二次和三次各算一次,比较几个特征值的相对误差——这是检查离散质量的最直接办法。
3.3 布洛赫周期边界条件的设置
在弱形式PDE接口下,还需要给原胞的相对面配上周期条件。COMSOL的“周期条件”节点可以选择Floquet周期类型,并指定三个方向上的波矢分量。
以简单立方原胞为例,需要设x=0与x=1两个面配对,y、z同理。注意坐标面的选择要与几何建立时一致,如果几何是从-0.5到0.5建的,边界就相应设为-0.5和0.5。
在周期条件节点的“Floquet波矢”设置里,三个分量直接引用前面定义得参数:
k_Bloch_x = 2pikx
k_Bloch_y = 2piky
k_Bloch_z = 2pikz
这里的kx、ky、kz是我们后续扫描时使用的倒格子坐标。这样设置的好处是扫描点直接写k点的“倒格矢坐标”(比如X点就是0.5,0,0),不用每次都手算rad/m。
需要提醒:周期条件只能用在相互对应且网格划分一致的面上。COMSOL在创建周期配对时通常会对网格做一致性处理,但如果之后你手动“编辑”过边界网格,有可能破坏配对关系,导致求解器报“周期性约束失效”之类的错误。我建议在网格序列完成后,再专门检查一遍周期配对映射,确保没有例外边界。
还有一个细节是:三维情况下,周期面的角边(三条棱的交线)也需要处理。简单做法是把棱也纳入周期约束,COMSOL在配对三个方向的周期面时,通常会自动处理好棱的约束继承。但个别版本可能出现棱上的约束冗余或冲突,表现为求解时自由度不足。如果遇到这种情况,可以在周期面设置里把“继承约束”选项打开,或者手动增加棱上的周期约束。
4. 能带计算与后处理:从特征值到能带曲线
4.1 布里渊区高对称点与k点路径采样
理论上一套能带图只需要沿不可约布里渊区边界扫描波矢即可。对简单立方晶格,不可约布里渊区的高对称点路径为:Γ-X-M-R-Γ。
在COMSOL里做扫描,方式是定义一个“参数化扫描”,把扫描变量设为kx、ky、kz。但直接同时扫三个变量,全部组合会爆炸。最聪明的办法是:定义一组辅助参数,每行对应路径上某个点。比如定义:
- 扫描步数N = 10
- 用“参数化曲线”逻辑,将kx设为路径坐标t的分段线性函数。
一种常用做法是在“全局定义”中定义一个路径参数s,范围0到4,依次对应Γ→X、X→M、M→R、R→Γ四段,然后通过if语句或者插值函数分别映射到kx、ky、kz。更干净的做法是在COMSOL里用“插值”函数定义曲线:第一个列是s,后面三列分别是kx、ky、kz,采样点即路径上的各个位置。
我个人更推荐后一种方法:把路径点数据提前算好,写成CSV文件,然后在COMSOL里用“插值函数”读入,扫描变量设为s。这样做的好处是路径规划、密度控制都在外部做,改起来也方便。例如想要每段10个点,则可以生成这样一张表:
| s | kx | ky | kz |
|---|---|---|---|
| 0.0 | 0.000 | 0.000 | 0.000 |
| 0.1 | 0.050 | 0.000 | 0.000 |
| ... | ... | ... | ... |
| 1.0 | 0.500 | 0.000 | 0.000 |
| 1.1 | 0.500 | 0.050 | 0.000 |
| ... | ... | ... | ... |
扫描时注意:特征值求解通常会为每个参数步生成一组特征值,但不同参数步之间的模式编号是独立的,不能直接按特征值编号连线。这一点对后处理制图非常关键,一会儿单独说。
4.2 特征值求解器配置与频率归一化
研究类型选择“特征值”。COMSOL的特征值求解器默认可能求的是从小到大排列的本征值,但具体排序方式和特征值的相对位置,在三维模型里往往会有交叉和简并。如果想稳定地获取前若干个低频模式,需要在求解器的设置中指定“所需特征值数量”,并设置好搜索区域,比如“搜索特征值附近的点:1e6”,单位为rad²/s²,这个取决于特征值的含义。
由于我们弱表达式里特征值eigvarl对应的是k₀²,物理上我们需要换算回频率:
f = sqrt(eigvarl) * c / (2π)
在COMSOL后处理中,可以直接在结果表达式里写:
f_norm = a * sqrt(eigvarl) / (2π)
这个归一化频率a/λ = fa/c是光子晶体能带图中常用横轴。如果你把晶格常数a设成了1,表达式就更简单。注意:能带图纵轴一般用“归一化频率fa/c”,如果直接用sqrt(eigvarl)/(2π),由于k₀ = ω/c = 2πf/c,得到的是a/λ。两者数值相等是因为a=1时fa/c = a/λ。这里单位比较绕,建议在正式画图前先用解析解验证一个简单算例(比如均匀介质里的平面波色散),确保换算没有差一两个数量级。
具体验证方法也不复杂:把介电球设成与背景一致,也就是全空间均匀介质,然后算一个k点,比如Γ点附近的特征值。理论值应满足f = c·|k|/(2π√ε),如果计算的频率和理论值一致,说明特征值到频率的换算是正确的。这一步能极大减少后处理的胡思乱想。
4.3 能带曲线绘制与模式识别
将参数化扫描计算完成后,处理特征值数据时有几个经典坑。
第一个坑是不同波矢间的模式配对。COMSOL参数化扫描得到的结果会以“参数s、特征值编号、特征值大小”的形式存放。直接按特征值编号画线,你会看到曲线像一团乱麻一样来回穿越,因为某些模式在波矢变化过程中会交换顺序,或者被识别为复特征值。
解决思路有两种。一种是对每个波矢得到的特征值按大小重新排序,然后按“最接近上一个波矢特征值”的原则做最近邻匹配。这个思路实现并不复杂,可以在COMSOL里写个小脚本,也可以导出数据到MATLAB或Python处理。另一种是检查各特征值的场模式图,手动确认哪些是目标模式、哪些是伪模。论文撰写阶段,我通常两种方法结合使用。
第二个坑是简并。三维光子晶体每个能带在高对称点附近往往存在简并态,例如X点的某些能带会成对出现。如果只看特征值数值,可能以为模式丢失了,其实只是两三个特征值几乎重合。处理时要把简并度考虑进去,能带曲线每个k点可以允许重频出现。
第三个坑是模式筛选。加了惩罚项以后,虽然伪模数量会大幅减少,但不代表完全消失。一个快速筛选方法是看特征值虚部的大小。物理上无损耗介质中频率应为实数,若某个模式虚部显著偏离零,则优先怀疑是伪模。实际COMSOL解得的特征值通常会带有很小的数值噪声虚部,但只要虚部相对于实部小几个数量级就可以接受。如果虚部过大(比如超过实部的1%),就要检查网格和惩罚项系数。
4.4 补充:从能带到器件参数
虽然这篇文章主要讲能带,但很多朋友做光子晶体最终是为了指导器件设计。比如做高Q谐振腔、波导或者BAW谐振器时,能带结构能给出模式的截止频率、群速度和有效折射率等参数。
在COMSOL里拿到特征值后,群速度可以用能带曲线对k求导得到,处理时要注意多能带交叉;有效折射率也可以用特征值计算:n_eff = k₀/|k|。如果材料里引入了损耗,特征值会是复数,实部决定谐振频率,虚部则对应损耗或增益,这时你能看到类似于“有效折射率虚部”的量。这个量在光子晶体光波导和谐振器设计中非常关键,损耗估算和模式泄漏分析都靠它。
5. 常见问题与排查技巧实录
5.1 特征值偏大或怎么扫都出现一堆零频模
这种情况最多的原因是单位混乱。比如几何以纳米建、光速以m/s代入、晶格常数又没归一化,而特征值eigvarl对应k₀²,最后换算频率时差了10的若干次方。建议一开始就把几何尺度归一化到晶格常数a,波长也以a为单位换算,就能规避大多数单位问题。
零频模大量出现,则一般是散度伪模。如果加了惩罚项后仍然顽固存在,尝试把pen值从0.01加大到0.2,或者检查周期边界是否设置完整。还有一种可能是你忘记把因变量的单元阶次设为至少“二次”:用线性元解三维矢量电磁问题时,零能模几乎必然占据特征谱前部。
5.2 高对称点的简并模算不出来或者错位
高对称点处的简并最容易出问题,因为求解器默认的搜索窗口可能把近简并模式漏掉或者合并。遇到这种情况,可以在该k点单独增加“所需特征值数量”,并缩小搜索区间的目标值。同时要注意:高对称点附近的波矢边界条件,相位在某些面上可能产生恒定偏移,这不会影响本征值,但会给解的结构带来一个任意相位因子。在后期画模式场图时,如果发现场分布带“整体旋转”,这是由布洛赫定理的规范自由度引起的合法现象。
5.3 参数化扫描中途报错或结果不连续
扫描时最常见的报错是“没有找到特征值,请尝试调整搜索区间”。原因通常是在某个k点,感兴趣的特征频率已经跑到当前搜索区间之外。解决办法不是调小搜索区间,而是先在一个代表性的低对称点做单点计算,确实了解频率范围,再设置合理的搜索窗口。
结果不连续还有个容易忽略的原因:网格在每个参数步会重新划分。如果网格序列前没有做“固定网格”设定,默认可能依据几何变化自适应调整,导致特征值的微小差异被放大成可见跳变。三维原胞几何一般不会随参数变化,所以扫描前务必把网格设置里的“自适应”关掉,保持各k点使用同一套网格。
5.4 内存溢出与计算时间过长
三维光子晶体计算对内存要求很高。一个原胞如果网格剖得较细,自由度轻松几十万甚至上百万。弱形式PDE的特征值求解器默认使用直接求解器,比如MUMPS或PARDISO,内存消耗非常大。这里有几个实用建议:
- 先用粗网格跑通整个流程,确认能带趋势合理后再加密网格。连趋势都还没看到就上细网格,浪费时间也容易打击信心。
- 开启“参数化扫描”前,先测试单点求解大概需要多少内存和时长,评估总耗时。
- 如果只是查看前几个低频带,可以设置求解器只计算最靠近目标值的前6或前10阶特征值,不必一次性算几十个。
- 适当使用局部网格加密,而不是全局加密。散射体球面附近、介质界面附近需要加密,远离界面的方角区域对低频带的影响较小。
5.5 一个隐藏很深的坑:几何棱边上的周期约束
三维原胞有12条棱、8个顶点。如果周期条件只配对了6个面而没处理棱,求解器会去解一个自由度约束不完整的模型。表面上能跑通,但会出现某些模式严重依赖网格甚至不收敛的结果。解决方案是:在三个方向的“周期条件”节点中,明确对“面”设置的同时,也检查棱上的约束;COMSOL通常提供“在边上”的选项,将其设为“周期条件”即可。如果界面找不到这个选项,可以通过在棱上再增加一个周期性点约束实现,但这会比较繁琐,建议升级到较新版本再处理。
6. 一点心得体会
三维光子晶体能带计算这件事,网上教程不少,但真正把方程推清楚再把弱形式写进COMSOL里的完整案例并不多。我最初也是看官方文档加上自己摸索,中间因为伪模问题纠结了将近两周,后来才意识到弱形式里加一个惩罚项就能解决,那个瞬间确实有豁然开朗的感觉。
如果你打算复现这篇文章里的流程,我给一个顺序建议:先从一维或二维周期结构开始,把弱形式和布洛赫边界跑通,确认特征值换算没有问题,再来挑战三维。三维的难度不在原理,而在计算规模和调试成本。网格先粗后细,k点先少后多,等曲线走势合理后再逐步加密加细,这会让你少走很多弯路。
最后留一个我实际在用的小技巧:把能带计算的主流程做成一个COMSOL“App”,在界面里留下“晶格常数”“介电常数”“半径”和“k点路径参数”四个输入框,团队成员想快速评估新结构时,直接填参数就能出图。弱形式方案一旦跑通,它的迁移成本很低,换结构、换材料、换晶型都只是几何重建和参数修改的问题。希望这篇文章能帮你把第一步迈得顺一些。