-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscalarmodesolver.py
More file actions
80 lines (63 loc) · 2.07 KB
/
scalarmodesolver.py
File metadata and controls
80 lines (63 loc) · 2.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
from numpy import *
import numpy as np
from scipy.sparse import spdiags
from scipy.sparse.linalg import eigsh,eigs
def scalarmodeEigsSolver(n, dx, dy, k0, xx, K = 10, bc = {'r':'a','l':'a','t':'a','b':'a'}, return_eigenvectors = True):
'''
INPUT-->
n : refractive index profile,
dx: x-coordinate step size,
dy: y-coordinate step size (solutions is not stable if dx == dy make dy = dx * 1e-9, makes modes to be aligned with xy axes),
k0: wavnumber (2pi/lambda0)
xx: grid (XY)
K = number of solutions to find
bc(optional) = custum boundary conditions
return_eigenvectors(optinal) = True or False
OUTPUT:
modes -> 3D array with the solutions of the eigenproblem (modes)
beta -> propagation constant of the modes
sm -> eigenproblem to solve (raw matrix in sparse mode)
kk.max -> use for latter normalize the propagations constant (equal to the highest solution (eigenvalue) )
'''
#Default boundary conditions
bct = {'r':'a','l':'a','t':'a','b':'a'}
bct.update(bc)
bc = bct
xx = xx.ravel().real
tx = ones_like(xx)
txp = tx
txm = tx
M = np.prod(n.shape)
Ny, Nx = n.shape
kk = (k0*n.ravel())**2
a = kk - 2 * (tx/dx**2 + tx/dy**2)
b = txp / dx**2
c = tx / dy**2
bl = txm / dx**2
#fix boundary
b[Nx::Nx]=0
bl[Nx-1::Nx]=0
if bc['r'] == 'a':
a[Nx-1::Nx] -= 1./dx**2
else:
a[Nx-1::Nx] += 1./dx**2
if bc['l'] =='a':
a[0::Nx] -= 1./dx**2
else:
a[0::Nx] += 1./dx**2
if bc['t'] =='a':
a[0:Nx] -= 1./dy**2
else:
a[0:Nx] += 1./dy**2
if bc['b'] =='a':
a[-Nx:] -= 1./dy**2
else:
a[-Nx:] += 1./dy**2
#Biuld the matrix
diags = np.array([-Nx,-1,0,1,Nx])
sm = spdiags([c,bl,a,b,c], diags, M, M, format = 'csr')
#Solve the eigenproblem
res = eigsh(sm, K, sigma = kk.max() , return_eigenvectors=return_eigenvectors)
modes = res[1].T.reshape(K, Ny, Nx)
beta = res[0]
return beta, modes, sm, kk.max()