예제 #1
0
def j0zero(s):
    
    """ method that computes root number s, s = 1,2,...,
        of the Besselfunction J0 where zj0 is the root,
        using table-values, asymptotic formulae and Newton-Raphsons method.
        Rellative error app. 1.0e-14 to 1.0e-15
        Args:
            s(integer): solutian array from last iteration

        Returns:
            zj0(float): root No. s of besselfunction
    """
    
    sz = np.array([2.4048225557695773, 5.520078110286311, 8.653727912911012, 11.79153443901428, 14.93091770848779])
    b0 = (s - 0.25)*np.pi
    b08 = 0.125/b0
    b082 = b08**2
    z0 = b0 + b08*(1. - b082*(124./3 -  b082*120928./15))
    
    if s <= 5:
        zj0 = sz[s - 1]
    elif s > 30:
        zj0 = z0
    else:
        dz0 = besselj(0, z0)/besselj(1,  z0)
        z0 = z0 + dz0
        zj0 = z0
    return zj0
예제 #2
0
def j0zero(s):
    """ method that computes root number s, s = 1,2,...,
        of the Besselfunction J0 where zj0 is the root,
        using table-values, asymptotic formulae and Newton-Raphsons method.
        Rellative error app. 1.0e-14 to 1.0e-15
        Args:
            s(integer): solutian array from last iteration

        Returns:
            zj0(float): root No. s of besselfunction
    """

    sz = np.array([
        2.4048225557695773, 5.520078110286311, 8.653727912911012,
        11.79153443901428, 14.93091770848779
    ])
    b0 = (s - 0.25) * np.pi
    b08 = 0.125 / b0
    b082 = b08**2
    z0 = b0 + b08 * (1. - b082 * (124. / 3 - b082 * 120928. / 15))

    if s <= 5:
        zj0 = sz[s - 1]
    elif s > 30:
        zj0 = z0
    else:
        dz0 = besselj(0, z0) / besselj(1, z0)
        z0 = z0 + dz0
        zj0 = z0
    return zj0
예제 #3
0
def hankel_transform(wavefield, max_radius, bessel_zeros, n_zeros=0, multipool=True):
    n = len(wavefield)
    if n_zeros <= 0: n_zeros = n

    wavefield = wavefield.conjugate().T
    m1 = (numpy.abs(besselj(1, bessel_zeros[:n])) / max_radius).conjugate().T
    max_frequency = bessel_zeros[n] / (2 * numpy.pi * max_radius)
    m2 = m1 * max_radius / max_frequency
    f = numpy.divide(wavefield, m1)

    bessel_zeros_nz = bessel_zeros[0:n_zeros]
    bessel_zeros_n  = bessel_zeros[n]
    f_nz            = f[0:n_zeros]
    bessel_jn = numpy.abs(besselj(1, bessel_zeros_nz)) / (2 / bessel_zeros_n)
    bessel_jm = numpy.abs(besselj(1, bessel_zeros))

    if multipool:
        args = __create_args(__N_CPU, bessel_zeros[0:n], bessel_jm[0:n], bessel_zeros_nz, bessel_zeros_n, bessel_jn, f_nz, n)

        p = multiprocessing.Pool(__N_CPU)
        result = numpy.concatenate(p.map(__calculate, args))
        p.close()
    else:
        result = __v_inner_loop(bessel_zeros[0:n], bessel_jm[0:n], bessel_zeros_nz, bessel_zeros_n, bessel_jn, f_nz)

    result = result.conjugate().T
    result = numpy.multiply(result, m2)
    result = result.conjugate().T

    return result
예제 #4
0
def _compute_kernel_2d(R, shape):
    J = np.mgrid[[slice(-(s//2), (s+1)//2) for s in shape]]
    piabsJ = np.pi * np.linalg.norm(J, axis=0)
    Jzero = tuple(s//2 for s in shape)

    K_hat = (2*R)**(-1) * R**2 / (piabsJ**2 - R**2) * (
        1 + 1j*np.pi/2 * (
            piabsJ * besselj(1, piabsJ) * hankel1(0, R) -
            R * besselj(0, piabsJ) * hankel1(1, R)
        )
    )
    K_hat[Jzero] = -1/(2*R) + 1j*np.pi/4 * hankel1(1, R)
    K_hat[piabsJ == R] = 1j*np.pi*R/8 * (
        besselj(0, R) * hankel1(0, R) + besselj(1, R) * hankel1(1, R)
    )
    return 2 * R * fftshift(K_hat)
예제 #5
0
def HankelAccept(wavelength, magfield, thickness, q, Iq, theta, modelname):
#==============================================================================
#     HankelTransform with fixed circular acceptance angle (circular aperture) for Time of Flight SESANS
#==============================================================================
#acceptq is the q-space needed to create limited acceptance effect
    SElength= wavelength*magfield
    G = np.zeros_like(SElength, 'd')
    threshold=2*pi*theta/wavelength
    for i, SElength_i in enumerate(SElength):
        allq=np.linspace() #for calculating the Q-range of the  scattering power integral
        allIq=np.linspace()  # This is the model applied to the allq q-space. Needs to refference the model somehow
        alldq = (allq[1]-allq[0])*1e10
        sigma[i]=wavelength[i]^2*thickness/2/pi*np.sum(allIq*allq*alldq)
        s[i]=1-exp(-sigma)

        dq = (q[1]-q[0])*1e10
        a = (x<threshold)
        acceptq = a*q
        acceptIq = a*Iq

        G[i] = np.sum(besselj(0, acceptq*SElength_i)*acceptIq*acceptq*dq)

#        G[i]=np.sum(integral)

    G *= dq*1e10*2*pi

    P = exp(thickness*wavelength**2/(4*pi**2)*(G-G[0]))
예제 #6
0
def HankelAccept(wavelength, magfield, thickness, q, Iq, theta, modelname):
    #==============================================================================
    #     HankelTransform with fixed circular acceptance angle (circular aperture) for Time of Flight SESANS
    #==============================================================================
    #acceptq is the q-space needed to create limited acceptance effect
    SElength = wavelength * magfield
    G = np.zeros_like(SElength, 'd')
    threshold = 2 * pi * theta / wavelength
    for i, SElength_i in enumerate(SElength):
        allq = np.linspace(
        )  #for calculating the Q-range of the  scattering power integral
        allIq = np.linspace(
        )  # This is the model applied to the allq q-space. Needs to refference the model somehow
        alldq = (allq[1] - allq[0]) * 1e10
        sigma[i] = wavelength[i] ^ 2 * thickness / 2 / pi * np.sum(
            allIq * allq * alldq)
        s[i] = 1 - exp(-sigma)

        dq = (q[1] - q[0]) * 1e10
        a = (x < threshold)
        acceptq = a * q
        acceptIq = a * Iq

        G[i] = np.sum(
            besselj(0, acceptq * SElength_i) * acceptIq * acceptq * dq)


#        G[i]=np.sum(integral)

    G *= dq * 1e10 * 2 * pi

    P = exp(thickness * wavelength**2 / (4 * pi**2) * (G - G[0]))
예제 #7
0
def analyticSolution(r, t, eps):
    """ Method that calculates the analytic solution to the differential equation:
            dw/dt = w'' + w/r, w = w(r,t), 0 < r < 1
            where t is the time.
            The accuracy can be controlled by changing the value of sumtol1, which depicts the
            relative accuracy.
            
        Args:
            r(float): radial coordinat
            t(float): time
            eps(float): numerical tollerance

    
        Returns:
            w(float): velocity, us - ur

    """

    if r == 1:
        w = 0
    elif r < eps and t < eps:
        w = 1
    else:
        # calculate first element seperately
        n = 1
        lam1 = j0zero(n)
        arg1 = r * lam1
        term1 = np.exp(-t * lam1**2) * besselj(
            0, arg1) / (besselj(1, lam1) * lam1**3)
        sum1 = term1
        sumtol = 1 * 10**-8
        test = 1

        while test > sumtol:
            n = n + 1
            lamn = j0zero(n)
            arg = r * lamn
            term = np.exp(-t * lamn**2) * besselj(
                0, arg) / (besselj(1, lamn) * lamn**3)
            sum1 = sum1 + term
            test = np.abs(term / term1)

        w = 8 * sum1

    return w
예제 #8
0
def compute(x, rho, omega, mu):

    R = 0.01
    dpdx = -1
    alpha = R * sqrt(rho * omega / mu)

    numerator = besselj(0, 1j**1.5 * alpha * x / R)
    denominator = besselj(0, 1j**1.5 * alpha)

    bracket = 1 - numerator / denominator
    coefficient = dpdx * 1j / (rho * omega)

    profile = coefficient * bracket
    profile = profile.real
    maxValue = np.amax(profile)
    profile = profile / maxValue

    return profile
예제 #9
0
def analyticSolution(r,t,eps):
    
    """ Method that calculates the analytic solution to the differential equation:
            dw/dt = w'' + w/r, w = w(r,t), 0 < r < 1
            where t is the time.
            The accuracy can be controlled by changing the value of sumtol1, which depicts the
            relative accuracy.
            
        Args:
            r(float): radial coordinat
            t(float): time
            eps(float): numerical tollerance

    
        Returns:
            w(float): velocity, us - ur

    """
    
    if r == 1:
        w = 0
    elif r < eps and t < eps:
        w = 1
    else:
        # calculate first element seperately
        n = 1
        lam1 = j0zero(n)
        arg1 = r*lam1
        term1 = np.exp(-t*lam1**2)*besselj(0,arg1)/(besselj(1,lam1)*lam1**3)
        sum1 = term1
        sumtol = 1*10**-8
        test = 1
        
        while test > sumtol:
            n = n + 1
            lamn = j0zero(n)
            arg = r*lamn
            term = np.exp(-t*lamn**2)*besselj(0,arg)/(besselj(1,lamn)*lamn**3)
            sum1 = sum1 + term
            test = np.abs(term/term1)
        
        w = 8 * sum1
    
    return w
예제 #10
0
def __calculate(args):
    index_i, index_f, c, Bessel_Jn, Bessel_Jm, F, Nzeros, N = args

    H = numpy.full((index_f - index_i), 0j)

    for jj in range(index_i, index_f):
        C = besselj(0, c[:Nzeros] * c[jj] / c[N]) / (Bessel_Jn * Bessel_Jm[jj])
        H[jj - index_i] = numpy.dot(C[:Nzeros], F[:Nzeros])

    return H
예제 #11
0
def Hankel_Transform_MGS(h, R, c, Nzeros=0, multipool=True):
    N = len(h)

    if Nzeros <= 0: Nzeros = N

    V = c[N] / (2 * numpy.pi * R)

    h = h.conjugate().T

    m1 = (numpy.abs(besselj(1, c[0:N])) / R).conjugate().T
    m2 = m1 * R / V

    F = numpy.divide(h, m1)

    Bessel_Jn = numpy.abs(besselj(1, c[0:Nzeros])) / (2 / c[N])
    Bessel_Jm = numpy.abs(besselj(1, c))

    if multipool:
        args = __create_args(__N_CPU, c, Bessel_Jn, Bessel_Jm, F, Nzeros, N)

        p = multiprocessing.Pool(__N_CPU)
        H = numpy.concatenate(p.map(__calculate, args))
        p.close()
    else:
        H = numpy.full(N, 0j)

        for jj in range(0, N):
            C = besselj(
                0, c[0:Nzeros] * c[jj] / c[N]) / (Bessel_Jn * Bessel_Jm[jj])
            H[jj] = numpy.dot(C[0:Nzeros], F[0:Nzeros])

    H = H.conjugate().T
    H = numpy.multiply(H, m2)
    H = H.conjugate().T

    return H
예제 #12
0
def hankel(SElength, wavelength, thickness, q, Iq):
    r"""
    Compute the expected SESANS polarization for a given SANS pattern.

    Uses the hankel transform followed by the exponential.  The values for *zz*
    (or spin echo length, or delta), wavelength and sample thickness should
    come from the dataset.  $q$ should be chosen such that the oscillations
    in $I(q)$ are well sampled (e.g., $5 \cdot 2 \pi/d_{\max}$).

    *SElength* [A] is the set of $z$ points at which to compute the
    Hankel transform

    *wavelength* [m]  is the wavelength of each individual point *zz*

    *thickness* [cm] is the sample thickness.

    *q* [A$^{-1}$] is the set of $q$ points at which the model has been
    computed. These should be equally spaced.

    *I* [cm$^{-1}$] is the value of the SANS model at *q*
    """

    from sas.sascalc.data_util.nxsunit import Converter
    wavelength = Converter(wavelength[1])(wavelength[0], "A")
    thickness = Converter(thickness[1])(thickness[0], "A")
    Iq = Converter("1/cm")(Iq,
                           "1/A")  # All models default to inverse centimeters
    SElength = Converter(SElength[1])(SElength[0], "A")

    G = np.zeros_like(SElength, 'd')
    #==============================================================================
    #     Hankel Transform method if "wavelength" is a scalar; mono-chromatic SESANS
    #==============================================================================
    for i, SElength_i in enumerate(SElength):
        integral = besselj(0, q * SElength_i) * Iq * q
        G[i] = np.sum(integral)
    G0 = np.sum(Iq * q)

    # [m^-1] step size in q, needed for integration
    dq = (q[1] - q[0])

    # integration step, convert q into [m**-1] and 2 pi circle integration
    G *= dq * 2 * pi
    G0 = np.sum(Iq * q) * dq * 2 * np.pi

    P = exp(thickness * wavelength**2 / (4 * pi**2) * (G - G0))

    return P
예제 #13
0
def hankel(SElength, wavelength, thickness, q, Iq):
    r"""
    Compute the expected SESANS polarization for a given SANS pattern.

    Uses the hankel transform followed by the exponential.  The values for *zz*
    (or spin echo length, or delta), wavelength and sample thickness should
    come from the dataset.  $q$ should be chosen such that the oscillations
    in $I(q)$ are well sampled (e.g., $5 \cdot 2 \pi/d_{\max}$).

    *SElength* [A] is the set of $z$ points at which to compute the
    Hankel transform

    *wavelength* [m]  is the wavelength of each individual point *zz*

    *thickness* [cm] is the sample thickness.

    *q* [A$^{-1}$] is the set of $q$ points at which the model has been
    computed. These should be equally spaced.

    *I* [cm$^{-1}$] is the value of the SANS model at *q*
    """

    from sas.sascalc.data_util.nxsunit import Converter
    wavelength = Converter(wavelength[1])(wavelength[0],"A")
    thickness = Converter(thickness[1])(thickness[0],"A")
    Iq = Converter("1/cm")(Iq,"1/A") # All models default to inverse centimeters
    SElength = Converter(SElength[1])(SElength[0],"A")

    G = np.zeros_like(SElength, 'd')
#==============================================================================
#     Hankel Transform method if "wavelength" is a scalar; mono-chromatic SESANS
#==============================================================================
    for i, SElength_i in enumerate(SElength):
        integral = besselj(0, q*SElength_i)*Iq*q
        G[i] = np.sum(integral)
    G0 = np.sum(Iq*q)

    # [m^-1] step size in q, needed for integration
    dq = (q[1]-q[0])

    # integration step, convert q into [m**-1] and 2 pi circle integration
    G *= dq*2*pi
    G0 = np.sum(Iq*q)*dq*2*np.pi

    P = exp(thickness*wavelength**2/(4*pi**2)*(G-G0))

    return P
예제 #14
0
def calc_ftk_svd(n_bessel, eps, pf_grid, tr_grid):
    all_UU = [None] * (2 * n_bessel + 1)
    all_SSVV = [None] * (2 * n_bessel + 1)
    all_rnks = np.zeros(2 * n_bessel + 1, dtype=np.int32)

    xnodesr = pf_grid['xnodesr']
    all_delta = tr_grid['all_delta']
    n_delta = tr_grid['n_delta']
    n_omega = tr_grid['n_omega']
    n_trans = tr_grid['n_trans']

    for qp in range(-n_bessel, n_bessel + 1):
        J_n = besselj(qp, -all_delta[:, np.newaxis] * xnodesr[np.newaxis, :])

        U, S, Vh = np.linalg.svd(J_n)

        ind = S > eps
        rnk = sum(ind)
        all_rnks[qp + n_bessel] = rnk

        all_UU[qp + n_bessel] = U[:, :rnk]
        all_SSVV[qp + n_bessel] = S[:rnk, np.newaxis] * Vh[:rnk, :]

    SSVV_big = np.concatenate(all_SSVV, axis=0)

    UUU = np.concatenate(all_UU, axis=1)

    all_omega = np.concatenate(
        [2 * np.pi / n_om * np.arange(n_om) for n_om in n_omega if n_om > 0])

    all_qp = np.concatenate([(k - n_bessel) * np.ones(n)
                             for k, n in enumerate(all_rnks)])

    vec_omega = np.exp(1j * all_qp[np.newaxis, :] *
                       (all_omega[:, np.newaxis] - np.pi / 2))

    BigMul_left = np.zeros((sum(all_rnks), n_trans), dtype=np.complex128)
    cnt = 0
    for kk in range(n_delta):
        n_om = n_omega[kk]
        BigMul_left[:, cnt:cnt + n_om] = (UUU[kk, :][np.newaxis, :].T *
                                          vec_omega[cnt:cnt + n_om, :].T)
        cnt += n_om

    return all_rnks, BigMul_left, SSVV_big
예제 #15
0
def pointils2(band,wave):
    #VERSION 2 updates for replanned optics (smaller grating footprint)
    gratingsizes = np.array([81., 81., 84.4, 84.4])
    #make function to generate pointils.
    #convolution of grating function with airy function for the relevant band
    deltawave = 1e-6
    [sigma,alpha,beta0,order,fcam] = get_geocarb_gratinginfo(band)
    gratingsize=gratingsizes[band]
    #find central wavelength
    cenwave = 0.5*(wave[len(wave)//2]+wave[len(wave)//2+1])#gratinglambda(sigma,alpha,beta0,m=order)
    #wave=np.arange(0.001*2/deltawave)*deltawave+cenwave-0.001
    #compute beta angles for these wavelengths
    betas = betaangle(wave,sigma,alpha,m=order)

    #FIRST DO GRATING FUNCTION
    #number of illuminated grooves
    Ngrooves = gratingsize*1000./sigma
    #phase shift
    deltaphi = 2*np.pi*sigma/cenwave*(np.sin(betas*dtor)-np.sin(beta0*dtor))
    #total phase shift across grating
    phi = Ngrooves*deltaphi
    inten = 1/Ngrooves**2*(np.sin(phi/2)/np.sin(deltaphi/2))**2
    deltawave = wave-cenwave

    #NOW FOR AIRY FUNCTION
    k  = 2*np.pi/cenwave
    ap = 75./2./2.                   #radius of aperture in mm (extra factor of two from descope)
    bx = k*ap*1000.*np.sin((betas-beta0)*dtor)
    #take into account that beam speed in spectral direction
    #has changed due to grating magnification
    bx = bx*np.cos(beta0*dtor)/np.cos(alpha*dtor)
    airy = (2*besselj(1,bx)/bx)**2
    #pdb.set_trace()
    airy = airy/np.nanmax(airy)
    #diffraction limit FWHM
    diffFWHM = cenwave*3.2*np.sqrt(2)*np.cos(alpha*dtor)/np.cos(beta0*dtor)   

    #POINT ILS IS CONVOLUTION OF GRATING FUNCTION WITH AIRY FUNCTION
    pointils = convolve1d(inten,airy, mode='constant', cval=0.0)
    #pdb.set_trace()
    pointils = pointils/pointils.max()
    return pointils
예제 #16
0
    def _LvN_propagate(self, S, NAC, dt):
        nexp = 7

        Heff = S - ii * NAC
        self._LvN_evals(Heff)

        R = dt * (self.e_max - self.e_min) / 2
        G = dt * self.e_min
        X = -ii * self.dt * Heff / R

        c = np.full((nexp, ), 2)
        c[0] = 1
        phi = [self.rho, np.dot(X, self.rho) - np.dot(self.rho, X)]
        for k in range(2, nexp):
            phi.append(2 * (np.dot(X, phi[k - 1]) - np.dot(phi[k - 1], X)) +
                       phi[k - 2])

        a = [np.exp(ii * (R + G)) * c[k] * besselj(k, R) for k in range(nexp)]

        rho_dt = np.zeros_like(self.rho)
        for k in range(nexp):
            rho_dt += a[k] * phi[k]

        self.rho = rho_dt
예제 #17
0
def calculateEigenPair(a, c0, f, azimuthal_m, radial_n, mode_type, sign=1):
    if mode_type not in {"Kelvin", "Poincare"}:
        raise ValueError("Unknown mode_type: '" + mode_type + "'")

    if sign not in {-1, 1}:
        raise ValueError("Invalid sign: '" + str(sign) + "'")

    if mode_type == 'Kelvin' and sign == 1:
        raise ValueError(
            "Invalid parameter selection. Kelvin modes with clockwise phase propagation do not exist"
        )

    bracket_factor = 2e-2
    eps = 1e-7

    PoincareEqn = lambda sig: (a / np.sqrt(c0**2 / (sig**2 - f**2))) * (
        (1 / azimuthal_m) * besselj(azimuthal_m - 1, a / np.sqrt(c0**2 / (
            sig**2 - f**2))) /
        (a / np.sqrt(c0**2 / (sig**2 - f**2))) * besselj(
            azimuthal_m, a / np.sqrt(c0**2 / (sig**2 - f**2)))) - 1 + (f / sig)

    KelvinEqn = lambda sig: (a / np.sqrt(c0**2 / (f**2 - sig**2))) * (
        (1 / azimuthal_m) * besseli(azimuthal_m - 1, a / np.sqrt(c0**2 / (
            f**2 - sig**2))) /
        (a / np.sqrt(c0**2 / (f**2 - sig**2))) * besseli(
            azimuthal_m, a / np.sqrt(c0**2 / (f**2 - sig**2)))) - 1 + (f / sig)

    # Calculate sigma
    if mode_type == 'Poincare' and sign == 1:
        sig = f
        for n in range(0, radial_n):
            rt = root(PoincareEqn,
                      method="bisect",
                      bracket=[(1 + eps) * sig, (1 + bracket_factor) * sig])
            if rt.root is None:
                print(
                    "Did not find an eigenvalue in expected range for Poincare mode with n="
                    + str(n))
            sig = rt.root
    elif mode_type == 'Poincare' and sign == -1:
        sig = -f
        for n in range(0, radial_n):
            rt = root(PoincareEqn,
                      method="bisect",
                      bracket=[(1 + bracket_factor) * sig, (1 + eps) * sig])
            if rt.root is None:
                print(
                    "Did not find an eigenvalue in expected range for Poincare mode with n="
                    + str(n))
            sig = rt.root
    else:
        sig = -f
        for n in range(
                0, radial_n
        ):  # Can also restrict n's on kelvin mode using Csanady's restriction on S.
            rt = root(KelvinEqn,
                      method="bisect",
                      bracket=[(1 - eps) * sig, -eps])
            if rt.root is None:
                print(
                    "Did not find an eigenvalue in expected range for Kelvin mode with n="
                    + str(n))
            sig = rt.root

    Theta = lambda theta: np.exp(1j * azimuthal_m * theta)
    if mode_type == "Kelvin":
        R = lambda r: besseli(azimuthal_m,
                              np.sqrt((f**2 - sig**2) / c0**2) * r)
    else:
        #Poincare
        R = lambda r: besselj(azimuthal_m,
                              np.sqrt((sig**2 - f**2) / c0**2) * r)

    eigenfunction = lambda r, theta: R(r) * Theta(theta)
    return (sig, (lambda r, theta: eigenfunction(r, theta)))
예제 #18
0
def find_boundary_data(f, dt, xbdy, ybdy, ν, J, κ, M, k_i, k_e):
    '''
    Computes u and du/dv on the boundary by solving the BIE system
    
    Attributes
    ======
    kernel of the double layer, L
    kernel of the single layer, M
    solution on the boundary, u
    normal derivative on the boundary, dvu
    '''
    
    E_C = 0.5772156649015328606065120900824;  # Euler's constant
    N = M / 2;
    m = np.arange(1, N);
    k_ratio = k_e/k_i
    
    # Create array for ifft...
    a = [0]
    a.extend(1/m)
    a.append(1/N)
    a.extend((1/m)[::-1])

    Rj = -2 * np.pi * np.fft.ifft(a);
    R = np.real(toeplitz(Rj, Rj));

    # Prepare arrays for solving integral equation of the boundary (Kress pt. 2)
    L_e = np.zeros((M, M), dtype=complex);
    M_e = np.zeros((M, M), dtype=complex);
    L_i = np.zeros((M, M), dtype=complex);
    M_i = np.zeros((M, M), dtype=complex);
    
    L1_e = np.zeros((M, M), dtype=complex);
    L2_e = np.zeros((M, M), dtype=complex);
    M1_e = np.zeros((M, M), dtype=complex);
    M2_e = np.zeros((M, M), dtype=complex);
    
    L1_i = np.zeros((M, M), dtype=complex);
    L2_i = np.zeros((M, M), dtype=complex);
    M1_i = np.zeros((M, M), dtype=complex);
    M2_i = np.zeros((M, M), dtype=complex);

    A = np.zeros((2*M, 2*M), dtype=complex);
    F = np.zeros(2*M, dtype=complex);
    for m in range(0, M):
        for n in range(0, M):
                rdiff = np.asarray([xbdy[m] - xbdy[n], ybdy[m] - ybdy[n]]);
            distance = sqrt(np.power(rdiff[:][0], 2) + np.power(rdiff[:][1], 2));
            M1_e[m][n] = -0.5 / np.pi * J[n] * besselj(0, k_e * distance);
            M1_i[m][n] = -0.5 / np.pi * J[n] * besselj(0, k_i * distance);
            if m == n:
                #Implementration of the Kress Quadrature
                L1_e[m][n] = 0;
                L2_e[m][n] = 0.5 / np.pi * κ[n] * J[n];
                M2_e[m][n] = J[n] * ( 0.5 * 1j - E_C / np.pi - 0.5 / np.pi * np.log( 0.25 * np.power(k_e, 2) * np.power(J[n], 2)));
                
                L1_i[m][n] = 0;
                L2_i[m][n] = 0.5 / np.pi * κ[n] * J[n];
                M2_i[m][n] = J[n] * ( 0.5 * 1j - E_C / np.pi - 0.5 / np.pi * np.log( 0.25 * np.power(k_i, 2) * np.power(J[n], 2)));
            
            else:
                #Compute cosθ and logterm for kernel calculation
                a = np.asmatrix([ν[0][n], ν[1][n]]);
                b = np.asmatrix(rdiff/distance);
                cosθ = np.asscalar(np.matmul(a, b.transpose()));
                
                logterm = log(float(4 * np.power(sin(0.5 * (m - n) * dt), 2)));
                
                #Compute kernels for the BIE system
                L1_e[m][n] = 0.5 * k_e / np.pi * J[n] * cosθ * besselj(1, k_e * distance);
                L2_e[m][n] = 0.5 * 1j * k_e * J[n] * cosθ * hankel1(1, k_e * distance) - L1_e[m][n] * logterm;
                M2_e[m][n] = 0.5 * 1j * J[n] * hankel1(0, k_e * distance) - M1_e[m][n] * logterm;
                
                L1_i[m][n] = 0.5 * k_i / np.pi * J[n] * cosθ * besselj(1, k_i * distance);
                L2_i[m][n] = 0.5 * 1j * k_i * J[n] * cosθ * hankel1(1, k_i * distance) - L1_i[m][n] * logterm;
                M2_i[m][n] = 0.5 * 1j * J[n] * hankel1(0, k_i * distance) - M1_i[m][n] * logterm;
    
            L_e[m][n] = 0.5 * R[m][n] * (L1_e[m][n]) + 0.5 * (np.pi / N) * (L2_e[m][n]);
            M_e[m][n] = (0.5 * R[m][n] * (M1_e[m][n]) + 0.5 * (np.pi / N) * (M2_e[m][n]));
            
            L_i[m][n] = 0.5 * R[m][n] * (L1_i[m][n]) + 0.5 * (np.pi / N) * (L2_i[m][n]);
            M_i[m][n] = 0.5 * R[m][n] * (M1_i[m][n]) + 0.5 * (np.pi / N) * (M2_i[m][n]);
예제 #19
0
def find_boundary_data(f, B, M, k_i, k_e):
    '''
    Computes the boundary data (trace u and normal derivative dvu) 
    by solving the BIE system using Kress quadrature:
    (I/2 - De) u +  (k_e/k_i Se) dvu = f
    (I/2 + Di) u -        Si     dvu = 0
    
    Parameters
    ==========
    f: source (array)
    B: boundary, lambdified (class)
    M: number of quadrature points on the boundary (even integer)
    k_i: wavenumber interior domain (complex number)
    k_e: wavenumber exterior domain (complex number)
    
    Returns
    ==========
    u: solution on the boundary (array)
    dvu: normal derivative of the solution on the boundary (array)
    '''
    #Define the boundary features
    dt = 2.0 * np.pi / (M)
    θ = np.arange(0, 2 * np.pi, dt)
    x = B.y_l(θ)[0][:]
    y = B.y_l(θ)[1][:]
    ν = B.ν_l(θ)
    J = B.J_l(θ)
    κ = B.κ_l(θ)

    #Define other parameters
    k_ratio = k_e / k_i
    E_C = np.euler_gamma  # Euler's constant
    N = M / 2
    m = np.arange(1, N)

    # Create array for ifft
    a = [0]
    a.extend(1 / m)
    a.append(1 / N)
    a.extend((1 / m)[::-1])

    Rj = -2 * np.pi * np.fft.ifft(a)
    R = np.real(toeplitz(Rj, Rj))

    # Prepare arrays for solving integral equation of the boundary (Kress pt. 2)
    A = np.zeros((2 * M, 2 * M), dtype=complex)
    F = np.zeros(2 * M, dtype=complex)

    cosθ_mn = np.zeros((M, M), dtype=complex)
    logterm_mn = np.zeros((M, M), dtype=complex)

    besselj_0e_mn = np.zeros((M, M), dtype=complex)
    besselj_1e_mn = np.zeros((M, M), dtype=complex)
    hankel1_0e_mn = np.zeros((M, M), dtype=complex)
    hankel1_1e_mn = np.zeros((M, M), dtype=complex)

    besselj_0i_mn = np.zeros((M, M), dtype=complex)
    besselj_1i_mn = np.zeros((M, M), dtype=complex)
    hankel1_0i_mn = np.zeros((M, M), dtype=complex)
    hankel1_1i_mn = np.zeros((M, M), dtype=complex)

    logterm_o = {}
    for i in range(-M, M):
        if i != 0:
            logterm_o[i] = log(float(4 * np.power(np.sin(0.5 * i * dt), 2)))

    for m in range(0, M):
        for n in range(0, M):
            rdiff = np.asarray([x[m] - x[n], y[m] - y[n]])
            r_distance = sqrt(rdiff[:][0]**2 + rdiff[:][1]**2)
            besselj_0e_mn[m, n] = besselj(0, k_e * r_distance)
            besselj_0i_mn[m, n] = besselj(0, k_i * r_distance)
            if m != n:
                cosθ_mn[m, n] = ν[0][n] * (rdiff[0] / r_distance) + ν[1][n] * (
                    rdiff[1] / r_distance)
                logterm_mn[m, n] = logterm_o[m - n]

                besselj_1e_mn[m, n] = besselj(1, k_e * r_distance)
                hankel1_1e_mn[m, n] = hankel1(1, k_e * r_distance)
                hankel1_0e_mn[m, n] = hankel1(0, k_e * r_distance)

                besselj_1i_mn[m, n] = besselj(1, k_i * r_distance)
                hankel1_1i_mn[m, n] = hankel1(1, k_i * r_distance)
                hankel1_0i_mn[m, n] = hankel1(0, k_i * r_distance)

    #Compute kernels of exterior of boundary
    L1_e = 0.5 * k_e / np.pi * J * cosθ_mn * besselj_1e_mn
    L2_e = 0.5 * 1j * k_e * J * cosθ_mn * hankel1_1e_mn - L1_e * logterm_mn
    M1_e = -0.5 / np.pi * J * besselj_0e_mn
    M2_e = 0.5 * 1j * J * hankel1_0e_mn - M1_e * logterm_mn

    # Usage of Kress Quadrature
    diag = np.arange(0, M)
    M2_e[diag,
         diag] = J * (0.5 * 1j - E_C / np.pi - 0.5 / np.pi * np.log(0.25 *
                                                                    (k_e**2) *
                                                                    (J**2)))
    L1_e[diag, diag] = 0
    L2_e[diag, diag] = 0.5 / np.pi * κ * J

    L_e = 0.5 * R * L1_e + 0.5 * (np.pi / N) * L2_e
    M_e = 0.5 * R * M1_e + 0.5 * (np.pi / N) * M2_e

    #Calculate kernels of interior of boundary
    L1_i = 0.5 * k_i / np.pi * J * cosθ_mn * besselj_1i_mn
    L2_i = 0.5 * 1j * k_i * J * cosθ_mn * hankel1_1i_mn - L1_i * logterm_mn
    M1_i = -0.5 / np.pi * J * besselj_0i_mn
    M2_i = 0.5 * 1j * J * hankel1_0i_mn - M1_i * logterm_mn

    #Replace diagonals where m=n with exception cases
    L1_i[diag, diag] = 0
    L2_i[diag, diag] = 0.5 / np.pi * κ * J
    M2_i[diag,
         diag] = J * (0.5j - E_C / np.pi - 0.5 / np.pi * np.log(0.25 *
                                                                (k_i**2) *
                                                                (J**2)))

    L_i = 0.5 * R * L1_i + 0.5 * (np.pi / N) * L2_i
    M_i = 0.5 * R * M1_i + 0.5 * (np.pi / N) * M2_i

    #Matrix of combined representation formulas
    A11 = 0.5 * np.identity(M) - L_e
    A12 = k_ratio * M_e
    A21 = 0.5 * np.identity(M) + L_i
    A22 = -M_i

    #Combine A's into one matrix, A
    A[0:M, 0:M] = A11
    A[0:M, M:2 * M] = A12
    A[M:2 * M, 0:M] = A21
    A[M:2 * M, M:2 * M] = A22

    #Make matrix for f and 0's, call it F
    F[0:M] = f

    #Solve for u and dvu from AU = F
    U = np.linalg.solve(A, F)
    u = U[0:M]
    dvu = U[M:2 * M]
    return u, dvu
예제 #20
0
    def fanNoise(self, S, theta, Thrust, power_Watts):
        """      
      Inputs
        1.S           - distance from observer location to noise source [m]
        2.theta       - angle from thrust direction to observer location [rad]
        2.Thrust      - thrust [N]
        3.power_watts - power in watts, from a SINGLE rotor

      Calculates and stores:
        spl - Sound pressure level in dB
      """

        NtoLb = 0.224809  # Newtons to lb
        WtoHp = 0.00134102  # Watts to hp
        #        m2f   = 1.0/0.3048         # meters to feet
        Pref = 0.0002  # dynes/cm^2
        k = 6.1e-27  # proportionality constant

        # Average blade CL
        CL = 6 * self.ctsigma  # Ct / geom.solidity

        # Thrust in pounds
        T_lb = Thrust * NtoLb

        # Parameters
        VTip = self.tipspeed  # tip speed, m/s
        S_ft = S * m2f  # Distance to source in ft
        R_ft = self.radius * m2f  # Radius in ft
        A_ft2 = self.area * m2f * m2f  # Disc area in ft^2
        P_Hp = power_Watts * WtoHp  # Power in Hp
        M_t = VTip / self.ainf  # tip mach number
        A_b = A_ft2 * self.solidity  # blade area, sq. ft

        #        print(self.power*0.001)
        #        print(self.solidity)
        #        print(S_ft, R_ft, A_ft2, P_Hp, M_t, A_b)
        #        quit()
        # Compute rotational noise
        m_max = 10  # Maximum harmonic number
        p_m = numpy.zeros(m_max)
        for m in range(1, m_max + 1):
            p_m[m-1] = 169.3 * m * self.nblade * R_ft * M_t / (S_ft * A_ft2) *       \
                      (0.76 * P_Hp / M_t**2 - T_lb * cos(theta)) *              \
                        besselj(m * self.nblade, 0.8 * M_t * m * self.nblade * sin(theta))

# Compute total RMS sound pressure level in dynes/cm^2 = 0.1 Pa
        p = numpy.sqrt(numpy.sum(numpy.square(p_m)))

        # Convert to SPL in dB's
        SPL_rotational = 20 * numpy.log10(p / Pref)

        # Vortex Noise (pg. 11)
        # SPL = 10 * log(k * A_b * V_0.7^6 / 10^-16) + 20 * log(CL/0.4) [dB at 300 ft]
        # where
        # k = constant of proportionality = 6.1e-27
        # k/1e-16 = 6.1e-11
        # A_b = propeller blade area [ft^2]
        # V_0.7 = velocity at 0.7 * radius

        #        SPL_vortex  = 10 * log10(k * A_b * (0.7 * VTip)**6 / 1e-16) + 20 * log10(CL / 0.4)
        SPL_vortex = 10 * log10(6.1e-11 * A_b *
                                (0.7 * VTip)**6) + 20 * log10(CL / 0.4)

        # Total noise
        # Adding atmospheric attenuation of 6 dB for every doubling of distance from reference
        spl = 10 * log10(10**(SPL_rotational / 10) + 10**
                         (SPL_vortex / 10)) - 6 * log2(S_ft / 300)

        return spl
예제 #21
0
def getlhs(W,M): return M


# define the PDE
pde = pde.Parabolic(NComponents = 2, Mesh = mesh, StiffMat = a.globalStiffMat, MassMat = a.globalMassMat)
pde.setNeumannFunc = gNeumann
pde.setSrcFunc = fsrc
pde.AssembBlockStiffMat = makeBlockMat
pde.AssembBlockMassMat = makeBlockMat
pde.AssembLHS = getlhs
import linsolv
W_free = makeBlockMat(pde.getFreeNodeArray(W))

# initial condition (bessel perturbation)
#J_m (k_mn * r) * Cos(theta) written in cartesian co-ordinates
f0 = [lambda p: c_10 + 0.03*c_10 * besselj(m, k_mn * np.sqrt(p[0]**2 + p[1]**2)) * p[0]/(1e-4 + np.sqrt(p[0]**2 + p[1]**2)),
      lambda p: c_20 + 0.03*c_20 * besselj(m, k_mn * np.sqrt(p[0]**2 + p[1]**2)) * p[0]/(1e-4 + np.sqrt(p[0]**2 + p[1]**2))]
        
u0 = np.zeros([mesh.NumNodes,2])
for i, node in enumerate(mesh.Nodes): 
        u0[i,0] = f0[0](node)
        u0[i,1] = f0[1](node)
        
# start time loop 
np.savetxt(outfile_fmt % 0, u0)
dt = 1e-4
        
print "dt = ", dt 
print "Mesh size = ", mesh.Diam
raw_input('Press any key to start time loop')
        
예제 #22
0
def __inner_loop_single_iteration(bessel_zeros_jj, bessel_jm_jj, bessel_zeros_nz, bessel_zeros_n, bessel_jn, f_nz):
    return numpy.dot(besselj(0, bessel_zeros_nz * bessel_zeros_jj / bessel_zeros_n) / (bessel_jn * bessel_jm_jj),
                     f_nz)
예제 #23
0
clf()
subplot(211)  # plot the SANS calculation
plot(q, I, 'k')
loglog(q, I)
xlim([0.01, 1])
ylim([1, 1e9])
xlabel(r'$Q [nm^{-1}]$')
ylabel(r'$d\Sigma/d\Omega [m^{-1}]$')

# Hankel transform to nice range for plot
nz = 61
zz = linspace(0, 240, nz)
# [nm], should be less than reciprocal from q
G = zeros(nz)
for i in range(len(zz)):
    integr = besselj(0, q * zz[i]) * I * q
    G[i] = sum(integr)
G = G * dq * 1e9 * 2 * pi
# integr step, conver q into [m**-1] and 2 pi circle integr
# plot(zz,G);
stt = th * Lambda**2 / 4 / pi / pi * G[
    0]  # scattering power according to SANS formalism
PP = exp(th * Lambda**2 / 4 / pi / pi * (G - G[0]))

subplot(212)
plot(zz, PP, 'k', label="Hankel transform")  # Hankel transform 1D
xlabel('spin-echo length [nm]')
ylabel('polarisation normalised')
hold(True)

# Cosine transformation of 2D scattering patern
예제 #24
0
opts = dict()

# --------------------------------------------------------------------------
# find phase factors

opts["criteria"] = criteria
max_order = ceil(1.4 * tau + np.log(1e14))
if np.mod(max_order, 2) == 1:
    max_order -= 1

# --------------------------------------------------------------------------
# even part

coeff = np.zeros((max_order // 2 + 1, 1))
for i in range(len(coeff)):
    coeff[i] = (-1)**(i) * besselj(2 * i, tau)

coeff[0] /= 2
[phi1, out1] = QSP_Solver(coeff, 0, opts)

print("- Info: \t\tQSP phase factors --- solved by L-BFGS\n")
print("- Parity: \t\t%s\n- Degree: \t\t%d\n", "even", max_order)
print("- Iteration times: \t%d\n", out1["iter"])
print("- CPU time: \t%.1f s\n", out1["time"])

#--------------------------------------------------------------------------
# odd part

coeff = np.zeros((max_order / 2 + 1, 1))
for i in range(len(coeff)):
    coeff[i] = (-1)**(i) * besselj(2 * i + 1, tau)
예제 #25
0
clf()
subplot(211)  # plot the SANS calculation
plot(q,I,'k')
loglog(q,I)
xlim([0.01, 1])
ylim([1, 1e9])
xlabel(r'$Q [nm^{-1}]$')
ylabel(r'$d\Sigma/d\Omega [m^{-1}]$')


# Hankel transform to nice range for plot
nz=61;
zz=linspace(0,240,nz); # [nm], should be less than reciprocal from q
G=zeros(nz);
for i in range(len(zz)):
    integr=besselj(0,q*zz[i])*I*q;
    G[i]=sum(integr);
G=G*dq*1e9*2*pi; # integr step, conver q into [m**-1] and 2 pi circle integr
# plot(zz,G);
stt= th*Lambda**2/4/pi/pi*G[0]  # scattering power according to SANS formalism
PP=exp(th*Lambda**2/4/pi/pi*(G-G[0]));

subplot(212)
plot(zz,PP,'k',label="Hankel transform") # Hankel transform 1D
xlabel('spin-echo length [nm]')
ylabel('polarisation normalised')
hold(True)

# Cosine transformation of 2D scattering patern
if False:
    qy,qz = meshgrid(q,q)
예제 #26
0
    def compute_oof(self, array, radii):
        array = array.astype(np.double)
        shape = array.shape
        output = np.zeros(shape)
        self.check_normalization(radii)
        imgfft = fft(array)
        x, y, z, sphere_radius = get_min_sphere_radius(shape, self.spacing)

        for radius in tqdm(radii):
            tqdm.write(f'Computing radius {radius:.3f}...')
            circle = circle_length(radius)
            nu = 1.5
            z = circle * EPSILON
            bessel = besselj(nu, z) / EPSILON**(3 / 2)
            base = radius / np.sqrt(2 * radius * self.sigma - self.sigma**2)
            exponent = self.normalization_type
            volume = get_sphere_volume(radius)
            normalization = volume / bessel / radius**2 * base**exponent

            exponent = -self.sigma**2 * 2 * np.pi**2 * sphere_radius**2
            num = normalization * np.exp(exponent)
            den = sphere_radius**(3 / 2)
            besselj_buffer = num / den

            cs = circle * sphere_radius
            a = np.sin(cs) / cs - np.cos(cs)
            b = np.sqrt(1 / (np.pi**2 * radius * sphere_radius))
            besselj_buffer = besselj_buffer * a * b * imgfft

            outputfeature_11 = np.real(ifft(x * x * besselj_buffer))
            outputfeature_12 = np.real(ifft(x * y * besselj_buffer))
            outputfeature_13 = np.real(ifft(x * z * besselj_buffer))
            outputfeature_22 = np.real(ifft(y * y * besselj_buffer))
            outputfeature_23 = np.real(ifft(y * z * besselj_buffer))
            outputfeature_33 = np.real(ifft(z * z * besselj_buffer))

            eigenvalues = eigenvalue_field33(
                outputfeature_11, outputfeature_12, outputfeature_13,
                outputfeature_22, outputfeature_23, outputfeature_33)
            lambda_1, lambda_2, lambda_3 = eigenvalues

            maxe = np.copy(lambda_1)
            mine = np.copy(lambda_1)
            mide = maxe + lambda_2 + lambda_3

            if self.use_absolute:
                maxe[np.abs(lambda_2) > np.abs(maxe)] = lambda_2[
                    np.abs(lambda_2) > np.abs(maxe)]
                mine[np.abs(lambda_2) < np.abs(mine)] = lambda_2[
                    np.abs(lambda_2) < np.abs(mine)]

                maxe[np.abs(lambda_3) > np.abs(maxe)] = lambda_3[
                    np.abs(lambda_3) > np.abs(maxe)]
                mine[np.abs(lambda_3) < np.abs(mine)] = lambda_3[
                    np.abs(lambda_3) < np.abs(mine)]
            else:
                maxe[lambda_2 > np.abs(maxe)] = lambda_2[
                    lambda_2 > np.abs(maxe)]
                mine[lambda_2 < np.abs(mine)] = lambda_2[
                    lambda_2 < np.abs(mine)]

                maxe[lambda_3 > np.abs(maxe)] = lambda_3[
                    lambda_3 > np.abs(maxe)]
                mine[lambda_3 < np.abs(mine)] = lambda_3[
                    lambda_3 < np.abs(mine)]

            mide -= maxe + mine

            if self.response_type == 0:
                tmpfeature = maxe
            elif self.response_type == 1:
                tmpfeature = maxe + mide
            elif self.response_type == 2:
                tmpfeature = np.sqrt(np.maximum(0, maxe * mide))
            elif self.response_type == 3:
                tmpfeature = np.sqrt(
                    np.maximum(0, maxe * mide) * np.maximum(0, mide))
            elif self.response_type == 4:
                tmpfeature = np.maximum(0, maxe)
            elif self.response_type == 5:
                tmpfeature = np.maximum(0, maxe + mide)

            stronger_response = np.abs(tmpfeature) > np.abs(output)
            output[stronger_response] = tmpfeature[stronger_response]
        return output
예제 #27
0
else:
    dia = float(input('Diameter of driver in mm : '))
    f = float(input('Frequency of interested in Hz : '))
#
c = 345.0
rho_a = 1.2
phi = arange(-1 * pi / 2.0, pi / 2.0 + pi / 1800.0, pi / 1800.0)
phi = phi[
    1:
    1800]  # Is this a bug? it's shifted to the right, past the end of the array.
#
a = dia / 1000.0
theta = arange(pi / 1800.0, pi, pi / 1800.0)
k = (2 * pi * f) / c
#
dir = 2 * divide(besselj(k * a, sin(theta)), (k * a * sin(theta)))
#
p = divide(dir, max(dir))
q = 20.0 * log10(p)
#
#p_s=[phi' p'];
q_s = (transpose(phi), transpose(q))
#
#Dirplot(q_s(:,1)*180/pi,q_s(:,2),'r-',[0 -30 5]);
ax = plt.subplot('111', projection='polar')
ax.plot(q_s[0], q_s[1], 'r-')

ax.set_rticks(range(-30, 1, 6))
ax.set_theta_offset(pi / 2.0)
ax.set_thetalim(thetamin=90, thetamax=-90)
ax.set_theta_direction(-1)