Professional Documents
Culture Documents
A 2D Electromagnetic Scattering Solver For Matlab: 1 Introduction and Method
A 2D Electromagnetic Scattering Solver For Matlab: 1 Introduction and Method
July 1, 2002
Since in the background, where ∆ε(r) = 0, the incident plane wave E 0 (r)
must be a solution of the homogenous equation
k02 = k · k
1
Equation 5 directly gives us the excitation terms in every point in space.
In order to compute the scattered field in and outside the scattering object
we solve the wave equation with a point source term where the solution as
mentioned above is the Green’s function G B .
0
∇ × ∇ × GB (r, r 0 ) − k02 εB GB (r, r 0 ) = δ(r − r ) (6)
It shows as well that the field in the background can be computed from the
solution inside the scatterer since ∆ε(r) = 0 is true outside. Splitting up
background and scatterer area greatly reduces computation needs since the
systems to be solved go with the order of N 2 . The fields in the background
are a simple linear superposition of the scatterer’s field.
The next step is to discretize equation 7 using E i = E(ri ) and GB i,j =
B 0
G (ri , rj ):
N
X
Ei = Ei0 + GB 2 2
i,j k0 ∆εj Ej Vj + Mi k0 ∆εi Ei (8)
j=1,j6=i
N holds the total number of cell elements of the area to be computed and V j
denotes the cell area (volume) which does not have to be necessarily equal
for each cell. Since Green’s function has a singularity for r = r 0 (’in the cen-
ter of the source’), one has to treat this case separately. This is done using
the Mi term. Lastly only Green’s function G B (r) and Mi needs to be defined:
i
GB (r, r 0 ) = H0 (kρ ρ)exp(ikz z) (9)
4
iπ
Mi = βγ (10)
2
k2
β = 1 − 2z
kB
Rief f 2i
γ= H1 (kρ Rief f ) + 2
kρ πkρ
Hα (ρ) denotes Hankelfunctions of the first kind. Since only TEM propaga-
tion is considered, kz = 0 holds true. Further
2
q
kρ = kx2 + ky2 (11)
p
ρ = (x − x0 )2 + (y − y 0 )2 (12)
1
ef f Vi 2
Ri = , Vi = dxi dyi (13)
π
2 Implementation in Matlab
Deriving a linear equation system of equation 8 is easy (N = 4, omitting V i ):
M1 ∆ε1 GB B GB
0
E1 E1 12 ∆ε2 G13 ∆ε3 14 ∆ε4 E1
E2 E20 2 GB B GB
+k0 21 ∆ε1 M2 ∆ε2 G23 ∆ε3 24 ∆ε4 E2
=
E3 E 0 B B
G ∆ε1 G ∆ε2 M3 ∆ε3 B
G24 ∆ε4 E3
3 31 32
E4 E40 GB41 ∆ε 1 G B ∆ε
42
B
2 G43 ∆ε4 M4 ∆ε4 E4
1 −GB 0 −GB
0
12 ∆ε2 14 ∆ε4 E1 E1
0 1 − M2 ∆ε2 0 −GB ∆ε E 0
4 2 E2
24
0 −GB = (14)
32 ∆ε2 1 −GB 34 ∆ε4
E3 E30
0 −GB 42 ∆ε2 0 1 − M4 ∆ε4 E4 E40
This leads to the following simplified equation system along with the recipe
to compute the background cells:
3
2.1 Data structures
The geometry information consists in this case only of the dielectric contrast
∆εi and (x, y)-coordinates of the corresponding cell. All cells have the same
shape and size and therefore no other data needs to be stored. A scattering
configuration like
1 1 1 1
1 3 3 1
1 3 3 1
1 1 1 1
is mapped to the linear array g_eometry:
index 1 2 3 4 5 6 7 8 ...
∆εi 0 0 0 0 0 2 2 0 ...
xi 0.5 1.5 2.5 3.5 0.5 1.5 2.5 3.5 ...
yi 0.5 0.5 0.5 0.5 1.5 1.5 1.5 1.5 ...
In a next step all distances ρij between each pair of cell are calculated
and stored into the matrix rho.
k=1;
for i=mat_indices
rho(k,:)=sqrt((g_eometry(3,i) - g_eometry(3,mat_indices)).^2 + ...
(g_eometry(4,i) - g_eometry(4,mat_indices)).^2);
k=k+1;
end
With the matrix rho the Green’s function elements for the scatterer cells
can easily be calculated like this. (Where ’mat’ stands for material, ∆ε i 6= 0;
the array mat_indices holds the indices of scatterer cells.)
G_mat = I/4*V_i*k0^2*besselh(0,1,k0*rho);
applying the correct values for the diagonal elements M i is done with
the following statement:
G_mat=full(spdiags((I*pi/2*beta*gamma)*k0^2*ones(mat_size,1),0,G_mat));
source=(E0*exp(I*kx*g_eometry(3,:)+I*ky*g_eometry(4,:))).’;
4
% apply epsilon
k=1;
for i=mat_indices
G_mat(:,k) = G_mat(:,k)* g_eometry(2,i);
k=k+1;
end
%solve it!
A_mat = eye(mat_size) - G_mat;
solution_mat=(A_mat\source(mat_indices)).’;
G_bg =I/4*V_i*k0^2*besselh(0,1,k0*rho);
5
The file then is read by Matlab and the values for ∆ε i are stored in the
geometry array along with the (x, y)-coordinates which are automatically
generated since regular cell sizes and spacing is used.
6
3 Examples
3.1 A simple rectangular block
This first example shows a quadratic block of 10 × 10 elements with a di-
electricum of ε = 3 and a background of ε = 1 . The wave is incident from
the left side. The patterns at λ = 1 and λ = 2 are maybe a bit confusing
since they do not gradually fit into the series of pictures. I assume that since
in both cases the width of the block is a integer multiple of the wavelength
no resonances occur and the scatterer appears to be invisible. No standing
wave settles in front of the block. Only the corners produce irregular fields.
Looking at the other wavelengths the pictures show very nice scattering
patters, most of them having standing waves in front of the scatterer and
two ’jet-streams’ of higher field intensity going away towards the upper and
lower right corner.
1.8 14
1.6
12
25 8
length = 40
25
length = 40
20 20
0.8 6
15 15
10 10
0.6
5 5 4
10 20 30 40 50 60 70 80 0.4 10 20 30 40 50 60 70 80
width = 80 width = 80
2
0.2
1.6 5
4.5
1.4
30 1 30
3
25 25
length = 40
length = 40
20 0.8 20 2.5
15 15
2
0.6
10 10
5 5 1.5
0.4
10 20 30 40 50 60 70 80 10 20 30 40 50 60 70 80 1
width = 80 width = 80
0.2
0.5
7
5 5
4.5 4.5
35 3.5 35 3.5
30 30
3 3
25 25
length = 40
length = 40
20 2.5 20 2.5
15 15
2 2
10 10
5 1.5 5 1.5
10 20 30 40 50 60 70 80 1 10 20 30 40 50 60 70 80 1
width = 80 width = 80
0.5 0.5
50 12
11
45
10
Scattering pattern lamda=4.5 Energy=16.2224 40 Scattering pattern lamda=4.75 Energy=3.7546
40 40
9
35 35 35
8
30 30
30
7
25 25
length = 40
length = 40
20 25 20 6
15 15 5
20
10 10
4
5 15 5
3
10 20 30 40 50 60 70 80 10 10 20 30 40 50 60 70 80
width = 80 width = 80 2
5
1
20 5
18 4.5
35 14 35 3.5
30 30
12 3
25
length = 40
25
length = 40
20 10 20 2.5
15 15
8 2
10 10
5 6 5 1.5
10 20 30 40 50 60 70 80 4 10 20 30 40 50 60 70 80 1
width = 80 width = 80
2 0.5
8
4.5 2.5
35 35
3
30 30
1.5
25 25
length = 40
length = 40
2.5
20 20
2
15 15
1
10 10
1.5
5 5
10 20 30 40 50 60 70 80 1 10 20 30 40 50 60 70 80 0.5
width = 80 width = 80
0.5
16
14
12
10
Energy
0
0 5 10 15 20 25 30 35 40
wavelength
Figure 7: The average Energy inside the scatteres object plotet against the
wavelength shows where resonance occurs. Actually I expected stronger res-
onances above the first peak at about λ = 4.6
9
3.2 A regular grid
This second example is a grid of sixteen 4 × 4 quadratic blocks which are
equally spaced. The wave is again incident from the left. This structure has
more resonances as the Energy plots show.
2.5
2
Energy
1.5
0.5
0
0 10 20 30 40 50 60 70 80 90 100
wavelength
Figure 8: The grid which is a more complex strucuture shows more different
resonances over a wider range of wavelengths.
8
2
1.8 7
35 1.4 35
30 30 5
1.2
25
length = 40
25
length = 40
1 20 4
20
15 15
0.8
3
10 10
5 0.6 5
2
10 20 30 40 50 60 70 80 0.4 10 20 30 40 50 60 70 80
width = 80 width = 80
1
0.2
10
5 3
4.5
2.5
Scattering pattern lamda=9 Energy=0.66719 4 Scattering pattern lamda=14.09 Energy=1.2346
40 40
35 3.5 35
2
30 30
3
25 25
length = 40
length = 40
20 2.5 20 1.5
15 15
2
10 10
1
5 1.5 5
10 20 30 40 50 60 70 80 1 10 20 30 40 50 60 70 80
width = 80 width = 80 0.5
0.5
3.5 2
3
Scattering pattern lamda=23.08 Energy=1.9285 Scattering pattern lamda=55.05 Energy=1.0644
40 40
2.5
35 35
1.5
30 30
25 2 25
length = 40
length = 40
20 20
15 1.5 15
10 10 1
5 1 5
10 20 30 40 50 60 70 80 10 20 30 40 50 60 70 80
width = 80 width = 80
0.5
0.5
1.6
1.5
35 1.3
30
1.2
25
length = 40
20 1.1
15
1
10
5
0.9
10 20 30 40 50 60 70 80
width = 80 0.8
0.7
11
4 Experiences
Writing this simple solver in Matlab gave me quite a good insight on how
numerical field solving prorams can do their work. I also noticed the need to
crosscheck the computed results with other existing solvers or methods. This
was especially obious as I found a ’simple’ mistake in my solver algorithm.
Instead of solving the equation system the correct way
solution_mat=(A_mat\source(mat_indices)).’;,
I typed solution_mat=(source(mat_indices)\(A_mat));.
Unfortuneatly I recieved a solution shown below, which could be possible
too. I also gained a deeper understanding of how electromagnetic waves
behave if they hit differnt objects. Last but no least I had great fun using
the condor tool on the tardis student computing cluster which allowed me
to set up many processes on different machines which run concurrently.
1.8
1.6
1.2
8
8
0.015
length = 10
1
length = 10
6 6
0.8
4 4
0.01
0.6
2 2
2 4 6 8 10 12 14 16 18 20 2 4 6 8 10 12 14 16 18 20 0.4
width = 20 0.005 width = 20
0.2
Figure 13: To the left the wrongly solved problem and to the right the (hope-
fully) more accurate solution. Both at λ = 1, the scatterer is a quadratic
block of 4 × 4 cells of ε = 3
12
5 Source code
The whole package consists of the following files
• main.m
• mov.m
• parameters.m
• g eom.m
• excitation.m
• solver mat.m
5.1 main.m
% Main routine
%
% 2D Scattering project
% by Beat Hangartner
tic
parameters
g_eom
excitation
solver_mat2
toc
figure(1)
contourf(S.*conj(S))
13
xlabel([’width = ’,num2str(width)])
colorbar
axis image
5.2 mov.m
% Movie
%
% 2D Scattering
% by Beat Hangartner
%
function E2=mov(start,stop,step)
E2=[];
write_jpg=1;
parameters
g_eom
range=start:step:(stop-step);
tic
for lamda=range
parameters
excitation
solver_mat2
if write_jpg==1
figure
contourf(S.*conj(S))
title([’Scattering pattern lamda=’,num2str(lamda),...
’ Energy=’,num2str(Energy)])
ylabel([’length = ’,num2str(len)])
xlabel([’width = ’,num2str(width)])
axis image
colorbar
saveas(gcf,[’./’,filename,’/’ ,int2str(lamda*100), ’.eps’]);
clf reset
end
E2=[E2,Energy];
end
toc
14
clf reset
figure
plot(range,E2);
title([’Average energy inside scatterer ’, filename])
xlabel([’wavelength’])
ylabel([’Energy’])
saveas(gcf,[’./’,filename,’/’ ,’Energy-’,num2str(start),’-’,num2str(stop),...
’-’,num2str(step), ’.eps’]);
5.3 parameters.m
% Parameters definition
%
% 2D Scattering
% by Beat Hangartner
%
% History
% 26.5.02 created
% 29.5.02 modified Filname format
%
% Dimensions follow the SI-System
% imaginary unit
I = sqrt(-1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Excitation parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Wavelength
if exist(’lamda’)==0
global lamda
lamda=1;
end;
15
ky_=0;
kz=0; %(2D)
kx=kx_/sqrt(kx_^2+ky_^2)*2*pi/lamda;
ky=ky_/sqrt(kx_^2+ky_^2)*2*pi/lamda;
k0=2*pi/lamda;
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Geometry parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Grid spaceing
dx = 1;
dy = dx;
%material file
%filename=’020-015-block1’;
filename=’020-010-block1’;
%filename=’002-002-block1’;
%filename=’010-010-block1’;
%filename=’080-040-block1’;
%filename=’080-040-grid’;
%Area
width=str2num(filename(1:3));
len=str2num(filename(5:7));
geom_size = len*width/dx/dy;
% effective radius
R_i_eff = sqrt(V_i/pi);
%%%%%%%%%%%%%%%%%%%%%%%%%%%
% solver parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%
beta=1-kz^2/k0^2;
16
gamma=R_i_eff/k0*besselh(1,1,R_i_eff*k0)+I*2/(pi*k0^2);
5.4 g eom.m
% Geometry array definition
%
% 2D Scattering
% by Beat Hangartner
%
% History
% 26.5.02 created
%
%
%%%%%%%%%%%%%%%%%%
% Geometry layout
%%%%%%%%%%%%%%%%%%%%%%
% Origin
% (0,0)
% |-----------------------------------> x-axis (width)
% | cell 1 | cell 2 |
% | x=0.5*dx | x=1.5*dx |
% | y=0.5*dy | y=0.5*dy |
% | | |
% | | |
% | | |
% |------------------------------------
% | cell 3 | cell 4 |
% | x=0.5*dx | x=1.5*dx |
% | y=1.5*dy | y=1.5*dy |
% | | |
% | | |
% | | |
% |-----------------------------------
% |
% \/
% y-axis (length)
global g_eometry
global bg_indices
17
global mat_indices
g_eometry =zeros(4,geom_size);
g_eometry(1,:)=1:geom_size;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% open material file
% and retrieve scatterer’s layout
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fid = fopen([’./’,filename,’/’,filename,’.m’]);
file = fread(fid)’;
fclose(fid);
for i=1:width/dx
g_eometry(4,[i-1+[1:width/dx:geom_size]])=0.5*dy:dy:len;
end
18
mat_indices = find(g_eometry(2,:)~=0);
5.5 excitation.m
% Excitation array
%
% 2D Scattering
% by Beat Hangartner
%
% History
% 26.5.02 created
%
global source
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% compute elements with contrast other than zero %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global Energy
rho=zeros(mat_size);
k=1;
for i=mat_indices
19
rho(k,:)=sqrt((g_eometry(3,i) - g_eometry(3,mat_indices)).^2 +...
(g_eometry(4,i) - g_eometry(4,mat_indices)).^2);
k=k+1;
end
%free memory
clear rho;
% apply epsilon
k=1;
for i=mat_indices
G_mat(:,k) = G_mat(:,k)* g_eometry(2,i);
k=k+1;
end
%free memory
clear G_mat;
solution_mat = (A_mat\source(mat_indices)).’;
%free memory
clear A_mat;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% compute background solutions %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
20
% put them into the hankelfunction
G_bg = I/4* V_i*k0^2*besselh(0,1,k0*rho);
%free memory
clear rho;
%free memory
clear G_bg;
solution = zeros(1,geom_size);
solution(mat_indices)=solution_mat;
solution(bg_indices)=solution_bg;
Energy = sum(solution(mat_indices).*conj(solution(mat_indices)))/mat_size;
5.7 020-010-block1.m
00000000000000000000
00000000000000000000
00000000000000000000
00000000000222200000
00000000000222200000
00000000000222200000
00000000000222200000
00000000000000000000
00000000000000000000
00000000000000000000
21
are afterwards stored to the directory belonging to the geometry file.
5.8.1 feldber.condor
##################################################################
##
## Scattering movies with MATLAB/Feldber and Condor
##
## compiled by Beat Hangartner
##
##################################################################
#
# For this example, variables not used by Condor are marked my_*
#
universe = vanilla
getenv = True # MATLAB needs local environment
initialdir = /home/bhangart/feldber/
my_prefix = feldber
#
# Seek max floating point performance
#
Rank = Kflops
#
# Feldber Constants
#
my_procs = 1
my_start_wl = 2
my_stop_wl = 100
my_step_wl = 1
#
# MATLAB does all the math there,
# Condor just does string substitution
#
my_start_wl_p = ($(my_start_wl) + ...
($(my_stop_wl)-$(my_start_wl))*$(Process)/$(my_procs))
my_stop_wl_p = ($(my_start_wl) + ...
($(my_stop_wl)-$(my_start_wl))*($(Process)+1)/$(my_procs))
22
#
# For MATLAB and other SEPP packages, the executable must be a script wrapper.
#
executable = feldber.sh
arguments = mov($(my_start_wl_p),$(my_stop_wl_p),$(my_step_wl));
#
# To redirect stdout and/or stderr to /dev/null, comment these out.
#
log = $(my_prefix).log
#output = $(my_prefix).$(Process).out
#error = $(my_prefix).$(Process).err
#
# Lastly, tell condor how many jobs to queue up.
#
queue $(my_procs)
5.8.2 feldber.sh
#!/bin/sh
#
# Filename: mandelbrot.sh
#
# We use a shell wrapper for two reasons:
#
# 1) By using "$*" we ensure that the matlab command string is
# passed as a single argument even if it contains spaces.
#
# 2) Condor changes argv[0], which causes problems for SEPP. Hence,
# whenever we run a program from /usr/sepp/bin/* we must use a
# shell script wrapper.
#
exec /usr/sepp/bin/matlab -nodisplay -nosplash -nojvm -r "$*"
23