Ansys Learning Forum › Forums › Discuss Simulation › Photonics › Arbitrary sign for eigen mode › Reply To: Arbitrary sign for eigen mode
March 21, 2024 at 4:44 am
amitrotem2
Subscriber
Â
Â
Â
Â
Here is an example with s-parameter sweep in FDTD.
Â
Â
##
clc;
cleardcard;
closeall;
newproject;
## design
x_shift = 100e-9; # length of blocks
y_shift = 1e-9; # offset for the first and last blocks
K = 3;
for (k=0:K){
  addrect; set("name", "rect"+num2str(k));
  set("x",k*x_shift);
}
selectpartial("rect");
set("x span",x_shift);
set("y",0);set("y span",1e-6);
set("z",0);set("z span",0.2e-6);
set("material", "Si (Silicon) - Palik");
### off set the first and last blocks
setnamed("rect0", "y", -y_shift);
setnamed("rect"+num2str(K), "y", Â y_shift);
## solver
addfdtd;
set("x min",-x_shift/2);set("x max",(K+0.5)*x_shift);
set("y",0);set("y span",K*y_shift+2e-6);
set("z",0);set("z span",1e-6);
set("mesh accuracy", 4);
setresource("FDTD", "GPU", true);
setnamed("FDTD", "express mode", true);
## ports in the middle of each block
for (k=0:K){
  addport();
  set("x", k*x_shift);
 if (1.5 < k){set("direction", "Backward");}
}
selectpartial("FDTD::ports::port");
set("auto update", false);
set("frequency dependent profile", false);
set("mode selection", "user select");
set("selected mode numbers", 2); # 2nd mode is antisymmetric and will show the issue
clearportmodedata;
seteigensolver("correct backward propagating modes", false);
seteigensolver("correct backward propagating modes when pml is present", false);
wavelength = 1560e-9;
setglobalsource("set frequency", true);
setglobalsource("center wavelength", wavelength);
setglobalsource("wavelength span", 0);
setglobalmonitor("wavelength center", wavelength);
setglobalmonitor("frequency points", 1);
setglobalmonitor("wavelength span", 0);
setglobalmonitor("use source limits", 1);
##Â
save("sign_arb.fsp");
## s-parameter sweep
addsweep(3);
runsweep;
sweepdata = getsweepresult("s-parameter sweep","S matrix");
Smat = pinch(sweepdata.S); # scattering matrix
### see the issue when propagating from port 3 to 4 vs fromÂ
?conj(Smat(3,1))*Smat(4,1); # excite port 1, and look at the propagating from port 3 to 4
?conj(Smat(3,2))*Smat(4,2); # excite port 2, and look at the propagating from port 3 to 4
?conj(Smat(2,4))*Smat(1,4); # excite port 4, and look at the propagating from port 2 to 1
?conj(Smat(2,3))*Smat(1,3); # excite port 3, and look at the propagating from port 2 to 1
##
neff_list = matrix(K+1);
S0 = matrix(K+1,K+1);
for (k=1:K+1){
  NEFF = getresult("FDTD::ports::port "+num2str(k), "neff");
  neff_list(k) = NEFF.neff;
  mode1 = getresult("FDTD::ports::port "+num2str(k), "mode profiles");
  for (j=1:K+1){
    mode2 = getresult("FDTD::ports::port "+num2str(j), "mode profiles");
    cr12 = pinch(cross(mode1.E2, mode2.H2));
    cr11 = pinch(cross(mode1.E2, mode1.H2));
    cr22 = pinch(cross(mode2.E2, mode2.H2));
    cr12 = integrate(pinch(cr12(:,:,1)), [1,2], pinch(mode1.y), pinch(mode1.z));
    cr11 = integrate(pinch(cr11(:,:,1)), [1,2], pinch(mode1.y), pinch(mode1.z));
    cr22 = integrate(pinch(cr22(:,:,1)), [1,2], pinch(mode1.y), pinch(mode1.z));
    S0(j,k) = cr12/sqrt(cr11*cr22);
  }
}
## modes have minus signs
image(real(S0));