I have a code in Python that helps me find the intersection points between two curves; each time the f(frequency)
equals one of the tangents (and cotangents), I save those values which correspond to the modes available for a given frequency. I iterate over a number of frequencies so I can know which modes propagate over which frequencies.
For each frequency (or pulsation) in my for loop, I find the intersection points with a program Intersection
that returns the x and y positions in an array. I only need the x values so I keep them in an array called X_inter
. I save each X_inter into a bigger array called arr_KX
for easier manipulation later on.
So to be clear, the rows of arr_KX
correspond to a given frequency and the columns correspond to a given mode (first column equals 0th mode and so on)
Now I will not know what the largest mode will be, therefore how many columns my array needs to have, until I have finished the if loop.
The problem is that for lower frequencies, I will have less modes than for higher frequencies. As you can see on the following code, when I try to resize the ‘arr_KX’ I will lose all previous information.
What should happen in the ideal case is that if a first frequency has 2 modes and a second frequency has 4, then arr_KX shows :
arr_KX = [[mode 1 of f1, mode 2 of f1, nan , nan ] , [ mode 1 of f2, mode 2 of f2, mode 3 of f2, mode 4 of f2]]
Or more readable:
arr_KX = [[m1,m2,nan,nan],[m1,m2,m3,m4]]
import numpy as np
import matplotlib.pyplot as plt
import Intersection as inter
np.seterr(all='ignore')
plt.clf()
height, width, lenght = 500e-6, 500e-6, 100e-6
d = height/2
c0 = 3e8
n_core = 5.2
n_cladding = 1.
FntSze = 15
"""
Solve this equations
"""
def cot(angle):
return np.cos(angle)/np.sin(angle)
def TE_LHS_sym(var1):
return np.tan(var1*d)
def TE_LHS_antisym(var2):
return -cot(var2*d)
def TE_RHS(var3,pulsation_):
return ((pulsation_**2*d**2*
(n_core**2-n_cladding**2)/(c0**2*var3**2*d**2))-1)**(0.5)
start, end, Nx, NN = 100e9, 1000e9 + 1, 1001 ,21
##Start and end of pulsation range, with NN the number of frequencies we work with and Nx the number of kx generated
f_range = np.linspace(start,end,NN)
w_range = f_range*2*np.pi
k = np.linspace(0,4*np.pi,Nx)/d
tol = 40. ##To limit the float points at discontinuity of tangents/cotangents
y_tan = TE_LHS_sym(k) ##Draw tan(kx*d)
y_tan[y_tan > tol] = np.nan ##Limits the aberrations at discontinuity
y_tan[y_tan < -tol] = np.nan
y_cot = TE_LHS_antisym(k) ##Draw cot(kx*d)
y_cot[y_cot > tol] = np.nan
y_cot[y_cot < -tol] = np.nan
init=0
size = 0
##PlOTTING
plt.figure(1)
plt.plot(k*d,y_tan,label='tan($k_{x0}d$)' )
plt.plot(k*d,y_cot)#,label='-cot($k_{x0}d$)')
for init,omega in enumerate(w_range): #Loop for pulsations, starting at max and ending at min
y_RHS = TE_RHS(k,omega) #Draws RHS, intersaction points with tan/cot will give kx_mode
y_RHS[y_RHS > tol] = np.nan
plt.plot(k*d,y_RHS,marker='',label='RHS at $f$ = '+ str(round(omega*1e-9/(2*np.pi),2)) + ' GHz')
##Find intersection points between tan/cot, they will give kx_mode for a given w
x_inter_tan,y_inter_tan = inter.intersection(k, y_tan, k, y_RHS)
x_inter_cot,y_inter_cot = inter.intersection(k, y_cot, k, y_RHS)
plt.plot(x_inter_cot*d, y_inter_cot, '+k') ##Draws inter points cot//RHS
plt.plot(x_inter_tan*d, y_inter_tan, '+k') ##Draws inter points tan//RHS
plt.xlabel("$k_{x}d$ (in $rad.m^{-1}$)",fontsize=FntSze)
plt.ylabel("",fontsize=FntSze)
X_inter = np.sort(np.concatenate([x_inter_cot.copy(),x_inter_tan.copy()])*d) #Gives kx_m*d for a w
KX_inter = X_inter/d
if KX_inter.shape[0] > size : #In order to know how many columns we need
size = KX_inter.shape[0]
arr_KX = np.zeros((NN,size)) #Create matrix NN*size == w_n*kx_modes
bb = KX_inter.resize(size) #Higher w_m have higher kx_modes, this sets them up in the same shape
arr_KX[int(init),:] = KX_inter #Matrix w_n*kx_modes appends line at w_n of the kx_modes
When confronted with this problem I tried to solve it many times but never found a good solution. So I did a workaround and decided to generate my frequencies from the highest to the lowest in order to always start with the highest number of modes possible. This works most of the time (emphasis on most of the time) but I want to know how I could solve this array problem without inversing the generation of frequencies since it’s going to give me some mayor problems as I continue working on the physics of this problem.
I can’t quite remember what I did exactly since it’s been weeks since I settled on my workaround, but I did try as many of the ‘solutions’ I could find on Google. Either with numpy
or just the basic commands from python, the problem would still persist or a new one would arise.
With reshape (I think), the issue was that the mode values from a frequency would go to another frequency.
So I would have:
arr_KX =[[mode1 of f1,mode2 of f1,mode1 of f2,mode2 of 2],[mode3 of f2, mode 4 of f2, nan, nan]]
Óscar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
2