Lumerical FDTD Solutions中内置的监视器只有点(零维)、线(一维)、矩形(二维)、长方体(三维)等基本形状,但在一些特殊的仿真中,实验者可能想要其他形状的监视器,例如圆形、球形、曲面等等。本文将从简单的二维监视器开始,设计圆形监视器,并建立分析组。
1. 原理
从原理上分析,监视器的作用是记录监视器所覆盖位置的电场和磁场数据,即 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。
2.分析组结构
添加分析组结构的变量
项目 | 类型 | 含义 |
---|---|---|
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);
}
3. 分析组的分析脚本
分析组内的监视器添加完成后,就要对这些结构获得的数据进行处理。编写数据分析脚本前先设置输入的参数(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函数计算的矩形监视器的透射率。
4. 结果