We have an exciting announcement about badges coming in May 2025. Until then, we will temporarily stop issuing new badges for course completions and certifications. However, all completions will be recorded and fulfilled after May 2025.

Ansys Learning Forum Forums Discuss Simulation Photonics Regarding box of monitors and far field simulations Reply To: Regarding box of monitors and far field simulations

pnair
Subscriber

Hello Amrita,

Thank you for the reply and a detailed explanation of farfield analysis group and the corrected script.

I run the simulation with the script suggested here. But, It is generating an error:

Target wavelength = 1.54e-06

Wavelength used = 1.54e-06

Angular distribution i=1, 1.54um

Projecting in x-y plane

Projecting in y-z plane

Projecting in x-z plane

Error: Result XY_halfspace: variable not found.

And, I am not able to visualize the farfied data in the xy_half space and its showing"failed to calculate results"

Please find the attached script that you have suggested here and I have used the same script for the simulations:

##############################################

# Far field from closed box

# This script calculates scattering cross-section and far field projection in half space

#

# Note: The far field projection calculation assumes that all of the monitors

# are in a single homogeneous material (i.e. there is no substrate)

# If a substrate is present, results from this object will be invalid.

# If multiple frequency points are collected, the projection can be slow!! One could reduce the halfspace resolution for faster analysis.

# For more information, see http://docs.lumerical.com/en/layout_analysis_projections_from_monitor.html

#

# symm x,y,z: symmetry boundary conditions

# 0 for no symmetry, 1 for symmetric, -1 for antisymmetric

# Autodetection is managed by examining fields at the symmetry boundary

# For more information, see http://docs.lumerical.com/en/index.html?ref_sim_obj_symmetric_anti-symmetric.html

#

# do halfspace: Calculate the far field in the full half space for all frequencies. This takes longer than the 1D radar line cross sections. 1 for yes, 0 for no

# do polar plot: Calculate the far field scattering angular distribution for a specified target wavelength. 1 for yes, 0 for no

# target wavelength: Desired wavelength for polar plot. The closest wavelength recorded by the monitors will be found and used for the plot.

# halfspace res: Define the resolution of the half space projection. This will significantly affect the time to run the analysis.

# polar plot res: Define the resolution of the polat plots.

#

# Output properties

# XY, YZ, XZ: E, |E|^2, |H|^2 far field profile of scattered field in plane, as a function of frequency

# XY_halfspace: E, |E|^2, |H|^2 in full upper/lower half space,, as a function of frequency. Similar to standard projection from a single monitor

#

# Tags: far field projection closed box

#

# Copyright 2015 Lumerical Solutions Inc

##############################################

 

##############################################

# automatically unfold field data if symmetry BC is applied

if (havedata("x1", "f")) {

symm_x = 0;

} else {

xtemp = getdata("y2", "x");

ztemp = getdata("y2", "z");

Eztemp = pinch(getdata("y2", "Ez"));

 

Ez2mid = sum(Eztemp(round(length(xtemp)/2), 1:length(ztemp))^2);

if (Ez2mid != 0) {

symm_x = 1;

} else {

symm_x = -1;

}

}

 

if (havedata("y1", "f")) {

symm_y = 0;

} else {

ytemp = getdata("x2", "y");

ztemp = getdata("x2", "z");

Eztemp = pinch(getdata("x2", "Ez"));

 

Ez2mid = sum(Eztemp(round(length(ytemp)/2), 1:length(ztemp))^2);

if (Ez2mid != 0) {

symm_y = 1;

} else {

symm_y = -1;

}

}

 

if(include_sub){

if (havedata("z1", "f")) {

symm_z = 0;

} else {

xtemp = getdata("y2", "x");

ztemp = getdata("y2", "z");

Eytemp = pinch(getdata("y2", "Ey"));

 

Ey2mid = sum(Eytemp(1:length(xtemp), round(length(ztemp)/2))^2);

if (Ey2mid != 0) {

symm_z = 1;

} else {

symm_z = -1;

}

}

}

f = getdata("x2","f"); # get freqency data

 

if (havedata("index","index_x")) { # get refractive index. Required to calcualte H2 from E2

n_index = getdata("index","index_x");

} else {

n_index = getdata("index","index_z");

}

##############################################

 

 

# define the angular resolution

phi = linspace(0,360,%polar plot res%); # user-modifiable in the Variables tab

npts = length(phi);

 

# define the field data matrices for angular distribution

E_xy = matrix(npts, 3, length(f)); # 3 for x, y, z component

E_yz = matrix(npts, 3, length(f)); # 3 for x, y, z component

E_xz = matrix(npts, 3, length(f)); # 3 for x, y, z component

E2_xy = matrix(npts,length(f));

E2_yz = matrix(npts,length(f));

E2_xz = matrix(npts,length(f));

H2_xy = matrix(npts,length(f));

H2_yz = matrix(npts,length(f));

H2_xz = matrix(npts,length(f));

 

 

# Identify the closest wavelength to target:

target_wavelength = %target wavelength%;

i_target = find(f,c/target_wavelength);

?"Target wavelength = " + num2str(target_wavelength);

?"Wavelength used = " + num2str(c/f(i_target));

 

 

if (havedata("z2","Ex")) { # have z data, 3D simulation

 

##############################################

# Angular distribution calculation for a 3D simulation begins

 

for (i = 1:length(f)){ # loop for all frequencies

 

# print the frequency point number running in the loop

?"Angular distribution i="+num2str(i)+", "+num2str(c/f(i)*1e6)+"um";

 

n = n_index(i); # select the frequency point for the index

 

######## x-y plane (phi=0 corresponds to the direction (1,0,0))

?" Projecting in x-y plane";

x = cos(phi*pi/180); y = sin(phi*pi/180); z = 0;

 

# Calculate far field by summing contribution from each monitor

temp = farfieldexact("x2",x,y,z,i) + farfieldexact("y2",x,y,z,i) + farfieldexact("z2",x,y,z,i);

if(havedata("x1")){

temp = temp - farfieldexact("x1",x,y,z,i);

}else{

temp2 = farfieldexact("x2",-x,y,z,i);

s = symm_x*[1,-1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(havedata("y1")){

temp = temp - farfieldexact("y1",x,y,z,i);

}else{

temp2 = farfieldexact("y2",x,-y,z,i);

s = symm_y*[-1,1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(include_sub){

if(havedata("z1")){

temp = temp - farfieldexact("z1",x,y,z,i);

}else{

temp2 = farfieldexact("z2",x,y,-z,i);

s = symm_z*[-1,-1,1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

}

E_xy (1:length(phi), 1:3, i) = temp;

E2_xy (1:length(phi), i) = sum(abs(temp)^2,2); # E2 = |Ex|^2 + |Ey|^2 + |Ez|^2

H2_xy (1:length(phi), i) = E2_xy (1:length(phi), i) * n^2 * eps0/mu0; # for a plane wave, E^2 and H^2 only differ by a factor of n^2*eps0/mu0

 

 

 

######## y-z plane (phi=0 corresponds to the direction (0,1,0))

?" Projecting in y-z plane";

x = 0; y = cos(phi*pi/180); z = sin(phi*pi/180);

 

# Calculate far field by summing contribution from each monitor

temp = farfieldexact("x2",x,y,z,i) + farfieldexact("y2",x,y,z,i) + farfieldexact("z2",x,y,z,i);

if(havedata("x1")){

temp = temp - farfieldexact("x1",x,y,z,i);

}else{

temp2 = farfieldexact("x2",-x,y,z,i);

s = symm_x*[1,-1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(havedata("y1")){

temp = temp - farfieldexact("y1",x,y,z,i);

}else{

temp2 = farfieldexact("y2",x,-y,z,i);

s = symm_y*[-1,1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(include_sub){

if(havedata("z1")){

temp = temp - farfieldexact("z1",x,y,z,i);

}else{

temp2 = farfieldexact("z2",x,y,-z,i);

s = symm_z*[-1,-1,1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

}

E_yz (1:length(phi), 1:3, i) = temp;

E2_yz (1:length(phi), i) = sum(abs(temp)^2,2); # E2 = |Ex|^2 + |Ey|^2 + |Ez|^2

H2_yz (1:length(phi), i) = E2_yz (1:length(phi), i) * n^2 * eps0/mu0; # for a plane wave, E^2 and H^2 only differ by a factor of n^2*eps0/mu0

 

 

 

######### x-z plane (phi=0 corresponds to the direction (1,0,0))

?" Projecting in x-z plane";

x = cos(phi*pi/180); y = 0; z = sin(phi*pi/180);

 

# Calculate far field by summing contribution from each monitor

temp = farfieldexact("x2",x,y,z,i) + farfieldexact("y2",x,y,z,i) + farfieldexact("z2",x,y,z,i);

if(havedata("x1")){

temp = temp - farfieldexact("x1",x,y,z,i);

}else{

temp2 = farfieldexact("x2",-x,y,z,i);

s = symm_x*[1,-1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(havedata("y1")){

temp = temp - farfieldexact("y1",x,y,z,i);

}else{

temp2 = farfieldexact("y2",x,-y,z,i);

s = symm_y*[-1,1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(include_sub){

if(havedata("z1")){

temp = temp - farfieldexact("z1",x,y,z,i);

}else{

temp2 = farfieldexact("z2",x,y,-z,i);

s = symm_z*[-1,-1,1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

}

E_xz (1:length(phi), 1:3, i) = temp;

E2_xz (1:length(phi), i) = sum(abs(temp)^2,2); # E2 = |Ex|^2 + |Ey|^2 + |Ez|^2

H2_xz (1:length(phi), i) = E2_xz (1:length(phi), i) * n^2 * eps0/mu0; # for a plane wave, E^2 and H^2 only differ by a factor of n^2*eps0/mu0

 

} # end of the angular distribution for loop

 

if (%do polar plot%) { # polar plot for target wavelength

polar(phi*pi/180, E2_xy(1:length(phi), i_target), E2_yz(1:length(phi), i_target), E2_xz(1:length(phi), i_target),

"angle (degrees)", "|E|^2", "|E|^2 vs angle @ "+num2str(c/f(i_target)*1e6)+"um");

legend("xy plane","yz plane","xz plane");

} # end of if polar plot

 

# create datasets for XY, YZ, XZ for angular distribution

XY = matrixdataset("XY");

XY.addparameter("phi",phi*pi/180.); #phi angle in radians

XY.addparameter("lambda",c/f,"f",f);

XY.addattribute("E",pinch(E_xy,2,1),pinch(E_xy,2,2),pinch(E_xy,2,3)); # Ex, Ey, Ez

XY.addattribute("E2",E2_xy);

XY.addattribute("H2",H2_xy);

 

YZ = matrixdataset("YZ");

YZ.addparameter("phi",phi*pi/180.); #phi angle in radians

YZ.addparameter("lambda",c/f,"f",f);

YZ.addattribute("E",pinch(E_yz,2,1),pinch(E_yz,2,2),pinch(E_yz,2,3)); # Ex, Ey, Ez

YZ.addattribute("E2",E2_yz);

YZ.addattribute("H2",H2_yz);

 

XZ = matrixdataset("XZ");

XZ.addparameter("phi",phi*pi/180.); #phi angle in radians

XZ.addparameter("lambda",c/f,"f",f);

XZ.addattribute("E",pinch(E_xz,2,1),pinch(E_xz,2,2),pinch(E_xz,2,3)); # Ex, Ey, Ez

XZ.addattribute("E2",E2_xz);

XZ.addattribute("H2",H2_xz);

# end of the angular distribution for a 3D simulation

##############################################

 

##############################################

# Halfspace calculation for a 3D simulation begins

 

# calculate the far field in XY upper/lower half space

if (%do halfspace%) {

 

res = %halfspace res%; # projection resolution, user-modifiable in the Variables tab

u1 = linspace(-1,1,res);

u2 = u1;

X = meshgridx(u1,u2); # These three lines define the orientation of the hemisphere (ie. XY based halfspace)

Y = meshgridy(u1,u2);

Z = sqrt(1-X^2-Y^2);

filter = abs(imag(Z))<=0; # filter out any values outside of hemisphere

filter2=matrix(res,res,length(f)); # same as filter, just for all frequencies

filter3=matrix(res,res,3,length(f)); # same as filter2, just for all frequencies, Ex, Ey, Ez

for (j=1:length(f)){ # just for filter2 and fitler3 for all frequencies

filter2(1:res,1:res,j)=filter;

filter3(1:res,1:res,1,j)=filter; filter3(1:res,1:res,2,j)=filter; filter3(1:res,1:res,3,j)=filter;

}

x = reshape(X,[res^2,1]); # reshape coordinate matrix into a vector. This is the required form for farfieldexact.

y = reshape(Y,[res^2,1]);

z = reshape(Z,[res^2,1]);

x = [x,x]; # Concatenate a 2nd copy of the vector, for the lower half space

y = [y,y];

z = [z,-z];

npts = length(z); # size of position vector

 

# define halfspace dataset

E_XY_halfspace = matrix (2*res^2,3,length(f));

E2_XY_halfspace = matrix (2*res^2,length(f));

H2_XY_halfspace = matrix (2*res^2,length(f));

 

 

for (i = 1 : length(f)) { # loop for all frequency points

 

?"Projecting in XY upper half space, i=" + num2str(i)+", "+num2str(c/f(i)*1e6)+"um";

# Calculate far field by summing contribution from each monitor

temp = farfieldexact("x2",x,y,z,i) + farfieldexact("y2",x,y,z,i) + farfieldexact("z2",x,y,z,i);

if(havedata("x1")){

temp = temp - farfieldexact("x1",x,y,z,i);

}else{

temp2 = farfieldexact("x2",-x,y,z,i);

s = symm_x*[1,-1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(havedata("y1")){

temp = temp - farfieldexact("y1",x,y,z,i);

}else{

temp2 = farfieldexact("y2",x,-y,z,i);

s = symm_y*[-1,1,-1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

if(include_sub){

if(havedata("z1")){

temp = temp - farfieldexact("z1",x,y,z,i);

}else{

temp2 = farfieldexact("z2",x,y,-z,i);

s = symm_z*[-1,-1,1];

temp2(1:npts,1) = s(1)*temp2(1:npts,1);

temp2(1:npts,2) = s(2)*temp2(1:npts,2);

temp2(1:npts,3) = s(3)*temp2(1:npts,3);

temp = temp - temp2;

}

}

E_XY_halfspace (1:2*res^2,1:3,i) = temp;

E2_XY_halfspace (1:2*res^2,i)= sum(abs(temp)^2,2); # E2 = |Ex|^2 + |Ey|^2 + |Ez|^2

} # end of halfspace for loop

 

E_XY_upper_halfspace = E_XY_halfspace(1:res^2,1:3,1:length(f)); # separate the upper/lower data

E_XY_lower_halfspace = E_XY_halfspace((res^2+1):(2*res^2),1:3,1:length(f));

E_XY_upper_halfspace = reshape(E_XY_upper_halfspace,[res,res,3,length(f)]); # reshape the data back into a 2D matrix

E_XY_lower_halfspace = reshape(E_XY_lower_halfspace,[res,res,3,length(f)]);

E_XY_upper_halfspace = E_XY_upper_halfspace*filter3; # set all values outside of hemisphere (ie. the corners of the matrices) to zero

E_XY_lower_halfspace = E_XY_lower_halfspace*filter3;

 

E2_XY_upper_halfspace = E2_XY_halfspace(1:res^2,1:length(f)); # separate the upper/lower data

E2_XY_lower_halfspace = E2_XY_halfspace((res^2+1):(2*res^2),1:length(f));

E2_XY_upper_halfspace = reshape(E2_XY_upper_halfspace,[res,res,length(f)]); # reshape the data back into a 2D matrix

E2_XY_lower_halfspace = reshape(E2_XY_lower_halfspace,[res,res,length(f)]);

E2_XY_upper_halfspace = E2_XY_upper_halfspace*filter2; # set all values outside of hemisphere (ie. the corners of the matrices) to zero

E2_XY_lower_halfspace = E2_XY_lower_halfspace*filter2;

 

# create halfspace dataset

XY_halfspace = matrixdataset("XY_halfspace");

XY_halfspace.addparameter("ux",u1);

XY_halfspace.addparameter("uy",u2);

XY_halfspace.addparameter("lambda",c/f,"f",f);

XY_halfspace.addattribute("E_upper",pinch(E_XY_upper_halfspace,3,1),pinch(E_XY_upper_halfspace,3,2),pinch(E_XY_upper_halfspace,3,3));

XY_halfspace.addattribute("E_lower",pinch(E_XY_lower_halfspace,3,1),pinch(E_XY_lower_halfspace,3,2),pinch(E_XY_lower_halfspace,3,3));

XY_halfspace.addattribute("E2_upper",E2_XY_upper_halfspace);

XY_halfspace.addattribute("E2_lower",E2_XY_lower_halfspace);

XY_halfspace.addattribute("H2_upper",E2_XY_upper_halfspace * n^2*eps0/mu0);

XY_halfspace.addattribute("H2_lower",E2_XY_lower_halfspace * n^2*eps0/mu0);

}

# end of the halfspace calculation for a 3D simulation

##############################################

 

# end of 3D

 

} else {

##############################################

# Angular distribution for a 2D simulation, only for the XY plane

 

for (i = 1 : length(f)) { # for all frequency points

 

n = n_index(i); # select the frequency point for the index

 

# x-y plane (phi=0 corresponds to the direction (0,1,0))

?" Projecting in x-y plane. 2D simulation.";

x = -sin(phi*pi/180);

y = cos(phi*pi/180);

z = 0;

 

temp = farfieldexact("x2",x,y,i) + farfieldexact("y2",x,y,i);

if(havedata("x1")){

temp = temp - farfieldexact("x1",x,y,i);

}else{

temp2 = farfieldexact("x2",-x,y,i);

s = symm_x*[1,-1,-1];

temp2(1:length(phi),1) = s(1)*temp2(1:length(phi),1);

temp2(1:length(phi),2) = s(2)*temp2(1:length(phi),2);

temp2(1:length(phi),3) = s(3)*temp2(1:length(phi),3);

temp = temp - temp2;

}

if(havedata("y1")){

temp = temp - farfieldexact("y1",x,y,i);

}else{

temp2 = farfieldexact("y2",x,-y,i);

s = symm_y*[-1,1,-1];

temp2(1:length(phi),1) = s(1)*temp2(1:length(phi),1);

temp2(1:length(phi),2) = s(2)*temp2(1:length(phi),2);

temp2(1:length(phi),3) = s(3)*temp2(1:length(phi),3);

temp = temp - temp2;

}

 

E_xy (1:length(phi), 1:3, i) = temp;

E2_xy (1:length(phi), i) = sum(abs(temp)^2,2); # E2 = |Ex|^2 + |Ey|^2 + |Ez|^2

H2_xy (1:length(phi), i) = E2_xy (1:length(phi), i) * n^2 * eps0/mu0; # for a plane wave, E^2 and H^2 only differ by a factor of n^2*eps0/mu0

 

} # end of for loop 2D

 

if (%do polar plot%) { # polar plot for target wavelength

polar(phi*pi/180, E2_xy(1:length(phi), i_target), "angle (degrees)", "|E|^2", "|E|^2 vs angle @ "+num2str(c/f(i_target)*1e6)+"um");

legend("xy plane");

} # end of if polar plot

 

# create dataset for XY

XY = matrixdataset("XY");

XY.addparameter("phi",phi*pi/180.); #phi angle in radians

XY.addparameter("lambda",c/f,"f",f);

XY.addattribute("E",pinch(E_xy,2,1),pinch(E_xy,2,2),pinch(E_xy,2,3)); # Ex, Ey, Ez

XY.addattribute("E2",E2_xy);

XY.addattribute("H2",H2_xy);

 

} # end of angular distribution for 2D simulation

Â