Esempio n. 1
0
def test_algebraic():
    assert round(getPhi(1, 2), 4) == 1.1071, "bad getPhi result at (1,2)"
    assert round(getPhi(1, 0), 4) == 0.0, "bad getPhi result at (1,0)"
    assert round(getPhi(-1, 0), 4) == 3.1416, "bad getPhi result at (-1,0)"
    assert round(getPhi(0, 0), 4) == 0.0, "bad getPhi result at (0,0)"

    assert round(arccosSTABLE(2), 4) == 0.0, "bad arccosStable at (2)"
    assert round(arccosSTABLE(-2), 4) == 3.1416, "bad arccosStable at (-2)"

    assert all(fastCross3D([1, 2, 3], [3, 2, 1]) == array(
        [-4, 8, -4])), "bad fastCross3D"

    assert round(fastSum3D([2.3, 5.6, 2.0]), 2) == 9.90, "bad fastSum3D"

    assert round(fastNorm3D([58.2, 25, 25]), 4) == 68.0973, "bad fastNorm3D"
Esempio n. 2
0
def Bfield_CircularCurrentLoop(i0, d0, pos):

    px, py, pz = pos

    r = sqrt(px**2 + py**2)
    phi = getPhi(px, py)
    z = pz

    r0 = d0 / 2  # radius of current loop

    # avoid singularity at CL
    #    print('WARNING: close to singularity - setting field to zero')
    #    return array([0,0,0])
    rr0 = r - r0
    if (-1e-12 < rr0 and rr0 <
            1e-12):  # rounding to eliminate the .5-.55 problem when sweeping
        if (-1e-12 < z and z < 1e-12):
            warn('Warning: getB Position directly on current line',
                 RuntimeWarning)
            return array([NaN, NaN, NaN])

    deltaP = sqrt((r + r0)**2 + z**2)
    deltaM = sqrt((r - r0)**2 + z**2)
    kappa = deltaP**2 / deltaM**2
    kappaBar = 1 - kappa

    # avoid discontinuity at r=0
    if (-1e-12 < r and r < 1e-12):
        Br = 0.
    else:
        Br = -2 * 1e-4 * i0 * (
            z / r / deltaM) * (ellipticK(kappaBar) - (2 - kappaBar) /
                               (2 - 2 * kappaBar) * ellipticE(kappaBar))
    Bz = -2 * 1e-4 * i0 * (1 /
                           deltaM) * (-ellipticK(kappaBar) +
                                      (2 - kappaBar - 4 * (r0 / deltaM)**2) /
                                      (2 - 2 * kappaBar) * ellipticE(kappaBar))

    # transfer to cartesian coordinates
    Bcy = array([Br, 0., Bz]) * 1000.  # mT output
    T_Cy_to_Kart = array([[cos(phi), -sin(phi), 0], [sin(phi),
                                                     cos(phi), 0], [0, 0, 1]])
    Bkart = T_Cy_to_Kart.dot(Bcy)

    return Bkart
Esempio n. 3
0
def Bfield_Cylinder(MAG, pos, dim, Nphi0):  # returns arr3

    D, H = dim  # magnet dimensions
    R = D / 2

    x, y, z = pos  # relative position
    r, phi = sqrt(x**2 + y**2), getPhi(x, y)  # cylindrical coordinates

    # Mag part in z-direction
    B0z = MAG[2]  # z-part of magnetization
    zP, zM = z + H / 2., z - H / 2.  # some important quantitites
    Rpr, Rmr = R + r, R - r

    # special cases:
    #   0. volume cases      no quantities are zero
    #   1. on surfaces:      one quantity is zero
    #   2. on edge lines:    two quantities are zero
    CASE = 0
    for case in array([Rmr, zP, zM]):
        if (case < 1e-15 and -1e-15 < case):
            CASE += 1
    # rounding is required to catch numerical problem cases like .5-.55=.05000000000000001
    #   which then result in 'normal' cases but the square eliminates the small digits

    # edge cases ----------------------------------------------
    if CASE == 2:
        warn('Warning: getB Position directly on magnet surface',
             RuntimeWarning)
        return array([NaN, NaN, NaN])

    # on-magnet surface cases----------------------------------
    elif CASE == 1:
        if Rmr == 0:  # on cylinder surface
            if abs(z) < H / 2:  # directly on magnet
                warn('Warning: getB Position directly on magnet surface',
                     RuntimeWarning)
                return array([NaN, NaN, NaN])
        else:  # on top or bottom surface
            if Rmr > 0:  # directly on magnet
                warn('Warning: getB Position directly on magnet surface',
                     RuntimeWarning)
                return array([NaN, NaN, NaN])

    # Volume Cases and off-magnet surface cases----------------

    SQ1 = sqrt(zP**2 + Rpr**2)
    SQ2 = sqrt(zM**2 + Rpr**2)

    alphP = R / SQ1
    alphM = R / SQ2
    betP = zP / SQ1
    betM = zM / SQ2
    kP = sqrt((zP**2 + Rmr**2) / (zP**2 + Rpr**2))
    kM = sqrt((zM**2 + Rmr**2) / (zM**2 + Rpr**2))
    gamma = Rmr / Rpr

    # radial field
    Br_Z = B0z * (alphP * elliptic(kP, 1, 1, -1) -
                  alphM * elliptic(kM, 1, 1, -1)) / pi
    Bx_Z = Br_Z * cos(phi)
    By_Z = Br_Z * sin(phi)

    # axial field
    Bz_Z = B0z * R / (Rpr) * (betP * elliptic(kP, gamma**2, 1, gamma) -
                              betM * elliptic(kM, gamma**2, 1, gamma)) / pi

    Bfield = array([Bx_Z, By_Z, Bz_Z])  # contribution from axial magnetization

    # Mag part in xy-direction requires a numeical algorithm
    B0xy = sqrt(MAG[0]**2 + MAG[1]**2)  # xy-magnetization amplitude
    if B0xy > 0:

        tetta = arctan2(MAG[1], MAG[0])
        gamma = arctan2(y, x)
        phi = gamma - tetta

        phi0s = 2 * pi / Nphi0  # discretization

        rR2 = 2 * r * R
        r2pR2 = r**2 + R**2

        def I1x(phi0, z0):
            if r2pR2 - rR2 * cos(phi - phi0) == 0:
                return -1 / 2 / (z - z0)**2
            else:
                G = 1 / sqrt(r2pR2 - rR2 * cos(phi - phi0) + (z - z0)**2)
                return (z - z0) * G / (r2pR2 - rR2 * cos(phi - phi0))

        #USE VECTORIZED CODE FOR THE SUMMATION !!!!

        # radial component
        Br_XY = B0xy * R / 2 / Nphi0 * sum([
            Sphi(n, Nphi0) * cos(phi0s * n) * (r - R * cos(phi - phi0s * n)) *
            (I1x(phi0s * n, -H / 2) - I1x(phi0s * n, H / 2))
            for n in arange(Nphi0 + 1)
        ])

        # angular component
        Bphi_XY = B0xy * R**2 / 2 / Nphi0 * sum([
            Sphi(n, Nphi0) * cos(phi0s * n) * sin(phi - phi0s * n) *
            (I1x(phi0s * n, -H / 2) - I1x(phi0s * n, H / 2))
            for n in arange(Nphi0 + 1)
        ])

        # axial component
        Bz_XY = B0xy * R / 2 / Nphi0 * sum([
            sum([(-1)**k * Sphi(n, Nphi0) * cos(phi0s * n) /
                 sqrt(r2pR2 - rR2 * cos(phi - phi0s * n) + (z - z0)**2)
                 for z0, k in zip([-H / 2, H / 2], [1, 2])])
            for n in arange(Nphi0 + 1)
        ])

        # translate r,phi to x,y coordinates
        phi = gamma
        Bx_XY = Br_XY * cos(phi) - Bphi_XY * sin(phi)
        By_XY = Br_XY * sin(phi) + Bphi_XY * cos(phi)

        Bfield = Bfield + array([Bx_XY, By_XY, Bz_XY])

        # add M if inside the cylinder to make B out of H
        if r < R and abs(z) < H / 2:
            Bfield += array([MAG[0], MAG[1], 0])

    return Bfield