Ejemplo n.º 1
0
def double_rr(wave,
              width,
              thickness,
              radius,
              gap,
              sw_angle=90,
              term='k',
              part='mag'):
    """Return coupling coefficients for a Racetrack Resonator
    
    Args:
        wave      (float/np.ndarray): wavelength in nm (1450 - 1650nm)
        width     (float/np.ndarray): width of waveguide in nm (400 - 600nm)
        thickness (float/np.ndarray): thickness of waveguide in nm (180 - 240nm)
        radius    (float/np.ndarray): radius of rings in nm 
        gap       (float/np.ndarray): gap between rings in nm(above 100nm)
        sw_angle  (float/np.ndarray): angle of waveguide walls in degrees (between 80 and 90)
        term      (str): either 't' or 'k'
        part      (str): 'mag', 'phase', or 'both'. Choose both if you want both phase and magnitude
        
    Returns:
        (complex np.ndarray): The coupling coefficient"""

    #clean everything
    wave, width, thickness, sw_angle, radius, gap = clean_inputs(
        (wave, width, thickness, sw_angle, radius, gap))
    #get coefficients
    ae, ao, ge, go, neff = get_coeffs(wave, width, thickness, sw_angle)

    #calculate everything
    B = lambda x: (np.pi * 2 * x * np.exp(-2 * x) *
                   (special.iv(1, 2 * x) + special.modstruve(-1, 2 * x))) / 2
    xe = ge * (radius + width / 2)
    xo = go * (radius + width / 2)
    z = 2 * (radius + width)

    #get closed form solution
    return get_closed_ans(ae, ao, ge, go, neff, wave, B, xe, xo, z, gap, term,
                          part)
Ejemplo n.º 2
0
    def predict(self, ports, wavelength):
        wavelength, width, thickness, sw_angle, radius, gap = self.clean_args(
            wavelength)
        ae, ao, ge, go, neff = get_coeffs(wavelength, width, thickness,
                                          sw_angle)

        #make sure ports are valid
        if not all(1 <= x <= 4 for x in ports):
            raise ValueError('Invalid Ports')

        #determine if cross or through port
        if abs(ports[1] - ports[0]) == 2:
            trig = np.cos
            offset = 0
        else:
            trig = np.sin
            offset = np.pi / 2

        #determine z distance
        if 1 in ports and 3 in ports:
            z_dist = np.pi * radius
        elif 1 in ports and 4 in ports:
            z_dist = np.pi * radius
        elif 2 in ports and 4 in ports:
            z_dist = np.pi * radius
        elif 2 in ports and 3 in ports:
            z_dist = np.pi * radius
        #if it's coming to itself, or to adjacent port
        else:
            return np.zeros(len(wavelength))

        #calculate everything
        B = lambda x: 0.5 * np.pi * 2 * x * np.exp(-2 * x) * (special.iv(
            1, 2 * x) + special.modstruve(-1, 2 * x))
        xe = ge * (radius + width / 2)
        xo = go * (radius + width / 2)
        return get_closed_ans(ae, ao, ge, go, neff, wavelength, gap, B, xe, xo,
                              offset, trig, z_dist)
Ejemplo n.º 3
0
 def _init_values_modstruve(self):
     temp_values = np.arange(0, 10, 0.001)
     self.value_map = special.modstruve(2, temp_values)
     c_max = np.amax(self.value_map)
     np.multiply(self.value_map, 1.0 / c_max, out=self.value_map)
     self.value_map = np.concatenate((self.value_map, self.value_map[::-1]))
Ejemplo n.º 4
0
        L_v = 2.7 * L_1
        # Upward
        sigma_w = 0.5 * sigma_1
        L_w = 0.66 * L_1

        U = (4 * L_u / V_ref) * sigma_u**2 / (
            (1 + 6 * f * L_u / V_ref)**(5. / 3.))
        V = (4 * L_v / V_ref) * sigma_v**2 / (
            (1 + 6 * f * L_v / V_ref)**(5. / 3.))
        W = (4 * L_w / V_ref) * sigma_w**2 / (
            (1 + 6 * f * L_w / V_ref)**(5. / 3.))

        kappa = 12 * np.sqrt((f / V_ref)**2 + (0.12 / L_u)**2)

        Rot = (2*U / (R * kappa)**3) * \
            (modstruve(1,2*R*kappa) - iv(1,2*R*kappa) - 2/np.pi + \
                R*kappa * (-2 * modstruve(-2,2*R*kappa) + 2 * iv(2,2*R*kappa) + 1) )

        # set NaNs to 0
        Rot[np.isnan(Rot)] = 0

        # Formulas from Section 6.3 of IEC 61400-1-2019
        # S_1_f = 0.05 * sigma_1**2. * (L_1 / V_hub) ** (-2./3.) * f **(-5./3)
        # S_2_f = S_3_f = 4. / 3. * S_1_f
        # sigma_k = np.sqrt(np.trapz(S_1_f, f))
        # print(sigma_k)
        # print(sigma_u)

        return U, V, W, Rot

Ejemplo n.º 5
0
def FourierIntegral(k):
    return sqrt(pi / 2) * (1 / k - special.kv(0, k) * special.modstruve(-1, k)
                           - special.kv(0, k) * special.modstruve(0, k))
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np
from scipy import special
fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = special.modstruve(0,R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))

fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
Ejemplo n.º 7
0
#Modstruve

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.pyplot as plt
from scipy import special
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)

Z = special.modstruve(6, R)
surf = ax.plot_surface(X,
                       Y,
                       Z,
                       rstride=1,
                       cstride=1,
                       cmap=cm.coolwarm,
                       linewidth=0,
                       antialiased=False)
ax.set_zlim(None, None)
ax.zaxis.set_major_locator(LinearLocator(10))
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
Ejemplo n.º 8
0
def racetrack(wave,
              width,
              thickness,
              radius,
              gap,
              length,
              sw_angle=90,
              term='k',
              part='mag'):
    """Return coupling coefficients for a Racetrack Resonator
    
    Args:
        wave      (float/np.ndarray): wavelength in nm (1450 - 1650nm)
        width     (float/np.ndarray): width of waveguide in nm (400 - 600nm)
        thickness (float/np.ndarray): thickness of waveguide in nm (180 - 240nm)
        radius    (float/np.ndarray): radius of ring in nm 
        gap       (float/np.ndarray): gap between bus and ring in nm(above 100nm)
        length    (float/np.ndarray): Length of straight portion of resonator in nm
        sw_angle  (float/np.ndarray): angle of waveguide walls in degrees (between 80 and 90)
        term      (str): either 't' or 'k'
        part      (str): 'mag', 'phase', or 'both'. Choose both if you want both phase and magnitude 
        
    Returns:
        (complex np.ndarray): The coupling coefficient"""
    #clean everything
    wave, width, thickness, sw_angle, radius, gap, length = clean_inputs(
        (wave, width, thickness, sw_angle, radius, gap, length))
    #get coefficients
    ae, ao, ge, go, neff_str = get_coeffs(wave, width, thickness, sw_angle)
    neff_bent = R_bent.predict(
        np.column_stack((wave / 1000, width / 1000, thickness / 1000,
                         radius / 1000, sw_angle)))

    #calculate everything
    B = lambda x: length * x / (radius + width / 2) + np.pi * x * np.exp(
        -x) * (special.iv(1, x) + special.modstruve(-1, x))
    xe = ge * (radius + width / 2)
    xo = go * (radius + width / 2)
    z = 2 * (radius + width) + length

    #get closed form solution
    #determine which parameter to get
    if term == 'k':
        trig = np.sin
        offset = np.pi / 2
        z_str = (radius + width / 2 + length)
        z_bent = np.pi * radius / 2
    elif term == 't':
        trig = np.cos
        offset = 0
        z_str = 2 * (radius + width / 2) + length
        z_bent = 0
    else:
        raise ValueError("Bad term parameter")

    #calculate magnitude
    if part == 'mag' or part == 'both':
        temp = ae * np.exp(-ge * gap) * B(xe) / ge + ao * np.exp(
            -go * gap) * B(xo) / go
        mag = trig(temp * np.pi / wave)

    #calculate phase
    if part == 'ph' or part == 'both':
        temp = ae * np.exp(-ge * gap) * B(xe) / ge - ao * np.exp(
            -go * gap) * B(xo) / go + 2 * (z_str * neff_str +
                                           z_bent * neff_bent)
        phase = (temp * np.pi / wave + offset)

    if part == 'mag':
        phase = 0
    if part == 'ph':
        mag = 1

    return mag * np.exp(-1j * phase)