Beispiel #1
0
def fullDet(b, nu):
    a = rho * b
    i = ivp(nu, u1*a) / (u1*a * iv(nu, u1*a))

    if nu == 1:
        k2 = -2
        k = 0
    else:
        k2 = 2 * nu / (u2 * b)**2 - 1 / (nu - 1)
        k = -1

    X = (1 / (u1*a)**2 + 1 / (u2*a)**2)

    P1 = jn(nu, u2*a) * yn(nu, u2*b) - yn(nu, u2*a) * jn(nu, u2*b)
    P2 = (jvp(nu, u2*a) * yn(nu, u2*b) - yvp(nu, u2*a) * jn(nu, u2*b)) / (u2 * a)
    P3 = (jn(nu, u2*a) * yvp(nu, u2*b) - yn(nu, u2*a) * jvp(nu, u2*b)) / (u2 * b)
    P4 = (jvp(nu, u2*a) * yvp(nu, u2*b) - yvp(nu, u2*a) * jvp(nu, u2*b)) / (u2 * a * u2 * b)

    A = (n12 * i**2 - n32 * nu**2 * X**2)

    if nu == 1:
        B = 0
    else:
        B = 2 * n22 * n32 * nu * X * (P1 * P4 - P2 * P3)

    return (n32 * k2 * A * P1**2 +
            (n12 + n22) * n32 * i * k2 * P1 * P2 -
            (n22 + n32) * k * A * P1 * P3 -
            (n12*n32 + n22*n22) * i * k * P1 * P4 +
            n22 * n32 * k2 * P2**2 -
            n22 * (n12 + n32) * i * k * P2 * P3 -
            n22 * (n22 + n32) * k * P2 * P4 -
            B)
Beispiel #2
0
 def Psi(self, r, neff, wl, nu, C):
     u = self.u(r, neff, wl)
     if neff < self.maxIndex(wl):
         psi = (C[0] * jn(nu, u) + C[1] * yn(nu, u) if C[1] else
                C[0] * jn(nu, u))
         psip = u * (C[0] * jvp(nu, u) + C[1] * yvp(nu, u) if C[1] else
                     C[0] * jvp(nu, u))
     else:
         psi = (C[0] * iv(nu, u) + C[1] * kn(nu, u) if C[1] else
                C[0] * iv(nu, u))
         psip = u * (C[0] * ivp(nu, u) + C[1] * kvp(nu, u) if C[1] else
                     C[0] * ivp(nu, u))
     # if numpy.isnan(psi):
     #     print(neff, self.maxIndex(wl), C, r)
     return psi, psip
Beispiel #3
0
    def __delta(self, nu, u1r1, u2r1, s1, s2, s3, n1sq, n2sq, n3sq):
        """s3 is sign of Delta"""
        if s1 < 0:
            f = ivp(nu, u1r1) / (iv(nu, u1r1) * u1r1)  # c
        else:
            jnnuu1r1 = jn(nu, u1r1)
            if jnnuu1r1 == 0:  # Avoid zero division error
                return float("inf")
            f = jvp(nu, u1r1) / (jnnuu1r1 * u1r1)  # a b d

        if s1 == s2:
            # b d
            kappa1 = -(n1sq + n2sq) * f / n2sq
            kappa2 = (n1sq * f * f / n2sq -
                      nu**2 * n3sq / n2sq * (1 / u1r1**2 - 1 / u2r1**2)**2)
        else:
            # a c
            kappa1 = (n1sq + n2sq) * f / n2sq
            kappa2 = (n1sq * f * f / n2sq -
                      nu**2 * n3sq / n2sq * (1 / u1r1**2 + 1 / u2r1**2)**2)

        d = kappa1**2 - 4 * kappa2
        if d < 0:
            return numpy.nan
        return u2r1 * (nu / u2r1**2 + (kappa1 + s3 * sqrt(d)) * 0.5)
def get_left_int_error(n, order):
    a = 2
    b = 30
    intervals = np.linspace(0, 1, n, endpoint=True) ** 2 * (b-a) + a
    discr = CompositeLegendreDiscretization(intervals, order)

    x = discr.nodes
 
    assert abs(discr.integral(1+0*x) - (b-a)) < 1e-13


    alpha = 4
    from scipy.special import jv, jvp
    f = jvp(alpha, x)

    num_int_f = jv(alpha, a) + discr.left_indefinite_integral(f)
    int_f = jv(alpha, x)

    if 0:
        pt.plot(x.ravel(), num_int_f.ravel())
        pt.plot(x.ravel(), int_f.ravel())
        pt.show()

    L2_err = np.sqrt(discr.integral((num_int_f - int_f)**2))
    return 1/n, L2_err
Beispiel #5
0
    def _hefield(self, wl, nu, neff, r):
        self._heceq(neff, wl, nu)
        for i, rho in enumerate(self.fiber._r):
            if r < rho:
                break
        else:
            i += 1
        layer = self.fiber.layers[i]
        n = layer.maxIndex(wl)
        u = layer.u(rho, neff, wl)
        urp = u * r / rho

        c1 = rho / u
        c2 = wl.k0 * c1
        c3 = nu * c1 / r if r else 0  # To avoid div by 0
        c6 = constants.Y0 * n * n

        if neff < n:
            B1 = jn(nu, u)
            B2 = yn(nu, u)
            F1 = jn(nu, urp) / B1
            F2 = yn(nu, urp) / B2 if i > 0 else 0
            F3 = jvp(nu, urp) / B1
            F4 = yvp(nu, urp) / B2 if i > 0 else 0
        else:
            c2 = -c2
            B1 = iv(nu, u)
            B2 = kn(nu, u)
            F1 = iv(nu, urp) / B1
            F2 = kn(nu, urp) / B2 if i > 0 else 0
            F3 = ivp(nu, urp) / B1
            F4 = kvp(nu, urp) / B2 if i > 0 else 0

        A, B, Ap, Bp = layer.C[:, 0] + layer.C[:, 1] * self.alpha

        Ez = A * F1 + B * F2
        Ezp = A * F3 + B * F4
        Hz = Ap * F1 + Bp * F2
        Hzp = Ap * F3 + Bp * F4

        if r == 0 and nu == 1:
            # Asymptotic expansion of Ez (or Hz):
            # J1(ur/p)/r (r->0) = u/(2p)
            if neff < n:
                f = 1 / (2 * jn(nu, u))
            else:
                f = 1 / (2 * iv(nu, u))
            c3ez = A * f
            c3hz = Ap * f
        else:
            c3ez = c3 * Ez
            c3hz = c3 * Hz

        Er = c2 * (neff * Ezp - constants.eta0 * c3hz)
        Ep = c2 * (neff * c3ez - constants.eta0 * Hzp)

        Hr = c2 * (neff * Hzp - c6 * c3ez)
        Hp = c2 * (-neff * c3hz + c6 * Ezp)

        return numpy.array((Er, Ep, Ez)), numpy.array((Hr, Hp, Hz))
Beispiel #6
0
def circle_wg_tm_mn(mesh, m=31, n=11, phi=90.0, radi=25.0):
    x, y = mesh[0], mesh[1]
    r, t = np.sqrt(x**2 + y**2), np.arctan(y / x)
    b = radi

    x0_mn = jn_zeros(m, n)[-1]
    x1_mn = jnp_zeros(m, n)[-1]

    if m == 0:
        e_m = 1
    else:
        e_m = 2

    func = np.sqrt(e_m / np.pi)
    func *= 1 / np.abs(jvp(m + 1, x0_mn))
    func *= (-jvp(m, x0_mn * r / b, 0) * np.cos(m * t) + m /
             x0_mn * jvp(m, x0_mn * r / b, 0) / r * np.sin(m * t))
    return func
Beispiel #7
0
def get_coefficients(Nterms, wavenumber_b, wavenumber_d, radius, epsilon_d,
                     epsilon_b):
    """Summarize the method."""
    n = np.arange(-Nterms, Nterms + 1)
    kb, kd = wavenumber_b, wavenumber_d
    a = radius

    an = (-jv(n, kb * a) / hankel2(n, kb * a) *
          ((epsilon_d * jvp(n, kd * a) /
            (epsilon_b * kd * a * jv(n, kd * a)) - jvp(n, kb * a) /
            (kb * a * jv(n, kb * a))) /
           (epsilon_d * jvp(n, kd * a) /
            (epsilon_b * kd * a * jv(n, kd * a)) - h2vp(n, kb * a) /
            (kb * a * hankel2(n, kb * a)))))

    cn = 1 / jv(n, kd * a) * (jv(n, kb * a) + an * hankel2(n, kb * a))

    return an, cn
Beispiel #8
0
 def lpConstants(self, r, neff, wl, nu, A):
     u = self.u(r, neff, wl)
     if neff < self.maxIndex(wl):
         W = constants.pi / 2
         return (W * (u * yvp(nu, u) * A[0] - yn(nu, u) * A[1]),
                 W * (jn(nu, u) * A[1] - u * jvp(nu, u) * A[0]))
     else:
         return ((u * kvp(nu, u) * A[0] - kn(nu, u) * A[1]),
                 (iv(nu, u) * A[1] - u * ivp(nu, u) * A[0]))
Beispiel #9
0
def cutoffHE2(b):
    nu = 2
    a = rho * b
    i = ivp(2, u1*a) / (u1*a * iv(2, u1*a))

    X = (1 / (u1*a)**2 + 1 / (u2*a)**2)

    P1 = jn(nu, u2*a) * yn(nu, u2*b) - yn(nu, u2*a) * jn(nu, u2*b)
    P2 = (jvp(nu, u2*a) * yn(nu, u2*b) - yvp(nu, u2*a) * jn(nu, u2*b)) / (u2 * a)
    P3 = (jn(nu, u2*a) * yvp(nu, u2*b) - yn(nu, u2*a) * jvp(nu, u2*b)) / (u2 * b)
    P4 = (jvp(nu, u2*a) * yvp(nu, u2*b) - yvp(nu, u2*a) * jvp(nu, u2*b)) / (u2 * a * u2 * b)

    A = 2 * nu / (u2 * b)**2 - 1 / (nu - 1)

    return (n22 / n32 * (i*P1 + P2) * (n12*i*P3 + n22 * P4) +
            (A * i * P1 + A * P2 + i*P3 + P4) * (n12*i*P1 + n22*P2) -
            n32 * nu**2 * X**2 * P1 * (A * P1 + P3) -
            n22 * nu * X * (nu * X * P1 * P3 + 2 * P1 * P4 - 2 * P2 * P3))
Beispiel #10
0
    def te0G(self, y):
        '''
		find the zeros of this function to find the TE0 modes
		works only for mu_h=mu_c=1
		'''

        aa = 4.0j * special.jvp(0, z) * np.log(y) / special.jv(0, y) / np.pi
        bb = self.cyl_n * y**2 - 4.0j / y / self.host_n
        return aa + bb
Beispiel #11
0
def solve_for_AB(k, R1, R2):

    # solve the system for A,B
    #
    #  / J'_m(k R1)   Y'_m(k R1) \ /A\  --  /0\
    #  \ J'_m(k R2)   Y'_m(k R2) / \B/  --  \0/

    M = numpy.zeros((2, 2))
    M[0][0] = special.jvp(1, k * R1, 1)  # Jprime_1 at R1
    M[0][1] = special.yvp(1, k * R1, 1)  # Yprime_1 at R1
    M[1][0] = special.jvp(1, k * R2, 1)  # Jprime_1 at R2
    M[1][1] = special.yvp(1, k * R2, 1)  # Yprime_1 at R2

    # close but no cigar to zero, otherwise it returns x=(0,0)
    b = numpy.array([1.e-16, 1.e-16])

    x = numpy.linalg.solve(M, b)

    return x[0], x[1]
Beispiel #12
0
def cutoffHE1(b):
    a = rho * b
    i = ivp(1, u1*a) / (u1*a * i1(u1*a))

    X = (1 / (u1*a)**2 + 1 / (u2*a)**2)

    P = j1(u2*a) * y1(u2*b) - y1(u2*a) * j1(u2*b)
    Ps = (jvp(1, u2*a) * y1(u2*b) - yvp(1, u2*a) * j1(u2*b)) / (u2 * a)

    return (i * P + Ps) * (n12 * i * P + n22 * Ps) - n32 * X * X * P * P
 def Er(self, r, z):
     """Radial field component dV/dr"""
     r /= self.r0
     z /= self.r0
     s = 0
     for (n,c) in enumerate(self.cns):
         if n==0:
             continue
         s += self.cns[n]*exp(-bessel_j0n[n]*z)*bessel_j0n[n]*special.jvp(0,bessel_j0n[n]*r)
     return s/self.r0
Beispiel #14
0
def test_bessel():

    x = np.linspace(0, 20, 100)

    for n in range(2):
        plt.plot(x, jn(n, x), 'r-')
        plt.plot(x, jvp(n, x), 'b-')

    #plt.ylim(0,3.5)
    plt.show()
Beispiel #15
0
def test_cylindrical_bessel_j_prime():
    order = np.random.randint(0, 10)
    value = np.random.rand(1).item()
    assert (roundScaler(NumCpp.bessel_jn_prime_Scaler(order, value),
                        NUM_DECIMALS_ROUND) == roundScaler(
                            sp.jvp(order, value).item(), NUM_DECIMALS_ROUND))

    shapeInput = np.random.randint(20, 100, [
        2,
    ])
    shape = NumCpp.Shape(shapeInput[0].item(), shapeInput[1].item())
    cArray = NumCpp.NdArray(shape)
    order = np.random.randint(0, 10)
    data = np.random.rand(shape.rows, shape.cols)
    cArray.setArray(data)
    assert np.array_equal(
        roundArray(NumCpp.bessel_jn_prime_Array(order, cArray),
                   NUM_DECIMALS_ROUND),
        roundArray(sp.jvp(order, data), NUM_DECIMALS_ROUND))
Beispiel #16
0
def cutoffHE1(b):
    a = rho * b
    i = ivp(1, u1 * a) / (u1 * a * i1(u1 * a))

    X = (1 / (u1 * a)**2 + 1 / (u2 * a)**2)

    P = j1(u2 * a) * y1(u2 * b) - y1(u2 * a) * j1(u2 * b)
    Ps = (jvp(1, u2 * a) * y1(u2 * b) - yvp(1, u2 * a) * j1(u2 * b)) / (u2 * a)

    return (i * P + Ps) * (n12 * i * P + n22 * Ps) - n32 * X * X * P * P
Beispiel #17
0
def hybrid_mode_HE_graphical(r_0, h_0, log_n, f0_0):

    f0 = f0_0 * 1e12
    r = r_0 * 1e-6
    h = h_0 * 1e-6

    epsilon_0 = 1
    epsilon_2 = epsilon_0

    e1, e2 = drude_model_Si(log_n, f0)
    # e1,e2 = drude_lorentz_model_Si(11.68,0,0,f0)
    epsilon_1 = e1

    c = 2.99792458e8
    lam = c / f0
    k0 = 2 * pi / lam
    n = 1
    m = 0

    beta = pi / h
    alpha = sqrt(k0**2 * epsilon_1 - beta**2)
    gamma1 = alpha
    gamma2 = sqrt(beta**2 - k0**2 * epsilon_0)
    u = gamma1 * r
    v = gamma2 * r
    # eta1 = jvp(1,u)/(u*j1(u)) + kvp(1,v)/(v*k1(v))
    # eta2 = (epsilon_1*k0**2)*jvp(1, u) / (u * j1(u)) + (k0**2)*kvp(1, v) / (v * k1(v))

    eta1 = jvp(n - 1, u) / (u * jvp(n, u)) - n / u**2
    eta2 = 1j * hankel1(n - 1, 1, 1j * v) / v / hankel1(n, 1,
                                                        1j * v) - n / v**2
    f_res_1 = abs(
        (eta1 + eta2) * (k0**2 * epsilon_1 * eta1 + k0**2 * epsilon_2 * eta2))
    f_res_2 = (n**2 * beta**2 * (1 / u**2 + 1 / v**2)**2)

    # eta1 = jvp(n-1,u)/(u*jvp(n,u)) + hankel1(n-1,v)/(v*hankel1(n,v))
    # eta2 = (epsilon_1*k0**2)*jvp(n-1, u) / (u * jvp(n,u)) + (k0**2)*hankel1(n-1, v) / (v * hankel1(n,v))
    # eta3 = (beta**2) * (1/u**2 + 1/v**2)**2
    #
    # f_res_1 = abs(eta1*eta2)
    # f_res_2 = eta3

    return f_res_1, f_res_2
Beispiel #18
0
def integrand_nopoles(a, p_bar, nu):
    
    #minimum value of a to keep p_perp real; equation 27
    a_min = (nu / nu_c) * (1. - np.cos(theta) * p_bar) / np.sqrt(1. - p_bar**2.)
    
    #check if a > a_min
    if(a <= a_min):
        return 0.    
    
    #gamma in terms of a, p_bar; equation 23
    gamma = (nu_c / nu) * a / (1. - np.cos(theta) * p_bar)
    
    #p_parallel, equation 21
    p_parallel = gamma * m * c * p_bar

    #p_perp, equation 22
    p_perp = m * c * np.sqrt(gamma**2. * (1. - p_bar**2.) - 1.)
    
    #this is gamma as a function of p_perp and p_parallel, equation 28
    gamma_check = np.sqrt((p_perp/(m * c))**2. + (p_parallel/(m * c))**2. + 1.)
    
    #Omega, equation 8
    Omega = omega_c / gamma
    
    omega = 2. * np.pi * nu

    #z, equation 5
    z = omega * np.sin(theta) * p_perp / (gamma * m * c * Omega) 
    
    #M, equation 6
    M = (np.cos(theta) - (p_parallel / (gamma * m * c))) / np.sin(theta)

    #N, equation 7
    N = p_perp / (gamma * m * c)

    #bessel function term in integrand (eq. 16); note that the 1/sin(pi * a) is taken out
    # so that we can use the CPV integration method
    bessel_term = np.pi * special.jv(a, z) * special.jvp(-a, z)
   
    #jv'(-a, z) blows up with a, and jv(a, z) goes to zero; 
    #they limit to -1/(pi*z) * sin(pi*a) as a -> inf 
    if(np.isnan(bessel_term) == True):
        bessel_term = - 1./z * np.sin(np.pi * a)
      
    jacobian = - m**3. * c**3. * (nu_c / nu) * gamma**2. / (p_perp * (1. - np.cos(theta) * p_bar))
    
    #dp_perp * dp_parallel from equation 
    dp_perp_dp_para = jacobian #*dadp_bar, which is notation we don't use for a numerical integral
    
    #d^3p from equation 26
    d3p = 2. * np.pi * p_perp * dp_perp_dp_para
    
    ans = M * N / Omega * Df(gamma, nu) * bessel_term * d3p
    
    return ans
Beispiel #19
0
def far_fields(radius, frequency, r, theta, phi):
    """
    Calculate the electric and magnetic fields in the far field of the aperture.
    :param r: The range to the field point (m).
    :param theta: The theta angle to the field point (rad).
    :param phi: The phi angle to the field point (rad).
    :param radius: The radius of the aperture (m).
    :param frequency: The operating frequency (Hz).
    :return: The electric and magnetic fields radiated by the aperture (V/m), (A/m).
    """
    # Calculate the wavenumber
    k = 2.0 * pi * frequency / c

    # Calculate the wave impedance
    eta = sqrt(mu_0 / epsilon_0)

    # Calculate the argument for the Bessel function
    z = k * radius * sin(theta)

    # Calculate the Bessel function
    bessel_term1 = 0.5 * ones_like(z)
    index = z != 0.0
    bessel_term1[index] = jv(1, z[index]) / z[index]

    # Calculate the Bessel function
    jnpz = 1.84118378134065
    denominator = (1.0 - (z / jnpz)**2)
    index = denominator != 0.0
    bessel_term2 = 0.377 * ones_like(z)
    bessel_term2[index] = jvp(1, z[index]) / denominator[index]

    # Define the radial-component of the electric far field (V/m)
    e_r = 0.0

    # Define the theta-component of the electric far field (V/m)
    e_theta = 1j * k * radius * jv(1, jnpz) * exp(
        -1j * k * r) / r * sin(phi) * bessel_term1

    # Define the phi-component of the electric far field (V/m)
    e_phi = 1j * k * radius * jv(1, jnpz) * exp(
        -1j * k * r) / r * cos(theta) * cos(phi) * bessel_term2

    # Define the radial-component of the magnetic far field (A/m)
    h_r = 0.0

    # Define the theta-component of the magnetic far field (A/m)
    h_theta = 1j * k * radius * jv(1, jnpz) * exp(
        -1j * k * r) / r * -cos(theta) * cos(phi) / eta * bessel_term2

    # Define the phi-component of the magnetic far field (A/m)
    h_phi = 1j * k * radius * jv(1, jnpz) * exp(
        -1j * k * r) / r * sin(phi) / eta * bessel_term1

    # Return all six components of the far field
    return e_r, e_theta, e_phi, h_r, h_theta, h_phi
Beispiel #20
0
    def EH_fields(self, ri, ro, nu, neff, wl, EH, tm=True):
        """

        modify EH in-place (for speed)

        """
        n = self.maxIndex(wl)
        u = self.u(ro, neff, wl)

        if ri == 0:
            if nu == 0:
                if tm:
                    self.C = numpy.array([1., 0., 0., 0.])
                else:
                    self.C = numpy.array([0., 0., 1., 0.])
            else:
                self.C = numpy.zeros((4, 2))
                self.C[0, 0] = 1  # Ez = 1
                self.C[2, 1] = 1  # Hz = alpha
        elif nu == 0:
            self.C = numpy.zeros(4)
            if tm:
                c = constants.Y0 * n * n
                idx = (0, 3)
                self.C[:2] = self.tetmConstants(ri, ro, neff, wl, EH, c, idx)
            else:
                c = -constants.eta0
                idx = (1, 2)
                self.C[2:] = self.tetmConstants(ri, ro, neff, wl, EH, c, idx)
        else:
            self.C = self.vConstants(ri, ro, neff, wl, nu, EH)

        # Compute EH fields
        if neff < n:
            c1 = wl.k0 * ro / u
            F3 = jvp(nu, u) / jn(nu, u)
            F4 = yvp(nu, u) / yn(nu, u)
        else:
            c1 = -wl.k0 * ro / u
            F3 = ivp(nu, u) / iv(nu, u)
            F4 = kvp(nu, u) / kn(nu, u)

        c2 = neff * nu / u * c1
        c3 = constants.eta0 * c1
        c4 = constants.Y0 * n * n * c1

        EH[0] = self.C[0] + self.C[1]
        EH[1] = self.C[2] + self.C[3]
        EH[2] = (c2 * (self.C[0] + self.C[1]) - c3 *
                 (F3 * self.C[2] + F4 * self.C[3]))
        EH[3] = (c4 * (F3 * self.C[0] + F4 * self.C[1]) - c2 *
                 (self.C[2] + self.C[3]))

        return EH
Beispiel #21
0
    def EH_fields(self, ri, ro, nu, neff, wl, EH, tm=True):
        """

        modify EH in-place (for speed)

        """
        n = self.maxIndex(wl)
        u = self.u(ro, neff, wl)

        if ri == 0:
            if nu == 0:
                if tm:
                    self.C = numpy.array([1., 0., 0., 0.])
                else:
                    self.C = numpy.array([0., 0., 1., 0.])
            else:
                self.C = numpy.zeros((4, 2))
                self.C[0, 0] = 1  # Ez = 1
                self.C[2, 1] = 1  # Hz = alpha
        elif nu == 0:
            self.C = numpy.zeros(4)
            if tm:
                c = constants.Y0 * n * n
                idx = (0, 3)
                self.C[:2] = self.tetmConstants(ri, ro, neff, wl, EH, c, idx)
            else:
                c = -constants.eta0
                idx = (1, 2)
                self.C[2:] = self.tetmConstants(ri, ro, neff, wl, EH, c, idx)
        else:
            self.C = self.vConstants(ri, ro, neff, wl, nu, EH)

        # Compute EH fields
        if neff < n:
            c1 = wl.k0 * ro / u
            F3 = jvp(nu, u) / jn(nu, u)
            F4 = yvp(nu, u) / yn(nu, u)
        else:
            c1 = -wl.k0 * ro / u
            F3 = ivp(nu, u) / iv(nu, u)
            F4 = kvp(nu, u) / kn(nu, u)

        c2 = neff * nu / u * c1
        c3 = constants.eta0 * c1
        c4 = constants.Y0 * n * n * c1

        EH[0] = self.C[0] + self.C[1]
        EH[1] = self.C[2] + self.C[3]
        EH[2] = (c2 * (self.C[0] + self.C[1]) -
                 c3 * (F3 * self.C[2] + F4 * self.C[3]))
        EH[3] = (c4 * (F3 * self.C[0] + F4 * self.C[1]) -
                 c2 * (self.C[2] + self.C[3]))

        return EH
Beispiel #22
0
    def order1(self, ps, v0_in):
        """
        Equation assuming O(1) periodic input
        
        Here we take the input as an phasor in the electrical RF domain
        and the output is returned as a phasor in the optical domain
        
        vm_in = [a0, a1, a2 ... an]
        where
        v(t) = sum_{k=0}^n a_k exp(j k w0) + c.c.

        vm_out = [a0, a1, a2 ... an, a-n ... a-1]
        where
        E(t) = sum_{k=-n}^n a_k exp(j k w0)

        Note:
        Currently only the dc and fundamental component of the signal are used.
        All other harmonics are assumed filtered out.
        """
        #Output signal will be complex
        pso = ps.copy()
        pso.real = False
        
        #Assume only fundamental harmonic and DC at input
        a0 = v0_in[0]
        a1,theta1 = np.abs(v0_in[1]), np.angle(v0_in[1])

        #Jacobi-Anger expansion
        k = pso.ms
        b1 = special.jv(k, self.v1*a1) * np.exp(1j*self.v1*a0 + 1j*k*(theta1+0.5*pi))
        b2 = special.jv(k, self.v2*a1) * np.exp(1j*self.phi + 1j*self.v2*a0 + 1j*k*(theta1+0.5*pi))
        bp1 = special.jvp(k, self.v1*a1) * np.exp(1j*self.v1*a0 + 1j*k*(theta1+0.5*pi))
        bp2 = special.jvp(k, self.v2*a1) * np.exp(1j*self.phi + 1j*self.v2*a0 + 1j*k*(theta1+0.5*pi))
        
        v0_out = self.eloss*self.Em*(b1 + self.a*b2)

        #Flag and store the O1 solution
        self.O1_solution = (ps,v0_in,b1,b2,bp1,bp2)
        self.O1_complete = True

        return pso, v0_out
Beispiel #23
0
 def norm(self, w, h, alpha, a, b):
     pol, n, m = alpha
     en = 1 if n == 0 else 2
     if self.clad(w).real < -1e6:
         radius = self.r
         if pol == 'E':
             u = jnp_zeros(n, m)[-1]
             jnu = jv(n, u)
             jnpu = 0.0
         else:
             u = jn_zeros(n, m)[-1]
             jnu = 0.0
             jnpu = jvp(n, u)
         return np.sqrt(a**2 * np.pi * radius**2 / en *
                        (1 - n**2 / u**2) * jnu**2 +
                        b**2 * np.pi * radius**2 / en * jnpu**2)
     # ac = a.conjugate()
     # bc = b.conjugate()
     u = self.samples.u(h**2, w, self.fill(w))
     jnu = jv(n, u)
     jnpu = jvp(n, u)
     v = self.samples.v(h**2, w, self.clad(w))
     knv = kv(n, v)
     knpv = kvp(n, v)
     # uc = u.conjugate()
     # jnuc = jnu.conjugate()
     # jnpuc = jnpu.conjugate()
     # vc = v.conjugate()
     # knvc = knv.conjugate()
     # knpvc = knpv.conjugate()
     val_u = 2 * np.pi * self.r**2 / en
     val_v = val_u * ((u * jnu) / (v * knv))**2
     # val_v = val_u * (uc * u * jnuc * jnu) / (vc * v * knvc * knv)
     upart_diag = self.upart_diag(n, u, jnu, jnpu, u, jnu, jnpu)
     vpart_diag = self.vpart_diag(n, v, knv, knpv, v, knv, knpv)
     upart_off = self.upart_off(n, u, jnu, u, jnu)
     vpart_off = self.vpart_off(n, v, knv, v, knv)
     return np.sqrt(val_u * (a * (a * upart_diag + b * upart_off) + b *
                             (b * upart_diag + a * upart_off)) - val_v *
                    (a * (a * vpart_diag + b * vpart_off) + b *
                     (b * vpart_diag + a * vpart_off)))
Beispiel #24
0
 def u_jnu_jnpu_pec(num_n, num_m):
     us = np.empty((2, num_n, num_m))
     jnus = np.empty((2, num_n, num_m))
     jnpus = np.empty((2, num_n, num_m))
     for n in range(num_n):
         us[0, n] = jnp_zeros(n, num_m)
         us[1, n] = jn_zeros(n, num_m)
         jnus[0, n] = jv(n, us[0, n])
         jnus[1, n] = np.zeros(num_m)
         jnpus[0, n] = np.zeros(num_m)
         jnpus[1, n] = jvp(n, us[1, n])
     return us, jnus, jnpus
Beispiel #25
0
def cutoffHE2(b):
    nu = 2
    a = rho * b
    i = ivp(2, u1 * a) / (u1 * a * iv(2, u1 * a))

    X = (1 / (u1 * a)**2 + 1 / (u2 * a)**2)

    P1 = jn(nu, u2 * a) * yn(nu, u2 * b) - yn(nu, u2 * a) * jn(nu, u2 * b)
    P2 = (jvp(nu, u2 * a) * yn(nu, u2 * b) -
          yvp(nu, u2 * a) * jn(nu, u2 * b)) / (u2 * a)
    P3 = (jn(nu, u2 * a) * yvp(nu, u2 * b) -
          yn(nu, u2 * a) * jvp(nu, u2 * b)) / (u2 * b)
    P4 = (jvp(nu, u2 * a) * yvp(nu, u2 * b) -
          yvp(nu, u2 * a) * jvp(nu, u2 * b)) / (u2 * a * u2 * b)

    A = 2 * nu / (u2 * b)**2 - 1 / (nu - 1)

    return (n22 / n32 * (i * P1 + P2) * (n12 * i * P3 + n22 * P4) +
            (A * i * P1 + A * P2 + i * P3 + P4) * (n12 * i * P1 + n22 * P2) -
            n32 * nu**2 * X**2 * P1 * (A * P1 + P3) - n22 * nu * X *
            (nu * X * P1 * P3 + 2 * P1 * P4 - 2 * P2 * P3))
Beispiel #26
0
    def effective_coated_N1(self, filling, polarization, orders=1):
        '''
		Calculate effective medium parameters using the
		coated cylinder model
		'''
        R = self.radius
        k = self.k_host
        mu_h = 1.0

        R2 = R / np.sqrt(filling)

        #aa0 = self.coeff(1,polarization)
        sum_ = 0.0 + 0j
        if polarization in ['H', 'TE']:

            if orders < 1: orders = 1
            for m in np.arange(1, orders + 1):
                # bessel functions
                J0 = special.jv(m, k * R2)
                H0 = special.hankel1(m, k * R2)
                JD0 = special.jvp(m, k * R2)
                HD0 = special.h1vp(m, k * R2)
                aa1 = self.coeff(m, 'TE')
                denom = JD0 + HD0 * aa1 + 0j
                numer = (J0 + H0 * aa1) + 0j
                sum_ = sum_ + m * numer / denom
            term = self.host_eps / (k * R2)
            return term * sum_ + 0j
        else:
            for m in np.arange(1, orders + 1):
                J0 = special.jv(m, k * R2)
                H0 = special.hankel1(m, k * R2)
                JD0 = special.jvp(m, k * R2)
                HD0 = special.h1vp(m, k * R2)
                aa1 = self.coeff(m, 'TM')
                denom = JD0 + HD0 * aa1 + 0j
                numer = (J0 + H0 * aa1) + 0j
                sum_ = sum_ + m * numer / denom
            term = self.host_mu / (k * R2)
            return term * sum_ + 0j
Beispiel #27
0
def cyl_modal_coefs(N, kr, arrayType):
    """
    Modal coefficients for rigid or open cylindrical array

    Parameters
    ----------
    N : int
        Maximum spherical harmonic expansion order.
    kr: ndarray
        Wavenumber-radius product. Dimension = (l).
    arrayType: str
        'open' or 'rigid'.

    Returns
    -------
    b_N : ndarray
        Modal coefficients. Dimension = (l, N+1)

    Raises
    -----
    TypeError, ValueError: if method arguments mismatch in type, dimension or value.

    Notes
    -----
    The `arrayType` options are:
    - 'open' for open array of omnidirectional sensors
    - 'rigid' for sensors mounted on a rigid baffle.

    """

    _validate_int('N', N)
    _validate_ndarray_1D('kr', kr, positive=True)
    _validate_string('arrayType', arrayType, choices=['open', 'rigid'])

    b_N = np.zeros((kr.size, N + 1), dtype='complex')

    for n in range(N + 1):

        if arrayType is 'open':
            b_N[:, n] = np.power(1j, n) * jv(n, kr)

        elif arrayType is 'rigid':
            jn = jv(n, kr)
            jnprime = jvp(n, kr, 1)
            hn = hankel2(n, kr)
            hnprime = h2vp(n, kr, 1)

            temp = np.power(1j, n) * (jn - (jnprime / hnprime) * hn)
            temp[np.where(kr == 0)] = 1 if n == 0 else 0.
            b_N[:, n] = temp

    return b_N
Beispiel #28
0
def linton_evans_coeffs(k, incAng, numCylinders, centres, radii, M):
    # Four-cylinder problem
    #if k<=20:
    #    M=40
    #elif 20<k<=40:
    #    M=80
    #elif 40<k<=60:
    #    M=120
    #elif 60<k<=120:
    #    M=180
    #elif k>120:
    #    M=300

    N = numCylinders
    origin = centres
    a = radii

    i = np.arange(0, N).reshape(-1, 1)
    j = np.arange(0, N).reshape(1, -1)

    R = np.sqrt((origin[j, 0] - origin[i, 0])**2 +
                (origin[j, 1] - origin[i, 1])**2)
    alpha = np.angle((origin[j, 0] - origin[i, 0]) + 1j *
                     (origin[j, 1] - origin[i, 1]))

    q = np.repeat(np.arange(N), 2 * M + 1).reshape(-1, 1)  # rows
    p = np.repeat(np.arange(N), 2 * M + 1).reshape(1, -1)  # cols
    m = np.repeat([np.arange(-M, M + 1)], N, axis=0).reshape(-1, 1)  # rows
    n = np.repeat([np.arange(-M, M + 1)], N, axis=0).reshape(1, -1)  # cols

    # Right-hand vector
    Iq = np.exp(
        1j * k *
        (origin[q, 0] * np.cos(incAng) + origin[q, 1] * np.sin(incAng)))
    exponential1 = np.exp(1j * m * (np.pi / 2 - incAng))
    RHS = -Iq * exponential1

    # Left-hand side matrix
    Znp = jvp(n, k * a[p]) / h1vp(n, k * a[p])
    exponential2 = np.exp(1j * (n - m) * alpha[p, q])
    Hnm = hankel1(n - m, k * R[p, q])
    LHS = Znp * exponential2 * Hnm

    Identity = np.identity(2 * M + 1)
    for cyl in range(N):
        LHS[cyl * (2 * M + 1):(cyl + 1) * (2 * M + 1),
            cyl * (2 * M + 1):(cyl + 1) * (2 * M + 1)] = Identity

    # Solve for values of Anq
    A = np.linalg.solve(LHS, RHS)

    return A
def fb_1_grad(i, k, x, y, x0=0, y0=0):
    X = x - x0
    Y = y - y0
    r = np.sqrt(X**2 + Y**2)
    angle = np.arctan2(Y, X)
    idx = i + 1
    j = special.jv(idx, k * r)
    dj = special.jvp(idx, k * r)
    c = np.cos(idx * angle)
    s = np.sin(idx * angle)
    dx = dj * k * X / r * s - j * c * Y / (X**2 + Y**2) * idx
    dy = dj * k * Y / r * s + j * c * X / (X**2 + Y**2) * idx
    return dx, dy
Beispiel #30
0
    def _ehceq(self, neff, wl, nu):
        u, w = self._uw(wl, neff)
        v2 = u * u + w * w
        nco = self.fiber.maxIndex(0, wl)
        ncl = self.fiber.minIndex(1, wl)
        delta = (1 - ncl**2 / nco**2) / 2
        jnu = jn(nu, u)
        knu = kn(nu, w)
        kp = kvp(nu, w)

        return (jvp(nu, u) * w * knu + kp * u * jnu * (1 - delta) -
                jnu * sqrt((u * kp * delta)**2 + ((nu * neff * v2 * knu) /
                                                  (nco * u * w))**2))
def fb_ca_dk(i, k, x, y, nu=1, x0=0, y0=0, phi0=0, sym=None):
    X = x - x0
    Y = y - y0
    r = np.sqrt(X**2 + Y**2)
    #r[r==0] = 1e-16
    angle = np.arctan2(Y, X) - phi0
    if sym == None:
        idx = i + 1
    if sym == "odd":
        idx = 2 * i + 1
    if sym == "even":
        idx = 2 * i + 2
    s = np.sin(nu * idx * angle)
    return r * special.jvp(nu * idx, k * r) * s
Beispiel #32
0
def eigensystem(b, m, ri, ro):
    r""" Computes the function associated with the eigensystem of the
    convected wave equation. The location of the zeros for this function
    correspond to the eigenvalues for the convected wave equation.

    The solution to the Bessel equation with boundary conditions applied
    yields a system of two linear equations.
    .. math::

        A x =
        \begin{bmatrix}
            J'_m(\mu \lambda)   &   Y'_m(\mu \lambda) \\
            J'_m(\mu)           &   Y'_m(\mu)
        \end{bmatrix}
        \begin{bmatrix}
            x_1 \\ x_2
        \end{bmatrix}
        = 0

    This procedure evaluates the function
    .. math::

        det(A) = f(b) = J_m(b*ri)*Y_m(b*ro)  -  J_m(b*ro)*Y_m(b*ri)

    So, this procedure can be passed to another routine such as numpy
    to find zeros.

    Args:
        b (float): coordinate.
        m (int): circumferential wave number.
        ri (float): inner radius of a circular annulus.
        ro (float): outer radius of a circular annulus.

    """
    f = sp.jvp(m, b * ri) * sp.yvp(m, b * ro) - sp.jvp(m, b * ro) * sp.yvp(
        m, b * ri)
    return f
Beispiel #33
0
    def _ehceq(self, neff, wl, nu):
        u, w = self._uw(wl, neff)
        v2 = u*u + w*w
        nco = self.fiber.maxIndex(0, wl)
        ncl = self.fiber.minIndex(1, wl)
        delta = (1 - ncl**2 / nco**2) / 2
        jnu = jn(nu, u)
        knu = kn(nu, w)
        kp = kvp(nu, w)

        return (jvp(nu, u) * w * knu +
                kp * u * jnu * (1 - delta) -
                jnu * sqrt((u * kp * delta)**2 +
                           ((nu * neff * v2 * knu) /
                            (nco * u * w))**2))
Beispiel #34
0
    def coeff_int(self, order, polarization, freq_index=None):
        #if self.frequency == None:
        #	raise Exception("ERROR: Frequency range has not been specified.")
        # for backward compatibility only

        mu1 = self.host_mu
        mu2 = self.cyl_mu
        if freq_index >= 0:
            z1 = self.kR_host[freq_index]
            z2 = self.kR_cyl[freq_index]
            k0 = self.k0[freq_index]
            kR_cyl = self.kR_cyl[freq_index]
            kR_host = self.kR_host[freq_index]
        else:
            z1 = self.kR_host
            z2 = self.kR_cyl
            k0 = self.k0
            kR_cyl = self.kR_cyl
            kR_host = self.kR_host

        bn = self.coeff(order, polarization, freq_index)
        ### POLARIZATION
        if polarization in ['TE', 'H']:
            JD1 = special.jvp(order, z1)
            JD2 = special.jvp(order, z2)
            HD1 = special.h1vp(order, z1)
            numer = HD1 * bn + JD1
            denom = JD2
            return numer / denom
        elif polarization in ['TM', 'E']:
            J2 = special.jv(order, z2)
            J1 = special.jv(order, z1)
            H1 = special.hankel1(order, z1)
            numer = H1 * bn + J1
            denom = J2
            return numer / denom
Beispiel #35
0
def JnYn(maxn, resolution):

    delta = numpy.pi / resolution
    z_table = numpy.mgrid[min(minz_j(maxn), minz_y(maxn)) : max(maxz_j(maxn), maxz_y(maxn)) : delta]

    J_table = []
    Jdot_table = []
    Y_table = []
    Ydot_table = []
    for n in range(maxn + 1):
        J_table.append(special.jn(n, z_table))
        Jdot_table.append(special.jvp(n, z_table))
        Y_table.append(special.yn(n, z_table))
        Ydot_table.append(special.yvp(n, z_table))

    return z_table, J_table, Jdot_table, Y_table, Ydot_table
def Bescoef(k,r,a,n):
    """
    The calculates the Bessel and Hankel function coef for the 
    incident and scattered wave solution.
    
    spec.jv(v,z) - Bessel Func of the first kind of order v
    spec.jvp(v,z) - first derivative of BF of the first kinda of order v
    spec.h1vp(v,z) - first derivative of Hankel Func of order v
    spec.hankel1(v,z) - Hankel func of the first kind of order v
    
    """
    
    kr , ka = k*r , k*a  
    coef = -(spec.jvp(n,ka,n=1)/spec.h1vp(n,ka,n=1))*spec.hankel1(n,kr)
    
    return coef
Beispiel #37
0
def linton_evans_coeffs(k,incAng,numCylinders,centres,radii,M):
    # Four-cylinder problem
    #if k<=20:
    #    M=40
    #elif 20<k<=40:
    #    M=80
    #elif 40<k<=60:
    #    M=120
    #elif 60<k<=120:
    #    M=180
    #elif k>120:
    #    M=300
        
    N = numCylinders
    origin = centres
    a = radii

    i = np.arange(0,N).reshape(-1,1)
    j = np.arange(0,N).reshape(1,-1)
    
    R = np.sqrt((origin[j,0]-origin[i,0])**2+(origin[j,1]-origin[i,1])**2)
    alpha = np.angle((origin[j,0]-origin[i,0]) +1j*(origin[j,1]-origin[i,1]))

    q = np.repeat(np.arange(N),2*M+1).reshape(-1,1) # rows
    p = np.repeat(np.arange(N),2*M+1).reshape(1,-1) # cols
    m = np.repeat([np.arange(-M,M+1)],N,axis=0).reshape(-1,1) # rows
    n = np.repeat([np.arange(-M,M+1)],N,axis=0).reshape(1,-1) # cols

    # Right-hand vector
    Iq = np.exp(1j*k*(origin[q,0]*np.cos(incAng)+origin[q,1]*np.sin(incAng)))
    exponential1 = np.exp(1j*m*(np.pi/2-incAng))
    RHS = - Iq * exponential1
    
    # Left-hand side matrix
    Znp = jvp(n,k*a[p]) / h1vp(n,k*a[p])
    exponential2 = np.exp(1j*(n-m)*alpha[p,q])
    Hnm = hankel1(n-m,k*R[p,q])
    LHS = Znp * exponential2 * Hnm

    Identity = np.identity(2*M+1)
    for cyl in range(N):
        LHS[cyl*(2*M+1):(cyl+1)*(2*M+1),cyl*(2*M+1):(cyl+1)*(2*M+1)] = Identity

    # Solve for values of Anq
    A=np.linalg.solve(LHS,RHS)

    return A
Beispiel #38
0
    def _hefield(self, wl, nu, neff, r):
        rho = self.fiber.outerRadius(0)
        k = wl.k0
        nco2 = self.fiber.maxIndex(0, wl)**2
        ncl2 = self.fiber.minIndex(1, wl)**2
        u = rho * k * sqrt(nco2 - neff**2)
        w = rho * k * sqrt(neff**2 - ncl2)
        v = rho * k * sqrt(nco2 - ncl2)

        jnu = jn(nu, u)
        knw = kn(nu, w)

        Delta = (1 - ncl2/nco2)/2
        b1 = jvp(nu, u) / (u * jnu)
        b2 = kvp(nu, w) / (w * knw)
        F1 = (u * w / v)**2 * (b1 + (1 - 2 * Delta)*b2) / nu
        F2 = (v / (u * w))**2 * nu / (b1 + b2)
        a1 = (F2 - 1) / 2
        a2 = (F2 + 1) / 2
        a3 = (F1 - 1) / 2
        a4 = (F1 + 1) / 2
        a5 = (F1 - 1 + 2 * Delta) / 2
        a6 = (F1 + 1 - 2 * Delta) / 2

        if r < rho:
            jmur = jn(nu-1, u * r / rho)
            jpur = jn(nu+1, u * r / rho)
            jnur = jn(nu, u * r / rho)
            er = -(a1 * jmur + a2 * jpur) / jnu
            ephi = -(a1 * jmur - a2 * jpur) / jnu
            ez = u / (k * neff * rho) * jnur / jnu
            hr = Y0 * nco2 / neff * (a3 * jmur - a4 * jpur) / jnu
            hphi = -Y0 * nco2 / neff * (a3 * jmur + a4 * jpur) / jnu
            hz = Y0 * u * F2 / (k * rho) * jnur / jnu
        else:
            kmur = kn(nu-1, w * r / rho)
            kpur = kn(nu+1, w * r / rho)
            knur = kn(nu, w * r / rho)
            er = -u / w * (a1 * kmur - a2 * kpur) / knw
            ephi = -u / w * (a1 * kmur + a2 * kpur) / knw
            ez = u / (k * neff * rho) * knur / knw
            hr = Y0 * nco2 / neff * u / w * (a5 * kmur + a6 * kpur) / knw
            hphi = -Y0 * nco2 / neff * u / w * (a5 * kmur - a6 * kpur) / knw
            hz = Y0 * u * F2 / (k * rho) * knur / knw

        return numpy.array((er, ephi, ez)), numpy.array((hr, hphi, hz))
Beispiel #39
0
    def coef(self, h, w, alpha):
        """Return the coefficients of TE- and TM- components which compose
        the hybrid mode.

        Args:
            h: A complex indicating the phase constant.
            w: A complex indicating the angular frequency
            alpha: A tuple (pol, n, m) where pol is 'M' for TM-like mode or
                'E' for TE-like mode, n is the order of the mode, and m is
                the number of modes in the order and the polarization.
        Returns:
            a: A complex indicating the coefficient of TE-component
            b: A complex indicating the coefficient of TM-component
        """
        e1 = self.fill(w)
        e2 = self.clad(w)
        pol, n, m = alpha
        w = w.real + 1j * w.imag
        h = h.real + 1j * h.imag
        if e2.real < -1e6:
            if pol == 'E':
                norm = self.norm(w, h, alpha, 1.0 + 0.0j, 0.0j)
                ai, bi = 1.0 / norm, 0.0
            else:
                norm = self.norm(w, h, alpha, 0.0j, 1.0 + 0.0j)
                ai, bi = 0.0, 1.0 / norm
        else:
            u = self.samples.u(h**2, w, e1)
            v = self.samples.v(h**2, w, e2)
            knv = kv(n, v)
            knpv = kvp(n, v)
            jnu = jv(n, u)
            jnpu = jvp(n, u)
            ci = -n * (u**2 + v**2) * jnu * knv / (u * v)
            if pol == 'E':
                ci *= (h / w)**2
                ci /= (e1 * jnpu * v * knv + e2 * knpv * u * jnu)
                norm = self.norm(w, h, alpha, 1.0 + 0.0j, ci)
                ai = 1.0 / norm
                bi = ci / norm
            else:
                ci /= (jnpu * v * knv + knpv * u * jnu)
                norm = self.norm(w, h, alpha, ci, 1.0 + 0.0j)
                bi = 1.0 / norm
                ai = ci / norm
        return ai, bi
Beispiel #40
0
    def _hefield(self, wl, nu, neff, r):
        rho = self.fiber.outerRadius(0)
        k = wl.k0
        nco2 = self.fiber.maxIndex(0, wl)**2
        ncl2 = self.fiber.minIndex(1, wl)**2
        u = rho * k * sqrt(nco2 - neff**2)
        w = rho * k * sqrt(neff**2 - ncl2)
        v = rho * k * sqrt(nco2 - ncl2)

        jnu = jn(nu, u)
        knw = kn(nu, w)

        Delta = (1 - ncl2 / nco2) / 2
        b1 = jvp(nu, u) / (u * jnu)
        b2 = kvp(nu, w) / (w * knw)
        F1 = (u * w / v)**2 * (b1 + (1 - 2 * Delta) * b2) / nu
        F2 = (v / (u * w))**2 * nu / (b1 + b2)
        a1 = (F2 - 1) / 2
        a2 = (F2 + 1) / 2
        a3 = (F1 - 1) / 2
        a4 = (F1 + 1) / 2
        a5 = (F1 - 1 + 2 * Delta) / 2
        a6 = (F1 + 1 - 2 * Delta) / 2

        if r < rho:
            jmur = jn(nu - 1, u * r / rho)
            jpur = jn(nu + 1, u * r / rho)
            jnur = jn(nu, u * r / rho)
            er = -(a1 * jmur + a2 * jpur) / jnu
            ephi = -(a1 * jmur - a2 * jpur) / jnu
            ez = u / (k * neff * rho) * jnur / jnu
            hr = Y0 * nco2 / neff * (a3 * jmur - a4 * jpur) / jnu
            hphi = -Y0 * nco2 / neff * (a3 * jmur + a4 * jpur) / jnu
            hz = Y0 * u * F2 / (k * rho) * jnur / jnu
        else:
            kmur = kn(nu - 1, w * r / rho)
            kpur = kn(nu + 1, w * r / rho)
            knur = kn(nu, w * r / rho)
            er = -u / w * (a1 * kmur - a2 * kpur) / knw
            ephi = -u / w * (a1 * kmur + a2 * kpur) / knw
            ez = u / (k * neff * rho) * knur / knw
            hr = Y0 * nco2 / neff * u / w * (a5 * kmur + a6 * kpur) / knw
            hphi = -Y0 * nco2 / neff * u / w * (a5 * kmur - a6 * kpur) / knw
            hz = Y0 * u * F2 / (k * rho) * knur / knw

        return numpy.array((er, ephi, ez)), numpy.array((hr, hphi, hz))
Beispiel #41
0
def JnYn(maxn, resolution):

    delta = numpy.pi / resolution
    z_table = numpy.mgrid[min(minz_j(maxn),minz_y(maxn)):
                              max(maxz_j(maxn), maxz_y(maxn)):delta]

    J_table = []
    Jdot_table = []
    Y_table = []
    Ydot_table = []
    for n in range(maxn+1):
        J_table.append(special.jn(n, z_table)) 
        Jdot_table.append(special.jvp(n, z_table))
        Y_table.append(special.yn(n, z_table))
        Ydot_table.append(special.yvp(n, z_table))

    return z_table, J_table, Jdot_table, Y_table, Ydot_table
Beispiel #42
0
def calc_bessel(x, y, radius, gradr=False):
    rho = (x**2 + y**2)**0.5

    zero = special.jn_zeros(0, 1)

    # See RT2 p75 for derivation
    norm_fac = np.pi**0.5*special.jv(1, zero)*radius
    z = rho*zero/radius
    in_beam = rho <= radius
    E = pyfftw.byte_align(special.jv(0, z)*in_beam/norm_fac)

    if gradr:
        gradrhoE = special.jvp(0, z, 1)*in_beam/norm_fac*zero/radius
        gradxE = pyfftw.byte_align(mathx.divide0(gradrhoE*x, rho))
        gradyE = pyfftw.byte_align(mathx.divide0(gradrhoE*y, rho))
        return E, (gradxE, gradyE)
    else:
        return E
Beispiel #43
0
    def jac(self, h2, args):
        """Return Jacobian of the characteristic equation

        Args:
            h2: A complex indicating the square of the phase constant.
            args: A tuple (w, n, e1, e2), where w indicates the angular
                frequency, n indicates  the order of the modes, e1 indicates
                the permittivity of the core, and e2 indicates the permittivity
                of the clad.
        Returns:
            val: A complex indicating the Jacobian of the characteristic
                equation.
        """
        w, pol, n, e1, e2 = args
        h2comp = h2.real + 1j * h2.imag
        u = self.u(h2comp, w, e1)
        v = self.v(h2comp, w, e2)
        jus = jv(n, u)
        jpus = jvp(n, u)
        kvs = kv(n, v)
        kpvs = kvp(n, v)
        du_dh2 = -self.r / (2 * u)
        dv_dh2 = self.r / (2 * v)
        te = jpus / u + kpvs * jus / (v * kvs)
        dte_du = (-(u * (1 - n**2 / u**2) * jus + 2 * jpus) / u**2 +
                  jpus * kpvs / (v * kvs))
        dte_dv = jus * (n**2 * kvs**2 / v + v *
                        (kvs**2 - kpvs**2) - 2 * kvs * kpvs) / (v**2 * kvs**2)
        tm = e1 * jpus / u + e2 * kpvs * jus / (v * kvs)
        dtm_du = e1 * dte_du
        dtm_dv = e2 * dte_dv
        if n == 0:
            if pol == 'M':
                val = dtm_du * du_dh2 + dtm_dv * dv_dh2
            else:
                val = dte_du * du_dh2 + dte_dv * dv_dh2
        else:
            dre_dh2 = -(n / w)**2 * jus * (jus * (
                (1 / u**2 + 1 / v**2)**2 - self.r * h2comp *
                (1 / u**4 - 1 / v**4)) + jpus * 2 * h2comp *
                                           (1 / u**2 + 1 / v**2)**2)
            val = ((dte_du * du_dh2 + dte_dv * dv_dh2) * tm +
                   (dtm_du * du_dh2 + dtm_dv * dv_dh2) * te + dre_dh2)
        return val
Beispiel #44
0
    def func_jac(self, h2, *args):
        """Return the value and Jacobian of the characteristic equation

        Args:
            h2: A complex indicating the square of the phase constant.
        Returns:
            val: 2 complexes indicating the left-hand value and Jacobian
                of the characteristic equation.
        """
        w, pol, n, e1, e2 = args
        h2comp = h2.real + 1j * h2.imag
        u = self.u(h2comp, w, e1)
        v = self.v(h2comp, w, e2)
        jus = jv(n, u)
        jpus = jvp(n, u)
        kvs = kv(n, v)
        kpvs = kvp(n, v)
        du_dh2 = -self.r / (2 * u)
        dv_dh2 = self.r / (2 * v)
        te = jpus / u + kpvs * jus / (v * kvs)
        dte_du = (-(u * (1 - n**2 / u**2) * jus + 2 * jpus) / u**2 +
                  jpus * kpvs / (v * kvs))
        dte_dv = jus * (n**2 * kvs**2 / v + v *
                        (kvs**2 - kpvs**2) - 2 * kvs * kpvs) / (v**2 * kvs**2)
        tm = e1 * jpus / u + e2 * kpvs * jus / (v * kvs)
        dtm_du = e1 * dte_du
        dtm_dv = e2 * dte_dv
        if n == 0:
            if pol == 'M':
                f = tm
                val = dtm_du * du_dh2 + dtm_dv * dv_dh2
            else:
                f = te
                val = dte_du * du_dh2 + dte_dv * dv_dh2
        else:
            f = (tm * te - h2comp * (n / w)**2 *
                 ((1 / u**2 + 1 / v**2) * jus)**2)
            dre_dh2 = -(n / w)**2 * jus * (jus * (
                (1 / u**2 + 1 / v**2)**2 - self.r * h2comp *
                (1 / u**4 - 1 / v**4)) + jpus * 2 * h2comp *
                                           (1 / u**2 + 1 / v**2)**2)
            val = ((dte_du * du_dh2 + dte_dv * dv_dh2) * tm +
                   (dtm_du * du_dh2 + dtm_dv * dv_dh2) * te + dre_dh2)
        return f, val
def fb_ca_grad(i, k, x, y, nu=1, x0=0, y0=0, phi0=0, sym=None):
    X = x - x0
    Y = y - y0
    r = np.sqrt(X**2 + Y**2)
    #r[r==0] = 1e-16
    angle = np.arctan2(Y, X) - phi0
    if sym == None:
        idx = i + 1
    if sym == "odd":
        idx = 2 * i + 1
    if sym == "even":
        idx = 2 * i + 2
    j = special.jv(idx * nu, k * r)
    dj = special.jvp(idx * nu, k * r)
    c = np.cos(nu * idx * angle)
    s = np.sin(nu * idx * angle)
    dx = dj * k * X / r * s - j * c * Y / (X**2 + Y**2) * nu * idx
    dy = dj * k * Y / r * s + j * c * X / (X**2 + Y**2) * nu * idx
    return dx, dy
Beispiel #46
0
    def Y(self, w, h, alpha, a, b):
        """Return the effective admittance of the waveguide mode

        Args:
            w: A complex indicating the angular frequency
            h: A complex indicating the phase constant.
            alpha: A tuple (pol, n, m) where pol is 'M' for TM-like mode or
                'E' for TE-like mode, n is the order of the mode, and m is
                the number of modes in the order and the polarization.
            a: A complex indicating the coefficient of TE-component
            b: A complex indicating the coefficient of TM-component
        Returns:
            y: A complex indicating the effective admittance
        """
        pol, n, m = alpha
        e1 = self.fill(w)
        e2 = self.clad(w)
        en = 1 if n == 0 else 2
        if e2.real < -1e6:
            if pol == 'E':
                val = h / w
            else:
                val = e1 * w / h
        else:
            u = self.samples.u(h**2, w, e1)
            jnu = jv(n, u)
            jnpu = jvp(n, u)
            v = self.samples.v(h**2, w, e2)
            knv = kv(n, v)
            knpv = kvp(n, v)
            val_u = 2 * np.pi * self.r**2 / en
            val_v = val_u * ((u * jnu) / (v * knv))**2
            upart_diag = self.upart_diag(n, u, jnu, jnpu, u, jnu, jnpu)
            vpart_diag = self.vpart_diag(n, v, knv, knpv, v, knv, knpv)
            upart_off = self.upart_off(n, u, jnu, u, jnu)
            vpart_off = self.vpart_off(n, v, knv, v, knv)
            val = (val_u * (h / w * a *
                            (a * upart_diag + b * upart_off) + e1 * w / h * b *
                            (b * upart_diag + a * upart_off)) - val_v *
                   (h / w * a *
                    (a * vpart_diag + b * vpart_off) + e2 * w / h * b *
                    (b * vpart_diag + a * vpart_off)))
        return val
Beispiel #47
0
    def vConstants(self, ri, ro, neff, wl, nu, EH):
        a = numpy.zeros((4, 4))
        n = self.maxIndex(wl)
        u = self.u(ro, neff, wl)
        urp = self.u(ri, neff, wl)

        if neff < n:
            B1 = jn(nu, u)
            B2 = yn(nu, u)
            F1 = jn(nu, urp) / B1
            F2 = yn(nu, urp) / B2
            F3 = jvp(nu, urp) / B1
            F4 = yvp(nu, urp) / B2
            c1 = wl.k0 * ro / u
        else:
            B1 = iv(nu, u)
            B2 = kn(nu, u)
            F1 = iv(nu, urp) / B1 if u else 1
            F2 = kn(nu, urp) / B2
            F3 = ivp(nu, urp) / B1 if u else 1
            F4 = kvp(nu, urp) / B2
            c1 = -wl.k0 * ro / u
        c2 = neff * nu / urp * c1
        c3 = constants.eta0 * c1
        c4 = constants.Y0 * n * n * c1

        a[0, 0] = F1
        a[0, 1] = F2
        a[1, 2] = F1
        a[1, 3] = F2
        a[2, 0] = F1 * c2
        a[2, 1] = F2 * c2
        a[2, 2] = -F3 * c3
        a[2, 3] = -F4 * c3
        a[3, 0] = F3 * c4
        a[3, 1] = F4 * c4
        a[3, 2] = -F1 * c2
        a[3, 3] = -F2 * c2

        return numpy.linalg.solve(a, EH)
Beispiel #48
0
    def _tmfield(self, wl, nu, neff, r):
        N = len(self.fiber)
        C = numpy.array((1, 0))
        EH = numpy.zeros(4)
        ri = 0

        for i in range(N-1):
            ro = self.fiber.outerRadius(i)
            layer = self.fiber.layers[i]
            n = layer.maxIndex(wl)
            u = layer.u(ro, neff, wl)

            if i > 0:
                C = layer.tetmConstants(ri, ro, neff, wl, EH,
                                        constants.Y0 * n * n, (0, 3))

            if r < ro:
                break

            if neff < n:
                c1 = wl.k0 * ro / u
                F3 = jvp(nu, u) / jn(nu, u)
                F4 = yvp(nu, u) / yn(nu, u)
            else:
                c1 = -wl.k0 * ro / u
                F3 = ivp(nu, u) / iv(nu, u)
                F4 = kvp(nu, u) / kn(nu, u)

            c4 = constants.Y0 * n * n * c1

            EH[0] = C[0] + C[1]
            EH[3] = c4 * (F3 * C[0] + F4 * C[1])

            ri = ro
        else:
            layer = self.fiber.layers[-1]
            u = layer.u(ro, neff, wl)
            # C =

        return numpy.array((0, ephi, 0)), numpy.array((hr, 0, hz))
Beispiel #49
0
    def eval_d_u_outwards(self, arg, sid):
        # Debug function
        # Only for true arc. At least at the moment
        k = self.k
        R = self.R
        a = self.a
        nu = self.nu

        r, th = domain_util.arg_to_polar_abs(self.boundary, a, arg, sid)

        d_u = 0

        for m in range(1, self.m_max+1):
            ac = self.fft_a_coef[m-1]
            if sid == 0:
                d_u += ac * k * jvp(m*nu, k*r, 1) * np.sin(m*nu*(th-a))
            elif sid == 1:
                d_u += ac * jv(m*nu, k*r) * m * nu * np.cos(m*nu*(th-a))
            elif sid == 2:
                d_u += -ac * jv(m*nu, k*r) * m * nu * np.cos(m*nu*(th-a))

        return d_u
Beispiel #50
0
def cylinder(wavenumber,xPlotPoints,yPlotPoints,radius=1.0):
    """ Analytical potential on hard cylinder with [1,0] incident wave (Jones)"""
    x = xPlotPoints
    y = yPlotPoints
    theta = np.arctan2(y,x)
    numPoints = len(x)

    nans=False,False
    N = 100
    
    while any(nans)==False:
        
        N += 50
        n = np.arange(0,N)
        neumann = 2*np.ones(N); neumann[0]=1

        dJ = jvp(n,wavenumber*radius,1)
        H1 = hankel1(n,wavenumber*radius)
        dH1 = h1vp(n,wavenumber*radius,1)
    
        nans = np.isnan(dJ) + np.isnan(H1) + np.isnan(dH1)
    
    dJ = dJ.compress(np.logical_not(nans))
    H1 = H1.compress(np.logical_not(nans))
    dH1 = dH1.compress(np.logical_not(nans))
    neumann = neumann.compress(np.logical_not(nans))
    n = n.compress(np.logical_not(nans))

    total = (-neumann * (1j**n) * dJ * H1 / dH1).reshape(-1,1)

    cosines = np.cos(n.reshape(-1,1)*theta)

    total = total * cosines

    incPotential = np.exp(1j*wavenumber*x).reshape(numPoints)
    fullPotential = np.sum(total,axis=0) + incPotential
    return fullPotential
 def z(self,x):
     'Z(x) equation that keeps showing up in waveguide modes'
     m, n, chi = self.m, self.n, self.root
     return yvp(m,chi,1)*jn(m,x)-jvp(m,chi,1)*yn(m,x)
def rJnp(r,n):
  return (0.5*sqrt(pi/(2*r))*jv(n+0.5,r) + sqrt(pi*r/2)*jvp(n+0.5,r))
 def root_equation(self,m,c,x):
     '''Radial root equation of Phi for TE mode'''
     return yvp(m,x,1)*jvp(m,c*x,1)-jvp(m,x,1)*yvp(m,c*x,1)
Beispiel #54
0
 def rfnd(self, n, x, d):
     return ss.jvp(n,x,d)
Beispiel #55
0
 def E_theta(self, r, theta, z):
     return -(jvp(self.l,k1*r,1])/k1) * np.cos(self.l* theta)*np.sin(k3*z)
	
	
if __name__ == '__main__':
	mesh = [25, 50, 100, 200, 300,500,1000,2000]
	convergence = np.zeros((0,2))
	for nPoints in mesh:
		y = homoCircle(nPoints, 1.0, 2.0, 1.0, 1.0, 1)
		scatMat = y.computeScatteringMatrix(y.Mmax)
	
		analScatMat = np.zeros(2*y.Mmax+1, dtype=complex)
		zc = y.nc*y.k
		zo = y.no*y.k
		eta = y.nc/y.no
		for i in range(2*y.Mmax+1):
			m = i-y.Mmax
			num = -(eta*jvp(m,zc)*hankel2(m,zo)-jn(m,zc)*h2vp(m,zo))
			den = eta*jvp(m,zc)*hankel1(m,zo)-jn(m,zc)*h1vp(m,zo)
			analScatMat[i] = num/den
		err = np.amax(np.abs(np.diag(analScatMat)-scatMat))
		print(err)
		print(analScatMat)

		# -- Mean areas of triangles
		convergence = np.insert(convergence, len(convergence), [np.mean(y.areas), err],axis=0)

	fig1 = plt.figure(figsize=(5,3))
	ax1 = fig1.add_subplot(111)
	plt.plot(convergence[:,0],convergence[:,1], ls='--', marker='o', label=r"Numerical Error")

	p = np.polyfit(np.log(convergence[:,0]),np.log(convergence[:,1]),1)
	ynew = np.exp(np.polyval(p,np.log(convergence[:,0])))
Beispiel #57
0
def coeq(v0, nu, fiber):
    r1, r2 = fiber.rho
    n1, n2, n3 = fiber.n

    na = sqrt(max(fiber.n)**2 - n3**2)
    K0 = v0 / (na * r2)
    beta = K0 * n3

    if n1 > n3:
        u1 = K0**2 * (n1**2 - n3**2)
        s1 = 1
    else:
        u1 = K0**2 * (n3**2 - n1**2)
        s1 = -1
    if n2 > n3:
        u2 = K0**2 * (n2**2 - n3**2)
        s2 = 1
    else:
        u2 = K0**2 * (n3**2 - n2**2)
        s2 = -1
    s = -s1 * s2

    u1r1 = u1 * r1
    u2r1 = u2 * r1
    u2r2 = u2 * r2

    X = (u2r1**2 + s * u1r1**2) * nu * beta
    if s1 == 1:
        Y = jvp(nu, u1r1) / jn(nu, u1r1)
    else:
        Y = ivp(nu, u1r1) / iv(nu, u1r1)

    ju2r1 = jn(nu, u2r1) if s2 == 1 else iv(nu, u2r1)
    nu2r1 = yn(nu, u2r1) if s2 == 1 else kn(nu, u2r1)
    jpu2r1 = jvp(nu, u2r1) if s2 == 1 else ivp(nu, u2r1)
    npu2r1 = yvp(nu, u2r1) if s2 == 1 else kvp(nu, u2r1)
    ju2r2 = jn(nu, u2r2) if s2 == 1 else iv(nu, u2r2)
    nu2r2 = yn(nu, u2r2) if s2 == 1 else kn(nu, u2r2)
    j1u2r2 = jn(nu+1, u2r2)
    n1u2r2 = yn(nu+1, u2r2)

    M = numpy.empty((4, 4))
    M[0, 0] = X * ju2r1
    M[0, 1] = X * nu2r1
    M[0, 2] = -K0 * (jpu2r1 * u1r1 + s * Y * ju2r1 * u2r1) * u1r1 * u2r1
    M[0, 3] = -K0 * (npu2r1 * u1r1 + s * Y * nu2r1 * u2r1) * u1r1 * u2r1
    M[1, 0] = -K0 * (n2**2 * jpu2r1 * u1r1 +
                     s * n1**2 * Y * ju2r1 * u2r1) * u1r1 * u2r1
    M[1, 1] = -K0 * (n2**2 * npu2r1 * u1r1 +
                     s * n1**2 * Y * nu2r1 * u2r1) * u1r1 * u2r1
    M[1, 2] = X * ju2r1
    M[1, 3] = X * nu2r1

    D201 = nu * n3 / u2r2 * (j1u2r2 * nu2r2 - ju2r2 * yn(nu+1, u2r2))
    D202 = -((n2**2 + n3**2) * nu * n1u2r2 * nu2r2 / u2r2 +
             n3**2 * nu * nu2r2**2 / (nu - 1))
    D203 = -(n2**2 * nu * ju2r2 * n1u2r2 / u2r2 +
             n3**2 * nu * nu2r2 * j1u2r2 / u2r2 +
             n3**2 * nu * (j1u2r2 * nu2r2 +
                           n1u2r2 * ju2r2) / (2 * (nu - 1)))
    D212 = -(n2**2 * nu * nu2r2 * j1u2r2 / u2r2 +
             n3**2 * nu * ju2r2 * n1u2r2 / u2r2 +
             n3**2 * nu * (n1u2r2 * ju2r2 +
                           j1u2r2 * nu2r2) / (2 * (nu - 1)))
    D213 = -((n2**2 + n3**2) * nu * j1u2r2 * ju2r2 / u2r2 +
             n3**2 * nu * ju2r2**2 / (nu - 1))
    D223 = nu * n2**2 * n3 / u2r2 * (j1u2r2 * nu2r2 - ju2r2 * n1u2r2)

    D30 = M[1, 1] * D201 - M[1, 2] * D202 + M[1, 3] * D203
    D31 = M[1, 0] * D201 - M[1, 2] * D212 + M[1, 3] * D213
    D32 = M[1, 0] * D202 - M[1, 1] * D212 + M[1, 3] * D223
    D33 = M[1, 0] * D203 - M[1, 1] * D213 + M[1, 2] * D223

    return M[0, 0] * D30 - M[0, 1] * D31 + M[0, 2] * D32 - M[0, 3] * D33
 def z_dash(self,x):
     ''' Z'(x) equation for waveguide mode '''
     m, n, chi = self.m, self.n, self.root
     # jvp(m,x,r) is the rth derivative of the bessel function of order m evaluated at x
     return yn(m,chi)*jvp(m,x,1)-jn(m,chi)*yvp(m,x,1)
def timeDelayEigenfunctionIm(r,m,nc,k):
	eps2 = np.imag(nc*nc)
	return np.imag(-1j*k*eps2*2.0*np.pi*r*r*np.conj(jn(m,nc*k*r))*jvp(m,nc*k*r))
def sMatrixElementCoefficients(k,n1,n2,m):
  A = -n1*hankel2(m,n2*k)*jvp(m,n1*k)+n2*jn(m,n1*k)*h2vp(m,n2*k)
  B = n1*hankel1(m,n2*k)*jvp(m,n1*k)-n2*jn(m,n1*k)*h1vp(m,n2*k)
  Ap = -n1*n1*jvp(m,n1*k,2)*hankel2(m,n2*k)+n2*n2*jn(m,n1*k)*h2vp(m,n2*k,2)
  Bp = n1*n1*jvp(m,n1*k,2)*hankel1(m,n2*k)-n2*n2*jn(m,n1*k)*h1vp(m,n2*k,2)
  return A, B, Ap, Bp