This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Unusual Eigenvalues in for EM wave in Transverse Cylindrical waveguide

0 votes

Hello,

I am solving the eigenvalue problem for a cylindrical waveguide. I followed the reference code from chapter 34. However, I can't find the right eigenvalue, as the field has many spikes. I used the following parameters in the SlepcEigenSolver() class to make sure it's close to the target k_0:

#k_0 = 2*pi/1.55 is the wavevector (lamba = 1.55 microns = c0/f)
eigensolver = SLEPcEigenSolver(A,B)
eigensolver.parameters["spectral_shift"] = ((2*pi/1.55)**2)
eigensolver.parameters["spectral_transform"] = "shift-and-invert"
eigensolver.parameters["spectrum"] = "target real" 

I am having a tough time trying to understand what is wrong. Any sort of guidance towards finding the right eigenvalues would appreciated.

Thanks a lot.

For reference, here is the code for reference:

from dolfin import *

# Test for PETSc and SLEPc
...

# Define mesh, function space

transverse_order = 2
axial_order = 1

# Importing GMSH file for single mode profile
mesh = Mesh("SMF.xml")
Nl = FunctionSpace(mesh, "N1curl", transverse_order)
Vl = FunctionSpace(mesh, "CG", axial_order)
combined_space = Nl * Vl

# Define basis and bilinear form
(N_i, L_i) = TestFunctions(combined_space)
(N_j, L_j) = TrialFunctions(combined_space)

# Define Dielectric constant for core radius = 1 micron
...
e_r = Dielectric()

# Relative permiability  (=1)
one_over_u_r = Constant(1.0)

# Define wave vector (in micron^(-1) units), wavelength of light = 1.550 microns

k_o_squared = Constant((2*pi/1.55)**2)

# Define Zero Boundary condition
class Zero_Boundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary

zero = Constant ( (0.0, 0.0, 0.0) )

dirichlet_bc = DirichletBC(combined_space, zero, Zero_Boundary())

# 2D curl function
def curl_t(w):
    return Dx(w[1],0) - Dx(w[0],1)

#Define Matrices A and B such that A*e = lambda*B*e (eigenvalue: lambda)

s_tt = one_over_u_r*dot(curl_t(N_i), curl_t(N_j))
t_tt = e_r*dot(N_i, N_j)

s_zz = one_over_u_r*dot(grad(L_i), grad(L_j))
t_zz = e_r*L_i*L_j

b_tt = one_over_u_r*dot(N_i, N_j)
b_tz = one_over_u_r*dot(N_i, grad(L_j))
b_zt = one_over_u_r*dot(grad(L_i), N_j)

# define the matrix entries a_ij, b_ij with * dx resulting in integration over 
# the domain of the mesh when assemble() is called
a = ( s_tt - k_o_squared * t_tt ) * dx
b = ( s_zz - k_o_squared * t_zz + b_tt + b_tz + b_zt ) * dx

# Assembling the matrices
A = PETScMatrix()
B = PETScMatrix()
assemble(a, tensor=A)
assemble(b, tensor=B)

# Applying boundary condition on the Matrices A,B
dirichlet_bc.apply(A)
dirichlet_bc.apply(B)

# Create eigensolver with generalized Hermitian condition

eigensolver = SLEPcEigenSolver(A,B)
eigensolver.parameters["spectral_shift"] = ((2*pi/1.55)**2)
eigensolver.parameters["spectral_transform"] = "shift-and-invert"
eigensolver.parameters["spectrum"] = "target real"


# Compute all eigenvalues of A x = \lambda B x
print "Computing eigenvalues. This can take a minute."
eigensolver.solve()
print "Eigenvalues computed: ",eigensolver.get_number_converged()

if eigensolver.get_number_converged() > 0:

    r, c, rx, cx = eigensolver.get_eigenpair(0)

    print "Eigenvalue : ",r

# Initialize function and assign eigenvector
    u = Function(combined_space,rx)
    transverse, axial = u.split()

# Plot eigenfunction
    plot(abs(axial))
    interactive()
asked Sep 1, 2016 by plastic_beach FEniCS Novice (190 points)
...