Lumerical FDTD Solutions中内置的监视器只有点(零维)、线(一维)、矩形(二维)、长方体(三维)等基本形状,但在一些特殊的仿真中,实验者可能想要其他形状的监视器,例如圆形、球形、曲面等等。本文将从简单的二维监视器开始,设计圆形监视器,并建立分析组。
从原理上分析,监视器的作用是记录监视器所覆盖位置的电场和磁场数据,即 D a t a ( x , y , z ; λ ) = f [ E ( x , y , z ; λ ) , H ( x , y , z ; λ ) ] Data(x,y,z;\lambda)=f[{\rm \bold E}(x,y,z;\lambda),{\rm \bold H}(x,y,z;\lambda)] Data(x,y,z;λ)=f[E(x,y,z;λ),H(x,y,z;λ)]因此,设计各种形状的监视器的方法显然有2种:
本文使用第二种方法,用二维矩形监视器构造圆监视器。设计方法非常简单。在图像处理中,我们经常使用掩膜来保留数据,避免其被处理。同样地,利用矩形监视器制作圆形监视器的过程中只保留圆形区域内的数据,圆形区域外的数据全部置为0。
Lumerical FDTD Solutions中计算透射率的函数是transmission(“monitor”)。Knowledge Base中关于transmission函数的定义如下:
T ( f ) = 1 2 ∫ m o n i t o r R e { P ( f ) } ⋅ n ^ d S s o u r c e p o w e r ( f ) T(f)=\frac{1}{2}\frac{\int_{\rm monitor} {\rm \bold {Re}} \{{\rm \bold P} (f)\}\cdot {\rm\bold{\hat n}}dS}{{\rm sourcepower}(f)} T(f)=21sourcepower(f)∫monitorRe{P(f)}⋅n^dS其中,sourcepower返回的是光源在频率 f f f的功率;作用是把监视器探测到的功率对光源归化。坡印廷矢量 P \rm\bold P P的实部在 x , y , z x,y,z x,y,z三个方向的分量表示为 R e { P } = ( P x , P y , P z ) {\rm\bold{Re}\{\bold P\}}=(P_x,P_y,P_z) Re{P}=(Px,Py,Pz) 同样,曲面微元在 x , y , z x,y,z x,y,z三个方向的大小可以表示为, n ^ \rm\bold{\hat n} n^是单位法向量。 n ^ d S = ( n x , n y , n z ) d S {\rm \bold {\hat n}}dS = (n_x, n_y, n_z)dS n^dS=(nx,ny,nz)dS两式相乘得到以下表达式:
R e { P } ⋅ n ^ d S = ( P x n x + P y n y + P z n z ) d S {\rm\bold{Re}\{\bold P\}}\cdot{\rm \bold {\hat n}}dS=(P_xn_x+P_yn_y+P_zn_z)dS Re{P}⋅n^dS=(Pxnx+Pyny+Pznz)dS并且 d S dS dS在直角坐标系中又可以写为:
d S = d x d y d z dS=dxdydz dS=dxdydz在FDTD Solutions中,因为监视器只垂直于坐标轴,表达式可以进一步简化。积分项简化为:
R e { P } ⋅ n ^ d S = { P x d y d z , X-normal , P y d x d z , Y-normal , P z d x d y , Z-normal . {\rm\bold{Re}\{\bold P\}}\cdot{\rm \bold {\hat n}}dS=\begin{cases} P_xdydz, & \text {X-normal}, \\ P_ydxdz, & \text {Y-normal}, \\ P_zdxdy, & \text {Z-normal}. \end{cases} Re{P}⋅n^dS=⎩⎪⎨⎪⎧Pxdydz,Pydxdz,Pzdxdy,X-normal,Y-normal,Z-normal.例如,垂直于 z z z轴的监视器, n ^ d S = n z d S = d S monitor = d x d y {\rm \bold {\hat n}}dS = n_zdS=dS_{\text {monitor}}=dxdy n^dS=nzdS=dSmonitor=dxdy积分项点乘的时候只有 P z P_z Pz被保留下来,其他分量都为0。
项目 | 类型 | 含义 |
---|---|---|
radius | 长度 | 圆形监视器半径 |
x0 | 长度 | 监视器中心的 x x x坐标 |
y0 | 长度 | 监视器中心的 y y y坐标 |
z0 | 长度 | 监视器中心的 z z z坐标 |
Normalized Axis | 字符串 | 监视器垂直的方向 |
其他更多的变量可以自己设置。
接下来编写分析组结构的脚本。基本思路为添加对应的监视器,只记录监视器法向对应的坡印廷矢量的分量(节省空间)。
# 具体脚本
deleteall;
addpower;
set("name", "power");
set("x", x0);
set("y", y0);
set("z", z0);
# Disable all data record
set("output Ex", false);
set("output Ey", false);
set("output Ez", false);
set("output Hx", false);
set("output Hy", false);
set("output Hz", false);
set("output Px", false);
set("output Py", false);
set("output Pz", false);
set("output power", false);
if (%Normalized Axis% == "x") {
set("monitor type", "2D X-normal");
set("y span", 2*radius);
set("z span", 2*radius);
set("output Px", true);
}
if (%Normalized Axis% == "y") {
set("monitor type", "2D Y-normal");
set("x span", 2*radius);
set("z span", 2*radius);
set("output Py", true);
}
if (%Normalized Axis% == "z") {
set("monitor type", "2D Z-normal");
set("x span", 2*radius);
set("y span", 2*radius);
set("output Pz", true);
}
分析组内的监视器添加完成后,就要对这些结构获得的数据进行处理。编写数据分析脚本前先设置输入的参数(Parameters)和输出的参数(Results)。
circularMask是圆形模板的示意图,T则是得到的透射率。
最后编写分析脚本
# 完整脚本
P = getresult("power", "P");
f = P.f;
lam = P.lambda;
if (%Normalized Axis% == "x") {
p = pinch(real(P.Px));
a = P.y;
b = P.z;
a0 = y0;
b0 = z0;
}
if (%Normalized Axis% == "y") {
p = pinch(real(P.Py));
a = P.x;
b = P.z;
a0 = x0;
b0 = z0;
}
if (%Normalized Axis% == "z") {
p = pinch(real(P.Pz));
a = P.x;
b = P.y;
a0 = x0;
b0 = y0;
}
mask = ones(length(a), length(a));
for (ii = 1 : length(a)) {
for (jj = 1 : length(b)) {
if ((a(ii)-a0)^2 + (b(jj)-b0)^2 > radius^2) {
mask(ii,jj) = 0;
}
}
}
m = mask(2:end, 2:end);
da = a(2:end) - a(1:end-1);
db = b(2:end) - b(1:end-1);
len = length(f);
power = zeros(len,1);
db = transpose(db);
ds = mult(da, db);
for (i = 1 : len) {
power(i) = sum(pinch(p(2:end, 2:end, i))*m*ds);
}
tran = 0.5*power/sourcepower(f);
T0 = transmission("power");
T = matrixdataset("T");
T.addparameter("Wavelength", lam, "Frequency", f);
T.addattribute("T0", T0);
T.addattribute("T", tran);
circularMask = matrixdataset("mask");
circularMask.addparameter("a", a);
circularMask.addparameter("b", b);
circularMask.addattribute("mask", mask);
T0是用transmission函数计算的矩形监视器的透射率。